Cubemap depth fbo attachments

This commit is contained in:
bloeys
2024-04-15 04:16:44 +04:00
parent 22ba9ca891
commit a5bea5a661
2 changed files with 74 additions and 33 deletions

View File

@ -11,6 +11,7 @@ const (
FramebufferAttachmentType_Unknown FramebufferAttachmentType = iota FramebufferAttachmentType_Unknown FramebufferAttachmentType = iota
FramebufferAttachmentType_Texture FramebufferAttachmentType_Texture
FramebufferAttachmentType_Renderbuffer FramebufferAttachmentType_Renderbuffer
FramebufferAttachmentType_Cubemap
) )
func (f FramebufferAttachmentType) IsValid() bool { func (f FramebufferAttachmentType) IsValid() bool {
@ -19,6 +20,8 @@ func (f FramebufferAttachmentType) IsValid() bool {
case FramebufferAttachmentType_Texture: case FramebufferAttachmentType_Texture:
fallthrough fallthrough
case FramebufferAttachmentType_Renderbuffer: case FramebufferAttachmentType_Renderbuffer:
fallthrough
case FramebufferAttachmentType_Cubemap:
return true return true
default: default:
@ -169,6 +172,10 @@ func (fbo *Framebuffer) NewColorAttachment(
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to unknown attachment type. Type=%d\n", attachType) logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to unknown attachment type. Type=%d\n", attachType)
} }
if attachType == FramebufferAttachmentType_Cubemap {
logging.ErrLog.Fatalf("failed creating color attachment because cubemaps can not be color attachments (at least in this implementation. You might be able to do it manually)\n")
}
if !attachFormat.IsColorFormat() { if !attachFormat.IsColorFormat() {
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to attachment data format not being a valid color type. Data format=%d\n", attachFormat) logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to attachment data format not being a valid color type. Data format=%d\n", attachFormat)
} }
@ -304,6 +311,30 @@ func (fbo *Framebuffer) NewDepthAttachment(
// Attach to fbo // Attach to fbo
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, a.Id) gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, a.Id)
} else if attachType == FramebufferAttachmentType_Cubemap {
// Create cubemap
gl.GenTextures(1, &a.Id)
if a.Id == 0 {
logging.ErrLog.Fatalf("failed to generate texture for framebuffer. GlError=%d\n", gl.GetError())
}
gl.BindTexture(gl.TEXTURE_CUBE_MAP, a.Id)
for i := 0; i < 6; i++ {
gl.TexImage2D(uint32(gl.TEXTURE_CUBE_MAP_POSITIVE_X+i), 0, attachFormat.GlInternalFormat(), int32(fbo.Width), int32(fbo.Height), 0, attachFormat.GlFormat(), gl.FLOAT, nil)
}
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE)
gl.BindTexture(gl.TEXTURE_2D, 0)
// Attach to fbo
gl.FramebufferTexture(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, a.Id, 0)
} }
fbo.UnBind() fbo.UnBind()

64
main.go
View File

