2

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?

}

1 Answers1

2

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.

Theraot
  • 31,890
  • 5
  • 57
  • 86
  • thank, you're right! my problem is the position of camera 'vec2 uv = -SCREEN_UV;' – Rubén ramirez Apr 23 '21 at 15:21
  • light does not influence if you use or not render_mode unshaded; now the new problem is performance, i hate the live :/ – Rubén ramirez Apr 23 '21 at 15:34
  • 1
    @Rubénramirez I didn't expect that you would need it negative. However I tested and I can confirm that would show a texture in the correct orientation. Godot does not seem to have screen coordinates upside down either (Although not exactly what ShaderToy uses, [see](https://stackoverflow.com/questions/58684315/shadertoy-fragcoord-vs-iresolution-vs-fragcolor), correcting for that won't work for this shader either). It appears to be the sampler coordinates instead. – Theraot Apr 23 '21 at 15:51
  • 1
    @Rubénramirez On performance, is it for mobile? The thing would help for sure are switching to GLES2 and lowering resolution of the game would help (see [Multiple resolutions](https://docs.godotengine.org/en/stable/tutorials/viewports/multiple_resolutions.html)). I'm not saying that is all you can do, but I don't know what else you could do. – Theraot Apr 23 '21 at 16:00
  • i think godot use coordinate, is why I put [-SCREEN_UV] i see on documentation returns inverted image [SCREEN_UV] and put - for y coordinate.. is wrong? the image is not negative – Rubén ramirez Apr 23 '21 at 17:01
  • 1
    @Rubénramirez Try this in shadertoy: `void mainImage( out vec4 fragColor, in vec2 fragCoord){vec2 uv = fragCoord/iResolution.xy; fragColor = vec4(uv.x,uv.y,0.0,1.0);}` And try this is Godot: `shader_type spatial; render_mode unshaded; void fragment () {vec2 uv = SCREEN_UV; ALBEDO = vec3(uv.x,uv.y,0.0);}` You should see the same result (black on the bottom left, green on the top left, yellow on the top right, red on the bottom right). So, the orientation of the coordinates is the same. However, it seems the sampler coordinates might not be, not sure if it at import or the `texture` function. – Theraot Apr 23 '21 at 17:08
  • wtf.. is true, i think is my shader.. I get seasick from reading so much my bad – Rubén ramirez Apr 23 '21 at 17:20
  • 1
    @Rubénramirez I remind you `SCREEN_UV` take the whole screen. Make the object bigger and position the camera so it covers the whole screen. If you want it tied to the object instead, use `UV`. – Theraot Apr 23 '21 at 17:34
  • I understand, thank you so much for your help! :) – Rubén ramirez Apr 23 '21 at 17:40