mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Improving shadows
This commit is contained in:
32
main.go
32
main.go
@ -51,7 +51,7 @@ type DirLight struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dSize float32 = 50
|
dSize float32 = 30
|
||||||
dNear float32 = 1
|
dNear float32 = 1
|
||||||
dFar float32 = 50
|
dFar float32 = 50
|
||||||
dPos = gglm.NewVec3(0, 10, 0)
|
dPos = gglm.NewVec3(0, 10, 0)
|
||||||
@ -163,7 +163,7 @@ var (
|
|||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
dirLight = DirLight{
|
dirLight = DirLight{
|
||||||
Dir: *gglm.NewVec3(0.57735, -0.57735, 0.57735).Normalize(),
|
Dir: *gglm.NewVec3(0, -0.5, -0.8).Normalize(),
|
||||||
DiffuseColor: *gglm.NewVec3(1, 1, 1),
|
DiffuseColor: *gglm.NewVec3(1, 1, 1),
|
||||||
SpecularColor: *gglm.NewVec3(1, 1, 1),
|
SpecularColor: *gglm.NewVec3(1, 1, 1),
|
||||||
}
|
}
|
||||||
@ -848,10 +848,19 @@ func (g *Game) Render() {
|
|||||||
|
|
||||||
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
||||||
|
|
||||||
|
//
|
||||||
// Render depth map for shadows
|
// Render depth map for shadows
|
||||||
|
//
|
||||||
depthMapFbo.BindWithViewport()
|
depthMapFbo.BindWithViewport()
|
||||||
depthMapFbo.Clear()
|
depthMapFbo.Clear()
|
||||||
|
|
||||||
|
// Culling front faces helps 'peter panning' when
|
||||||
|
// drawing shadow maps, but works only for solids with a back face (i.e. quads won't cast shadows).
|
||||||
|
// Check more here: https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping
|
||||||
|
gl.CullFace(gl.FRONT)
|
||||||
g.RenderScene(depthMapMat)
|
g.RenderScene(depthMapMat)
|
||||||
|
gl.CullFace(gl.BACK)
|
||||||
|
|
||||||
depthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
|
depthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
|
||||||
|
|
||||||
if renderToDepthMapFbo {
|
if renderToDepthMapFbo {
|
||||||
@ -932,14 +941,21 @@ func (g *Game) RenderScene(overrideMat *materials.Material) {
|
|||||||
window.Rend.DrawMesh(cubeMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(0, -3, 0)).Scale(gglm.NewVec3(20, 1, 20)), cubeMat)
|
window.Rend.DrawMesh(cubeMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(0, -3, 0)).Scale(gglm.NewVec3(20, 1, 20)), cubeMat)
|
||||||
|
|
||||||
// Cubes
|
// Cubes
|
||||||
rowSize := 1
|
|
||||||
for y := 0; y < rowSize; y++ {
|
|
||||||
for x := 0; x < rowSize; x++ {
|
|
||||||
tempModelMatrix.Translate(gglm.NewVec3(-6, 0, 0))
|
tempModelMatrix.Translate(gglm.NewVec3(-6, 0, 0))
|
||||||
window.Rend.DrawMesh(cubeMesh, tempModelMatrix, cubeMat)
|
window.Rend.DrawMesh(cubeMesh, tempModelMatrix, cubeMat)
|
||||||
}
|
|
||||||
tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0))
|
tempModelMatrix.Translate(gglm.NewVec3(0, -1, -4))
|
||||||
}
|
window.Rend.DrawMesh(cubeMesh, tempModelMatrix, cubeMat)
|
||||||
|
|
||||||
|
// Cubes generator
|
||||||
|
// rowSize := 1
|
||||||
|
// for y := 0; y < rowSize; y++ {
|
||||||
|
// for x := 0; x < rowSize; x++ {
|
||||||
|
// tempModelMatrix.Translate(gglm.NewVec3(-6, 0, 0))
|
||||||
|
// window.Rend.DrawMesh(cubeMesh, tempModelMatrix, cubeMat)
|
||||||
|
// }
|
||||||
|
// tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0))
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) DrawSkybox() {
|
func (g *Game) DrawSkybox() {
|
||||||
|
|||||||
@ -99,7 +99,7 @@ vec4 emissionTexColor;
|
|||||||
vec3 normalizedVertNorm;
|
vec3 normalizedVertNorm;
|
||||||
vec3 viewDir;
|
vec3 viewDir;
|
||||||
|
|
||||||
float CalcShadow(sampler2D shadowMap)
|
float CalcShadow(sampler2D shadowMap, vec3 lightDir)
|
||||||
{
|
{
|
||||||
// Move from clip space to NDC
|
// Move from clip space to NDC
|
||||||
vec3 projCoords = fragPosDirLight.xyz / fragPosDirLight.w;
|
vec3 projCoords = fragPosDirLight.xyz / fragPosDirLight.w;
|
||||||
@ -113,9 +113,13 @@ float CalcShadow(sampler2D shadowMap)
|
|||||||
// Closest depth is the closest depth value from the light's perspective
|
// Closest depth is the closest depth value from the light's perspective
|
||||||
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
||||||
|
|
||||||
|
// Bias in the range [0.005, 0.05] depending on the angle, where a higher
|
||||||
|
// angle gives a higher bias, as shadow acne gets worse with angle
|
||||||
|
float bias = max(0.05 * (1.0 - dot(normalizedVertNorm, lightDir)), 0.005);
|
||||||
|
|
||||||
// If our depth is larger than the lights closest depth,
|
// If our depth is larger than the lights closest depth,
|
||||||
// then there is something closer to the light than us, and so we are in shadow
|
// then there is something closer to the light than us, and so we are in shadow
|
||||||
float shadow = currentDepth > closestDepth ? 1.0 : 0.0;
|
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||||
|
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
@ -134,7 +138,7 @@ vec3 CalcDirLight()
|
|||||||
vec3 finalSpecular = specularAmount * dirLight.specularColor * specularTexColor.rgb;
|
vec3 finalSpecular = specularAmount * dirLight.specularColor * specularTexColor.rgb;
|
||||||
|
|
||||||
// Shadow
|
// Shadow
|
||||||
float shadow = CalcShadow(dirLight.shadowMap);
|
float shadow = CalcShadow(dirLight.shadowMap, lightDir);
|
||||||
|
|
||||||
return (finalDiffuse + finalSpecular) * (1.0 - shadow);
|
return (finalDiffuse + finalSpecular) * (1.0 - shadow);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user