mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Basic directional shadows
This commit is contained in:
253
main.go
253
main.go
@ -50,6 +50,29 @@ type DirLight struct {
|
||||
SpecularColor gglm.Vec3
|
||||
}
|
||||
|
||||
var (
|
||||
dSize float32 = 50
|
||||
dNear float32 = 1
|
||||
dFar float32 = 50
|
||||
dPos = gglm.NewVec3(0, 10, 0)
|
||||
)
|
||||
|
||||
func (d *DirLight) GetProjViewMat() gglm.Mat4 {
|
||||
|
||||
// Some arbitrary position for the directional light
|
||||
pos := dPos //gglm.NewVec3(0, 10, 0)
|
||||
|
||||
size := dSize //float32(50)
|
||||
nearClip := dNear //float32(1)
|
||||
farClip := dFar //float32(50)
|
||||
|
||||
projMat := gglm.Ortho(-size, size, -size, size, nearClip, farClip).Mat4
|
||||
// viewMat := gglm.LookAtRH(pos, gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0)).Mat4
|
||||
viewMat := gglm.LookAtRH(pos, pos.Clone().Add(d.Dir.Clone().Scale(10)), gglm.NewVec3(0, 1, 0)).Mat4
|
||||
|
||||
return *projMat.Mul(&viewMat)
|
||||
}
|
||||
|
||||
// Check https://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation for values
|
||||
type PointLight struct {
|
||||
Pos gglm.Vec3
|
||||
@ -99,12 +122,15 @@ var (
|
||||
yaw float32 = -1.5
|
||||
cam *camera.Camera
|
||||
|
||||
renderToFbo = true
|
||||
fboRenderDirectly = true
|
||||
fboScale = gglm.NewVec2(0.25, 0.25)
|
||||
fboOffset = gglm.NewVec2(0.75, -0.75)
|
||||
renderToDemoFbo = true
|
||||
renderToBackBuffer = true
|
||||
demoFboScale = gglm.NewVec2(0.25, 0.25)
|
||||
demoFboOffset = gglm.NewVec2(0.75, -0.75)
|
||||
demoFbo buffers.Framebuffer
|
||||
|
||||
renderToDepthMapFbo = true
|
||||
depthMapFboScale = gglm.NewVec2(0.25, 0.25)
|
||||
depthMapFboOffset = gglm.NewVec2(0.75, -0.2)
|
||||
depthMapFbo buffers.Framebuffer
|
||||
|
||||
screenQuadVao buffers.VertexArray
|
||||
@ -115,6 +141,7 @@ var (
|
||||
containerMat *materials.Material
|
||||
palleteMat *materials.Material
|
||||
skyboxMat *materials.Material
|
||||
depthMapMat *materials.Material
|
||||
debugDepthMat *materials.Material
|
||||
|
||||
cubeMesh *meshes.Mesh
|
||||
@ -124,8 +151,8 @@ var (
|
||||
|
||||
cubeModelMat = gglm.NewTrMatId()
|
||||
|
||||
drawSkybox = true
|
||||
debugDrawDepthBuffer bool
|
||||
renderSkybox = true
|
||||
renderDepthBuffer bool
|
||||
|
||||
skyboxCmap assets.Cubemap
|
||||
|
||||
@ -136,9 +163,9 @@ var (
|
||||
|
||||
// Lights
|
||||
dirLight = DirLight{
|
||||
Dir: *gglm.NewVec3(0, -0.8, 0.2).Normalize(),
|
||||
DiffuseColor: *gglm.NewVec3(0, 0, 0),
|
||||
SpecularColor: *gglm.NewVec3(0, 0, 0),
|
||||
Dir: *gglm.NewVec3(0.57735, -0.57735, 0.57735).Normalize(),
|
||||
DiffuseColor: *gglm.NewVec3(1, 1, 1),
|
||||
SpecularColor: *gglm.NewVec3(1, 1, 1),
|
||||
}
|
||||
pointLights = [...]PointLight{
|
||||
{
|
||||
@ -236,7 +263,8 @@ func (g *Game) handleWindowEvents(e sdl.Event) {
|
||||
g.WinHeight = e.Data2
|
||||
cam.AspectRatio = float32(g.WinWidth) / float32(g.WinHeight)
|
||||
|
||||
updateProjViewMat()
|
||||
cam.Update()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -351,8 +379,8 @@ func (g *Game) Init() {
|
||||
// Create materials and assign any unused texture slots to black
|
||||
//
|
||||
screenQuadMat = materials.NewMaterial("Screen Quad Mat", "./res/shaders/screen-quad.glsl")
|
||||
screenQuadMat.SetUnifVec2("scale", fboScale)
|
||||
screenQuadMat.SetUnifVec2("offset", fboOffset)
|
||||
screenQuadMat.SetUnifVec2("scale", demoFboScale)
|
||||
screenQuadMat.SetUnifVec2("offset", demoFboOffset)
|
||||
screenQuadMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
|
||||
unlitMat = materials.NewMaterial("Unlit mat", "./res/shaders/simple-unlit.glsl")
|
||||
@ -373,6 +401,7 @@ func (g *Game) Init() {
|
||||
whiteMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
whiteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
whiteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
whiteMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap))
|
||||
|
||||
containerMat = materials.NewMaterial("Container mat", "./res/shaders/simple.glsl")
|
||||
containerMat.Shininess = 64
|
||||
@ -389,6 +418,7 @@ func (g *Game) Init() {
|
||||
containerMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
containerMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
containerMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
containerMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap))
|
||||
|
||||
palleteMat = materials.NewMaterial("Pallete mat", "./res/shaders/simple.glsl")
|
||||
palleteMat.Shininess = 64
|
||||
@ -404,9 +434,12 @@ func (g *Game) Init() {
|
||||
palleteMat.SetUnifFloat32("material.shininess", palleteMat.Shininess)
|
||||
palleteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
palleteMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap))
|
||||
|
||||
debugDepthMat = materials.NewMaterial("Debug depth mat", "./res/shaders/debug-depth.glsl")
|
||||
|
||||
depthMapMat = materials.NewMaterial("Depth Map mat", "./res/shaders/depth-map.glsl")
|
||||
|
||||
skyboxMat = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl")
|
||||
skyboxMat.CubemapTex = skyboxCmap.TexID
|
||||
skyboxMat.SetUnifInt32("skybox", int32(materials.TextureSlot_Cubemap))
|
||||
@ -425,9 +458,13 @@ func (g *Game) Init() {
|
||||
screenQuadVao = buffers.NewVertexArray()
|
||||
screenQuadVao.AddVertexBuffer(screenQuadVbo)
|
||||
|
||||
// Fbos and lights
|
||||
g.initFbos()
|
||||
g.updateLights()
|
||||
updateProjViewMat()
|
||||
|
||||
// Initial camera update
|
||||
cam.Update()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
|
||||
func (g *Game) initFbos() {
|
||||
@ -460,6 +497,12 @@ func (g *Game) initFbos() {
|
||||
|
||||
func (g *Game) updateLights() {
|
||||
|
||||
// Directional light
|
||||
whiteMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
||||
containerMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
||||
palleteMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
||||
|
||||
// Point lights
|
||||
for i := 0; i < len(pointLights); i++ {
|
||||
|
||||
pl := &pointLights[i]
|
||||
@ -490,6 +533,7 @@ func (g *Game) updateLights() {
|
||||
palleteMat.SetUnifFloat32(indexString+".quadratic", pl.Quadratic)
|
||||
}
|
||||
|
||||
// Spotlights
|
||||
for i := 0; i < len(spotLights); i++ {
|
||||
|
||||
l := &spotLights[i]
|
||||
@ -553,10 +597,12 @@ func (g *Game) showDebugWindow() {
|
||||
// Camera
|
||||
imgui.Text("Camera")
|
||||
if imgui.DragFloat3("Cam Pos", &cam.Pos.Data) {
|
||||
updateProjViewMat()
|
||||
cam.Update()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
if imgui.DragFloat3("Cam Forward", &cam.Forward.Data) {
|
||||
updateProjViewMat()
|
||||
cam.Update()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
|
||||
imgui.Spacing()
|
||||
@ -572,17 +618,6 @@ func (g *Game) showDebugWindow() {
|
||||
|
||||
imgui.Spacing()
|
||||
|
||||
// Specular
|
||||
imgui.Text("Specular Settings")
|
||||
|
||||
if imgui.DragFloat("Specular Shininess", &whiteMat.Shininess) {
|
||||
whiteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
containerMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
palleteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
}
|
||||
|
||||
imgui.Spacing()
|
||||
|
||||
// Directional light
|
||||
imgui.Text("Directional Light")
|
||||
|
||||
@ -604,6 +639,22 @@ func (g *Game) showDebugWindow() {
|
||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
}
|
||||
|
||||
imgui.DragFloat("dSize", &dSize)
|
||||
imgui.DragFloat("dNear", &dNear)
|
||||
imgui.DragFloat("dFar", &dFar)
|
||||
imgui.DragFloat3("dPos", &dPos.Data)
|
||||
|
||||
imgui.Spacing()
|
||||
|
||||
// Specular
|
||||
imgui.Text("Specular Settings")
|
||||
|
||||
if imgui.DragFloat("Specular Shininess", &whiteMat.Shininess) {
|
||||
whiteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
containerMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
palleteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
}
|
||||
|
||||
imgui.Spacing()
|
||||
|
||||
// Point lights
|
||||
@ -700,25 +751,24 @@ func (g *Game) showDebugWindow() {
|
||||
imgui.EndListBox()
|
||||
}
|
||||
|
||||
// Fbo
|
||||
imgui.Text("Framebuffer")
|
||||
// Demo fbo
|
||||
imgui.Text("Demo Framebuffer")
|
||||
imgui.Checkbox("Render to demo FBO", &renderToDemoFbo)
|
||||
imgui.DragFloat2("Scale##0", &demoFboScale.Data)
|
||||
imgui.DragFloat2("Offset##0", &demoFboOffset.Data)
|
||||
|
||||
imgui.Checkbox("Render to FBO", &renderToFbo)
|
||||
imgui.Checkbox("Render Directly", &fboRenderDirectly)
|
||||
|
||||
if imgui.DragFloat2("Scale", &fboScale.Data) {
|
||||
screenQuadMat.SetUnifVec2("scale", fboScale)
|
||||
}
|
||||
|
||||
if imgui.DragFloat2("Offset", &fboOffset.Data) {
|
||||
screenQuadMat.SetUnifVec2("offset", fboOffset)
|
||||
}
|
||||
// Depth map fbo
|
||||
imgui.Text("Depth Map Framebuffer")
|
||||
imgui.Checkbox("Render to depth map FBO", &renderToDepthMapFbo)
|
||||
imgui.DragFloat2("Scale##1", &depthMapFboScale.Data)
|
||||
imgui.DragFloat2("Offset##1", &depthMapFboOffset.Data)
|
||||
|
||||
// Other
|
||||
imgui.Text("Other Settings")
|
||||
|
||||
imgui.Checkbox("Draw Skybox", &drawSkybox)
|
||||
imgui.Checkbox("Debug depth buffer", &debugDrawDepthBuffer)
|
||||
imgui.Checkbox("Render skybox", &renderSkybox)
|
||||
imgui.Checkbox("Render to back buffer", &renderToBackBuffer)
|
||||
imgui.Checkbox("Render depth buffer", &renderDepthBuffer)
|
||||
|
||||
imgui.End()
|
||||
}
|
||||
@ -746,7 +796,7 @@ func (g *Game) updateCameraLookAround() {
|
||||
// Update cam forward
|
||||
cam.UpdateRotation(pitch, yaw)
|
||||
|
||||
updateProjViewMat()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
|
||||
func (g *Game) updateCameraPos() {
|
||||
@ -777,45 +827,92 @@ func (g *Game) updateCameraPos() {
|
||||
}
|
||||
|
||||
if update {
|
||||
updateProjViewMat()
|
||||
cam.Update()
|
||||
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Render() {
|
||||
|
||||
if !renderToFbo {
|
||||
g.RenderScene()
|
||||
return
|
||||
}
|
||||
dirLightProjViewMat := dirLight.GetProjViewMat()
|
||||
|
||||
demoFbo.Bind()
|
||||
demoFbo.Clear()
|
||||
g.RenderScene()
|
||||
demoFbo.UnBind()
|
||||
// Set some uniforms
|
||||
whiteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
whiteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
|
||||
if fboRenderDirectly {
|
||||
g.RenderScene()
|
||||
}
|
||||
containerMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
containerMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
|
||||
screenQuadMat.DiffuseTex = demoFbo.Attachments[0].Id
|
||||
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
|
||||
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
||||
|
||||
// Render depth map for shadows
|
||||
depthMapFbo.BindWithViewport()
|
||||
depthMapFbo.Clear()
|
||||
g.RenderScene(depthMapMat)
|
||||
depthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
|
||||
|
||||
if renderToDepthMapFbo {
|
||||
screenQuadMat.DiffuseTex = depthMapFbo.Attachments[0].Id
|
||||
screenQuadMat.SetUnifVec2("offset", depthMapFboOffset)
|
||||
screenQuadMat.SetUnifVec2("scale", depthMapFboScale)
|
||||
screenQuadMat.Bind()
|
||||
window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6)
|
||||
}
|
||||
|
||||
func (g *Game) RenderScene() {
|
||||
if renderToBackBuffer {
|
||||
|
||||
if renderDepthBuffer {
|
||||
g.RenderScene(debugDepthMat)
|
||||
} else {
|
||||
g.RenderScene(nil)
|
||||
}
|
||||
}
|
||||
|
||||
if renderSkybox {
|
||||
g.DrawSkybox()
|
||||
}
|
||||
|
||||
if renderToDemoFbo {
|
||||
|
||||
demoFbo.Bind()
|
||||
demoFbo.Clear()
|
||||
|
||||
if renderDepthBuffer {
|
||||
g.RenderScene(debugDepthMat)
|
||||
} else {
|
||||
g.RenderScene(nil)
|
||||
}
|
||||
|
||||
if renderSkybox {
|
||||
g.DrawSkybox()
|
||||
}
|
||||
|
||||
demoFbo.UnBind()
|
||||
|
||||
screenQuadMat.DiffuseTex = demoFbo.Attachments[0].Id
|
||||
screenQuadMat.SetUnifVec2("offset", demoFboOffset)
|
||||
screenQuadMat.SetUnifVec2("scale", demoFboScale)
|
||||
|
||||
window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) RenderScene(overrideMat *materials.Material) {
|
||||
|
||||
tempModelMatrix := cubeModelMat.Clone()
|
||||
|
||||
whiteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
containerMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
|
||||
// See if we need overrides
|
||||
sunMat := palleteMat
|
||||
chairMat := palleteMat
|
||||
cubeMat := containerMat
|
||||
if debugDrawDepthBuffer {
|
||||
sunMat = debugDepthMat
|
||||
chairMat = debugDepthMat
|
||||
cubeMat = debugDepthMat
|
||||
|
||||
if overrideMat != nil {
|
||||
sunMat = overrideMat
|
||||
chairMat = overrideMat
|
||||
cubeMat = overrideMat
|
||||
}
|
||||
|
||||
// Draw dir light
|
||||
@ -843,10 +940,6 @@ func (g *Game) RenderScene() {
|
||||
}
|
||||
tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0))
|
||||
}
|
||||
|
||||
if drawSkybox {
|
||||
g.DrawSkybox()
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) DrawSkybox() {
|
||||
@ -867,12 +960,9 @@ func (g *Game) DeInit() {
|
||||
g.Win.Destroy()
|
||||
}
|
||||
|
||||
func updateProjViewMat() {
|
||||
func updateAllProjViewMats(projMat, viewMat gglm.Mat4) {
|
||||
|
||||
cam.Update()
|
||||
|
||||
projViewMat := cam.ProjMat.Clone()
|
||||
projViewMat.Mul(&cam.ViewMat)
|
||||
projViewMat := projMat.Clone().Mul(&viewMat)
|
||||
|
||||
unlitMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
whiteMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
@ -881,14 +971,13 @@ func updateProjViewMat() {
|
||||
debugDepthMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
|
||||
// Update skybox projViewMat
|
||||
viewMat := cam.ViewMat.Clone()
|
||||
viewMat.Set(0, 3, 0)
|
||||
viewMat.Set(1, 3, 0)
|
||||
viewMat.Set(2, 3, 0)
|
||||
viewMat.Set(3, 0, 0)
|
||||
viewMat.Set(3, 1, 0)
|
||||
viewMat.Set(3, 2, 0)
|
||||
viewMat.Set(3, 3, 0)
|
||||
skyboxMat.SetUnifMat4("projViewMat", cam.ProjMat.Clone().Mul(viewMat))
|
||||
|
||||
skyboxViewMat := viewMat.Clone()
|
||||
skyboxViewMat.Set(0, 3, 0)
|
||||
skyboxViewMat.Set(1, 3, 0)
|
||||
skyboxViewMat.Set(2, 3, 0)
|
||||
skyboxViewMat.Set(3, 0, 0)
|
||||
skyboxViewMat.Set(3, 1, 0)
|
||||
skyboxViewMat.Set(3, 2, 0)
|
||||
skyboxViewMat.Set(3, 3, 0)
|
||||
skyboxMat.SetUnifMat4("projViewMat", projMat.Clone().Mul(skyboxViewMat))
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ const (
|
||||
TextureSlot_Normal TextureSlot = 2
|
||||
TextureSlot_Emission TextureSlot = 3
|
||||
TextureSlot_Cubemap TextureSlot = 10
|
||||
TextureSlot_ShadowMap TextureSlot = 11
|
||||
)
|
||||
|
||||
type Material struct {
|
||||
@ -36,6 +37,9 @@ type Material struct {
|
||||
|
||||
// Cubemap
|
||||
CubemapTex uint32
|
||||
|
||||
// Shadowmaps
|
||||
ShadowMap uint32
|
||||
}
|
||||
|
||||
func (m *Material) Bind() {
|
||||
@ -66,6 +70,11 @@ func (m *Material) Bind() {
|
||||
gl.ActiveTexture(uint32(gl.TEXTURE0 + TextureSlot_Cubemap))
|
||||
gl.BindTexture(gl.TEXTURE_CUBE_MAP, m.CubemapTex)
|
||||
}
|
||||
|
||||
if m.ShadowMap != 0 {
|
||||
gl.ActiveTexture(uint32(gl.TEXTURE0 + TextureSlot_ShadowMap))
|
||||
gl.BindTexture(gl.TEXTURE_2D, m.ShadowMap)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Material) UnBind() {
|
||||
|
||||
21
res/shaders/depth-map.glsl
Executable file
21
res/shaders/depth-map.glsl
Executable file
@ -0,0 +1,21 @@
|
||||
//shader:vertex
|
||||
#version 410
|
||||
|
||||
layout(location=0) in vec3 vertPosIn;
|
||||
|
||||
uniform mat4 modelMat;
|
||||
uniform mat4 projViewMat;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projViewMat * modelMat * vec4(vertPosIn, 1);
|
||||
}
|
||||
|
||||
//shader:fragment
|
||||
#version 410
|
||||
|
||||
void main()
|
||||
{
|
||||
// This implicitly writes to the depth buffer with no color operations
|
||||
// Equivalent: gl_FragDepth = gl_FragCoord.z;
|
||||
}
|
||||
@ -10,10 +10,11 @@ out vec3 vertNormal;
|
||||
out vec2 vertUV0;
|
||||
out vec3 vertColor;
|
||||
out vec3 fragPos;
|
||||
out vec4 fragPosDirLight;
|
||||
|
||||
//MVP = Model View Projection
|
||||
uniform mat4 modelMat;
|
||||
uniform mat4 projViewMat;
|
||||
uniform mat4 dirLightProjViewMat;
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -22,12 +23,15 @@ void main()
|
||||
// This produces the normal matrix that multiplies with the model normal to produce the
|
||||
// world space normal. Based on 'One last thing' section from: https://learnopengl.com/Lighting/Basic-Lighting
|
||||
vertNormal = mat3(transpose(inverse(modelMat))) * vertNormalIn;
|
||||
vertNormal = mat3(transpose(inverse(modelMat))) * vertNormalIn;
|
||||
|
||||
vertUV0 = vertUV0In;
|
||||
vertColor = vertColorIn;
|
||||
|
||||
vec4 modelVert = modelMat * vec4(vertPosIn, 1);
|
||||
fragPos = modelVert.xyz;
|
||||
fragPosDirLight = dirLightProjViewMat * vec4(fragPos, 1);
|
||||
|
||||
gl_Position = projViewMat * modelVert;
|
||||
}
|
||||
|
||||
@ -48,6 +52,7 @@ struct DirLight {
|
||||
vec3 dir;
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
sampler2D shadowMap;
|
||||
};
|
||||
|
||||
uniform DirLight dirLight;
|
||||
@ -83,6 +88,7 @@ in vec3 vertColor;
|
||||
in vec3 vertNormal;
|
||||
in vec2 vertUV0;
|
||||
in vec3 fragPos;
|
||||
in vec4 fragPosDirLight;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
@ -93,6 +99,27 @@ vec4 emissionTexColor;
|
||||
vec3 normalizedVertNorm;
|
||||
vec3 viewDir;
|
||||
|
||||
float CalcShadow(sampler2D shadowMap)
|
||||
{
|
||||
// Move from clip space to NDC
|
||||
vec3 projCoords = fragPosDirLight.xyz / fragPosDirLight.w;
|
||||
|
||||
// Move from [-1,1] to [0, 1]
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
// currentDepth is the fragment depth from the light's perspective
|
||||
float currentDepth = projCoords.z;
|
||||
|
||||
// Closest depth is the closest depth value from the light's perspective
|
||||
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
||||
|
||||
// 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
|
||||
float shadow = currentDepth > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
vec3 CalcDirLight()
|
||||
{
|
||||
vec3 lightDir = normalize(-dirLight.dir);
|
||||
@ -106,7 +133,10 @@ vec3 CalcDirLight()
|
||||
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
||||
vec3 finalSpecular = specularAmount * dirLight.specularColor * specularTexColor.rgb;
|
||||
|
||||
return finalDiffuse + finalSpecular;
|
||||
// Shadow
|
||||
float shadow = CalcShadow(dirLight.shadowMap);
|
||||
|
||||
return (finalDiffuse + finalSpecular) * (1.0 - shadow);
|
||||
}
|
||||
|
||||
vec3 CalcPointLight(PointLight pointLight)
|
||||
|
||||
Reference in New Issue
Block a user