Shader not working

In this project: https://playcanvas.com/project/803940/overview/shadertest
I am trying to connect the script with the fragment shader as the chunk.
But for some reason is not working, even tho I followed the tutorial from Leonidas.
Does anyone know what’s the problem with this setup?


image

Hi @Dava ,

Can you make your project public? It doesn’t seem to open right now.

One thing I definitely see wrong there is that dAlbedo should be a vec3 not a vec4. Check the current definition of that shader chunk here:

Shader chunks are still an unofficial API so they can change from time to time. Though I think in the tutorial it was a vec3 as well, can’t remember :innocent:

2 Likes

It’s public now :slight_smile:

So a number of things you need to do to get your shader included in the material shader (right now it’s not!):

  1. To override the diffuse shader chunk change your override to the following (shader chunk name has been updated since the tutorial was written):
this.material.chunks.diffusePS = this.shader.resource;
  1. As soon as you do that your shader will compile and you will get a list of the errors you need to fix:

ERROR: 0:148: 'UV' : undeclared identifier

Since you didn’t reference any texture in your material, your pixel shader doesn’t include texture coordinates. Meaning you can’t use the $UV variable to target those. That’s easy to fix, just add a texture to your diffuse slot, any will do, even a blank one.

ERROR: 0:198: 'constructor' : not enough data provided for construction
ERROR: 0:198: '=' : dimension mismatch
ERROR: 0:198: 'assign' : cannot convert from 'const 4-component vector of float' to 'highp 3-component vector of float'

The following line in your shader code has two mistakes:

dAlbedo =vec4(1,1,1);

a. That’s a vec3 not a vec4, hence the constructor error.
b. dAlbedo excepts a vec3 not a vec4, hence the dimension mismatch error and not being able to convert to vec3.

The fix would be:

dAlbedo =vec3(1,1,1);

You can also try putting a random color there and you will see your shader working:

dAlbedo =vec3(0.5,0.0,1.0);

Good luck!

3 Likes

It’s working now , but I still get errors :confused:
image

You need to head to the bottom of the shader full text to find the exact error.

Oh , sorry , thanks for info :slight_smile:
Hmm i guess something about texture

Yeah, you are still missing mapping a texture to your material, so the UV coords variable gets included.

Check my reply above on how to fix that.

1 Like


I think i am not doing something correctly

Yeah, what I meant was add a texture to your material in editor. That will force the shader to include UV coordinates to the shader.

There are other ways to do that, that’s the simplest I think.

2 Likes

I have 5 questions regarding the GLSL inside Playcanvas @Leonidas

1 Since dAlbedo approves the only vec3, how can we add transparency data ?
2 Is it possible to add text inside GLSL somehow?
3 About resolution, is that determined by the texture we add on diffuse slot in material?
4 In your tutorial, I saw this line of code “texture2DSRGB(uWaterPattern, uvWater).$CH” , what does $CH stands for, and is there any explanation about texture2DSRGB how it works
5 I made this shader, for optimization purposes, is it possible if the user doesn’t want the ring
on the ball, can I just remove this part code somehow, or that kind of optimization is useless or not possible

  1. For opacity, you can use opacity chunk.
  2. Short answer is no, you can’t display text in shader. A shader is a simple function that outputs a single color value, which is applied to all pixels at the same time.
  3. if you mean iResolution, its your canvas resolution.
  4. texture2DSRGB is a convenience function to read the color value via sampler2D at provided UV coordinates. It is the same as sampler2D(texture, uv);. The acronim $CH stands for Channel, and points to the Channel field in the Editor (refer to the last screenshot from @Leonidas).
  5. You can add some uniform, e.g. uRingScale which would scale that ring to 0 or 1. You would then material.setParameter("uRingScale", scale); from script to affect the visiiblity of the ring.

Opacity chunk:

2 Likes

Hi @LeXXik

About opacity chunk, for some reason, it’s not working on my model and there are 0 examples online

This is mine opacity chunk:
image

And this is where I set the opacity chunk

Do you have any idea why it’s not working ?

Probably because the shader chunk property is called .opacityPS, not opacity.

If I would face a similar issue, where I don’t see an expected result of the shader, I would use SpectorJS (Chrome plugin). It is very simple to use - click a button and it will record your current frame. You then simply select the draw call, where you expect your material to be rendered and check the fragment shader code to see what’s up. I would then see that the fragment shader code has a default chunk code in it, and not the one I was presumably replacing with. I would then check if I am assigning it to the correct property, where I would find that I was not.

You can find this and other chunk property names here:

2 Likes

And another way to get the compiled shader, if you know your material name, and it’s unique, is to type this in the browser console:

pc.app.assets.find('Material Name').resource.shader.definition;

image

2 Likes