How to make a Line2 fading out shader


I have an mapbox map where I have a three js layer, the way it is set up I can’t use world positions, everything is relative to the center point, although this is not a problem right now. I want to add a line based on real world coordinates and I have managed this, a Line2 that looks as it should. My problem is I want to make the “tail” part of it fade out. How would I make a shader to do this? I have managed to fade out each line segment but that does not look as nice because some segments at longer the others and the hard transition from one segment to another. I want it to be smooth the entire way, any easy shader for this?

Best Regards

What do you mean by fade out? Do you mean thinning of the line width or do you mean fade out color wise but maintaining the the width of the line?

If you want thinning, you may want to take a look at THREE.Meshline, it has thinning built-in and the package is quite thin (the repository is not really maintained at the moment but it might work for you).

Otherwise maybe you could try using fog to fade out lines in the distance? It’s probably the easiest way to fade out lines in the distance.

You can pretty easily change the color of each line vertex, so the line will have color gradient running along it.

If you need the color to fade out via transparency, you could use vertexAlphas parameter for the material, and assign 4 component colors to vertices but I think it works only for meshes and not implemented for lines yet. Instead of lines you could use thin cylinders.

Hello! Thank you for both of you for quick answers! What I want is a line where the start of it has opacity 1 and the end of it has opacity 0. It should be. Anime smooth fading transition for the opacity for the entire length of the line. I have managed to do this per vertex but it did not look good as some vertexes are longer then others. Between two vertexes there is one segment.

What do you mean by using small cylinders? Would that solve this problem? My other thought would that not slow performance down?

EDIT: Fog won’t really work because the line can get back and forth. I will attach a picture soon that explains more what I mean.

Edit 2:

@tfoller @jacopocolo
This is what I mean, I have a line here, when the green marker is that is where the “start point” is, I want the opacity to be 1 there, at the end of the line, after following it all the way, in the end kinda next to the marker I want the opacity to be 0, between I want a smooth transition the entire way, any easy way to do this?

Call .computeLineDistances() on your geometry for fat lines, then process distances in shaders of LineMaterial.
But from my experience, Fat Lines and transparency is not a good combination, as the result may be not what you expect.

I am sorry, I don’t really follow, could you provide and example?

The following code from three.js/webxr_vr_cubes example shows a line that gradually vanishes.


Not sure if that can be used as a starting point.

This is how you can make anything to change smoothly along a polygon:

smooth contains the amount of total distance at each point and runs from 0 to 1.

This won’t work for transparency, the library doesn’t have a built-in support for it, so you need to write a custom shader (ShaderMaterial) to pass smooth as a uniform to each vertex. Not super hard to do.

If you need “thick” lines then you have to use some 3d geometry for each line segment, not just a line, and colorize vertices at the beginning and the end of that geometry piece accordingly.

First, it’s a handful, second, as prisoner849 noticed, it might not look nice as the connection points between these pieces, especially when they are transparent, won’t match perfectly and their walls will overlay on top of each other.

To make it look good you need a custom geometry generator and a custom shader, so I’d say no easy way to do it.

The dist contains only the vertexes correct? I have managed to make each vertex less and less transparent, but I want this transition to happen smoothly and therefor I would like to do it via the fragmentshader, but I have not found a good way for this.

As you can see in this picture I have managed to do this but here the opacity changes at each vertex, I want the transition to be smooth along the entire line.

dist in that example is the distance of each vertex from the beginning of the line counted along the line, smooth maps that distance to the range of [0, 1], so if you pass smooth as an attribute to the vertex shader and use interpolated value in the fragment shader it will be your transparency.

The biggest problem here is to make a geometry for the thick line. The line you have on your image, do you have a code for it to show via jsfiddle or codepen?

Is this line 2D or 3D?
Do you rotate camera around it?

I am starting to understand now, you have the length of each vertex and then you have a transparency for the start and end for each vertex and with the length it can calculate for each pixel? But still how do you know how “far along the line” you are? Is this correct? I am sorry if I misunderstand, I am new to shaders.

Yes, this is 3d, you can rotate around it and the line can go in x, y and z. It would be really hard to isolate the code into a jsfiddle/codepen because the project is huge and in a lot of files, however I can try to send the parts that matter. The line is generated based on real world coordinates. I am using a 3d mapbox world with a three js layer on top of it.

EDIT: what I don’t understand is how do I do the interpolation? What value in the fragmentshader tells me how “far” along I am on the vertex? Or I am completely misunderstanding this?

Distance from first line coord to last line coord

I am sorry, what do you mean by this?

First coord is 0% opacity, last coord is 100% opacity. in shader calcalute distance from first coord to current coord and divide to total length from first line to last to set opacity. If its right.
Maybe 2d distance

Hi! Yes, but this is the hard part, how do I get current cord in fragmentshader? Not the vertex point, i already have that.

Could you send a jsfiddle or the fragmentshader of this? Does this use world positioning?

For good transparent sorting

I don’t understand what you mean, the images you sent, how did you do them?

Not that good anyway :thinking: