is there a equivalent to unity lerp function in Godot shader. I have tried Mix function it does not work. I have attached the screenshot of what is required. Any help is appreciated. Thanks in advance

  • xyz replied to this.
  • sstelkar You could probably do it by fudging screen UVs but it's better to use object's UV for multiple reasons, one being a nice zoom independent preview in editor and the other is that tilting the bottle may hide considerable parts of the screen space gradient at the top/bottom. Instead, better to transform local uv space to stretch between top and bottom of bottle's rotated bounding box.

    Easiest way is to construct a shear matrix that shears the uv space around uv center (.5,.5) for a certain angle, to compensate for the tilt caused by rotation. Calculating this angle is the trickiest part, but here's the recipe:

    float scaleRatio = length(MODEL_MATRIX[0]) / length(MODEL_MATRIX[1]);
    float imageRatio = TEXTURE_PIXEL_SIZE.y / TEXTURE_PIXEL_SIZE.x;
    float shearAngle = atan(MODEL_MATRIX[0].y * scaleRatio * imageRatio, MODEL_MATRIX[0].x );

    If you don't have non-proportional scaling on the bottle sprite, simply remove scaleRatio from calculation.

    Once you have the angle, construct the shearMatrix with following basis vectors:

    shearMatrix = mat4(
    	vec4(1.0, sin(shearAngle), 0.0, 0.0), 
    	vec4(0.0, cos(shearAngle), 0.0, 0.0), 
    	vec4(0.0, 0.0, 1.0, 0.0), 
    	vec4(0.0, 0.5, 0.0, 0.0)
    );

    The above should be done in vertex function and the shearMatrix passed to fragment function as a varying.
    In fragment shader, subtract the object space UV from (.5,.5) to bring it to center and then multiply it with the shearMatrix. Use resulting V to drive your gradients.

    sstelkar mix() is lerp(). In what way it "doesn't work"?

    I cannot mix 2 colours in Godot like as show in the unity screenshot.
    like the shader where you have both blue and red separate based on some weightage

      sstelkar I cannot

      What do you mean? You most certainly can.

      sstelkar You can. See the reply above.

      For anyone else struggling with Shader Graph nodes from Unity possibly still missing in Godot: you can replicate them on your own very easily. Shader Graph is well documented, so you don't even have to look through the sources yourself.

      For example:
      ShaderGraph "Blend Node", the "Overwrite" mode. Source from documentation:

      void Unity_Blend_Overwrite_float4(float4 Base, float4 Blend, float Opacity, out float4 Out) {
      Out = lerp(Base, Blend, Opacity);
      }

      Converted to Godot:
      void Godot_Blend_Overwrite_vec4(vec4 Base, vec4 Blend, float Opacity, out vec4 Out){
      Out = mix(Base, Blend, Opacity);
      }

      As you can see, "mix" is the Godot equivalent to "lerp" from Unity, and "float4" becomes "vec4". It's all simple and documented, you just have to learn how and what to look/search for.




      I'm building a bottle fill game. all the logic is working. I'm able to work without shader above image is without using shaders. I'm trying to use shader for the animation part to make it nicer running into trouble

      • xyz replied to this.

        sstelkar So where's the problem? Mix in the shader appears to be working as intended.

          xyz
          Not sure why there is a difference in editor and when you run the scene.
          Only 2 colour are appearing when scene is run.
          Also when you zoom in colour disappear in editor, only one colour is visible.

          • xyz replied to this.

            sstelkar The problem is likely in u/v coordinate you use as an input to your stepping nodes. You should use object space UV, not screen space.

              xyz
              Is there an input for object uv, if it is not an elaborate process. Can you please show me how to get object uv.

              Also in unity position of world is used subtracting object position, so that there is a liquid flow effect.

              award
              basically I want to subtract object position from world space,to get liquid flow effect

              • xyz replied to this.

                sstelkar By "liquid flow" you mean keeping the gradient always horizontal when you rotate the bottle?

                  xyz
                  yes. That would only be possible if the colours do not change in y axis, even when the bottle is rotated. Need position node for this to work or anything that is a substitute in Godot. Thanks

                  • xyz replied to this.

                    sstelkar That has nothing to do with mix or lerp though, so you should rephrase your original question or open a new thread.

                      sstelkar changed the title to create a gradient texture that does not change vertically when object is moved .

                      sstelkar You could probably do it by fudging screen UVs but it's better to use object's UV for multiple reasons, one being a nice zoom independent preview in editor and the other is that tilting the bottle may hide considerable parts of the screen space gradient at the top/bottom. Instead, better to transform local uv space to stretch between top and bottom of bottle's rotated bounding box.

                      Easiest way is to construct a shear matrix that shears the uv space around uv center (.5,.5) for a certain angle, to compensate for the tilt caused by rotation. Calculating this angle is the trickiest part, but here's the recipe:

                      float scaleRatio = length(MODEL_MATRIX[0]) / length(MODEL_MATRIX[1]);
                      float imageRatio = TEXTURE_PIXEL_SIZE.y / TEXTURE_PIXEL_SIZE.x;
                      float shearAngle = atan(MODEL_MATRIX[0].y * scaleRatio * imageRatio, MODEL_MATRIX[0].x );

                      If you don't have non-proportional scaling on the bottle sprite, simply remove scaleRatio from calculation.

                      Once you have the angle, construct the shearMatrix with following basis vectors:

                      shearMatrix = mat4(
                      	vec4(1.0, sin(shearAngle), 0.0, 0.0), 
                      	vec4(0.0, cos(shearAngle), 0.0, 0.0), 
                      	vec4(0.0, 0.0, 1.0, 0.0), 
                      	vec4(0.0, 0.5, 0.0, 0.0)
                      );

                      The above should be done in vertex function and the shearMatrix passed to fragment function as a varying.
                      In fragment shader, subtract the object space UV from (.5,.5) to bring it to center and then multiply it with the shearMatrix. Use resulting V to drive your gradients.

                        xyz
                        Perfect. works as described.
                        Support and speed of response was pleasantly surprising and fast.

                        xyz
                        Can you please tell me your years of experience in shader programming.
                        Also since godot 4 has switched to vulkan, what is the future of godot shaders in coming years?