Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.6k views
in Technique[技术] by (71.8m points)

How does one apply a one way decrease in opacity along a curved line geometry in three.js?

I've tried making replacing the material with an image of a gradient but that did not work, I've also looked into vertex shaders but those seemed to use inputs from the scene while rendering to change the color where as I just want one constant effect.

I also tried seeing if I could manually set an opacity for each point on the curve but there didn't seem to be a way to do that either.

Here's the section of code that make the ellipses, don't mind some of the specific variables in use, it's part of a project I've been working on for a while.

        var curve = new THREE.EllipseCurve(
            foci(1000 * earth_barycenter.Data[9] * base.a, semiminor(1000 * earth_barycenter.Data[9] * base.a, base.e)), 0,            // where the middle is
            1000 * earth_barycenter.Data[9] * base.a, semiminor(1000 * earth_barycenter.Data[9] * base.a, base.e),           // xRadius, yRadius
            0, 2 * Math.PI,  // aStartAngle, aEndAngle
            false,            // aClockwise
            0                 // aRotation
        );
        var material = color
        var geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(points))
        var orbit = new THREE.Line(geometry, material);
        scene.add(orbit);

The effect I'm going for is pretty much this: space engine screenshot

And this is what I currently have: my project


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a few ways to do this, I can describe how I see this working using the fragment shader.

You are right that shaders need input from the scene to animate, you can input time to make it consistently animate without worrying about user input. After you add time as uniform to your material, you can have a global or something called time, set it to zero, then in your update or animate function you can:

    time += 0.001;
    material.uniforms.time.value = time;

Then the rings are full meshes with no moving parts, like just like a basic ring, then in the fragment shader you pass in time and you just assign the output color like this:

vec4 color = vec4(1, 1, 1, mod(uv.x+time,1.0)); // the alpha value is the last one

then you just have to make sure the the UVs on your ring are set up that x axis is along the parameter and the y axis is the radius. I am not sure how three.js lays out the UVs for the line mesh, but you can make something like this in a 3d modeling software and set the UVs yourself. This might be too much of a pain if you aren't familiar with 3d modeling. If this seems like too much for right now, I'd suggest using a gradient texture upon the 3d model, and rotating it. Maybe update your question with what went wrong when you tried that. In working with three.js I always advise not shying away from getting 3d models from elsewhere and loading them in, for me, it usually is a faster way to get the desired effect.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...