zworld/engine/render/pass/depth_pass.go
2024-01-14 22:56:06 +08:00

115 lines
2.7 KiB
Go

package pass
import (
"github.com/vkngwrapper/core/v2/core1_0"
"zworld/engine/object"
"zworld/engine/object/mesh"
"zworld/engine/renderapi"
"zworld/engine/renderapi/command"
"zworld/engine/renderapi/framebuffer"
"zworld/engine/renderapi/renderpass"
"zworld/engine/renderapi/renderpass/attachment"
"zworld/engine/renderapi/vulkan"
)
type DepthPass struct {
gbuffer GeometryBuffer
app vulkan.App
pass renderpass.T
fbuf framebuffer.Array
materials MaterialCache
meshQuery *object.Query[mesh.Mesh]
}
var _ Pass = &ForwardPass{}
func NewDepthPass(
app vulkan.App,
depth vulkan.Target,
gbuffer GeometryBuffer,
) *DepthPass {
pass := renderpass.New(app.Device(), renderpass.Args{
Name: "Depth",
ColorAttachments: []attachment.Color{
{
Name: NormalsAttachment,
LoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
Image: attachment.FromImageArray(gbuffer.Normal()),
},
{
Name: PositionAttachment,
LoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
Image: attachment.FromImageArray(gbuffer.Position()),
},
},
DepthAttachment: &attachment.Depth{
LoadOp: core1_0.AttachmentLoadOpClear,
StencilLoadOp: core1_0.AttachmentLoadOpClear,
StoreOp: core1_0.AttachmentStoreOpStore,
FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
ClearDepth: 1,
Image: attachment.FromImageArray(depth.Surfaces()),
},
Subpasses: []renderpass.Subpass{
{
Name: MainSubpass,
Depth: true,
ColorAttachments: []attachment.Name{NormalsAttachment, PositionAttachment},
},
},
})
fbuf, err := framebuffer.NewArray(gbuffer.Frames(), app.Device(), "depth", gbuffer.Width(), gbuffer.Height(), pass)
if err != nil {
panic(err)
}
return &DepthPass{
gbuffer: gbuffer,
app: app,
pass: pass,
fbuf: fbuf,
materials: NewDepthMaterialCache(app, pass, gbuffer.Frames()),
meshQuery: object.NewQuery[mesh.Mesh](),
}
}
func (p *DepthPass) Record(cmds command.Recorder, args renderapi.Args, scene object.Component) {
opaque := p.meshQuery.
Reset().
Where(isDrawForward(false)).
Collect(scene)
cmds.Record(func(cmd command.Buffer) {
cmd.CmdBeginRenderPass(p.pass, p.fbuf[args.Frame])
})
cam := CameraFromArgs(args)
groups := MaterialGroups(p.materials, args.Frame, opaque)
groups.Draw(cmds, cam, nil)
cmds.Record(func(cmd command.Buffer) {
cmd.CmdEndRenderPass()
})
}
func (p *DepthPass) Name() string {
return "Depth"
}
func (p *DepthPass) Destroy() {
p.fbuf.Destroy()
p.pass.Destroy()
p.materials.Destroy()
}