How can I make the custom shader stop?

I saw this tutorial. However, the effects keeps looping. How can I control it to fade in then stop and show the full model. Or fade out then stop and show the full model. And not just loop.

I know it has to do with the time variable. Here’s what I tried but couldn’t get it to work

CustomShader.prototype.update = function(dt) {

    this.time += dt;

       

    // Bounce value of t 0->1->0

    var t = (this.time % 2);

    if (t > 1) {

        t = 1 - (t - 1);

    }

    if (t < 0.01) {//when t is less than this, it's close to showing the full model

        console.log("faded in");

        //now stop shader and show full model

        this.enabled = false;//doing this doesn't work, the effect is still there, close to finish but not finished yet.

       

    }

    // Update the time value in the material

    this.material.setParameter('uTime', t);

};

Hi @Marks,

Here is one way to do this, I’ve added a second method that can be called to set the effect state and use that to control the time flow:

CustomShader.prototype.effectState = function(state) {

    this.effectState = state;
};

CustomShader.prototype.update = function(dt) {

    if(this.effectState){
        this.time += dt;
    }else{
        this.time -= dt;
    }

    // clamp time between 0 - 1
    this.time = pc.math.clamp(this.time, 0.0, 1.0);   

    // Update the time value in the material
    this.material.setParameter('uTime', this.time);
};

I replaced the update method, added the effectState method and called this.effectState(true); in the initialitze and nothing happened.

In addition, would it be possible to make the effect start from a specific point of the model and go from there? Such as the bottom, top, left or right of the model? Instead of fading in uniformly?

Yes, that’s example code that you should adapt to your project. I wouldn’t expect it to work out of the box.

Try sharing a sample project to be able to debug this effectively.

Ok, I’m using this project to try to achieve the results I want. Major issue right now is that once the diamond fades in and the effect finishes, there are still blue stripes on it

Anyone? If I can at least be able to fade in without having the blue stripes in the end and be able to control how many seconds to do the whole thing, I’d greatly appreciate it. I found that this line on the fragment shader

image

when commented out fixed the problem of having the blue lines in the end, but removes the blue lines altogether which isn’t what I want.

I couldn’t exactly make it fade in/out with x seconds, but I added a factor to multiply dt so I can control better how long the effect will take. So can just increase or decrease the factor until I’m satisfied. Not ideal, but good enough.

I could also fix the blue stripes at the end.

@Leonidas can you take a look? Is there an easy way to set up a spot where it starts to fade out or fade in ? For example, to start fading in from top to bottom, or bottom to top, etc.

How can I disable the shader so I can do something like

material.blendType = pc.BLEND_NORMAL;
material.opacity = 0.5;

I can’t set the opacity of the materials if I have this shader. I don’t know how to disable it. Even if I do material.shader = null, it still doesn’t work. I want to use the shader’s effect, but later want to disable it and set the opacity of the model

Sorry I was not able to see to your project, I will take a look later.

A shader is always tight to a material. Swap the material used by your models with a regular one and the shader will stop rendering.

I tried swapping the material, it doesn’t work. There’s the red button to set opacity, and the yellow makes the model fade in with the shader. I can only set the opacity if I disable the shader script.

On the script to set opacity, I save the original materials on an array and set them back before setting the opacity, it doesn’t work. Maybe I’m missing something. Same project.

EDIT

I fixed it, it’s working now. But I noticed that without the shader the diamond has shadows, but when I fade in with the shader there are no shadows. Once it finishes fading, I switch back to the old materials with shadow.

So I only have 3 questions now

  1. Is it possible to have this shader work with shadows?
  2. Is it possible to fade in/out from the top/bottom/left/right of the model, instead of uniformly?
  3. How can I make the diamond have no shadows and look like when I use the shader to fade in, but without using the shader? Maybe this is better. Right now the diamond is affected by light which gives it shadow, but when I use the shader the diamond becomes unaffected by it. I tried messing with different settings on the diamond’s material, but light always affects it. I want it to look bright without shadows just like when I use the shader.
  1. The example is using the Basic Material, not the Standard Material. It sounds like you would be better off using the Standard Material and overriding the opacity and diffuse chunks

  2. It is possible but it’s a bit tricky as what would you define as the top/left/right etc of the model? Left side on the model on the screen or in the world? At the moment, the fade effect is defined buy the height map and UVs on the model. Having different UVs and/or a different height map will give you a different effect.

  3. See 1

Here’s an example of it being converted to Standard Material chunks: https://playcanvas.com/project/990841/overview/custom-shader-chunks

I’ve added sliders for ‘uTime’ so I can debug it more easily.

The material opacity is now independent from the effect so you can fade the whole thing in and out

2 Likes

Hi yaustar. Thanks for all the info.

  1. The example is using the Basic Material, not the Standard Material. It sounds like you would be better off using the Standard Material and overriding the opacity and diffuse chunks

I didn’t even know there were 2 types. In the editor, there’s only an option to create a material, but that material is the standard one. How do I create a basic material in the editor? I see there’s an option of changing the shading from physical to phong, but that’s not it.

You can’t, it has to be created at runtime. The Base material is pretty much featureless and is generally reserved for when you want full control via shaders and build upwards as shown in the current shader tutorial and some of our engine examples.

Personally, I never use the Base Material. https://developer.playcanvas.com/api/pc.BasicMaterial.html

I think the base material is great because I always have to fight to make the model be illuminated properly from all angles by using 2 or 3 lights, but with the basic material only the whole model looks how it’s supposed to be out of the box. I was always like “how can I make the model not be affected by light and just be properly bright”. Now I know the answer.

Please add the basic material to the editor ;_;.

You can disable lighting on the material and use the emissive map? Does that not give you the result you need?

If you have an example of what you want something to look like and an example project, please create a new thread.

You can disable lighting on the material and use the emissive map? Does that not give you the result you need?

The diamond for example. I could not make it look how it looks when the dissolve shader is making it fade in. I tried messing with every setting of the material of the diamond.

The one on the far left is using the colour texture as emissiveMap as mentioned in my last post:

The one at the back is using the basic material with the shader

Project: https://playcanvas.com/project/406044/overview/tutorial-custom-shaders

2 Likes

Is there a way to make the effect but with the model invisible? For example, the diamond fades in. I just want to see the dissolve, not the model. So the idea is to take the dimensions of the model to make the effect, but not show the model itself. I thought that by setting the alpha to 0 this would work, but it fades the effect itself as well. I want to see the lines only now.

Yes it is possible, the blue areas is where the height value is between uTime and uTime + 0.04 and opacity is 0 where height is less than uTime.

You will need to modify the shader so that opacity is also 0 where height is more than uTime + 0.04