Sending variables from gui to fragment shader

This was written when using Defold version 1.6.3.

Sending variables to the shader program from a game object script is easy.

go.set("go#some_sprite", "primary_colour", vmath.vector4(0.5, 1, 0, 1))

Besides the above code, your custom material file also needs a Fragment Constant set with identical value: primary_color, type being: User.

Oh and the sprite needs to actually use that material.

You’re done now. :herb:


Oh what about sprites that are used in gui? Well… Get ready to make your own custom renderer… Fortunately it is surprisingly easy!

Links that helped me to figure things out:

Relevant code

gui_colour.fp

uniform lowp vec4 primary_colour;

custom.render_script

function init(self)
    -- New pridicate which is what needs to be in the materials file "Tags" section.
    self.gui_tint_pred = render.predicate({ "gui_colour" })
   
    ...

    self.constants = render.constant_buffer()
    self.constants.primary_colour = vmath.vector4(1, 0, 0, 1)
end

function update(self)

    ...

    render.draw(self.gui_pred, { frustum = frustum })

    -- Add the custom material which is set in the custom render file
    render.enable_material("gui_mat")
    render.draw(self.gui_tint_pred, {
        frustum = frustum,
        constants = self.constants
    })
    render.disable_material()

    render.draw(self.text_pred, { frustum = frustum })

    ...

end

function on_message(self, message_id, message)

    ...

    if message_id == hash("change_primary_colour") then
        self.constants.primary_colour = message.p
    end
end

cake.gui_script

msg.post("@render:", "change_primary_colour", { p = vmath.vector4(0.5, 1, 0, 1) })
5 Likes

But what if every node of the gui need a different variables on the shader side?

I am not entirely sure, but I think that would require a new material and a lot of duplicate render code for each different node. Alternatively each node would have its constant buffer variable but then the fragment shader needs to decide which to use.

It would be nice if it was possible to just gui.set(..) for each node.