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
|
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
|
// Check https://wiki.ogre3d.org/tiki-index.php?page=-Point+Light+Attenuation for values
|
||||||
type PointLight struct {
|
type PointLight struct {
|
||||||
Pos gglm.Vec3
|
Pos gglm.Vec3
|
||||||
@ -99,12 +122,15 @@ var (
|
|||||||
yaw float32 = -1.5
|
yaw float32 = -1.5
|
||||||
cam *camera.Camera
|
cam *camera.Camera
|
||||||
|
|
||||||
renderToFbo = true
|
renderToDemoFbo = true
|
||||||
fboRenderDirectly = true
|
renderToBackBuffer = true
|
||||||
fboScale = gglm.NewVec2(0.25, 0.25)
|
demoFboScale = gglm.NewVec2(0.25, 0.25)
|
||||||
fboOffset = gglm.NewVec2(0.75, -0.75)
|
demoFboOffset = gglm.NewVec2(0.75, -0.75)
|
||||||
demoFbo buffers.Framebuffer
|
demoFbo buffers.Framebuffer
|
||||||
|
|
||||||
|
renderToDepthMapFbo = true
|
||||||
|
depthMapFboScale = gglm.NewVec2(0.25, 0.25)
|
||||||
|
depthMapFboOffset = gglm.NewVec2(0.75, -0.2)
|
||||||
depthMapFbo buffers.Framebuffer
|
depthMapFbo buffers.Framebuffer
|
||||||
|
|
||||||
screenQuadVao buffers.VertexArray
|
screenQuadVao buffers.VertexArray
|
||||||
@ -115,6 +141,7 @@ var (
|
|||||||
containerMat *materials.Material
|
containerMat *materials.Material
|
||||||
palleteMat *materials.Material
|
palleteMat *materials.Material
|
||||||
skyboxMat *materials.Material
|
skyboxMat *materials.Material
|
||||||
|
depthMapMat *materials.Material
|
||||||
debugDepthMat *materials.Material
|
debugDepthMat *materials.Material
|
||||||
|
|
||||||
cubeMesh *meshes.Mesh
|
cubeMesh *meshes.Mesh
|
||||||
@ -124,8 +151,8 @@ var (
|
|||||||
|
|
||||||
cubeModelMat = gglm.NewTrMatId()
|
cubeModelMat = gglm.NewTrMatId()
|
||||||
|
|
||||||
drawSkybox = true
|
renderSkybox = true
|
||||||
debugDrawDepthBuffer bool
|
renderDepthBuffer bool
|
||||||
|
|
||||||
skyboxCmap assets.Cubemap
|
skyboxCmap assets.Cubemap
|
||||||
|
|
||||||
@ -136,9 +163,9 @@ var (
|
|||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
dirLight = DirLight{
|
dirLight = DirLight{
|
||||||
Dir: *gglm.NewVec3(0, -0.8, 0.2).Normalize(),
|
Dir: *gglm.NewVec3(0.57735, -0.57735, 0.57735).Normalize(),
|
||||||
DiffuseColor: *gglm.NewVec3(0, 0, 0),
|
DiffuseColor: *gglm.NewVec3(1, 1, 1),
|
||||||
SpecularColor: *gglm.NewVec3(0, 0, 0),
|
SpecularColor: *gglm.NewVec3(1, 1, 1),
|
||||||
}
|
}
|
||||||
pointLights = [...]PointLight{
|
pointLights = [...]PointLight{
|
||||||
{
|
{
|
||||||
@ -236,7 +263,8 @@ func (g *Game) handleWindowEvents(e sdl.Event) {
|
|||||||
g.WinHeight = e.Data2
|
g.WinHeight = e.Data2
|
||||||
cam.AspectRatio = float32(g.WinWidth) / float32(g.WinHeight)
|
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
|
// Create materials and assign any unused texture slots to black
|
||||||
//
|
//
|
||||||
screenQuadMat = materials.NewMaterial("Screen Quad Mat", "./res/shaders/screen-quad.glsl")
|
screenQuadMat = materials.NewMaterial("Screen Quad Mat", "./res/shaders/screen-quad.glsl")
|
||||||
screenQuadMat.SetUnifVec2("scale", fboScale)
|
screenQuadMat.SetUnifVec2("scale", demoFboScale)
|
||||||
screenQuadMat.SetUnifVec2("offset", fboOffset)
|
screenQuadMat.SetUnifVec2("offset", demoFboOffset)
|
||||||
screenQuadMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
screenQuadMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||||
|
|
||||||
unlitMat = materials.NewMaterial("Unlit mat", "./res/shaders/simple-unlit.glsl")
|
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.dir", &dirLight.Dir)
|
||||||
whiteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
whiteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||||
whiteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
whiteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||||
|
whiteMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap))
|
||||||
|
|
||||||
containerMat = materials.NewMaterial("Container mat", "./res/shaders/simple.glsl")
|
containerMat = materials.NewMaterial("Container mat", "./res/shaders/simple.glsl")
|
||||||
containerMat.Shininess = 64
|
containerMat.Shininess = 64
|
||||||
@ -389,6 +418,7 @@ func (g *Game) Init() {
|
|||||||
containerMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
containerMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||||
containerMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
containerMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||||
containerMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
containerMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||||
|
containerMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap))
|
||||||
|
|
||||||
palleteMat = materials.NewMaterial("Pallete mat", "./res/shaders/simple.glsl")
|
palleteMat = materials.NewMaterial("Pallete mat", "./res/shaders/simple.glsl")
|
||||||
palleteMat.Shininess = 64
|
palleteMat.Shininess = 64
|
||||||
@ -404,9 +434,12 @@ func (g *Game) Init() {
|
|||||||
palleteMat.SetUnifFloat32("material.shininess", palleteMat.Shininess)
|
palleteMat.SetUnifFloat32("material.shininess", palleteMat.Shininess)
|
||||||
palleteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
palleteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
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")
|
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 = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl")
|
||||||
skyboxMat.CubemapTex = skyboxCmap.TexID
|
skyboxMat.CubemapTex = skyboxCmap.TexID
|
||||||
skyboxMat.SetUnifInt32("skybox", int32(materials.TextureSlot_Cubemap))
|
skyboxMat.SetUnifInt32("skybox", int32(materials.TextureSlot_Cubemap))
|
||||||
@ -425,9 +458,13 @@ func (g *Game) Init() {
|
|||||||
screenQuadVao = buffers.NewVertexArray()
|
screenQuadVao = buffers.NewVertexArray()
|
||||||
screenQuadVao.AddVertexBuffer(screenQuadVbo)
|
screenQuadVao.AddVertexBuffer(screenQuadVbo)
|
||||||
|
|
||||||
|
// Fbos and lights
|
||||||
g.initFbos()
|
g.initFbos()
|
||||||
g.updateLights()
|
g.updateLights()
|
||||||
updateProjViewMat()
|
|
||||||
|
// Initial camera update
|
||||||
|
cam.Update()
|
||||||
|
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) initFbos() {
|
func (g *Game) initFbos() {
|
||||||
@ -460,6 +497,12 @@ func (g *Game) initFbos() {
|
|||||||
|
|
||||||
func (g *Game) updateLights() {
|
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++ {
|
for i := 0; i < len(pointLights); i++ {
|
||||||
|
|
||||||
pl := &pointLights[i]
|
pl := &pointLights[i]
|
||||||
@ -490,6 +533,7 @@ func (g *Game) updateLights() {
|
|||||||
palleteMat.SetUnifFloat32(indexString+".quadratic", pl.Quadratic)
|
palleteMat.SetUnifFloat32(indexString+".quadratic", pl.Quadratic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Spotlights
|
||||||
for i := 0; i < len(spotLights); i++ {
|
for i := 0; i < len(spotLights); i++ {
|
||||||
|
|
||||||
l := &spotLights[i]
|
l := &spotLights[i]
|
||||||
@ -553,10 +597,12 @@ func (g *Game) showDebugWindow() {
|
|||||||
// Camera
|
// Camera
|
||||||
imgui.Text("Camera")
|
imgui.Text("Camera")
|
||||||
if imgui.DragFloat3("Cam Pos", &cam.Pos.Data) {
|
if imgui.DragFloat3("Cam Pos", &cam.Pos.Data) {
|
||||||
updateProjViewMat()
|
cam.Update()
|
||||||
|
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||||
}
|
}
|
||||||
if imgui.DragFloat3("Cam Forward", &cam.Forward.Data) {
|
if imgui.DragFloat3("Cam Forward", &cam.Forward.Data) {
|
||||||
updateProjViewMat()
|
cam.Update()
|
||||||
|
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.Spacing()
|
imgui.Spacing()
|
||||||
@ -572,17 +618,6 @@ func (g *Game) showDebugWindow() {
|
|||||||
|
|
||||||
imgui.Spacing()
|
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
|
// Directional light
|
||||||
imgui.Text("Directional Light")
|
imgui.Text("Directional Light")
|
||||||
|
|
||||||
@ -604,6 +639,22 @@ func (g *Game) showDebugWindow() {
|
|||||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
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()
|
imgui.Spacing()
|
||||||
|
|
||||||
// Point lights
|
// Point lights
|
||||||
@ -700,25 +751,24 @@ func (g *Game) showDebugWindow() {
|
|||||||
imgui.EndListBox()
|
imgui.EndListBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fbo
|
// Demo fbo
|
||||||
imgui.Text("Framebuffer")
|
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)
|
// Depth map fbo
|
||||||
imgui.Checkbox("Render Directly", &fboRenderDirectly)
|
imgui.Text("Depth Map Framebuffer")
|
||||||
|
imgui.Checkbox("Render to depth map FBO", &renderToDepthMapFbo)
|
||||||
if imgui.DragFloat2("Scale", &fboScale.Data) {
|
imgui.DragFloat2("Scale##1", &depthMapFboScale.Data)
|
||||||
screenQuadMat.SetUnifVec2("scale", fboScale)
|
imgui.DragFloat2("Offset##1", &depthMapFboOffset.Data)
|
||||||
}
|
|
||||||
|
|
||||||
if imgui.DragFloat2("Offset", &fboOffset.Data) {
|
|
||||||
screenQuadMat.SetUnifVec2("offset", fboOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
imgui.Text("Other Settings")
|
imgui.Text("Other Settings")
|
||||||
|
|
||||||
imgui.Checkbox("Draw Skybox", &drawSkybox)
|
imgui.Checkbox("Render skybox", &renderSkybox)
|
||||||
imgui.Checkbox("Debug depth buffer", &debugDrawDepthBuffer)
|
imgui.Checkbox("Render to back buffer", &renderToBackBuffer)
|
||||||
|
imgui.Checkbox("Render depth buffer", &renderDepthBuffer)
|
||||||
|
|
||||||
imgui.End()
|
imgui.End()
|
||||||
}
|
}
|
||||||
@ -746,7 +796,7 @@ func (g *Game) updateCameraLookAround() {
|
|||||||
// Update cam forward
|
// Update cam forward
|
||||||
cam.UpdateRotation(pitch, yaw)
|
cam.UpdateRotation(pitch, yaw)
|
||||||
|
|
||||||
updateProjViewMat()
|
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) updateCameraPos() {
|
func (g *Game) updateCameraPos() {
|
||||||
@ -777,45 +827,92 @@ func (g *Game) updateCameraPos() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if update {
|
if update {
|
||||||
updateProjViewMat()
|
cam.Update()
|
||||||
|
updateAllProjViewMats(cam.ProjMat, cam.ViewMat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Render() {
|
func (g *Game) Render() {
|
||||||
|
|
||||||
if !renderToFbo {
|
dirLightProjViewMat := dirLight.GetProjViewMat()
|
||||||
g.RenderScene()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
demoFbo.Bind()
|
// Set some uniforms
|
||||||
demoFbo.Clear()
|
whiteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||||
g.RenderScene()
|
whiteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||||
demoFbo.UnBind()
|
|
||||||
|
|
||||||
if fboRenderDirectly {
|
containerMat.SetUnifVec3("camPos", &cam.Pos)
|
||||||
g.RenderScene()
|
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)
|
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()
|
tempModelMatrix := cubeModelMat.Clone()
|
||||||
|
|
||||||
whiteMat.SetUnifVec3("camPos", &cam.Pos)
|
// See if we need overrides
|
||||||
containerMat.SetUnifVec3("camPos", &cam.Pos)
|
|
||||||
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
|
||||||
|
|
||||||
sunMat := palleteMat
|
sunMat := palleteMat
|
||||||
chairMat := palleteMat
|
chairMat := palleteMat
|
||||||
cubeMat := containerMat
|
cubeMat := containerMat
|
||||||
if debugDrawDepthBuffer {
|
|
||||||
sunMat = debugDepthMat
|
if overrideMat != nil {
|
||||||
chairMat = debugDepthMat
|
sunMat = overrideMat
|
||||||
cubeMat = debugDepthMat
|
chairMat = overrideMat
|
||||||
|
cubeMat = overrideMat
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw dir light
|
// Draw dir light
|
||||||
@ -843,10 +940,6 @@ func (g *Game) RenderScene() {
|
|||||||
}
|
}
|
||||||
tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0))
|
tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
if drawSkybox {
|
|
||||||
g.DrawSkybox()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) DrawSkybox() {
|
func (g *Game) DrawSkybox() {
|
||||||
@ -867,12 +960,9 @@ func (g *Game) DeInit() {
|
|||||||
g.Win.Destroy()
|
g.Win.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateProjViewMat() {
|
func updateAllProjViewMats(projMat, viewMat gglm.Mat4) {
|
||||||
|
|
||||||
cam.Update()
|
projViewMat := projMat.Clone().Mul(&viewMat)
|
||||||
|
|
||||||
projViewMat := cam.ProjMat.Clone()
|
|
||||||
projViewMat.Mul(&cam.ViewMat)
|
|
||||||
|
|
||||||
unlitMat.SetUnifMat4("projViewMat", projViewMat)
|
unlitMat.SetUnifMat4("projViewMat", projViewMat)
|
||||||
whiteMat.SetUnifMat4("projViewMat", projViewMat)
|
whiteMat.SetUnifMat4("projViewMat", projViewMat)
|
||||||
@ -881,14 +971,13 @@ func updateProjViewMat() {
|
|||||||
debugDepthMat.SetUnifMat4("projViewMat", projViewMat)
|
debugDepthMat.SetUnifMat4("projViewMat", projViewMat)
|
||||||
|
|
||||||
// Update skybox projViewMat
|
// Update skybox projViewMat
|
||||||
viewMat := cam.ViewMat.Clone()
|
skyboxViewMat := viewMat.Clone()
|
||||||
viewMat.Set(0, 3, 0)
|
skyboxViewMat.Set(0, 3, 0)
|
||||||
viewMat.Set(1, 3, 0)
|
skyboxViewMat.Set(1, 3, 0)
|
||||||
viewMat.Set(2, 3, 0)
|
skyboxViewMat.Set(2, 3, 0)
|
||||||
viewMat.Set(3, 0, 0)
|
skyboxViewMat.Set(3, 0, 0)
|
||||||
viewMat.Set(3, 1, 0)
|
skyboxViewMat.Set(3, 1, 0)
|
||||||
viewMat.Set(3, 2, 0)
|
skyboxViewMat.Set(3, 2, 0)
|
||||||
viewMat.Set(3, 3, 0)
|
skyboxViewMat.Set(3, 3, 0)
|
||||||
skyboxMat.SetUnifMat4("projViewMat", cam.ProjMat.Clone().Mul(viewMat))
|
skyboxMat.SetUnifMat4("projViewMat", projMat.Clone().Mul(skyboxViewMat))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ const (
|
|||||||
TextureSlot_Normal TextureSlot = 2
|
TextureSlot_Normal TextureSlot = 2
|
||||||
TextureSlot_Emission TextureSlot = 3
|
TextureSlot_Emission TextureSlot = 3
|
||||||
TextureSlot_Cubemap TextureSlot = 10
|
TextureSlot_Cubemap TextureSlot = 10
|
||||||
|
TextureSlot_ShadowMap TextureSlot = 11
|
||||||
)
|
)
|
||||||
|
|
||||||
type Material struct {
|
type Material struct {
|
||||||
@ -36,6 +37,9 @@ type Material struct {
|
|||||||
|
|
||||||
// Cubemap
|
// Cubemap
|
||||||
CubemapTex uint32
|
CubemapTex uint32
|
||||||
|
|
||||||
|
// Shadowmaps
|
||||||
|
ShadowMap uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Material) Bind() {
|
func (m *Material) Bind() {
|
||||||
@ -66,6 +70,11 @@ func (m *Material) Bind() {
|
|||||||
gl.ActiveTexture(uint32(gl.TEXTURE0 + TextureSlot_Cubemap))
|
gl.ActiveTexture(uint32(gl.TEXTURE0 + TextureSlot_Cubemap))
|
||||||
gl.BindTexture(gl.TEXTURE_CUBE_MAP, m.CubemapTex)
|
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() {
|
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 vec2 vertUV0;
|
||||||
out vec3 vertColor;
|
out vec3 vertColor;
|
||||||
out vec3 fragPos;
|
out vec3 fragPos;
|
||||||
|
out vec4 fragPosDirLight;
|
||||||
|
|
||||||
//MVP = Model View Projection
|
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
uniform mat4 projViewMat;
|
uniform mat4 projViewMat;
|
||||||
|
uniform mat4 dirLightProjViewMat;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -22,12 +23,15 @@ void main()
|
|||||||
// This produces the normal matrix that multiplies with the model normal to produce the
|
// 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
|
// 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;
|
||||||
|
vertNormal = mat3(transpose(inverse(modelMat))) * vertNormalIn;
|
||||||
|
|
||||||
vertUV0 = vertUV0In;
|
vertUV0 = vertUV0In;
|
||||||
vertColor = vertColorIn;
|
vertColor = vertColorIn;
|
||||||
|
|
||||||
vec4 modelVert = modelMat * vec4(vertPosIn, 1);
|
vec4 modelVert = modelMat * vec4(vertPosIn, 1);
|
||||||
fragPos = modelVert.xyz;
|
fragPos = modelVert.xyz;
|
||||||
|
fragPosDirLight = dirLightProjViewMat * vec4(fragPos, 1);
|
||||||
|
|
||||||
gl_Position = projViewMat * modelVert;
|
gl_Position = projViewMat * modelVert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +52,7 @@ struct DirLight {
|
|||||||
vec3 dir;
|
vec3 dir;
|
||||||
vec3 diffuseColor;
|
vec3 diffuseColor;
|
||||||
vec3 specularColor;
|
vec3 specularColor;
|
||||||
|
sampler2D shadowMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform DirLight dirLight;
|
uniform DirLight dirLight;
|
||||||
@ -83,6 +88,7 @@ in vec3 vertColor;
|
|||||||
in vec3 vertNormal;
|
in vec3 vertNormal;
|
||||||
in vec2 vertUV0;
|
in vec2 vertUV0;
|
||||||
in vec3 fragPos;
|
in vec3 fragPos;
|
||||||
|
in vec4 fragPosDirLight;
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
@ -93,6 +99,27 @@ vec4 emissionTexColor;
|
|||||||
vec3 normalizedVertNorm;
|
vec3 normalizedVertNorm;
|
||||||
vec3 viewDir;
|
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 CalcDirLight()
|
||||||
{
|
{
|
||||||
vec3 lightDir = normalize(-dirLight.dir);
|
vec3 lightDir = normalize(-dirLight.dir);
|
||||||
@ -106,7 +133,10 @@ vec3 CalcDirLight()
|
|||||||
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
||||||
vec3 finalSpecular = specularAmount * dirLight.specularColor * specularTexColor.rgb;
|
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)
|
vec3 CalcPointLight(PointLight pointLight)
|
||||||
|
|||||||
Reference in New Issue
Block a user