Shadertoy - uniform variables needs explanation (SOLVED)

Hi,

So I’ve tried with Defold Shadertoy tutorial and it’s ok, everything is clear here for me, more or less. But when it goes to implement different shader for example Raindrops it’s a bit harder. I’ve managed to change resolution and time for Defold but what about other uniform variables like iChannel0? Could you please help me with this one and maybe explain more about how you deal with them in other cases?
Following that, I think I will be able to overcome these warnings and understand what is done in line 67 (creation of vector color, commented now).

WARNING:GRAPHICS: WARNING: 0:13: ‘’ : #version directive missing
ERROR: 0:66: ‘iChannel0’ : undeclared identifier
ERROR: 0:66: ‘texture’ : no matching overloaded function found (using implicit conversion)
ERROR: 0:66: ‘rgb’ : vector field selection out of range

Code:

// Maximum number of cells a ripple can cross.
#define MAX_RADIUS 2

// Set to 1 to hash twice. Slower, but less patterns.
#define DOUBLE_HASH 0

// Hash functions shamefully stolen from:
// https://www.shadertoy.com/view/4djSRW
#define HASHSCALE1 .1031
#define HASHSCALE3 vec3(.1031, .1030, .0973)

#define speed  0.010

float hash12(vec2 p)
{
	vec3 p3  = fract(vec3(p.xyx) * HASHSCALE1);
	p3 += dot(p3, p3.yzx + 19.19);
	return fract((p3.x + p3.y) * p3.z);
}

vec2 hash22(vec2 p)
{
	vec3 p3 = fract(vec3(p.xyx) * HASHSCALE3);
	p3 += dot(p3, p3.yzx+19.19);
	return fract((p3.xx+p3.yz)*p3.zy);

}

varying mediump vec2 var_texcoord0;
uniform lowp vec4 time;

void main()
{
	vec2 res = vec2(1.0, 1.0); 
	vec2 uv = var_texcoord0.xy * res.xy - 0.5;
	vec2 p0 = floor(uv);
	float resolution = 0.0;

	float time = time.x * speed + 0.25; 

	float circles = 0.;
	for (int j = -MAX_RADIUS; j <= MAX_RADIUS; ++j)
	{
		for (int i = -MAX_RADIUS; i <= MAX_RADIUS; ++i)
		{
			vec2 pi = p0 + vec2(i, j);
			#if DOUBLE_HASH
			vec2 h = hash22(pi);
			#else
			vec2 h = pi;
			#endif
			vec2 p = pi + hash22(h);
			
			float t = fract(0.3*time + hash12(h));
			float d = length(p - uv) - (float(MAX_RADIUS) + 1.)*t;

			circles += (1. - t) * (1. - t)
			* mix(sin(31.*d) * 0.5 + 0.5, 1., 0.1)
			* smoothstep(-0.6, -0.3, d)
			* smoothstep(0., -0.3, d);
		}
	}

	float intensity = mix(0.01, 0.15, smoothstep(0.1, 0.6, abs(fract(0.05*time + 0.5)*2.-1.)));
	vec3 n = vec3(dFdx(circles), dFdy(circles), 0.);
	n.z = sqrt(1. - dot(n.xy, n.xy));
	//vec3 color = texture(iChannel0, uv/resolution - intensity*n.xy).rgb + 5.*pow(clamp(dot(n, normalize(vec3(1., 0.7, 0.5))), 0., 1.), 6.);
	//gl_FragColor = vec4(color, 1.0)
	gl_FragColor = vec4(var_texcoord0.xy, 0.0, 1.0);
}

I’m not an expert in ShaderToy, but I’ll try to explain some of the errors below:

This is “just” a warning, so it could be ignored. If you run into trouble in the future of missing GLSL functionality, you could add a directive at the top with #version 110 or #version 120 etc. But for now I would ignore it. :slight_smile:

ShaderToy seems to automatically expose some input sources such as the iChannelN uniforms. On ST this can be a couple of different data formats/sources, but I guess to most common is textures.

To solve this in your case, I would add;

uniform sampler2D iChannel0;

to the top of your shader, and in the material file make sure there is a sampler with the same name.

Defold use a slightly old GLSL version to support OpenGL ES 2.0 (which is the common OGL version for the platforms we support), which means that modern GLSL functions such as texture is not natively supported. However, from what I understand of the shader above, it should be safe to replace it with a call to texture2D instead.

This error might disappear once you fix the above error regarding texture.

4 Likes

Thanks @sven, we got rid of errors :wink: but what I get is only a black screen from this color vector obtained from texture2D. How can I debug Fragment program easily? Is there an option to print something (vector I want to assign to gl_FragColor) in the Defold console? Additionally, do this sampler iChannel0 needs to have something specified? I left it like the default:

samplers {
name: “iChannel0”
wrap_u: WRAP_MODE_REPEAT
wrap_v: WRAP_MODE_REPEAT
filter_min: FILTER_MODE_MIN_NEAREST
filter_mag: FILTER_MODE_MAG_NEAREST
}

The sampler settings looks good! :+1:

I did a quick stab at using the raindrops-shader you linked. One important thing to remember when converting to Defold is that you need to expose the same data inputs that ShaderToy does. Shown here:

Looking through the shader you can see that these four are used in this particular shader;

  • Uniform values: iResolution, iTime and iMouse - need to supply the shader with these from a script
  • Texture: iChannel0 - the texture is automatically supplied by Defold

These uniforms needs to be defined in the material file, as described earlier.

But we also need to add these ourselves to the shader file, something like this:

uniform lowp vec4 iResolution;
uniform lowp vec4 iTime;
uniform sampler2D iChannel0;
uniform lowp vec4 iMouse;

The last thing we need to do is add some code to a script that will send these values to the shader at runtime;

function init(self)
	self.time = 0
	msg.post(".", "acquire_input_focus")
	sprite.set_constant("#sprite", "iResolution", vmath.vector4(1024.0, 1024.0, 0,0))
end

function update(self, dt)
	self.time = self.time + dt
	sprite.set_constant("#sprite", "iTime", vmath.vector4(self.time, 0,0,0))
end

function on_input(self, action_id, action)
	if action_id == hash("touch") and not action.released then
		sprite.set_constant("#sprite", "iMouse", vmath.vector4(action.x, action.y, 0,0))
	end
end

And voilà;

I’m adding the finished project here for you to inspect: raindrops.zip (1.2 MB)


A quick note about shaders; they can generally be quite hard to debug, especially since you don’t have any “regular” debugging options such as breakpoints and logging/printing functionality. I would even say that debugging shaders calls for it’s own manual.

5 Likes

Wow! :smile: Indeed, it works great! Thanks a lot for a clear explanation and priceless help! :smile: As I see, those are the most frequently used uniform variables. It’s a pity, that there is no straightforward debug option :frowning: Now, I’ll try to experiment and hopefully, will share results :wink:

2 Likes