mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Normal mapping
This commit is contained in:
101
main.go
101
main.go
@ -36,6 +36,7 @@ import (
|
||||
- Point light shadows ✅
|
||||
- Spotlight shadows ✅
|
||||
- Create VAO struct independent from VBO to support multi-VBO use cases (e.g. instancing) ✅
|
||||
- Normals maps
|
||||
- UBO support
|
||||
- HDR
|
||||
- Cascaded shadow mapping
|
||||
@ -226,6 +227,7 @@ var (
|
||||
unlitMat materials.Material
|
||||
whiteMat materials.Material
|
||||
containerMat materials.Material
|
||||
groundMat materials.Material
|
||||
palleteMat materials.Material
|
||||
skyboxMat materials.Material
|
||||
depthMapMat materials.Material
|
||||
@ -309,8 +311,8 @@ var (
|
||||
InnerCutoffRad: 15 * gglm.Deg2Rad,
|
||||
OuterCutoffRad: 20 * gglm.Deg2Rad,
|
||||
|
||||
NearPlane: 1,
|
||||
FarPlane: 30,
|
||||
NearPlane: 2,
|
||||
FarPlane: 50,
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -498,6 +500,16 @@ func (g *Game) Init() {
|
||||
logging.ErrLog.Fatalln("Failed to load texture. Err: ", err)
|
||||
}
|
||||
|
||||
brickwallDiffuseTex, err := assets.LoadTexturePNG("./res/textures/brickwall.png", &assets.TextureLoadOptions{})
|
||||
if err != nil {
|
||||
logging.ErrLog.Fatalln("Failed to load texture. Err: ", err)
|
||||
}
|
||||
|
||||
brickwallNormalTex, err := assets.LoadTexturePNG("./res/textures/brickwall-normal.png", &assets.TextureLoadOptions{})
|
||||
if err != nil {
|
||||
logging.ErrLog.Fatalln("Failed to load texture. Err: ", err)
|
||||
}
|
||||
|
||||
skyboxCmap, err = assets.LoadCubemapTextures(
|
||||
"./res/textures/sb-right.jpg", "./res/textures/sb-left.jpg",
|
||||
"./res/textures/sb-top.jpg", "./res/textures/sb-bottom.jpg",
|
||||
@ -517,11 +529,11 @@ func (g *Game) Init() {
|
||||
screenQuadMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
|
||||
unlitMat = materials.NewMaterial("Unlit mat", "./res/shaders/simple-unlit.glsl")
|
||||
unlitMat.Settings.Set(materials.MaterialSettings_HasModelMat)
|
||||
unlitMat.Settings.Set(materials.MaterialSettings_HasModelMtx)
|
||||
unlitMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
|
||||
whiteMat = materials.NewMaterial("White mat", "./res/shaders/simple.glsl")
|
||||
whiteMat.Settings.Set(materials.MaterialSettings_HasModelMat | materials.MaterialSettings_HasNormalMat)
|
||||
whiteMat.Settings.Set(materials.MaterialSettings_HasModelMtx | materials.MaterialSettings_HasNormalMtx)
|
||||
whiteMat.Shininess = 64
|
||||
whiteMat.DiffuseTex = whiteTex.TexID
|
||||
whiteMat.SpecularTex = blackTex.TexID
|
||||
@ -529,7 +541,7 @@ func (g *Game) Init() {
|
||||
whiteMat.EmissionTex = blackTex.TexID
|
||||
whiteMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
whiteMat.SetUnifInt32("material.specular", int32(materials.TextureSlot_Specular))
|
||||
// whiteMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
whiteMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
whiteMat.SetUnifInt32("material.emission", int32(materials.TextureSlot_Emission))
|
||||
whiteMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
whiteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
@ -541,7 +553,7 @@ func (g *Game) Init() {
|
||||
whiteMat.SetUnifInt32("spotLightShadowMaps", int32(materials.TextureSlot_ShadowMap_Array1))
|
||||
|
||||
containerMat = materials.NewMaterial("Container mat", "./res/shaders/simple.glsl")
|
||||
containerMat.Settings.Set(materials.MaterialSettings_HasModelMat | materials.MaterialSettings_HasNormalMat)
|
||||
containerMat.Settings.Set(materials.MaterialSettings_HasModelMtx | materials.MaterialSettings_HasNormalMtx)
|
||||
containerMat.Shininess = 64
|
||||
containerMat.DiffuseTex = containerDiffuseTex.TexID
|
||||
containerMat.SpecularTex = containerSpecularTex.TexID
|
||||
@ -549,7 +561,7 @@ func (g *Game) Init() {
|
||||
containerMat.EmissionTex = blackTex.TexID
|
||||
containerMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
containerMat.SetUnifInt32("material.specular", int32(materials.TextureSlot_Specular))
|
||||
// containerMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
containerMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
containerMat.SetUnifInt32("material.emission", int32(materials.TextureSlot_Emission))
|
||||
containerMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
containerMat.SetUnifFloat32("material.shininess", containerMat.Shininess)
|
||||
@ -560,8 +572,28 @@ func (g *Game) Init() {
|
||||
containerMat.SetUnifInt32("pointLightCubeShadowMaps", int32(materials.TextureSlot_Cubemap_Array))
|
||||
containerMat.SetUnifInt32("spotLightShadowMaps", int32(materials.TextureSlot_ShadowMap_Array1))
|
||||
|
||||
groundMat = materials.NewMaterial("Ground mat", "./res/shaders/simple.glsl")
|
||||
groundMat.Settings.Set(materials.MaterialSettings_HasModelMtx | materials.MaterialSettings_HasNormalMtx)
|
||||
groundMat.Shininess = 64
|
||||
groundMat.DiffuseTex = brickwallDiffuseTex.TexID
|
||||
groundMat.SpecularTex = blackTex.TexID
|
||||
groundMat.NormalTex = brickwallNormalTex.TexID
|
||||
groundMat.EmissionTex = blackTex.TexID
|
||||
groundMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
groundMat.SetUnifInt32("material.specular", int32(materials.TextureSlot_Specular))
|
||||
groundMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
groundMat.SetUnifInt32("material.emission", int32(materials.TextureSlot_Emission))
|
||||
groundMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
groundMat.SetUnifFloat32("material.shininess", groundMat.Shininess)
|
||||
groundMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
groundMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
groundMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
groundMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap1))
|
||||
groundMat.SetUnifInt32("pointLightCubeShadowMaps", int32(materials.TextureSlot_Cubemap_Array))
|
||||
groundMat.SetUnifInt32("spotLightShadowMaps", int32(materials.TextureSlot_ShadowMap_Array1))
|
||||
|
||||
palleteMat = materials.NewMaterial("Pallete mat", "./res/shaders/simple.glsl")
|
||||
palleteMat.Settings.Set(materials.MaterialSettings_HasModelMat | materials.MaterialSettings_HasNormalMat)
|
||||
palleteMat.Settings.Set(materials.MaterialSettings_HasModelMtx | materials.MaterialSettings_HasNormalMtx)
|
||||
palleteMat.Shininess = 64
|
||||
palleteMat.DiffuseTex = palleteTex.TexID
|
||||
palleteMat.SpecularTex = blackTex.TexID
|
||||
@ -569,10 +601,11 @@ func (g *Game) Init() {
|
||||
palleteMat.EmissionTex = blackTex.TexID
|
||||
palleteMat.SetUnifInt32("material.diffuse", int32(materials.TextureSlot_Diffuse))
|
||||
palleteMat.SetUnifInt32("material.specular", int32(materials.TextureSlot_Specular))
|
||||
// palleteMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
palleteMat.SetUnifInt32("material.normal", int32(materials.TextureSlot_Normal))
|
||||
palleteMat.SetUnifInt32("material.emission", int32(materials.TextureSlot_Emission))
|
||||
palleteMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
palleteMat.SetUnifFloat32("material.shininess", palleteMat.Shininess)
|
||||
palleteMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
palleteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
palleteMat.SetUnifInt32("dirLight.shadowMap", int32(materials.TextureSlot_ShadowMap1))
|
||||
@ -580,16 +613,16 @@ func (g *Game) Init() {
|
||||
palleteMat.SetUnifInt32("spotLightShadowMaps", int32(materials.TextureSlot_ShadowMap_Array1))
|
||||
|
||||
debugDepthMat = materials.NewMaterial("Debug depth mat", "./res/shaders/debug-depth.glsl")
|
||||
debugDepthMat.Settings.Set(materials.MaterialSettings_HasModelMat)
|
||||
debugDepthMat.Settings.Set(materials.MaterialSettings_HasModelMtx)
|
||||
|
||||
depthMapMat = materials.NewMaterial("Depth Map mat", "./res/shaders/depth-map.glsl")
|
||||
depthMapMat.Settings.Set(materials.MaterialSettings_HasModelMat)
|
||||
depthMapMat.Settings.Set(materials.MaterialSettings_HasModelMtx)
|
||||
|
||||
arrayDepthMapMat = materials.NewMaterial("Array Depth Map mat", "./res/shaders/array-depth-map.glsl")
|
||||
arrayDepthMapMat.Settings.Set(materials.MaterialSettings_HasModelMat)
|
||||
arrayDepthMapMat.Settings.Set(materials.MaterialSettings_HasModelMtx)
|
||||
|
||||
omnidirDepthMapMat = materials.NewMaterial("Omnidirectional Depth Map mat", "./res/shaders/omnidirectional-depth-map.glsl")
|
||||
omnidirDepthMapMat.Settings.Set(materials.MaterialSettings_HasModelMat)
|
||||
omnidirDepthMapMat.Settings.Set(materials.MaterialSettings_HasModelMtx)
|
||||
|
||||
skyboxMat = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl")
|
||||
skyboxMat.CubemapTex = skyboxCmap.TexID
|
||||
@ -674,6 +707,7 @@ func (g *Game) updateLights() {
|
||||
// Directional light
|
||||
whiteMat.ShadowMapTex1 = dirLightDepthMapFbo.Attachments[0].Id
|
||||
containerMat.ShadowMapTex1 = dirLightDepthMapFbo.Attachments[0].Id
|
||||
groundMat.ShadowMapTex1 = dirLightDepthMapFbo.Attachments[0].Id
|
||||
palleteMat.ShadowMapTex1 = dirLightDepthMapFbo.Attachments[0].Id
|
||||
|
||||
// Point lights
|
||||
@ -684,35 +718,43 @@ func (g *Game) updateLights() {
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".pos", &p.Pos)
|
||||
containerMat.SetUnifVec3(indexString+".pos", &p.Pos)
|
||||
groundMat.SetUnifVec3(indexString+".pos", &p.Pos)
|
||||
palleteMat.SetUnifVec3(indexString+".pos", &p.Pos)
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".diffuseColor", &p.DiffuseColor)
|
||||
containerMat.SetUnifVec3(indexString+".diffuseColor", &p.DiffuseColor)
|
||||
groundMat.SetUnifVec3(indexString+".diffuseColor", &p.DiffuseColor)
|
||||
palleteMat.SetUnifVec3(indexString+".diffuseColor", &p.DiffuseColor)
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".specularColor", &p.SpecularColor)
|
||||
containerMat.SetUnifVec3(indexString+".specularColor", &p.SpecularColor)
|
||||
groundMat.SetUnifVec3(indexString+".specularColor", &p.SpecularColor)
|
||||
palleteMat.SetUnifVec3(indexString+".specularColor", &p.SpecularColor)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".constant", p.Constant)
|
||||
containerMat.SetUnifFloat32(indexString+".constant", p.Constant)
|
||||
groundMat.SetUnifFloat32(indexString+".constant", p.Constant)
|
||||
palleteMat.SetUnifFloat32(indexString+".constant", p.Constant)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".linear", p.Linear)
|
||||
containerMat.SetUnifFloat32(indexString+".linear", p.Linear)
|
||||
groundMat.SetUnifFloat32(indexString+".linear", p.Linear)
|
||||
palleteMat.SetUnifFloat32(indexString+".linear", p.Linear)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".quadratic", p.Quadratic)
|
||||
containerMat.SetUnifFloat32(indexString+".quadratic", p.Quadratic)
|
||||
groundMat.SetUnifFloat32(indexString+".quadratic", p.Quadratic)
|
||||
palleteMat.SetUnifFloat32(indexString+".quadratic", p.Quadratic)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".farPlane", p.FarPlane)
|
||||
containerMat.SetUnifFloat32(indexString+".farPlane", p.FarPlane)
|
||||
groundMat.SetUnifFloat32(indexString+".farPlane", p.FarPlane)
|
||||
palleteMat.SetUnifFloat32(indexString+".farPlane", p.FarPlane)
|
||||
}
|
||||
|
||||
whiteMat.CubemapArrayTex = pointLightDepthMapFbo.Attachments[0].Id
|
||||
containerMat.CubemapArrayTex = pointLightDepthMapFbo.Attachments[0].Id
|
||||
groundMat.CubemapArrayTex = pointLightDepthMapFbo.Attachments[0].Id
|
||||
palleteMat.CubemapArrayTex = pointLightDepthMapFbo.Attachments[0].Id
|
||||
|
||||
// Spotlights
|
||||
@ -726,31 +768,38 @@ func (g *Game) updateLights() {
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
containerMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
groundMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
palleteMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
containerMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
groundMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
palleteMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
containerMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
groundMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
palleteMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
|
||||
whiteMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
containerMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
groundMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
palleteMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".innerCutoff", innerCutoffCos)
|
||||
containerMat.SetUnifFloat32(indexString+".innerCutoff", innerCutoffCos)
|
||||
groundMat.SetUnifFloat32(indexString+".innerCutoff", innerCutoffCos)
|
||||
palleteMat.SetUnifFloat32(indexString+".innerCutoff", innerCutoffCos)
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".outerCutoff", outerCutoffCos)
|
||||
containerMat.SetUnifFloat32(indexString+".outerCutoff", outerCutoffCos)
|
||||
groundMat.SetUnifFloat32(indexString+".outerCutoff", outerCutoffCos)
|
||||
palleteMat.SetUnifFloat32(indexString+".outerCutoff", outerCutoffCos)
|
||||
}
|
||||
|
||||
whiteMat.ShadowMapTexArray1 = spotLightDepthMapFbo.Attachments[0].Id
|
||||
containerMat.ShadowMapTexArray1 = spotLightDepthMapFbo.Attachments[0].Id
|
||||
groundMat.ShadowMapTexArray1 = spotLightDepthMapFbo.Attachments[0].Id
|
||||
palleteMat.ShadowMapTexArray1 = spotLightDepthMapFbo.Attachments[0].Id
|
||||
}
|
||||
|
||||
@ -797,6 +846,7 @@ func (g *Game) showDebugWindow() {
|
||||
if imgui.DragFloat3("Ambient Color", &ambientColor.Data) {
|
||||
whiteMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
containerMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
groundMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
palleteMat.SetUnifVec3("ambientColor", &ambientColor)
|
||||
}
|
||||
|
||||
@ -810,18 +860,21 @@ func (g *Game) showDebugWindow() {
|
||||
if imgui.DragFloat3("Direction", &dirLight.Dir.Data) {
|
||||
whiteMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
containerMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
groundMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
palleteMat.SetUnifVec3("dirLight.dir", &dirLight.Dir)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Diffuse Color", &dirLight.DiffuseColor.Data) {
|
||||
whiteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
containerMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
groundMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
palleteMat.SetUnifVec3("dirLight.diffuseColor", &dirLight.DiffuseColor)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Specular Color", &dirLight.SpecularColor.Data) {
|
||||
whiteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
containerMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
groundMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
palleteMat.SetUnifVec3("dirLight.specularColor", &dirLight.SpecularColor)
|
||||
}
|
||||
|
||||
@ -838,6 +891,7 @@ func (g *Game) showDebugWindow() {
|
||||
if imgui.DragFloat("Specular Shininess", &whiteMat.Shininess) {
|
||||
whiteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
containerMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
groundMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
palleteMat.SetUnifFloat32("material.shininess", whiteMat.Shininess)
|
||||
}
|
||||
|
||||
@ -861,18 +915,21 @@ func (g *Game) showDebugWindow() {
|
||||
if imgui.DragFloat3("Pos", &pl.Pos.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".pos", &pl.Pos)
|
||||
containerMat.SetUnifVec3(indexString+".pos", &pl.Pos)
|
||||
groundMat.SetUnifVec3(indexString+".pos", &pl.Pos)
|
||||
palleteMat.SetUnifVec3(indexString+".pos", &pl.Pos)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Diffuse Color", &pl.DiffuseColor.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".diffuseColor", &pl.DiffuseColor)
|
||||
containerMat.SetUnifVec3(indexString+".diffuseColor", &pl.DiffuseColor)
|
||||
groundMat.SetUnifVec3(indexString+".diffuseColor", &pl.DiffuseColor)
|
||||
palleteMat.SetUnifVec3(indexString+".diffuseColor", &pl.DiffuseColor)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Specular Color", &pl.SpecularColor.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".specularColor", &pl.SpecularColor)
|
||||
containerMat.SetUnifVec3(indexString+".specularColor", &pl.SpecularColor)
|
||||
groundMat.SetUnifVec3(indexString+".specularColor", &pl.SpecularColor)
|
||||
palleteMat.SetUnifVec3(indexString+".specularColor", &pl.SpecularColor)
|
||||
}
|
||||
|
||||
@ -901,24 +958,28 @@ func (g *Game) showDebugWindow() {
|
||||
if imgui.DragFloat3("Pos", &l.Pos.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
containerMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
groundMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
palleteMat.SetUnifVec3(indexString+".pos", &l.Pos)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Dir", &l.Dir.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
containerMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
groundMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
palleteMat.SetUnifVec3(indexString+".dir", &l.Dir)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Diffuse Color", &l.DiffuseColor.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
containerMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
groundMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
palleteMat.SetUnifVec3(indexString+".diffuseColor", &l.DiffuseColor)
|
||||
}
|
||||
|
||||
if imgui.DragFloat3("Specular Color", &l.SpecularColor.Data) {
|
||||
whiteMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
containerMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
groundMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
palleteMat.SetUnifVec3(indexString+".specularColor", &l.SpecularColor)
|
||||
}
|
||||
|
||||
@ -928,6 +989,7 @@ func (g *Game) showDebugWindow() {
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".innerCutoff", cos)
|
||||
containerMat.SetUnifFloat32(indexString+".innerCutoff", cos)
|
||||
groundMat.SetUnifFloat32(indexString+".innerCutoff", cos)
|
||||
palleteMat.SetUnifFloat32(indexString+".innerCutoff", cos)
|
||||
}
|
||||
|
||||
@ -937,6 +999,7 @@ func (g *Game) showDebugWindow() {
|
||||
|
||||
whiteMat.SetUnifFloat32(indexString+".outerCutoff", cos)
|
||||
containerMat.SetUnifFloat32(indexString+".outerCutoff", cos)
|
||||
groundMat.SetUnifFloat32(indexString+".outerCutoff", cos)
|
||||
palleteMat.SetUnifFloat32(indexString+".outerCutoff", cos)
|
||||
}
|
||||
|
||||
@ -1033,8 +1096,8 @@ func (g *Game) updateCameraPos() {
|
||||
}
|
||||
|
||||
var (
|
||||
renderDirLightShadows = true
|
||||
renderPointLightShadows = true
|
||||
renderDirLightShadows = false
|
||||
renderPointLightShadows = false
|
||||
renderSpotLightShadows = true
|
||||
|
||||
rotatingCubeSpeedDeg1 float32 = 45
|
||||
@ -1049,6 +1112,7 @@ func (g *Game) Render() {
|
||||
|
||||
whiteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
containerMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
groundMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||
|
||||
rotatingCubeTrMat1.Rotate(rotatingCubeSpeedDeg1*gglm.Deg2Rad*timing.DT(), 0, 1, 0)
|
||||
@ -1092,6 +1156,7 @@ func (g *Game) renderDirectionalLightShadowmap() {
|
||||
|
||||
whiteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
containerMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
groundMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||
|
||||
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
||||
@ -1133,6 +1198,7 @@ func (g *Game) renderSpotLightShadowmaps() {
|
||||
|
||||
whiteMat.SetUnifMat4(projViewMatIndexStr, &projViewMat)
|
||||
containerMat.SetUnifMat4(projViewMatIndexStr, &projViewMat)
|
||||
groundMat.SetUnifMat4(projViewMatIndexStr, &projViewMat)
|
||||
palleteMat.SetUnifMat4(projViewMatIndexStr, &projViewMat)
|
||||
|
||||
// Set depth uniforms
|
||||
@ -1209,11 +1275,13 @@ func (g *Game) RenderScene(overrideMat *materials.Material) {
|
||||
sunMat := &palleteMat
|
||||
chairMat := &palleteMat
|
||||
cubeMat := &containerMat
|
||||
groundMat := &groundMat
|
||||
|
||||
if overrideMat != nil {
|
||||
sunMat = overrideMat
|
||||
chairMat = overrideMat
|
||||
cubeMat = overrideMat
|
||||
groundMat = overrideMat
|
||||
}
|
||||
|
||||
// Draw dir light
|
||||
@ -1233,7 +1301,7 @@ func (g *Game) RenderScene(overrideMat *materials.Material) {
|
||||
|
||||
// Ground
|
||||
groundTrMat := gglm.NewTrMatId()
|
||||
window.Rend.DrawMesh(&cubeMesh, groundTrMat.Translate(0, -3, 0).Scale(20, 1, 20), cubeMat)
|
||||
window.Rend.DrawMesh(&cubeMesh, groundTrMat.Translate(0, -3, 0).Scale(20, 1, 20), groundMat)
|
||||
|
||||
// Cubes
|
||||
tempModelMatrix.Translate(-6, 0, 0)
|
||||
@ -1283,6 +1351,7 @@ func updateAllProjViewMats(projMat, viewMat gglm.Mat4) {
|
||||
unlitMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
whiteMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
containerMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
groundMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
palleteMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
debugDepthMat.SetUnifMat4("projViewMat", projViewMat)
|
||||
|
||||
|
||||
@ -25,8 +25,8 @@ type MaterialSettings uint64
|
||||
|
||||
const (
|
||||
MaterialSettings_None MaterialSettings = iota
|
||||
MaterialSettings_HasModelMat MaterialSettings = 1 << (iota - 1)
|
||||
MaterialSettings_HasNormalMat
|
||||
MaterialSettings_HasModelMtx MaterialSettings = 1 << (iota - 1)
|
||||
MaterialSettings_HasNormalMtx
|
||||
)
|
||||
|
||||
func (ms *MaterialSettings) Set(flags MaterialSettings) {
|
||||
|
||||
@ -17,13 +17,37 @@ type SubMesh struct {
|
||||
|
||||
type Mesh struct {
|
||||
Name string
|
||||
/*
|
||||
Vao has the following shader attribute layout:
|
||||
- Loc0: Pos
|
||||
- Loc1: Normal
|
||||
- Loc2: UV0
|
||||
- Loc3: Tangent
|
||||
- (Optional) Color
|
||||
|
||||
Optional stuff appear in the order in this list, depending on what other optional stuff exists.
|
||||
|
||||
For example:
|
||||
- If color exists it will be in Loc3, otherwise it is unset
|
||||
*/
|
||||
Vao buffers.VertexArray
|
||||
SubMeshes []SubMesh
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultMeshLoadFlags are the flags always applied when loading a new mesh regardless
|
||||
// of what post process flags are used when loading a mesh.
|
||||
//
|
||||
// Defaults to: asig.PostProcessTriangulate | asig.PostProcessCalcTangentSpace;
|
||||
// Note: changing this will break the normal lit shaders, which expect tangents to be there
|
||||
DefaultMeshLoadFlags asig.PostProcess = asig.PostProcessTriangulate | asig.PostProcessCalcTangentSpace
|
||||
)
|
||||
|
||||
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (Mesh, error) {
|
||||
|
||||
scene, release, err := asig.ImportFile(modelPath, asig.PostProcessTriangulate|postProcessFlags)
|
||||
finalPostProcessFlags := DefaultMeshLoadFlags | postProcessFlags
|
||||
|
||||
scene, release, err := asig.ImportFile(modelPath, finalPostProcessFlags)
|
||||
if err != nil {
|
||||
return Mesh{}, errors.New("Failed to load model. Err: " + err.Error())
|
||||
}
|
||||
@ -42,8 +66,17 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (Mesh, e
|
||||
vbo := buffers.NewVertexBuffer()
|
||||
ibo := buffers.NewIndexBuffer()
|
||||
|
||||
// Initial sizes assuming one submesh that has vertex pos+normals+texCoords, and 3 indices per face
|
||||
var vertexBufData []float32 = make([]float32, 0, len(scene.Meshes[0].Vertices)*3*3*2)
|
||||
// Estimate a useful prealloc capacity based on the first submesh that has vertex pos+normals+tangents+texCoords
|
||||
vertexBufDataCapacity := len(scene.Meshes[0].Vertices) * 3 * 3 * 3 * 2
|
||||
|
||||
// Increase capacity depending on what the mesh has
|
||||
if len(scene.Meshes[0].ColorSets) > 0 && len(scene.Meshes[0].ColorSets[0]) > 0 {
|
||||
vertexBufDataCapacity *= 4
|
||||
}
|
||||
|
||||
var vertexBufData []float32 = make([]float32, 0, vertexBufDataCapacity)
|
||||
|
||||
// Initial size assumes 3 indices per face
|
||||
var indexBufData []uint32 = make([]uint32, 0, len(scene.Meshes[0].Faces)*3)
|
||||
|
||||
// fmt.Printf("\nMesh %s has %d meshe(s) with first mesh having %d vertices\n", name, len(scene.Meshes), len(scene.Meshes[0].Vertices))
|
||||
@ -52,12 +85,25 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (Mesh, e
|
||||
|
||||
sceneMesh := scene.Meshes[i]
|
||||
|
||||
// We always want tangents and UV0
|
||||
if len(sceneMesh.Tangents) == 0 {
|
||||
sceneMesh.Tangents = make([]gglm.Vec3, len(sceneMesh.Vertices))
|
||||
}
|
||||
|
||||
if len(sceneMesh.TexCoords[0]) == 0 {
|
||||
sceneMesh.TexCoords[0] = make([]gglm.Vec3, len(sceneMesh.Vertices))
|
||||
}
|
||||
|
||||
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}}
|
||||
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
|
||||
hasColorSet0 := len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0
|
||||
|
||||
layoutToUse := []buffers.Element{
|
||||
{ElementType: buffers.DataTypeVec3}, // Position
|
||||
{ElementType: buffers.DataTypeVec3}, // Normals
|
||||
{ElementType: buffers.DataTypeVec3}, // Tangents
|
||||
{ElementType: buffers.DataTypeVec2}, // UV0
|
||||
}
|
||||
|
||||
if hasColorSet0 {
|
||||
layoutToUse = append(layoutToUse, buffers.Element{ElementType: buffers.DataTypeVec4})
|
||||
}
|
||||
|
||||
@ -79,8 +125,14 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (Mesh, e
|
||||
}
|
||||
}
|
||||
|
||||
arrs := []arrToInterleave{{V3s: sceneMesh.Vertices}, {V3s: sceneMesh.Normals}, {V2s: v3sToV2s(sceneMesh.TexCoords[0])}}
|
||||
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
|
||||
arrs := []arrToInterleave{
|
||||
{V3s: sceneMesh.Vertices},
|
||||
{V3s: sceneMesh.Normals},
|
||||
{V3s: sceneMesh.Tangents},
|
||||
{V2s: v3sToV2s(sceneMesh.TexCoords[0])},
|
||||
}
|
||||
|
||||
if hasColorSet0 {
|
||||
arrs = append(arrs, arrToInterleave{V4s: sceneMesh.ColorSets[0]})
|
||||
}
|
||||
|
||||
|
||||
@ -29,11 +29,11 @@ func (r *Rend3DGL) DrawMesh(mesh *meshes.Mesh, modelMat *gglm.TrMat, mat *materi
|
||||
r.BoundMat = mat
|
||||
}
|
||||
|
||||
if mat.Settings.Has(materials.MaterialSettings_HasModelMat) {
|
||||
if mat.Settings.Has(materials.MaterialSettings_HasModelMtx) {
|
||||
mat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||
}
|
||||
|
||||
if mat.Settings.Has(materials.MaterialSettings_HasNormalMat) {
|
||||
if mat.Settings.Has(materials.MaterialSettings_HasNormalMtx) {
|
||||
normalMat := modelMat.Clone().InvertAndTranspose().ToMat3()
|
||||
mat.SetUnifMat3("normalMat", &normalMat)
|
||||
}
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
#version 410
|
||||
|
||||
layout(location=0) in vec3 vertPosIn;
|
||||
layout(location=2) in vec2 vertUV0In;
|
||||
layout(location=3) in vec3 vertColorIn;
|
||||
layout(location=2) in vec3 vertTangentIn;
|
||||
layout(location=3) in vec2 vertUV0In;
|
||||
layout(location=4) in vec3 vertColorIn;
|
||||
|
||||
out vec2 vertUV0;
|
||||
out vec3 vertColor;
|
||||
|
||||
@ -3,8 +3,9 @@
|
||||
|
||||
layout(location=0) in vec3 vertPosIn;
|
||||
layout(location=1) in vec3 vertNormalIn;
|
||||
layout(location=2) in vec2 vertUV0In;
|
||||
layout(location=3) in vec3 vertColorIn;
|
||||
layout(location=2) in vec3 vertTangentIn;
|
||||
layout(location=3) in vec2 vertUV0In;
|
||||
layout(location=4) in vec3 vertColorIn;
|
||||
|
||||
out vec2 vertUV0;
|
||||
out vec3 vertColor;
|
||||
|
||||
@ -1,63 +1,34 @@
|
||||
//shader:vertex
|
||||
#version 410
|
||||
|
||||
#define NUM_SPOT_LIGHTS 4
|
||||
#define NUM_POINT_LIGHTS 8
|
||||
|
||||
//
|
||||
// Inputs
|
||||
//
|
||||
layout(location=0) in vec3 vertPosIn;
|
||||
layout(location=1) in vec3 vertNormalIn;
|
||||
layout(location=2) in vec2 vertUV0In;
|
||||
layout(location=3) in vec3 vertColorIn;
|
||||
layout(location=2) in vec3 vertTangentIn;
|
||||
layout(location=3) in vec2 vertUV0In;
|
||||
layout(location=4) in vec3 vertColorIn;
|
||||
|
||||
//
|
||||
// Uniforms
|
||||
//
|
||||
uniform vec3 camPos;
|
||||
uniform mat4 modelMat;
|
||||
uniform mat3 normalMat;
|
||||
uniform mat4 projViewMat;
|
||||
uniform mat4 dirLightProjViewMat;
|
||||
|
||||
#define NUM_SPOT_LIGHTS 4
|
||||
uniform mat4 spotLightProjViewMats[NUM_SPOT_LIGHTS];
|
||||
|
||||
out vec3 vertNormal;
|
||||
out vec2 vertUV0;
|
||||
out vec3 vertColor;
|
||||
out vec3 fragPos;
|
||||
out vec4 fragPosDirLight;
|
||||
out vec4 fragPosSpotLight[NUM_SPOT_LIGHTS];
|
||||
|
||||
void main()
|
||||
{
|
||||
vertNormal = normalMat * vertNormalIn;
|
||||
|
||||
vertUV0 = vertUV0In;
|
||||
vertColor = vertColorIn;
|
||||
|
||||
vec4 modelVert = modelMat * vec4(vertPosIn, 1);
|
||||
fragPos = modelVert.xyz;
|
||||
fragPosDirLight = dirLightProjViewMat * vec4(fragPos, 1);
|
||||
|
||||
for (int i = 0; i < NUM_SPOT_LIGHTS; i++)
|
||||
fragPosSpotLight[i] = spotLightProjViewMats[i] * vec4(fragPos, 1);
|
||||
|
||||
gl_Position = projViewMat * modelVert;
|
||||
}
|
||||
|
||||
//shader:fragment
|
||||
#version 410
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
// sampler2D normal;
|
||||
sampler2D emission;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
uniform Material material;
|
||||
|
||||
struct DirLight {
|
||||
vec3 dir;
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
sampler2D shadowMap;
|
||||
};
|
||||
|
||||
uniform DirLight dirLight;
|
||||
|
||||
struct PointLight {
|
||||
@ -69,8 +40,137 @@ struct PointLight {
|
||||
float quadratic;
|
||||
float farPlane;
|
||||
};
|
||||
uniform PointLight pointLights[NUM_POINT_LIGHTS];
|
||||
|
||||
struct SpotLight {
|
||||
vec3 pos;
|
||||
vec3 dir;
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
float innerCutoff;
|
||||
float outerCutoff;
|
||||
};
|
||||
uniform SpotLight spotLights[NUM_SPOT_LIGHTS];
|
||||
|
||||
//
|
||||
// Outputs
|
||||
//
|
||||
out vec2 vertUV0;
|
||||
out vec3 vertColor;
|
||||
|
||||
out vec3 fragPos;
|
||||
out vec3 fragPosDirLight;
|
||||
out vec4 fragPosSpotLight[NUM_SPOT_LIGHTS];
|
||||
|
||||
out vec3 tangentCamPos;
|
||||
out vec3 tangentFragPos;
|
||||
out vec3 tangentVertNormal;
|
||||
out vec3 tangentDirLightDir;
|
||||
out vec3 tangentSpotLightPositions[NUM_SPOT_LIGHTS];
|
||||
out vec3 tangentSpotLightDirections[NUM_SPOT_LIGHTS];
|
||||
out vec3 tangentPointLightPositions[NUM_POINT_LIGHTS];
|
||||
|
||||
void main()
|
||||
{
|
||||
vertUV0 = vertUV0In;
|
||||
vertColor = vertColorIn;
|
||||
vec4 modelVert = modelMat * vec4(vertPosIn, 1);
|
||||
|
||||
// Tangent-BiTangent-Normal matrix for normal mapping
|
||||
vec3 T = normalize(vec3(modelMat * vec4(vertTangentIn, 0.0)));
|
||||
vec3 N = normalize(vec3(modelMat * vec4(vertNormalIn, 0.0)));
|
||||
|
||||
// Ensure T is orthogonal with respect to N
|
||||
T = normalize(T - dot(T, N) * N);
|
||||
|
||||
vec3 B = cross(N, T);
|
||||
mat3 tbnMtx = transpose(mat3(T, B, N));
|
||||
|
||||
tangentVertNormal = tbnMtx * normalMat * vertNormalIn;
|
||||
|
||||
// Lighting related
|
||||
fragPos = modelVert.xyz;
|
||||
fragPosDirLight = vec3(dirLightProjViewMat * vec4(fragPos, 1));
|
||||
|
||||
tangentCamPos = tbnMtx * camPos;
|
||||
tangentFragPos = tbnMtx * fragPos;
|
||||
tangentDirLightDir = tbnMtx * dirLight.dir;
|
||||
|
||||
for (int i = 0; i < NUM_POINT_LIGHTS; i++)
|
||||
tangentPointLightPositions[i] = tbnMtx * pointLights[i].pos;
|
||||
|
||||
for (int i = 0; i < NUM_SPOT_LIGHTS; i++)
|
||||
{
|
||||
fragPosSpotLight[i] = spotLightProjViewMats[i] * vec4(fragPos, 1);
|
||||
|
||||
tangentSpotLightPositions[i] = tbnMtx * spotLights[i].pos;
|
||||
tangentSpotLightDirections[i] = tbnMtx * spotLights[i].dir;
|
||||
}
|
||||
|
||||
gl_Position = projViewMat * modelVert;
|
||||
}
|
||||
|
||||
//shader:fragment
|
||||
#version 410
|
||||
|
||||
/*
|
||||
Note that while all lighting calculations are done in tangent space,
|
||||
shadow mapping is done in world space.
|
||||
|
||||
The exception is the bias calculation. Since the bias relies on the normal
|
||||
and the normal is in tangent space, we use a tangent space fragment position
|
||||
with it, but the rest of shadow processing is in world space.
|
||||
*/
|
||||
|
||||
#define NUM_SPOT_LIGHTS 4
|
||||
#define NUM_POINT_LIGHTS 8
|
||||
|
||||
//
|
||||
// Inputs
|
||||
//
|
||||
in vec3 fragPos;
|
||||
in vec2 vertUV0;
|
||||
in vec3 vertColor;
|
||||
in vec3 fragPosDirLight;
|
||||
in vec4 fragPosSpotLight[NUM_SPOT_LIGHTS];
|
||||
|
||||
in vec3 tangentCamPos;
|
||||
in vec3 tangentFragPos;
|
||||
in vec3 tangentVertNormal;
|
||||
in vec3 tangentDirLightDir;
|
||||
in vec3 tangentSpotLightPositions[NUM_SPOT_LIGHTS];
|
||||
in vec3 tangentSpotLightDirections[NUM_SPOT_LIGHTS];
|
||||
in vec3 tangentPointLightPositions[NUM_POINT_LIGHTS];
|
||||
|
||||
//
|
||||
// Uniforms
|
||||
//
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
sampler2D normal;
|
||||
sampler2D emission;
|
||||
float shininess;
|
||||
};
|
||||
uniform Material material;
|
||||
|
||||
struct DirLight {
|
||||
vec3 dir;
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
sampler2D shadowMap;
|
||||
};
|
||||
uniform DirLight dirLight;
|
||||
|
||||
struct PointLight {
|
||||
vec3 pos;
|
||||
vec3 diffuseColor;
|
||||
vec3 specularColor;
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
float farPlane;
|
||||
};
|
||||
uniform PointLight pointLights[NUM_POINT_LIGHTS];
|
||||
uniform samplerCubeArray pointLightCubeShadowMaps;
|
||||
|
||||
@ -82,37 +182,29 @@ struct SpotLight {
|
||||
float innerCutoff;
|
||||
float outerCutoff;
|
||||
};
|
||||
|
||||
#define NUM_SPOT_LIGHTS 4
|
||||
uniform SpotLight spotLights[NUM_SPOT_LIGHTS];
|
||||
uniform sampler2DArray spotLightShadowMaps;
|
||||
|
||||
uniform vec3 camPos;
|
||||
uniform vec3 ambientColor = vec3(0.2, 0.2, 0.2);
|
||||
|
||||
in vec3 vertColor;
|
||||
in vec3 vertNormal;
|
||||
in vec2 vertUV0;
|
||||
in vec3 fragPos;
|
||||
in vec4 fragPosDirLight;
|
||||
in vec4 fragPosSpotLight[NUM_SPOT_LIGHTS];
|
||||
|
||||
//
|
||||
// Outputs
|
||||
//
|
||||
out vec4 fragColor;
|
||||
|
||||
//
|
||||
// Global variables used as cache for lighting calculations
|
||||
//
|
||||
vec3 tangentViewDir;
|
||||
vec4 diffuseTexColor;
|
||||
vec4 specularTexColor;
|
||||
vec4 emissionTexColor;
|
||||
vec3 normalizedVertNorm;
|
||||
vec3 viewDir;
|
||||
|
||||
float CalcDirShadow(sampler2D shadowMap, vec3 lightDir)
|
||||
float CalcDirShadow(sampler2D shadowMap, vec3 tangentLightDir)
|
||||
{
|
||||
// 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;
|
||||
vec3 projCoords = fragPosDirLight * 0.5 + 0.5;
|
||||
|
||||
// If sampling outside the depth texture then force 'no shadow'
|
||||
if(projCoords.z > 1)
|
||||
@ -123,7 +215,7 @@ float CalcDirShadow(sampler2D shadowMap, vec3 lightDir)
|
||||
|
||||
// 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 - dot(normalizedVertNorm, lightDir)), 0.005);
|
||||
float bias = max(0.05 * (1 - dot(normalizedVertNorm, tangentLightDir)), 0.005);
|
||||
|
||||
// 'Percentage Close Filtering'.
|
||||
// Basically get soft shadows by averaging this texel and surrounding ones
|
||||
@ -148,14 +240,14 @@ float CalcDirShadow(sampler2D shadowMap, vec3 lightDir)
|
||||
|
||||
vec3 CalcDirLight()
|
||||
{
|
||||
vec3 lightDir = normalize(-dirLight.dir);
|
||||
vec3 lightDir = normalize(-tangentDirLightDir);
|
||||
|
||||
// Diffuse
|
||||
float diffuseAmount = max(0.0, dot(normalizedVertNorm, lightDir));
|
||||
vec3 finalDiffuse = diffuseAmount * dirLight.diffuseColor * diffuseTexColor.rgb;
|
||||
|
||||
// Specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
vec3 halfwayDir = normalize(lightDir + tangentViewDir);
|
||||
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
||||
vec3 finalSpecular = specularAmount * dirLight.specularColor * specularTexColor.rgb;
|
||||
|
||||
@ -165,9 +257,9 @@ vec3 CalcDirLight()
|
||||
return (finalDiffuse + finalSpecular) * (1 - shadow);
|
||||
}
|
||||
|
||||
float CalcPointShadow(int lightIndex, vec3 lightPos, vec3 lightDir, float farPlane) {
|
||||
float CalcPointShadow(int lightIndex, vec3 worldLightPos, vec3 tangentLightDir, float farPlane) {
|
||||
|
||||
vec3 lightToFrag = fragPos - lightPos;
|
||||
vec3 lightToFrag = fragPos - worldLightPos;
|
||||
|
||||
float closestDepth = texture(pointLightCubeShadowMaps, vec4(lightToFrag, lightIndex)).r;
|
||||
|
||||
@ -177,7 +269,8 @@ float CalcPointShadow(int lightIndex, vec3 lightPos, vec3 lightDir, float farPla
|
||||
// Get depth of current fragment
|
||||
float currentDepth = length(lightToFrag);
|
||||
|
||||
float bias = max(0.05 * (1 - dot(normalizedVertNorm, lightDir)), 0.005);
|
||||
float bias = max(0.05 * (1 - dot(normalizedVertNorm, tangentLightDir)), 0.005);
|
||||
|
||||
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
return shadow;
|
||||
@ -190,28 +283,29 @@ vec3 CalcPointLight(PointLight pointLight, int lightIndex)
|
||||
return vec3(0);
|
||||
}
|
||||
|
||||
vec3 lightDir = normalize(pointLight.pos - fragPos);
|
||||
vec3 tangentLightPos = tangentPointLightPositions[lightIndex];
|
||||
vec3 tangentLightDir = normalize(tangentLightPos - tangentFragPos);
|
||||
|
||||
// Diffuse
|
||||
float diffuseAmount = max(0.0, dot(normalizedVertNorm, lightDir));
|
||||
float diffuseAmount = max(0.0, dot(normalizedVertNorm, tangentLightDir));
|
||||
vec3 finalDiffuse = diffuseAmount * pointLight.diffuseColor * diffuseTexColor.rgb;
|
||||
|
||||
// Specular
|
||||
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||
vec3 halfwayDir = normalize(tangentLightDir + tangentViewDir);
|
||||
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
||||
vec3 finalSpecular = specularAmount * pointLight.specularColor * specularTexColor.rgb;
|
||||
|
||||
// Attenuation
|
||||
float distToLight = length(pointLight.pos - fragPos);
|
||||
float distToLight = length(tangentLightPos - tangentFragPos);
|
||||
float attenuation = 1 / (pointLight.constant + pointLight.linear * distToLight + pointLight.quadratic * (distToLight * distToLight));
|
||||
|
||||
// Shadow
|
||||
float shadow = CalcPointShadow(lightIndex, pointLight.pos, lightDir, pointLight.farPlane);
|
||||
float shadow = CalcPointShadow(lightIndex, pointLight.pos, tangentLightDir, pointLight.farPlane);
|
||||
|
||||
return (finalDiffuse + finalSpecular) * attenuation * (1 - shadow);
|
||||
}
|
||||
|
||||
float CalcSpotShadow(vec3 lightDir, int lightIndex)
|
||||
float CalcSpotShadow(vec3 tangentLightDir, int lightIndex)
|
||||
{
|
||||
// Move from clip space to NDC
|
||||
vec3 projCoords = fragPosSpotLight[lightIndex].xyz / fragPosSpotLight[lightIndex].w;
|
||||
@ -228,7 +322,7 @@ float CalcSpotShadow(vec3 lightDir, int lightIndex)
|
||||
|
||||
// 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 - dot(normalizedVertNorm, lightDir)), 0.005);
|
||||
float bias = max(0.05 * (1 - dot(normalizedVertNorm, tangentLightDir)), 0.005);
|
||||
|
||||
// 'Percentage Close Filtering'.
|
||||
// Basically get soft shadows by averaging this texel and surrounding ones
|
||||
@ -256,12 +350,13 @@ vec3 CalcSpotLight(SpotLight light, int lightIndex)
|
||||
if (light.innerCutoff == 0)
|
||||
return vec3(0);
|
||||
|
||||
vec3 fragToLightDir = normalize(light.pos - fragPos);
|
||||
vec3 tangentLightDir = tangentSpotLightDirections[lightIndex];
|
||||
vec3 fragToLightDir = normalize(tangentSpotLightPositions[lightIndex] - tangentFragPos);
|
||||
|
||||
// Spot light cone with full intensity within inner cutoff,
|
||||
// and falloff between inner-outer cutoffs, and zero
|
||||
// light after outer cutoff
|
||||
float theta = dot(fragToLightDir, normalize(-light.dir));
|
||||
float theta = dot(fragToLightDir, normalize(-tangentLightDir));
|
||||
float epsilon = (light.innerCutoff - light.outerCutoff);
|
||||
float intensity = clamp((theta - light.outerCutoff) / epsilon, float(0), float(1));
|
||||
|
||||
@ -273,7 +368,7 @@ vec3 CalcSpotLight(SpotLight light, int lightIndex)
|
||||
vec3 finalDiffuse = diffuseAmount * light.diffuseColor * diffuseTexColor.rgb;
|
||||
|
||||
// Specular
|
||||
vec3 halfwayDir = normalize(fragToLightDir + viewDir);
|
||||
vec3 halfwayDir = normalize(fragToLightDir + tangentViewDir);
|
||||
float specularAmount = pow(max(dot(normalizedVertNorm, halfwayDir), 0.0), material.shininess);
|
||||
vec3 finalSpecular = specularAmount * light.specularColor * specularTexColor.rgb;
|
||||
|
||||
@ -286,12 +381,20 @@ vec3 CalcSpotLight(SpotLight light, int lightIndex)
|
||||
void main()
|
||||
{
|
||||
// Shared values
|
||||
tangentViewDir = normalize(tangentCamPos - tangentFragPos);
|
||||
diffuseTexColor = texture(material.diffuse, vertUV0);
|
||||
specularTexColor = texture(material.specular, vertUV0);
|
||||
emissionTexColor = texture(material.emission, vertUV0);
|
||||
|
||||
normalizedVertNorm = normalize(vertNormal);
|
||||
viewDir = normalize(camPos - fragPos);
|
||||
// Read normal data encoded [0,1]
|
||||
normalizedVertNorm = texture(material.normal, vertUV0).rgb;
|
||||
|
||||
// Handle no normal map
|
||||
if (normalizedVertNorm == vec3(0))
|
||||
normalizedVertNorm = normalize(tangentVertNormal);
|
||||
else
|
||||
// Remap normal to [-1,1]
|
||||
normalizedVertNorm = normalize(normalizedVertNorm * 2.0 - 1.0);
|
||||
|
||||
// Light contributions
|
||||
vec3 finalColor = CalcDirLight();
|
||||
|
||||
@ -3,8 +3,9 @@
|
||||
|
||||
layout(location=0) in vec3 vertPosIn;
|
||||
layout(location=1) in vec3 vertNormalIn;
|
||||
layout(location=2) in vec2 vertUV0In;
|
||||
layout(location=3) in vec3 vertColorIn;
|
||||
layout(location=2) in vec3 vertTangentIn;
|
||||
layout(location=3) in vec2 vertUV0In;
|
||||
layout(location=4) in vec3 vertColorIn;
|
||||
|
||||
out vec3 vertUV0;
|
||||
|
||||
|
||||
BIN
res/textures/brickwall-normal.png
Executable file
BIN
res/textures/brickwall-normal.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
BIN
res/textures/brickwall.png
Executable file
BIN
res/textures/brickwall.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
Reference in New Issue
Block a user