# Shader opacity based on z

**URL:** <https://discourse.threejs.org/t/shader-opacity-based-on-z/43227>\
**Category:** Questions\
**Tags:** customshadermaterial, textures, shaders\
**Created:** [October 4, 2022, 3:48pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227 "2022-10-04T15:48:49Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 4, 2022, 3:48pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/1 "2022-10-04T15:48:49Z")

</div>

Hi,

I’m trying to write a shader which fades in and out at 2 different z values.

So step 1 I tried to get it to work with just z passing 0 but the result is the alpha channel of the image is black but the image is displayed.

Fragment shaders:

```
vec4 color = texture2D(uTexture, vUv);
gl_FragColor = vec4(color);

// Hidden as expected (but is there a command to exit program to prevent gpu use?)
gl_FragColor.a = 0.0;

// Expected 1/2 transparent, but instead alpha channel is black and all is 50% transparent
// gl_FragColor.a = 0.5;

// Expected texture to be displayed on plane with transparency intact,
// but transparent areas of texture are black and the image parts are displayed correctly
// gl_FragColor.a = 1;

// If I use gl_FragColor.a *= pow( gl_FragCoord.z, 50.0 );
// this fades with alpha channel correct but not sure on values of
// gl_FragCoord.z and what value pow() is returning and why
// is it a multiplier, wouldn't that take it far beyond a 0.0 to 1.0 range?

```

I was going to code something like this:

```
vec4 color = texture2D(uTexture, vUv);
gl_FragColor = vec4(color);

// hide anything that is over under z:-12
if (gl_FragCoord.z < -12.0){
    gl_FragColor.a = 0.0;
    // Is there some command to prevent render? or exit program? To optimise?
}

// fade in range
if (gl_FragCoord.z >= -12.0 && gl_FragCoord.z <= -10){
    // code to set opacity from -12.0 to -10.0
}

// fade out range
if (gl_FragCoord.z >= -1.0 && gl_FragCoor.z <= 0){
    // code to set opacity from -1.0 to 0.0
}

// hide after 0
if (gl_FragCoord.z > 0.0){
    gl_FragColor.a = 0.0;
    // Is there some command to prevent render? or exit program? To optimise?
}

```

I’m not clued up with shaders as you can see, anyone got any tips?

Thanks

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [October 4, 2022, 4:29pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/2 "2022-10-04T16:29:42Z")

</div>

you can check [this thread on discord](https://discord.com/channels/685241246557667386/1022978417697767545/1024054280832946308)

---

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 4, 2022, 5:36pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/3 "2022-10-04T17:36:50Z")

</div>

Its all greyed out.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [October 4, 2022, 6:35pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/4 "2022-10-04T18:35:59Z")

</div>

Related:

> <https://stackoverflow.com/questions/52290198/three-js-object-fade-in-out-or-apply-opacity>

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [October 4, 2022, 9:06pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/5 "2022-10-04T21:06:57Z")

</div>

you have to join the server 1st. but any way, there is a [working shader example](https://jsfiddle.net/pecxsfaL/) although the math is off

---

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 4, 2022, 9:09pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/6 "2022-10-04T21:09:49Z")

</div>

> [@Mugen87](#):
>
> Related:
> 
> [javascript - three.js object fade in/out or apply opacity - Stack Overflow](https://stackoverflow.com/questions/52290198/three-js-object-fade-in-out-or-apply-opacity)

Yep that’s the last section of my comments in the 1st code sample, it odd that works but setting the alpha value directly from 0.0 to 1.0 breaks the transparency/alpha channel of the texture (png).

I will try injecting numbers into it in the morning and see if I can get actual values for what \*= pow(val1,val2) is actually generating. Also that multiplier would mean it’s multiplier incrementing. Might see if I can re-construct it in JS so I can see what values are actually being generated in

```
gl_FragColor.a *= pow( gl_FragCoord.z, 50.0 );

```

So I can push the values into the shader for the alpha to work at 2 Z ranges (in and out). And then do it all in the shader itself.

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [October 4, 2022, 9:12pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/7 "2022-10-04T21:12:59Z")

</div>

> [@makc3d](#):
>
> the math is off

and here is another useful link from the thread: [opengl - How do I convert gl\_FragCoord to a world space point in a fragment shader? - Stack Overflow](https://stackoverflow.com/a/38938587)

---

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 5, 2022, 12:00pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/8 "2022-10-05T12:00:58Z")

</div>

> [@makc3d](#):
>
> you have to join the server 1st. but any way, there is a [working shader example](https://jsfiddle.net/pecxsfaL/) although the math is off

I’ve done a conversion on the original which uses vars bunny and kitty (lol), to z and a (pos, alpha value). No joy.

> **[(Attempt 1) ThreeJS Fragment shader fade in and out at a specified z position...](https://jsfiddle.net/AllForTheCode/ox1syjub/57)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

Will try a re-work of your 2nd links code shortly.

---

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 5, 2022, 1:33pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/9 "2022-10-05T13:33:36Z")

</div>

Here’s an attempt using the 2nd example and various others, still no luck. Passing a z of 0.0 should set the alpha to 1.0 and under 0.0 the alpha should be set to 0.5

> **[(Attempt 2) ThreeJS Fragment shader fade in and out at a specified z position...](https://jsfiddle.net/AllForTheCode/u97ne5qf/210/)**
>
> Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.

I have the following code to get the current Z of the pixel? that I wish to evaluate for setting the alpha/opacity

```
vec4 ndc = vec4(
   (gl_FragCoord.x / screen_width - 0.5) * 2.0,
   (gl_FragCoord.y / screen_height - 0.5) * 2.0,
   (gl_FragCoord.z - 0.5) * 2.0, 1.0
);

vec4 clip = inverse_view_proj * ndc;
vec3 vertex = (clip / clip.w).xyz;

```

And this

```
float z = gl_FragCoord.z / gl_FragCoord.w;
vec3 test = vec3(0.0,0.0,(gl_FragCoord.z / gl_FragCoord.w));

```

I then tried to evaluate

- ndc.z
- clip.z
- vertex.z
- test.z

using

```
if (var.z >= 0.0) {
    a = 1.0 // set alpha to 1.0
} else {
    a = 0.5 // set alpha to 0.5
}

```

and

```
if (var.z >= 1.0) {
    a = 1.0 // set alpha to 1.0
} else {
    a = 0.5 // set alpha to 0.5
}

```

**Results using \>= 0.0:**

- ndc.z: a = 1.0 at all times
- clip.z: a = 1.0 at all times
- vertex.z: a = 0.5 at all times
- test.z: a = 1.0 at all times (test.z appears to be around 5.0)

**Results using \>= 1.0:**

- ndc.z: a = 0.5 at all times
- clip.z: a = 0.5 at all times
- vertex.z: a = 0.5 at all times
- test.z: a = 1.0 at all times

Which leads me to think that the way to get z for all of the above vars **ndc** , **clip** , **vertex** and **test** is incorrect, also it might suggest that z is not being adjusted when the mesh is being moved via mesh.position.z

This code is working when tested manually setting **a**

```
gl_FragColor = vec4( vec3( 1.0 ), a );

```

  

* * *

By playing with the if statement value, I found that test.z is around 5.0 and I can see a transition there but it never changes so can’t be used.

Anyone know the code to get the updating z of that pixel? point? vertex? on each run of the shader program? Is is possible or do I need to update a var in the shader in the render/animation loop for each plane I have?

or am I on the wrong mindset?

Thanks

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [October 5, 2022, 6:02pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/10 "2022-10-05T18:02:13Z")

</div>

> [@Darcey](#):
>
> the code to get the updating z of that pixel? point? vertex? on each run of the shader program?

there are two ways to supply params:

- attributes (these are unique per vertex)
- uniforms (these are per draw call, uniform across all the vertices)

you can check [three.js examples](https://threejs.org/examples/?q=attribute#webgl_custom_attributes) to see how to use both

---

<div class="post-metadata">

**Author:** ![Darcey](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/darcey/32/8015_2.png) [@Darcey](https://discourse.threejs.org/u/Darcey)\
**Post date:** [October 5, 2022, 6:39pm UTC](https://discourse.threejs.org/t/shader-opacity-based-on-z/43227/11 "2022-10-05T18:39:55Z")

</div>

I need more information on shaders, I need to buy a book on shaders or something before I can work this out…

I’ve posted it as a job on this forum:

> [@Quick custom shader to fade in and fade out at 2 Z ranges](https://discourse.threejs.org/t/quick-custom-shader-to-fade-in-and-fade-out-at-2-z-ranges/43289):
>
> Easy job for someone who knows shaders. £40 GBP via PayPal. Please message me if your interested and detail any questions you may have. Requirements A single ThreeJS webpage (zip) with a plane using a ShaderMaterial which has a transparent PNG on it (make sure parts of the PNG are transparent). This plane then needs to move from vector3(0,0,-20) to vector3(0,0,3), repeating/looping. The plane must start fading in at Z: -20 to -17 and then fade out from Z: -3 to 0 (these values will be editab…
