ShaderBlock

ShaderBlocks are objects that can hold large amounts of data and can be sent to Shaders. It is common to use "uniform" variables to send data to shaders, but uniforms are usually limited to a few kilobytes in size. ShaderBlocks are useful for a few reasons:

On systems that support compute shaders, ShaderBlocks can optionally be "writable". A writable ShaderBlock is a little bit slower than a non-writable one, but shaders can modify its contents and it can be much, much larger than a non-writable ShaderBlock.

Constructor

lovr.graphics.newShaderBlockCreate a new ShaderBlock.

Methods

ShaderBlock:getOffsetGet the byte offset of a variable in the ShaderBlock.
ShaderBlock:getShaderCodeGet a GLSL string that defines the ShaderBlock in a Shader.
ShaderBlock:getSizeGet the size of the ShaderBlock.
ShaderBlock:readRead a variable from the ShaderBlock.
ShaderBlock:sendUpdate a variable in the ShaderBlock.
ShaderBlock:getTypeGet the type of the ShaderBlock.

Notes

Example

function lovr.load()
  -- Create a ShaderBlock to store positions for 1000 models
  block = lovr.graphics.newShaderBlock('uniform', {
    modelPositions = { 'mat4', 1000 }
  }, { usage = 'static' })

  -- Write some random transforms to the block
  local transforms = {}
  for i = 1, 1000 do
    transforms[i] = lovr.math.mat4()
    local random, randomNormal = lovr.math.random, lovr.math.randomNormal
    transforms[i]:translate(randomNormal(8), randomNormal(8), randomNormal(8))
    transforms[i]:rotate(random(2 * math.pi), random(), random(), random())
  end
  block:send('modelPositions', transforms)

  -- Create the shader, injecting the shader code for the block
  shader = lovr.graphics.newShader(
    block:getShaderCode('ModelBlock') .. [[
    vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
      return projection * transform * modelPositions[gl_InstanceID] * vertex;
    }
  ]])

  -- Bind the block to the shader
  shader:sendBlock('ModelBlock', block)
  model = lovr.graphics.newModel('monkey.obj')
end

-- Draw the model 1000 times, using positions from the shader block
function lovr.draw()
  lovr.graphics.setShader(shader)
  model:draw(lovr.math.mat4(), 1000)
  lovr.graphics.setShader()
end

See also