153 lines
3.8 KiB
Go
153 lines
3.8 KiB
Go
package pass
|
|
|
|
import (
|
|
"github.com/vkngwrapper/core/v2/core1_0"
|
|
"zworld/engine/render/uniform"
|
|
"zworld/engine/renderapi/command"
|
|
"zworld/engine/renderapi/descriptor"
|
|
"zworld/engine/renderapi/material"
|
|
"zworld/engine/renderapi/renderpass"
|
|
"zworld/engine/renderapi/shader"
|
|
"zworld/engine/renderapi/texture"
|
|
"zworld/engine/renderapi/vertex"
|
|
"zworld/engine/renderapi/vulkan"
|
|
)
|
|
|
|
type LightDescriptors struct {
|
|
descriptor.Set
|
|
Camera *descriptor.Uniform[uniform.Camera]
|
|
Lights *descriptor.Storage[uniform.Light]
|
|
Diffuse *descriptor.Sampler
|
|
Normal *descriptor.Sampler
|
|
Position *descriptor.Sampler
|
|
Occlusion *descriptor.Sampler
|
|
Shadow *descriptor.SamplerArray
|
|
}
|
|
|
|
type LightShader interface {
|
|
Bind(command.Buffer, int)
|
|
Descriptors(int) *LightDescriptors
|
|
Destroy()
|
|
}
|
|
|
|
type lightShader struct {
|
|
mat *material.Material[*LightDescriptors]
|
|
instances []*material.Instance[*LightDescriptors]
|
|
|
|
diffuseTex []texture.T
|
|
normalTex []texture.T
|
|
positionTex []texture.T
|
|
occlusionTex []texture.T
|
|
}
|
|
|
|
func NewLightShader(app vulkan.App, pass renderpass.T, gbuffer GeometryBuffer, occlusion vulkan.Target) LightShader {
|
|
mat := material.New(
|
|
app.Device(),
|
|
material.Args{
|
|
Shader: app.Shaders().Fetch(shader.NewRef("light")),
|
|
Pass: pass,
|
|
Subpass: LightingSubpass,
|
|
Pointers: vertex.ParsePointers(vertex.T{}),
|
|
DepthTest: false,
|
|
},
|
|
&LightDescriptors{
|
|
Camera: &descriptor.Uniform[uniform.Camera]{
|
|
Stages: core1_0.StageFragment,
|
|
},
|
|
Lights: &descriptor.Storage[uniform.Light]{
|
|
Stages: core1_0.StageFragment,
|
|
Size: 256,
|
|
},
|
|
Diffuse: &descriptor.Sampler{
|
|
Stages: core1_0.StageFragment,
|
|
},
|
|
Normal: &descriptor.Sampler{
|
|
Stages: core1_0.StageFragment,
|
|
},
|
|
Position: &descriptor.Sampler{
|
|
Stages: core1_0.StageFragment,
|
|
},
|
|
Occlusion: &descriptor.Sampler{
|
|
Stages: core1_0.StageFragment,
|
|
},
|
|
Shadow: &descriptor.SamplerArray{
|
|
Stages: core1_0.StageFragment,
|
|
Count: 32,
|
|
},
|
|
})
|
|
|
|
frames := gbuffer.Frames()
|
|
lightsh := mat.InstantiateMany(app.Pool(), frames)
|
|
|
|
var err error
|
|
diffuseTex := make([]texture.T, frames)
|
|
normalTex := make([]texture.T, frames)
|
|
positionTex := make([]texture.T, frames)
|
|
occlusionTex := make([]texture.T, frames)
|
|
for i := 0; i < frames; i++ {
|
|
diffuseTex[i], err = texture.FromImage(app.Device(), "deferred-diffuse", gbuffer.Diffuse()[i], texture.Args{
|
|
Filter: texture.FilterNearest,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
normalTex[i], err = texture.FromImage(app.Device(), "deferred-normal", gbuffer.Normal()[i], texture.Args{
|
|
Filter: texture.FilterNearest,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
positionTex[i], err = texture.FromImage(app.Device(), "deferred-position", gbuffer.Position()[i], texture.Args{
|
|
Filter: texture.FilterNearest,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
occlusionTex[i], err = texture.FromImage(app.Device(), "deferred-ssao", occlusion.Surfaces()[i], texture.Args{
|
|
Filter: texture.FilterNearest,
|
|
})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
lightDesc := lightsh[i].Descriptors()
|
|
lightDesc.Diffuse.Set(diffuseTex[i])
|
|
lightDesc.Normal.Set(normalTex[i])
|
|
lightDesc.Position.Set(positionTex[i])
|
|
lightDesc.Occlusion.Set(occlusionTex[i])
|
|
}
|
|
|
|
return &lightShader{
|
|
mat: mat,
|
|
instances: lightsh,
|
|
|
|
diffuseTex: diffuseTex,
|
|
normalTex: normalTex,
|
|
positionTex: positionTex,
|
|
occlusionTex: occlusionTex,
|
|
}
|
|
}
|
|
|
|
func (ls *lightShader) Bind(buf command.Buffer, frame int) {
|
|
ls.instances[frame].Bind(buf)
|
|
}
|
|
func (ls *lightShader) Descriptors(frame int) *LightDescriptors {
|
|
return ls.instances[frame].Descriptors()
|
|
}
|
|
|
|
func (ls *lightShader) Destroy() {
|
|
for _, view := range ls.diffuseTex {
|
|
view.Destroy()
|
|
}
|
|
for _, view := range ls.normalTex {
|
|
view.Destroy()
|
|
}
|
|
for _, view := range ls.positionTex {
|
|
view.Destroy()
|
|
}
|
|
for _, view := range ls.occlusionTex {
|
|
view.Destroy()
|
|
}
|
|
ls.mat.Destroy()
|
|
}
|