bjorn 2 лет назад
Родитель
Сommit
f3134f320d

+ 2 - 2
examples/Interaction/Controller_Models/main.lua

@@ -7,10 +7,10 @@ function lovr.load()
   if not next(models) then print('No models loaded') end
 end
 
-function lovr.draw()
+function lovr.draw(pass)
   for hand, model in pairs(models) do
     if lovr.headset.isTracked(hand) then
-      model:draw(mat4(lovr.headset.getPose(hand)))
+      pass:draw(model, mat4(lovr.headset.getPose(hand)))
     end
   end
 end

+ 55 - 65
examples/Optimization/Instancing_-_Compute/main.lua

@@ -5,84 +5,74 @@ ASSUME_FRAMERATE = 1/120
 function lovr.load()
   MONKEYS = 500
 
-  if not lovr.graphics.getFeatures().compute then
-    error("This example requires compute shaders to run, but compute shaders are not supported on this machine.")
-  end
-
-  -- Create a ShaderBlock to store positions for lots of models
-  block = lovr.graphics.newShaderBlock('compute', {
-    modelTransforms = { 'mat4', MONKEYS },
-    modelTransformsPerFrame = { 'mat4', MONKEYS }
-  }, { usage = 'dynamic' }) -- "Dynamic" means "compute shaders can write to this"
-
-  -- Write some random transforms to the block
+  -- Create some random transforms
   local random, randomNormal = lovr.math.random, lovr.math.randomNormal
-  do
-    local transforms = {}
-    for i = 1, MONKEYS do
-      local position = vec3(randomNormal(8), randomNormal(8), randomNormal(8))
-      local orientation = quat(random(2 * math.pi), random(), random(), random())
-      local scale = vec3(.75)
-      transforms[i] = mat4(position, scale, orientation)
-    end
-    block:send('modelTransforms', transforms)
+  local transforms = {}
+  for i = 1, MONKEYS do
+    local position = vec3(randomNormal(8), randomNormal(8), randomNormal(8))
+    local orientation = quat(random(2 * math.pi), random(), random(), random())
+    local scale = vec3(.75)
+    transforms[i] = mat4(position, scale, orientation)
   end
+
   -- More random transforms-- this will correspond to the transform applied to each monkey per frame
-  do
-    local transforms = {}
-    for i = 1, MONKEYS do
-      local position = vec3(randomNormal(1), randomNormal(8), randomNormal(8)):mul(ASSUME_FRAMERATE)
-      local radianSwing = ASSUME_FRAMERATE * math.pi / 2
-      local orientation = quat(random(-radianSwing, radianSwing), random(), random(), random())
-      local scale = vec3(1)
-      transforms[i] = mat4(position, scale, orientation)
-    end
-    block:send('modelTransformsPerFrame', transforms)
+  local offsets = {}
+  for i = 1, MONKEYS do
+    local position = vec3(randomNormal(1), randomNormal(8), randomNormal(8)):mul(ASSUME_FRAMERATE)
+    local radianSwing = ASSUME_FRAMERATE * math.pi / 2
+    local orientation = quat(random(-radianSwing, radianSwing), random(), random(), random())
+    local scale = vec3(1)
+    offsets[i] = mat4(position, scale, orientation)
   end
 
+  -- Create a Buffer to store positions for lots of models
+  transformBuffer = lovr.graphics.newBuffer(transforms, 'mat4')
+  offsetBuffer = lovr.graphics.newBuffer(offsets, 'mat4')
+
   -- Create the compute shader, we will run this once per frame
