Update Shader Constant [SOLVED]

Hi!

I’m playing with shaders in Defold.
I’m very new to shaders but have managed to learn the basics.

I have a sprite, which has a material, which has FP and VP.

My question is:
How do you update the time variable in the FP? As I understand it has to come from the game itself? not sure…
Can you help me do it in Defold?

I read this ( http://stackoverflow.com/questions/6230512/opengl-es-2-0-shader-how-is-time-variable-called ).

Thank you!

If you need the time variable you would add a constant in your material and the set that constant from the update method of a script.

Read here about materials and how to add constants:
http://www.defold.com/doc/materials

1 Like

I uploaded a portion of our code that we use to animate tilemaps with a shader to github. It does more or less what you want, passing a variable to a shader from the update loop.

2 Likes

Thank you very much Johan!

I did as you said and it worked as I intended :smiley:

1 Like

Johan and/or Ivan:

It’s driving me insane… I can’t seem to figure out what I’m doing wrong…

I have my material called Background.material

name: “BackgroundMaterial”
tags: “tile”
vertex_program: “/builtins/materials/sprite.vp”
fragment_program: “/main/Background/Background.fp”
vertex_constants {
name: “view_proj”
type: CONSTANT_TYPE_VIEWPROJ
}
vertex_constants {
name: “world”
type: CONSTANT_TYPE_WORLD
}
fragment_constants {
name: “tint”
type: CONSTANT_TYPE_USER
value {
x: 1.0
y: 1.0
z: 1.0
w: 1.0
}
}
fragment_constants {
name: “offset”
type: CONSTANT_TYPE_USER
}

As you can see, it has the “tile” tag

I have my render_script with the following on_message (when invoqued it does print in the console the “debugging” text)

function on_message(self, message_id, message)
if message_id == hash(“clear_color”) then
self.clear_color = message.color
elseif message_id == hash(“set_view_projection”) then
self.view = message.view
elseif message_id == hash(“bgColor”) then
local constants = render.constant_buffer()
constants.offset = vmath.vector4(-0.1171875,0.0390625,-0.78125,0)
render.draw(self.tile_pred, constants)
print(“It’s getting here”);
end
end

and “/main/Background/Background.fp” does the following:

varying mediump vec4 position;
varying mediump vec2 var_texcoord0;

uniform lowp sampler2D DIFFUSE_TEXTURE;
uniform lowp vec4 tint;
uniform lowp vec4 offset;

void main()
{
//Verde
//lowp vec4 offset_pm = vec4(-0.1171875,0.0390625,-0.78125,0);

//Azul
//lowp vec4 offset_pm = vec4(-0.546875,-0.078125,0.0390625,0);

//Violeta
//lowp vec4 offset_pm = vec4(-0.0390625,-0.3125,-0.15625,0);

//Rojo
//lowp vec4 offset_pm = vec4(0.1953125,-0.390625,-0.5859375,0);

//Naranja
//lowp vec4 offset_pm = vec4(0.3125,-0.15625,-0.546875,0);

//Amarillo
//lowp vec4 offset_pm = vec4(0.1171875,0.078125,-0.6640625,0);
lowp vec4 offset_pm = vec4(offset.xyz,0);        
gl_FragColor = texture2D(DIFFUSE_TEXTURE, var_texcoord0.xy) + offset_pm;

}

If I uncomment any of the “lowp vec4 offset_pm =” hardcoded lines, it works just fine… bue when I send them as constants it does nothing…

I can’t seem to find what I’m doing wrong… I’ve been digging into documentation the past 2 days but… well no result.

Thanks

You need to get that call to render.draw() into the update() function of your render script. on_message() is called when messages are delivered at the end of the frame so everything has already been drawn.

I did it so because, otherwise, if I do this:

function init(self)
self.constants = render.constant_buffer()
self.tile_pred = render.predicate({“tile”})
self.constants.offset = vmath.vector4(-0.1171875,0.0390625,-0.78125,0)
end
function update(self, dt)
render.draw(self.tile_pred,self.constants)
end

I get the following error:

ERROR:SCRIPT: main/Background/Background.script:10: bad argument #4 to ‘draw’ (RenderScriptInstance expected, got userdata)
stack traceback:
[C]: in function ‘draw’
main/Background/Background.script:10: in function <main/Background/Background.script:9>

It should be in the update function of the render-script, not the game object

1 Like

Ok, great, that work just fine.

:smiley: