example.shader

shaders can be quite tricky but are very powerful once you learn to use them.

all of these will assume you have this as your base code

local cube = c3d.geometry.cube_simple():push():reposition(0,0,1)

function c3d.update()
    cube:set_rotation(0,1,0,os.epoch("utc")/20)
end

vertex

wave effect

cube:set_vertex_shader(function(x,y,z,...)
    local t = os.epoch("utc")

    y = y + math.sin(x*10+t/200)/5 -- adds the wave effect to the height of the vertex offset by the x of it and time

    return c3d.shader.default.vertex(x,y,z,...) -- applies the default transforms to the modified vertex
end)

geometry

triangles colored by their index

cube:set_geometry_shader(function(triangle,index)
    function triangle.fs() -- modifies the triangles fragment shader to return the color of the triangle dependent on the index
        return 2^(index%15)
    end

    return triangle -- returns modified triangle
end)

fragment

random noise fragment shader

cube:set_frag_shader(function(pixel_data)
    return 2^(math.random(0,1)*15)
end)

CC color gradient made using a fragment and vertex shader

local random_color_lookup = setmetatable({},{__index=function(this,index)
    local c = math.random(0,15)
    rawset(this,index,c)
    return c
end}) -- a special table which has "infinite" amount of random colors on its indices

cube:set_vertex_shader(function(...)
    local x,y,z,w = c3d.shader.default.vertex(vertex,...)

    return x,y,z,w,{epic_color=random_color_lookup[vertex.index]} -- adds the color to be interpolated between the vertices
end)

cube:set_frag_shader(function(pixel_data)
    return 2^math.ceil(math.min(math.max(pixel_data.frag.epic_color,0),15)) -- gets the interpolated fragment passed from the vertex shader and clamps it
end)