-  computeShader = lovr.graphics.newComputeShader(
-    string.format(block:getShaderCode('ModelBlock') .. [[
-      #define MONKEYS %d
-      layout(local_size_x = MONKEYS, local_size_y = 1, local_size_z = 1) in;
-      void compute() {
-        uint i = gl_LocalInvocationID.x;
-        modelTransforms[i] = modelTransforms[i] * modelTransformsPerFrame[i];
-      }
-    ]], MONKEYS)
-  )
-  computeShader:sendBlock('ModelBlock', block)
+  computeShader = lovr.graphics.newShader([[
+    layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
 
-  -- Create the display shader, injecting the shader code for the block
-  shader = lovr.graphics.newShader(
-    block:getShaderCode('ModelBlock') .. [[
-    out vec3 vNormal;
-    vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
-      vNormal = lovrNormal;
-      return projection * transform * modelTransforms[lovrInstanceID] * vertex;
-    }
-  ]], [[
-    in vec3 vNormal;
-    vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
-      return vec4(vNormal * .5 + .5, 1.);
+    layout(set = 0, binding = 0) buffer TransformBuffer { mat4 Transforms[]; };
+    layout(set = 0, binding = 1) buffer OffsetBuffer { mat4 Offsets[]; };
+
+    Constants {
+      uint monkeyCount;
+    };
+
+    void lovrmain() {
+      uint i = GlobalThreadID.x;
+      if (i >= monkeyCount) return;
+      Transforms[i] = Transforms[i] * Offsets[i];
     }
   ]])
 
-  -- Bind the block to the shader
-  shader:sendBlock('ModelBlock', block)
+  -- Create the display shader, injecting the shader code for the block
+  shader = lovr.graphics.newShader([[
+    layout(set = 2, binding = 0) buffer TransformBuffer { mat4 Transforms[]; };
+
+    vec4 lovrmain() {
+      return Projection * View * Transforms[InstanceIndex] * Transform * VertexPosition;
+    }
+  ]], 'normal')
 
   model = lovr.graphics.newModel('monkey.obj')
-  lovr.graphics.setCullingEnabled(true)
-  lovr.graphics.setBlendMode(nil)
 end
 
-function lovr.update()
-  lovr.graphics.compute(computeShader,1,1,1)
-end
+-- Draw many copies of the model using instancing, with transforms from a buffer
+function lovr.draw(pass)
+  local computer = lovr.graphics.getPass('compute')
+  computer:setShader(computeShader)
+  computer:send('monkeyCount', MONKEYS)
+  computer:send('TransformBuffer', transformBuffer)
+  computer:send('OffsetBuffer', offsetBuffer)
+  computer:compute(math.ceil(MONKEYS / 32))
+
+  pass:setShader(shader)
+  pass:send('TransformBuffer', transformBuffer)
+  pass:setCullMode('back')
+  pass:setBlendMode(nil)
+  pass:draw(model, mat4(), nil, nil, MONKEYS)
 
--- Draw many copies of the model using instancing, with transforms from the shader block
-function lovr.draw()
-  lovr.graphics.setShader(shader)
-  model:draw(mat4(), MONKEYS)
-  lovr.graphics.setShader()
+  return lovr.graphics.submit(computer, pass)
 end

+ 0 - 58
examples/Optimization/Mask/main.lua

@@ -1,58 +0,0 @@
-function lovr.load()
-  lovr.graphics.setBackgroundColor(1, 1, 1)
-  mask = lovr.headset.getDisplayMask()
-
-  -- Print the mesh, for debugging
-  if mask then
-    print('mask = {')
-    for i = 1, #mask do
-      print(string.format('\t{ %f, %f }', mask[i][1], mask[i][2]))
-    end
-    print('}')
-  else
-    print('No mask found')
-  end
-
-  shader = lovr.graphics.newShader([[
-    vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
-
-      // Rescale mesh coordinates from (0,1) to (-1,1)
-      vertex.xy *= 2.;
-      vertex.xy -= 1.;
-
-      // Flip the mesh if it's being drawn in the right eye
-      if (lovrViewID == 1) {
-        vertex.x = -vertex.x;
-      }
-
-      return vertex;
-    }
-  ]], [[
-    // The fragment shader returns solid black for illustration purposes.  It could be transparent.
-    vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
-      return vec4(0., 0., 0., 1.);
-    }
-  ]])
-
-  if mask then
-    mesh = lovr.graphics.newMesh({ { 'lovrPosition', 'float', 2 } }, mask, 'triangles')
-  end
-end
-
-function lovr.draw()
-  if mask then
-    -- Mask out parts of the display that aren't visible to skip rendering those pixels later
-    lovr.graphics.setShader(shader)
-    mesh:draw()
-    lovr.graphics.setShader()
-
-    -- Draw a red cube
-    lovr.graphics.setColor(0xff0000)
-    lovr.graphics.cube('fill', 0, 1.7, -1, .5, lovr.timer.getTime())
-    lovr.graphics.setColor(0xffffff)
-  else
-    lovr.graphics.setColor(0x000000)
-    lovr.graphics.print('No mask found.', 0, 1.7, -3, .2)
-    lovr.graphics.setColor(0xffffff)
-  end
-end