lovr icon indicating copy to clipboard operation
lovr copied to clipboard

Feature request: Per-stage DefaultShaders

Open mcclure opened this issue 4 years ago • 4 comments

I have a file shader/basic.lua in my standard Lovr project:

https://github.com/mcclure/lovr-ent/blob/stable/lua/shader/basic.lua

As you see, it consists entirely of copypastes from shaders.c. This is so I can do stuff like this:

local shaderBasic = require "shader.basic"
local redShader = lovr.graphics.newShader(shaderBasic.defaultVertex, [[
    vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
        return vec4(1,0,0,1);
    }
]], {} )

Lovr has a feature that halfway helps with this: https://lovr.org/docs/DefaultShader

This lets you request lovr.graphics.newShader("unlit"), and you get the default unlit vertex and fragment shaders.

It would be great if instead we could do: lovr.graphics.newShader("unlit", [[ vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { return vec4(1,0,0,1); } ]])

IE, newShader could recognize when vertex and fragment strings have been passed in but one is a DefaultShader, and insert the correct vertex or fragment shader from shaders.c. Then I wouldn't need basic.lua anymore.

mcclure avatar Apr 01 '20 20:04 mcclure

This replaces a less-useful issue I filed: https://github.com/bjornbytes/lovr/issues/231

mcclure avatar Apr 01 '20 20:04 mcclure

From a discussion:

lovr.graphics.getDefaultShaderCode(DefaultShader, [ShaderStage])

bjornbytes avatar May 20 '20 20:05 bjornbytes

Another thing that may help here is to split each shader into lots of tiny little helper functions. So you'd have dozens of these little functions e.g.:

  • lovrComputeSkinningMatrix
  • lovrGetVertexDepth
  • lovrGetFogIntensity
  • lovrGetAmbientOcclusion
  • lovrGetDiffuseColor
  • lovrGetEmissiveColor
  • lovrGetNormalMatrix
  • lovrComputeDirectLighting
  • lovrComputeIndirectLighting
  • lovrApplyTonemapping
  • lovrEvaluateSphericalHarmonics
  • lovrComputeStandardShading

They'd all be in the "prefix" section available to all shaders, and DefaultShaders would just be a few lines that wire some of the helper functions together. User shaders would then have an easier time extending built in stuff since they can more easily combine things together. THREE.js takes a similar approach to this.

I'd want to make sure it can work with SPIR-V though. Merging two spirv modules together manually at runtime doesn't seem too bad.

bjornbytes avatar Jun 07 '20 18:06 bjornbytes

This is implemented on dev branch.

bjornbytes avatar Aug 04 '22 21:08 bjornbytes