Feature request: Per-stage DefaultShaders
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.
This replaces a less-useful issue I filed: https://github.com/bjornbytes/lovr/issues/231
From a discussion:
lovr.graphics.getDefaultShaderCode(DefaultShader, [ShaderStage])
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.:
lovrComputeSkinningMatrixlovrGetVertexDepthlovrGetFogIntensitylovrGetAmbientOcclusionlovrGetDiffuseColorlovrGetEmissiveColorlovrGetNormalMatrixlovrComputeDirectLightinglovrComputeIndirectLightinglovrApplyTonemappinglovrEvaluateSphericalHarmonicslovrComputeStandardShading
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.
This is implemented on dev branch.