Search code examples
glslshadergodot

how to pass shader COLOR on ALBEDO


ALBEDO is vec3 and COLOR is vec4.. I need make pass COLOR to ALBEDO on Godot.. This shader work on shadertype itemscanvas but not working on spatial material..

shader_type  spatial;
uniform float amp = 0.1;
uniform vec4 tint_color = vec4(0.0, 0.5,0.99, 1);
uniform sampler2D iChannel0;
void fragment ()
{

        vec2 uv = FRAGCOORD.xy / (1.0/VIEWPORT_SIZE).xy;// (1.0/SCREEN_PIXEL_SIZE) for  shader_type canvas_item

        vec2 p = uv +
        (vec2(.5)-texture(iChannel0, uv*0.3+vec2(TIME*0.05, TIME*0.025)).xy)*amp +
        (vec2(.5)-texture(iChannel0, uv*0.3-vec2(-TIME*0.005, TIME*0.0125)).xy)*amp;
        vec4 a = texture(iChannel0, p)*tint_color;

        ALBEDO = a.xyz; //the w channel is not important, works without it on shader_type canvas_item but if used this on 3d spatial the effect no pass.. whats problem?

}

Solution

  • For ALPHA and ALBEDO: ALBEDO = a.xyz; is correct. For a.w, usually you would do this: ALPHA = a.w;. However, in this case, it appears that a.w is always 1. So there is no point.

    I'll pick on the rest of the code. Keep in mind that I do not know how it should look like, nor have any idea of the texture for the sampler2D (I'm guessing noise texture, seamless).


    Check your render mode. Being from ShaderToy, there is a chance you want render_mode unshaded;, which will make lights not affect the material. see Render Modes.


    For ease of use, You can use hints. In particular, Write the tint color like this:

    uniform vec4 tint_color: hint_color = vec4(0.0, 0.5,0.99, 1);
    

    So Godot gives you a color picker in the shader parameters. See Uniforms.

    You could also use hint_range(0, 1) for amp. However, I'm not sure about that.


    Double check your coordinates. I suspect this FRAGCOORD.xy / (1.0/VIEWPORT_SIZE).xy should be SCREEN_UV (or UV, if it should stay with the object that has the material).

    Was the original like this:

    vec2 i_resolution = 1.0/SCREEN_PIXEL_SIZE;
    vec2 uv = FRAGCOORD.xy/i_resolution;
    

    As I said in the prior answer, 1.0 / SCREEN_PIXEL_SIZE is VIEWPORT_SIZE. Replace it. We have:

    vec2 i_resolution = VIEWPORT_SIZE;
    vec2 uv = FRAGCOORD.xy/i_resolution;
    

    Inline:

    vec2 uv = FRAGCOORD.xy/VIEWPORT_SIZE;
    

    As I said in the prior answer, FRAGCOORD.xy/VIEWPORT_SIZE is SCREEN_UV (or UV if you don't want the material to depend on the position on screen). Replace it. We have:

    vec2 uv = SCREEN_UV;
    

    Even if that is not what you want, it is a good for testing.

    Try moving the camera. Is that what you want? No? Try vec2 uv = UV; instead. In fact, a variable is hard to justify at that point.