Created
December 21, 2022 16:55
-
-
Save jmiskovic/aaa905da484ab6a770d1fa518651ff18 to your computer and use it in GitHub Desktop.
directional shadow mapping in lovr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local light_pose = lovr.math.newMat4() | |
local light_view = lovr.math.newMat4() | |
local light_projection = lovr.math.newMat4():perspective(math.rad(120), 1, 0.01) | |
--light_projection:orthographic(-5, 5, -5, 5, 100, -100) -- why is near and far inverted? ¯\_(ツ)_/¯ | |
local depthBufferSize = 1024 | |
local depthtex = lovr.graphics.newTexture(depthBufferSize, depthBufferSize, {format = 'd32f', mipmaps = false, usage = {'render', 'sample'}}) | |
local shadowmapper = lovr.graphics.newShader( | |
[[ | |
layout( push_constant ) uniform constants { | |
mat4 LightSpaceMatrix; | |
} PushConstants; | |
layout(location = 1) out vec4 PositionLight; | |
vec4 lovrmain() { | |
PositionLight = PushConstants.LightSpaceMatrix * Transform * vec4(VertexPosition.xyz, 1.f); | |
return DefaultPosition; | |
} | |
]],[[ | |
layout(set = 2, binding = 0) uniform texture2D DepthBuffer; | |
layout(location = 1) in vec4 PositionLight; // fragment position inside the light-space | |
vec4 lovrmain() { | |
vec2 projCoords = PositionLight.xy / PositionLight.w * 0.5 + 0.5; | |
float closestDepth; | |
if ((projCoords.x > 0.) && (projCoords.x < 1.) && | |
(projCoords.y > 0.) && (projCoords.y < 1.)) | |
closestDepth = getPixel(DepthBuffer, projCoords).r; | |
else | |
closestDepth = 0.; | |
float currentDepth = PositionLight.z / PositionLight.w; | |
float currentDepth_biased = currentDepth + 0.00003; | |
float shadow = (currentDepth_biased < 0. || closestDepth < currentDepth_biased) ? 1.0 : 0.3; | |
vec4 color = DefaultColor; | |
return color * vec4(vec3(shadow), 1.0); | |
} | |
]]) | |
function drawScene(pass, depthFromLight) | |
local t = lovr.timer.getTime() | |
pass:setColor(0xf2b63d) -- rotating fan | |
pass:box(mat4(0, 1.75, -4):rotate(t, 0,1,0):rotate(math.pi / 3 * 0, 0,1,0):rotate(math.rad(10), 1,0,0):scale(1, 0.05, 0.15)) | |
pass:box(mat4(0, 1.75, -4):rotate(t, 0,1,0):rotate(math.pi / 3 * 1, 0,1,0):rotate(math.rad(10), 1,0,0):scale(1, 0.05, 0.15)) | |
pass:box(mat4(0, 1.75, -4):rotate(t, 0,1,0):rotate(math.pi / 3 * 2, 0,1,0):rotate(math.rad(10), 1,0,0):scale(1, 0.05, 0.15)) | |
pass:setColor(0x8fcccb) -- a vertical box | |
lovr.math.setRandomSeed(1) | |
for _ = 1, 20 do -- some boxy columns | |
local height = lovr.math.randomNormal(0.2, 1) | |
local shade = 0.3 + 0.4 * lovr.math.random() | |
pass:setColor(shade, shade, shade) | |
pass:box( | |
lovr.math.randomNormal(5, 0), | |
height / 2, | |
lovr.math.randomNormal(5, -4), | |
0.3, height, 0.3) | |
end | |
pass:setColor(0xd46e33) -- the floor | |
pass:box(0, 0, 0, 50, 0.2, 50) | |
end | |
function lovr.update(dt) | |
local t = lovr.timer.getTime() / 8 | |
light_pose:target( | |
vec3(1, 2.5, -4):add(2 * math.sin(t), 0, math.cos(t)), | |
vec3(0, 0, -4)) | |
light_view:set(light_pose):invert() | |
-- render to depth buffer from light perspective | |
local pass = lovr.graphics.getPass('render', {depth = {texture=depthtex}, samples = 1}) | |
pass:setCullMode('front') | |
pass:setProjection(1, light_projection) | |
pass:setViewPose(1, light_pose) | |
drawScene(pass) | |
lovr.graphics.submit(pass) | |
end | |
function lovr.draw(pass) | |
--[[ debug-output of depth buffer texture | |
local w, h = lovr.system.getWindowDimensions() | |
local size = h / 4 | |
pass:setViewport(0, 0, size, size) | |
pass:fill(depthtex) | |
pass:setViewport(0, 0, w, h) | |
--]] | |
pass:setCullMode('back') | |
pass:setColor(0xfff4e0) | |
pass:cone(mat4(light_pose):rotate(math.pi, 0,1,0):scale(0.07)) -- light position | |
pass:setShader(shadowmapper) | |
local light_space_matrix = light_projection * light_view | |
pass:send('LightSpaceMatrix', light_space_matrix) | |
pass:send('DepthBuffer', depthtex) | |
drawScene(pass) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment