144 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			144 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"github.com/vkngwrapper/core/v2/core1_0"
							 | 
						||
| 
								 | 
							
									"zworld/engine/object"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/command"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/descriptor"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/framebuffer"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/material"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/renderpass"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/renderpass/attachment"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/shader"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/texture"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/vertex"
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/vulkan"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type PostProcessPass struct {
							 | 
						||
| 
								 | 
							
									LUT texture.Ref
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									app   vulkan.App
							 | 
						||
| 
								 | 
							
									input vulkan.Target
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									quad  vertex.Mesh
							 | 
						||
| 
								 | 
							
									mat   *material.Material[*PostProcessDescriptors]
							 | 
						||
| 
								 | 
							
									desc  []*material.Instance[*PostProcessDescriptors]
							 | 
						||
| 
								 | 
							
									fbufs framebuffer.Array
							 | 
						||
| 
								 | 
							
									pass  renderpass.T
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inputTex []texture.T
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _ Pass = &PostProcessPass{}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type PostProcessDescriptors struct {
							 | 
						||
| 
								 | 
							
									descriptor.Set
							 | 
						||
| 
								 | 
							
									Input *descriptor.Sampler
							 | 
						||
| 
								 | 
							
									LUT   *descriptor.Sampler
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func NewPostProcessPass(app vulkan.App, target vulkan.Target, input vulkan.Target) *PostProcessPass {
							 | 
						||
| 
								 | 
							
									var err error
							 | 
						||
| 
								 | 
							
									p := &PostProcessPass{
							 | 
						||
| 
								 | 
							
										LUT: texture.PathRef("textures/color_grading/none.png"),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										app:   app,
							 | 
						||
| 
								 | 
							
										input: input,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p.quad = vertex.ScreenQuad("blur-pass-quad")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p.pass = renderpass.New(app.Device(), renderpass.Args{
							 | 
						||
| 
								 | 
							
										Name: "PostProcess",
							 | 
						||
| 
								 | 
							
										ColorAttachments: []attachment.Color{
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												Name:        OutputAttachment,
							 | 
						||
| 
								 | 
							
												Image:       attachment.FromImageArray(target.Surfaces()),
							 | 
						||
| 
								 | 
							
												LoadOp:      core1_0.AttachmentLoadOpDontCare,
							 | 
						||
| 
								 | 
							
												FinalLayout: core1_0.ImageLayoutShaderReadOnlyOptimal,
							 | 
						||
| 
								 | 
							
											},
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										Subpasses: []renderpass.Subpass{
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												Name:             MainSubpass,
							 | 
						||
| 
								 | 
							
												ColorAttachments: []attachment.Name{OutputAttachment},
							 | 
						||
| 
								 | 
							
											},
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p.mat = material.New(
							 | 
						||
| 
								 | 
							
										app.Device(),
							 | 
						||
| 
								 | 
							
										material.Args{
							 | 
						||
| 
								 | 
							
											Shader:     app.Shaders().Fetch(shader.NewRef("postprocess")),
							 | 
						||
| 
								 | 
							
											Pass:       p.pass,
							 | 
						||
| 
								 | 
							
											Pointers:   vertex.ParsePointers(vertex.T{}),
							 | 
						||
| 
								 | 
							
											DepthTest:  false,
							 | 
						||
| 
								 | 
							
											DepthWrite: false,
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										&PostProcessDescriptors{
							 | 
						||
| 
								 | 
							
											Input: &descriptor.Sampler{
							 | 
						||
| 
								 | 
							
												Stages: core1_0.StageFragment,
							 | 
						||
| 
								 | 
							
											},
							 | 
						||
| 
								 | 
							
											LUT: &descriptor.Sampler{
							 | 
						||
| 
								 | 
							
												Stages: core1_0.StageFragment,
							 | 
						||
| 
								 | 
							
											},
							 | 
						||
| 
								 | 
							
										})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									frames := input.Frames()
							 | 
						||
| 
								 | 
							
									p.fbufs, err = framebuffer.NewArray(frames, app.Device(), "blur", target.Width(), target.Height(), p.pass)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										panic(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									p.desc = p.mat.InstantiateMany(app.Pool(), frames)
							 | 
						||
| 
								 | 
							
									p.inputTex = make([]texture.T, frames)
							 | 
						||
| 
								 | 
							
									for i := 0; i < input.Frames(); i++ {
							 | 
						||
| 
								 | 
							
										inputKey := fmt.Sprintf("post-input-%d", i)
							 | 
						||
| 
								 | 
							
										p.inputTex[i], err = texture.FromImage(app.Device(), inputKey, p.input.Surfaces()[i], texture.Args{
							 | 
						||
| 
								 | 
							
											Filter: texture.FilterNearest,
							 | 
						||
| 
								 | 
							
											Wrap:   texture.WrapClamp,
							 | 
						||
| 
								 | 
							
										})
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											// todo: clean up
							 | 
						||
| 
								 | 
							
											panic(err)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										p.desc[i].Descriptors().Input.Set(p.inputTex[i])
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return p
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (p *PostProcessPass) Record(cmds command.Recorder, args renderapi.Args, scene object.Component) {
							 | 
						||
| 
								 | 
							
									quad := p.app.Meshes().Fetch(p.quad)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// refresh color lut
							 | 
						||
| 
								 | 
							
									lutTex := p.app.Textures().Fetch(p.LUT)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									cmds.Record(func(cmd command.Buffer) {
							 | 
						||
| 
								 | 
							
										cmd.CmdBeginRenderPass(p.pass, p.fbufs[args.Frame])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										desc := p.desc[args.Frame]
							 | 
						||
| 
								 | 
							
										desc.Bind(cmd)
							 | 
						||
| 
								 | 
							
										desc.Descriptors().LUT.Set(lutTex)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										quad.Draw(cmd, 0)
							 | 
						||
| 
								 | 
							
										cmd.CmdEndRenderPass()
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (p *PostProcessPass) Name() string {
							 | 
						||
| 
								 | 
							
									return "PostProcess"
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (p *PostProcessPass) Destroy() {
							 | 
						||
| 
								 | 
							
									for _, tex := range p.inputTex {
							 | 
						||
| 
								 | 
							
										tex.Destroy()
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									p.fbufs.Destroy()
							 | 
						||
| 
								 | 
							
									p.pass.Destroy()
							 | 
						||
| 
								 | 
							
									p.mat.Destroy()
							 | 
						||
| 
								 | 
							
								}
							 |