@ -127,10 +127,10 @@ var (
demoFboOffset = gglm.NewVec2(0.75, -0.75) demoFboOffset = gglm.NewVec2(0.75, -0.75)
demoFbo buffers.Framebuffer demoFbo buffers.Framebuffer
renderToDepthMapFbo = true showDirLightDepthMapFbo = true
depthMapFboScale = gglm.NewVec2(0.25, 0.25) dirLightDepthMapFboScale = gglm.NewVec2(0.25, 0.25)
depthMapFboOffset = gglm.NewVec2(0.75, -0.2) dirLightDepthMapFboOffset = gglm.NewVec2(0.75, -0.2)
depthMapFbo buffers.Framebuffer dirLightDepthMapFbo buffers.Framebuffer
screenQuadVao buffers.VertexArray screenQuadVao buffers.VertexArray
screenQuadMat *materials.Material screenQuadMat *materials.Material
@ -140,7 +140,7 @@ var (
containerMat *materials.Material containerMat *materials.Material
palleteMat *materials.Material palleteMat *materials.Material
skyboxMat *materials.Material skyboxMat *materials.Material
depthMapMat *materials.Material dirLightDepthMapMat *materials.Material
debugDepthMat *materials.Material debugDepthMat *materials.Material
cubeMesh *meshes.Mesh cubeMesh *meshes.Mesh
@ -437,7 +437,7 @@ func (g *Game) Init() {
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") dirLightDepthMapMat = 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
@ -484,22 +484,32 @@ func (g *Game) initFbos() {
assert.T(demoFbo.IsComplete(), "Demo fbo is not complete after init") assert.T(demoFbo.IsComplete(), "Demo fbo is not complete after init")
// Depth map fbo // Depth map fbo
depthMapFbo = buffers.NewFramebuffer(1024, 1024) dirLightDepthMapFbo = buffers.NewFramebuffer(1024, 1024)
depthMapFbo.SetNoColorBuffer() dirLightDepthMapFbo.SetNoColorBuffer()
depthMapFbo.NewDepthAttachment( dirLightDepthMapFbo.NewDepthAttachment(
buffers.FramebufferAttachmentType_Texture, buffers.FramebufferAttachmentType_Texture,
buffers.FramebufferAttachmentDataFormat_DepthF32, buffers.FramebufferAttachmentDataFormat_DepthF32,
) )
assert.T(depthMapFbo.IsComplete(), "Depth map fbo is not complete after init") assert.T(dirLightDepthMapFbo.IsComplete(), "Depth map fbo is not complete after init")
// Cubemap fbo
cubemapFbo := buffers.NewFramebuffer(1024, 1024)
cubemapFbo.SetNoColorBuffer()
cubemapFbo.NewDepthAttachment(
buffers.FramebufferAttachmentType_Cubemap,
buffers.FramebufferAttachmentDataFormat_DepthF32,
)
assert.T(cubemapFbo.IsComplete(), "Cubemap fbo is not complete after init")
} }
func (g *Game) updateLights() { func (g *Game) updateLights() {
// Directional light // Directional light
whiteMat.ShadowMap = depthMapFbo.Attachments[0].Id whiteMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
containerMat.ShadowMap = depthMapFbo.Attachments[0].Id containerMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
palleteMat.ShadowMap = depthMapFbo.Attachments[0].Id palleteMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
// Point lights // Point lights
for i := 0; i < len(pointLights); i++ { for i := 0; i < len(pointLights); i++ {
@ -752,15 +762,15 @@ func (g *Game) showDebugWindow() {
// Demo fbo // Demo fbo
imgui.Text("Demo Framebuffer") imgui.Text("Demo Framebuffer")
imgui.Checkbox("Render to demo FBO", &renderToDemoFbo) imgui.Checkbox("Show FBO##0", &renderToDemoFbo)
imgui.DragFloat2("Scale##0", &demoFboScale.Data) imgui.DragFloat2("Scale##0", &demoFboScale.Data)
imgui.DragFloat2("Offset##0", &demoFboOffset.Data) imgui.DragFloat2("Offset##0", &demoFboOffset.Data)
// Depth map fbo // Depth map fbo
imgui.Text("Depth Map Framebuffer") imgui.Text("Directional Light Depth Map Framebuffer")
imgui.Checkbox("Render to depth map FBO", &renderToDepthMapFbo) imgui.Checkbox("Show FBO##1", &showDirLightDepthMapFbo)
imgui.DragFloat2("Scale##1", &depthMapFboScale.Data) imgui.DragFloat2("Scale##1", &dirLightDepthMapFboScale.Data)
imgui.DragFloat2("Offset##1", &depthMapFboOffset.Data) imgui.DragFloat2("Offset##1", &dirLightDepthMapFboOffset.Data)
// Other // Other
imgui.Text("Other Settings") imgui.Text("Other Settings")
@ -845,13 +855,13 @@ func (g *Game) Render() {
palleteMat.SetUnifVec3("camPos", &cam.Pos) palleteMat.SetUnifVec3("camPos", &cam.Pos)
palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat) palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat) dirLightDepthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
// //
// Render depth map for shadows // Render depth map for shadows
// //
depthMapFbo.BindWithViewport() dirLightDepthMapFbo.BindWithViewport()
depthMapFbo.Clear() dirLightDepthMapFbo.Clear()
// Culling front faces helps 'peter panning' when // 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). // drawing shadow maps, but works only for solids with a back face (i.e. quads won't cast shadows).
@ -859,15 +869,15 @@ func (g *Game) Render() {
// //
// Some note that this is too troublesome and fails in many cases. Might be better to remove. // Some note that this is too troublesome and fails in many cases. Might be better to remove.
gl.CullFace(gl.FRONT) gl.CullFace(gl.FRONT)
g.RenderScene(depthMapMat) g.RenderScene(dirLightDepthMapMat)
gl.CullFace(gl.BACK) gl.CullFace(gl.BACK)
depthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight)) dirLightDepthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
if renderToDepthMapFbo { if showDirLightDepthMapFbo {
screenQuadMat.DiffuseTex = depthMapFbo.Attachments[0].Id screenQuadMat.DiffuseTex = dirLightDepthMapFbo.Attachments[0].Id
screenQuadMat.SetUnifVec2("offset", depthMapFboOffset) screenQuadMat.SetUnifVec2("offset", dirLightDepthMapFboOffset)
screenQuadMat.SetUnifVec2("scale", depthMapFboScale) screenQuadMat.SetUnifVec2("scale", dirLightDepthMapFboScale)
screenQuadMat.Bind() screenQuadMat.Bind()
window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6) window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6)
} }