aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2019-04-27 16:43:56 +0200
committerj-p <jp_bruyere@hotmail.com>2019-05-02 03:07:11 +0200
commit58eddf11cc951caca5aca1e7f33610fc1e58e5ff (patch)
tree3ff0e390e498be1894900cbc8bf543200139f894
parent04160ef015304a7f28308ea43aa1a959b84a78fc (diff)
Renderer class, lights ubo for multiple light handling
-rw-r--r--samples/deferred/deferred.csproj2
-rw-r--r--samples/deferred/deferredPbrRenderer.cs452
-rw-r--r--samples/deferred/main.cs477
-rw-r--r--samples/deferred/shaders/GBuffPbr.frag9
-rw-r--r--samples/deferred/shaders/GBuffPbr.vert3
-rw-r--r--samples/deferred/shaders/compose.frag102
-rw-r--r--samples/deferred/shaders/debug.vert3
-rw-r--r--samples/deferred/shaders/tone_mapping.frag3
-rw-r--r--vke/src/CommandPool.cs13
-rw-r--r--vke/src/Device.cs11
-rw-r--r--vke/src/Model.cs5
11 files changed, 564 insertions, 516 deletions
diff --git a/samples/deferred/deferred.csproj b/samples/deferred/deferred.csproj
index 7fca916..0b3a0ad 100644
--- a/samples/deferred/deferred.csproj
+++ b/samples/deferred/deferred.csproj
@@ -29,7 +29,7 @@
<Datas Include="..\data\**\*.*">
<Link>data\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Datas>
- <Compile Include="main.cs;EnvironmentPipeline.cs" />
+ <Compile Include="main.cs;EnvironmentPipeline.cs;deferredPbrRenderer.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Numerics" />
diff --git a/samples/deferred/deferredPbrRenderer.cs b/samples/deferred/deferredPbrRenderer.cs
new file mode 100644
index 0000000..2099670
--- /dev/null
+++ b/samples/deferred/deferredPbrRenderer.cs
@@ -0,0 +1,452 @@
+using System;
+using System.Numerics;
+using System.Runtime.InteropServices;
+using Glfw;
+using VK;
+using CVKL;
+
+namespace deferred {
+ class DeferredPbrRenderer : IDisposable {
+ Device dev;
+ SwapChain swapChain;
+ PresentQueue presentQueue;
+
+ VkSampleCountFlags samples = VkSampleCountFlags.SampleCount4;
+ VkFormat hdrFormat = VkFormat.R32g32b32a32Sfloat;
+
+ public enum DebugView {
+ none,
+ color,
+ normal,
+ pos,
+ occlusion,
+ emissive,
+ metallic,
+ roughness,
+ depth,
+ prefill,
+ irradiance
+ }
+
+ public DebugView currentDebugView = DebugView.none;
+
+ public struct Matrices {
+ public Matrix4x4 projection;
+ public Matrix4x4 model;
+ public Matrix4x4 view;
+ public Vector4 camPos;
+ public float exposure;
+ public float gamma;
+ public float prefilteredCubeMipLevels;
+ public float scaleIBLAmbient;
+ }
+
+ public struct Light {
+ public Vector4 position;
+ public Vector4 color;
+ }
+
+ public Matrices matrices = new Matrices {
+ gamma = 1.2f,
+ exposure = 2.0f,
+ scaleIBLAmbient = 1.0f,
+ };
+
+ Light[] lights = {
+ new Light {
+ position = new Vector4(1),
+ color = new Vector4(1)
+ }
+ };
+ public Vector4 lightPos = new Vector4 (1, 0, 0, 0);
+
+ Framebuffer[] frameBuffers;
+ Image gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg;
+
+ DescriptorPool descriptorPool;
+ DescriptorSetLayout descLayoutMain, descLayoutTextures, descLayoutGBuff;
+ DescriptorSet dsMain, dsGBuff;
+
+ public PipelineCache pipelineCache;
+ Pipeline gBuffPipeline, composePipeline, toneMappingPipeline, debugPipeline;
+
+ HostBuffer uboMatrices, uboLights;
+
+ RenderPass renderPass;
+
+ PbrModel model;
+ public EnvironmentCube envCube;
+
+ public BoundingBox modelAABB;
+
+ const int SP_SKYBOX = 0;
+ const int SP_MODELS = 1;
+ const int SP_COMPOSE = 2;
+ const int SP_TONE_MAPPING = 3;
+
+ public DeferredPbrRenderer (Device dev, SwapChain swapChain, PresentQueue presentQueue, float nearPlane, float farPlane) {
+ this.dev = dev;
+ this.swapChain = swapChain;
+ this.presentQueue = presentQueue;
+
+ pipelineCache = new PipelineCache (dev);
+
+ init (nearPlane, farPlane);
+ }
+
+ void init (float nearPlane, float farPlane) {
+
+ renderPass = new RenderPass (dev, samples);
+
+ renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1);//swapchain image
+ renderPass.AddAttachment (dev.GetSuitableDepthFormat(), VkImageLayout.DepthStencilAttachmentOptimal, samples);
+ renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.ColorAttachmentOptimal, samples, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff0 (color + roughness) and final color before resolve
+ renderPass.AddAttachment (VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal, samples, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff1 (emit + metal)
+ renderPass.AddAttachment (VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal, samples, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff2 (normals + AO)
+ renderPass.AddAttachment (VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal, samples, VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.DontCare);//GBuff3 (Pos + depth)
+ renderPass.AddAttachment (hdrFormat, VkImageLayout.ColorAttachmentOptimal, samples);//hdr color
+
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+ renderPass.ClearValues.Add (new VkClearValue { depthStencil = new VkClearDepthStencilValue (1.0f, 0) });
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+ renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
+
+ SubPass[] subpass = { new SubPass (), new SubPass (), new SubPass(), new SubPass() };
+ //skybox
+ subpass[SP_SKYBOX].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal);
+ //models
+ subpass[SP_MODELS].AddColorReference (new VkAttachmentReference (2, VkImageLayout.ColorAttachmentOptimal),
+ new VkAttachmentReference (3, VkImageLayout.ColorAttachmentOptimal),
+ new VkAttachmentReference (4, VkImageLayout.ColorAttachmentOptimal),
+ new VkAttachmentReference (5, VkImageLayout.ColorAttachmentOptimal));
+ subpass[SP_MODELS].SetDepthReference (1, VkImageLayout.DepthStencilAttachmentOptimal);
+ subpass[SP_MODELS].AddPreservedReference (0);
+
+ //compose
+ subpass[SP_COMPOSE].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal);
+ subpass[SP_COMPOSE].AddInputReference (new VkAttachmentReference (2, VkImageLayout.ShaderReadOnlyOptimal),
+ new VkAttachmentReference (3, VkImageLayout.ShaderReadOnlyOptimal),
+ new VkAttachmentReference (4, VkImageLayout.ShaderReadOnlyOptimal),
+ new VkAttachmentReference (5, VkImageLayout.ShaderReadOnlyOptimal));
+ //tone mapping
+ subpass[SP_TONE_MAPPING].AddColorReference ((samples == VkSampleCountFlags.SampleCount1) ? 0u : 2u, VkImageLayout.ColorAttachmentOptimal);
+ subpass[SP_TONE_MAPPING].AddInputReference (new VkAttachmentReference (6, VkImageLayout.ShaderReadOnlyOptimal));
+ if (samples != VkSampleCountFlags.SampleCount1)
+ subpass[SP_TONE_MAPPING].AddResolveReference (0, VkImageLayout.ColorAttachmentOptimal);
+
+ renderPass.AddSubpass (subpass);
+
+ renderPass.AddDependency (Vk.SubpassExternal, SP_SKYBOX,
+ VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.ColorAttachmentOutput,
+ VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
+ renderPass.AddDependency (SP_SKYBOX, SP_MODELS,
+ VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
+ VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
+ renderPass.AddDependency (SP_MODELS, SP_COMPOSE,
+ VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
+ VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
+ renderPass.AddDependency (SP_COMPOSE, SP_TONE_MAPPING,
+ VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
+ VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
+ renderPass.AddDependency (SP_TONE_MAPPING, Vk.SubpassExternal,
+ VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe,
+ VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead);
+
+
+ descriptorPool = new DescriptorPool (dev, 3,
+ new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer, 3),
+ new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 3),
+ new VkDescriptorPoolSize (VkDescriptorType.InputAttachment, 6)
+ );
+
+ descLayoutMain = new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),//matrices and params
+ new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),//lights
+ new VkDescriptorSetLayoutBinding (5, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer));//materials
+
+ descLayoutTextures = new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
+ new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
+ );
+
+ descLayoutGBuff = new DescriptorSetLayout (dev,
+ new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//color + roughness
+ new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//emit + metal
+ new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//normals + AO
+ new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//Pos + depth
+ new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));//hdr
+
+ dsMain = descriptorPool.Allocate (descLayoutMain);
+ dsGBuff = descriptorPool.Allocate (descLayoutGBuff);
+
+ GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, samples);
+
+ if (samples != VkSampleCountFlags.SampleCount1) {
+ cfg.multisampleState.sampleShadingEnable = true;
+ cfg.multisampleState.minSampleShading = 0.5f;
+ }
+ cfg.Cache = pipelineCache;
+ cfg.Layout = new PipelineLayout (dev, descLayoutMain, descLayoutTextures, descLayoutGBuff);
+ cfg.Layout.AddPushConstants (
+ new VkPushConstantRange (VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf<Matrix4x4> ()),
+ new VkPushConstantRange (VkShaderStageFlags.Fragment, sizeof (int), 64)
+ );
+ cfg.RenderPass = renderPass;
+ cfg.SubpassIndex = SP_MODELS;
+ cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
+ cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
+ cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
+ //cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
+
+ cfg.AddVertexBinding<PbrModel.Vertex> (0);
+ cfg.SetVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat, VkFormat.R32g32Sfloat);
+
+ using (SpecializationInfo constants = new SpecializationInfo (
+ new SpecializationConstant<float> (0, nearPlane),
+ new SpecializationConstant<float> (1, farPlane))) {
+
+ cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/GBuffPbr.vert.spv");
+ cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/GBuffPbr.frag.spv", constants);
+
+ gBuffPipeline = new GraphicPipeline (cfg);
+ }
+
+ //COMPOSE PIPELINE
+ cfg.blendAttachments.Clear ();
+ cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
+ cfg.ResetShadersAndVerticesInfos ();
+ cfg.SubpassIndex = SP_COMPOSE;
+ cfg.Layout = gBuffPipeline.Layout;
+ cfg.depthStencilState.depthTestEnable = false;
+ cfg.depthStencilState.depthWriteEnable = false;
+ using (SpecializationInfo constants = new SpecializationInfo (
+ new SpecializationConstant<uint> (0, (uint)lights.Length))) {
+ cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
+ cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/compose.frag.spv", constants);
+ composePipeline = new GraphicPipeline (cfg);
+ }
+ //DEBUG DRAW use subpass of compose
+ cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/show_gbuff.frag.spv");
+ cfg.SubpassIndex = SP_COMPOSE;
+ debugPipeline = new GraphicPipeline (cfg);
+ //TONE MAPPING
+ cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/tone_mapping.frag.spv");
+ cfg.SubpassIndex = SP_TONE_MAPPING;
+ toneMappingPipeline = new GraphicPipeline (cfg);
+
+ envCube = new EnvironmentCube (dsMain, gBuffPipeline.Layout, presentQueue, renderPass);
+
+ matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels;
+ uboMatrices = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices, true);
+ uboLights = new HostBuffer<Light> (dev, VkBufferUsageFlags.UniformBuffer, lights, true);
+
+ string[] modelPathes = {
+ "../data/models/DamagedHelmet/glTF/DamagedHelmet.gltf",
+ "/home/jp/gltf/chessold/scene.gltf",
+ "../data/models/Hubble.glb",
+ "../data/models/MER_static.glb",
+ "../data/models/ISS_stationary.glb",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Avocado/glTF/Avocado.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BarramundiFish/glTF/BarramundiFish.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BoomBoxWithAxes/glTF/BoomBoxWithAxes.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Box/glTF/Box.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/EnvironmentTest/glTF/EnvironmentTest.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/MetalRoughSpheres/glTF/MetalRoughSpheres.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/OrientationTest/glTF/OrientationTest.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Buggy/glTF/Buggy.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/2CylinderEngine/glTF-Embedded/2CylinderEngine.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/FlightHelmet/glTF/FlightHelmet.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/GearboxAssy/glTF/GearboxAssy.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Lantern/glTF/Lantern.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/SciFiHelmet/glTF/SciFiHelmet.gltf",
+ "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Sponza/glTF/Sponza.gltf",
+ "/mnt/devel/vkChess/data/chess.gltf",
+ "/home/jp/gltf/camaro/scene.gltf"
+ };
+
+ model = new PbrModel (presentQueue, modelPathes[0],
+ descLayoutTextures,
+ AttachmentType.Color,
+ AttachmentType.PhysicalProps,
+ AttachmentType.Normal,
+ AttachmentType.AmbientOcclusion,
+ AttachmentType.Emissive);
+ //model = new Model (presentQueue, "../data/models/chess.gltf");
+ //model = new Model (presentQueue, "../data/models/Sponza/glTF/Sponza.gltf");
+ //model = new Model (dev, presentQueue, "../data/models/icosphere.gltf");
+ //model = new Model (dev, presentQueue, cmdPool, "../data/models/cube.gltf");
+ DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutMain);
+ uboUpdate.Write (dev, dsMain,
+ uboMatrices.Descriptor,
+ envCube.irradianceCube.Descriptor,
+ envCube.prefilterCube.Descriptor,
+ envCube.lutBrdf.Descriptor,
+ uboLights.Descriptor,
+ model.materialUBO.Descriptor);
+
+ modelAABB = model.DefaultScene.AABB;
+ }
+
+ public void buildCommandBuffers (CommandBuffer[] cmds) {
+ for (int i = 0; i < swapChain.ImageCount; ++i) {
+ cmds[i].Start ();
+ recordDraw (cmds[i], frameBuffers[i]);
+ cmds[i].End ();
+ }
+ }
+
+ void recordDraw (CommandBuffer cmd, Framebuffer fb) {
+ renderPass.Begin (cmd, fb);
+
+ cmd.SetViewport (fb.Width, fb.Height);
+ cmd.SetScissor (fb.Width, fb.Height);
+
+ cmd.BindDescriptorSet (gBuffPipeline.Layout, dsMain);
+
+ envCube.RecordDraw (cmd);
+ renderPass.BeginSubPass (cmd);
+
+ gBuffPipeline.Bind (cmd);
+ model.Bind (cmd);
+ model.DrawAll (cmd, gBuffPipeline.Layout);
+
+ renderPass.BeginSubPass (cmd);
+
+ cmd.BindDescriptorSet (composePipeline.Layout, dsGBuff, 2);
+
+ if (currentDebugView == DebugView.none)
+ composePipeline.Bind (cmd);
+ else {
+ debugPipeline.Bind (cmd);
+ uint debugValue = (uint)currentDebugView - 1;
+ debugValue += (uint)((envCube.debugFace << 8) + (envCube.debugMip << 16));
+ cmd.PushConstant (debugPipeline.Layout, VkShaderStageFlags.Fragment, debugValue, (uint)Marshal.SizeOf<Matrix4x4> ());
+ }
+
+ cmd.Draw (3, 1, 0, 0);
+
+ renderPass.BeginSubPass (cmd);
+ toneMappingPipeline.Bind (cmd);
+ cmd.Draw (3, 1, 0, 0);
+
+ renderPass.End (cmd);
+ }
+
+ #region update
+ public void UpdateView (Camera camera) {
+ camera.AspectRatio = (float)swapChain.Width / swapChain.Height;
+
+ lights[0].position = lightPos;
+
+ matrices.projection = camera.Projection;
+ matrices.view = camera.View;
+ matrices.model = camera.Model;
+
+
+ matrices.camPos = new Vector4 (
+ -camera.Position.Z * (float)Math.Sin (camera.Rotation.Y) * (float)Math.Cos (camera.Rotation.X),
+ camera.Position.Z * (float)Math.Sin (camera.Rotation.X),
+ camera.Position.Z * (float)Math.Cos (camera.Rotation.Y) * (float)Math.Cos (camera.Rotation.X),
+ 0
+ );
+
+ uboMatrices.Update (matrices, (uint)Marshal.SizeOf<Matrices> ());
+ }
+
+ #endregion
+
+ void createGBuff () {
+ gbColorRough?.Dispose ();
+ gbEmitMetal?.Dispose ();
+ gbN_AO?.Dispose ();
+ gbPos?.Dispose ();
+ hdrImg?.Dispose ();
+
+ gbColorRough = new Image (dev, swapChain.ColorFormat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
+ gbEmitMetal = new Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
+ gbN_AO = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
+ gbPos = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
+ hdrImg = new Image (dev, hdrFormat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransientAttachment, VkMemoryPropertyFlags.DeviceLocal | VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
+
+ gbColorRough.CreateView ();
+ gbColorRough.CreateSampler ();
+ gbColorRough.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+ gbEmitMetal.CreateView ();
+ gbEmitMetal.CreateSampler ();
+ gbEmitMetal.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+ gbN_AO.CreateView ();
+ gbN_AO.CreateSampler ();
+ gbN_AO.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+ gbPos.CreateView ();
+ gbPos.CreateSampler ();
+ gbPos.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+ hdrImg.CreateView ();
+ hdrImg.CreateSampler ();
+ hdrImg.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
+
+ DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutGBuff);
+ uboUpdate.Write (dev, dsGBuff, gbColorRough.Descriptor,
+ gbEmitMetal.Descriptor,
+ gbN_AO.Descriptor,
+ gbPos.Descriptor,
+ hdrImg.Descriptor);
+ gbColorRough.SetName ("GBuffColorRough");
+ gbEmitMetal.SetName ("GBuffEmitMetal");
+ gbN_AO.SetName ("GBuffN");
+ gbPos.SetName ("GBuffPos");
+ hdrImg.SetName ("HDRimg");
+ }
+
+ public void Resize () {
+ if (frameBuffers != null)
+ for (int i = 0; i < swapChain.ImageCount; ++i)
+ frameBuffers[i]?.Dispose ();
+
+ createGBuff ();
+
+ frameBuffers = new Framebuffer[swapChain.ImageCount];
+
+ for (int i = 0; i < swapChain.ImageCount; ++i) {
+ frameBuffers[i] = new Framebuffer (renderPass, swapChain.Width, swapChain.Height, new Image[] {
+ swapChain.images[i], null, gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg});
+ }
+ }
+
+ public void Dispose () {
+ dev.WaitIdle ();
+ for (int i = 0; i < swapChain.ImageCount; ++i)
+ frameBuffers[i]?.Dispose ();
+
+ gbColorRough.Dispose ();
+ gbEmitMetal.Dispose ();
+ gbN_AO.Dispose ();
+ gbPos.Dispose ();
+ hdrImg.Dispose ();
+
+ gBuffPipeline.Dispose ();
+ composePipeline.Dispose ();
+ toneMappingPipeline.Dispose ();
+ debugPipeline.Dispose ();
+
+ descLayoutMain.Dispose ();
+ descLayoutTextures.Dispose ();
+ descLayoutGBuff.Dispose ();
+
+ uboMatrices.Dispose ();
+ uboLights.Dispose ();
+ model.Dispose ();
+ envCube.Dispose ();
+
+ descriptorPool.Dispose ();
+ }
+ }
+}
diff --git a/samples/deferred/main.cs b/samples/deferred/main.cs
index def9ee0..c20be6e 100644
--- a/samples/deferred/main.cs
+++ b/samples/deferred/main.cs
@@ -21,422 +21,38 @@ namespace deferred {
VkSampleCountFlags samples = VkSampleCountFlags.SampleCount4;
VkFormat hdrFormat = VkFormat.R32g32b32a32Sfloat;
- enum DebugView {
- none,
- color,
- normal,
- pos,
- occlusion,
- emissive,
- metallic,
- roughness,
- depth,
- prefill,
- irradiance
- }
-
- DebugView currentDebugView = DebugView.none;
-
- public struct Matrices {
- public Matrix4x4 projection;
- public Matrix4x4 model;
- public Matrix4x4 view;
- public Vector4 camPos;
- public Vector4 lightPos;
- public float exposure;
- public float gamma;
- public float prefilteredCubeMipLevels;
- public float scaleIBLAmbient;
- public uint lightsCount;
- public float debugViewEquation;
- }
-
- public struct Light {
- public Vector4 position;
- public Vector4 color;
- }
-
- public Matrices matrices = new Matrices {
- lightPos = Vector4.Normalize (new Vector4 (0.7f, 0.6f, 0.2f, 0.0f)),
- gamma = 1.2f,
- exposure = 2.0f,
- scaleIBLAmbient = 1.0f,
- lightsCount = 1,
- debugViewEquation = 0
- };
-
- Light[] lights = {
- new Light {
- position = new Vector4(1,1,1,0),
- color = new Vector4(1)
- }
- };
-
- Framebuffer[] frameBuffers;
- Image gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg;
-
- DescriptorPool descriptorPool;
- DescriptorSetLayout descLayoutMain, descLayoutTextures, descLayoutGBuff;
- DescriptorSet dsMain, dsGBuff;
-
- PipelineCache pipelineCache;
- Pipeline gBuffPipeline, composePipeline, toneMappingPipeline, debugPipeline;
-
- HostBuffer uboMats;
-
- RenderPass renderPass;
-
- PbrModel model;
- EnvironmentCube envCube;
-
- Vector4 lightPos = new Vector4 (1, 0, 0, 0);
- BoundingBox modelAABB;
-
- const int SP_SKYBOX = 0;
- const int SP_MODELS = 1;
- const int SP_COMPOSE = 2;
- const int SP_TONE_MAPPING = 3;
+ DeferredPbrRenderer renderer;
Program () {
- pipelineCache = new PipelineCache (dev);
-
camera = new Camera (Utils.DegreesToRadians (45f), 1f, 0.1f, 16f);
-
- init ();
-
camera.SetPosition (0, 0, 3);
- camera.Model = Matrix4x4.CreateScale (1f / Math.Max (Math.Max (modelAABB.max.X, modelAABB.max.Y), modelAABB.max.Z));
- //camera.Model = Matrix4x4.CreateScale (0.02f);
- }
-
- void init () {
-
- renderPass = new RenderPass (dev, samples);
-
- renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1);//swapchain image
- renderPass.AddAttachment (dev.GetSuitableDepthFormat(), VkImageLayout.DepthStencilAttachmentOptimal, samples);
- renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.ColorAttachmentOptimal, samples);//GBuff0 (color + roughness) and final color before resolve
- renderPass.AddAttachment (VkFormat.R8g8b8a8Unorm, VkImageLayout.ColorAttachmentOptimal, samples);//GBuff1 (emit + metal)
- renderPass.AddAttachment (VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal, samples);//GBuff2 (normals + AO)
- renderPass.AddAttachment (VkFormat.R16g16b16a16Sfloat, VkImageLayout.ColorAttachmentOptimal, samples);//GBuff3 (Pos + depth)
- renderPass.AddAttachment (hdrFormat, VkImageLayout.ColorAttachmentOptimal, samples);//hdr color
-
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
- renderPass.ClearValues.Add (new VkClearValue { depthStencil = new VkClearDepthStencilValue (1.0f, 0) });
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
- renderPass.ClearValues.Add (new VkClearValue { color = new VkClearColorValue (0.0f, 0.0f, 0.0f) });
-
- SubPass[] subpass = { new SubPass (), new SubPass (), new SubPass(), new SubPass() };
- //skybox
- subpass[SP_SKYBOX].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal);
- //models
- subpass[SP_MODELS].AddColorReference (new VkAttachmentReference (2, VkImageLayout.ColorAttachmentOptimal),
- new VkAttachmentReference (3, VkImageLayout.ColorAttachmentOptimal),
- new VkAttachmentReference (4, VkImageLayout.ColorAttachmentOptimal),
- new VkAttachmentReference (5, VkImageLayout.ColorAttachmentOptimal));
- subpass[SP_MODELS].SetDepthReference (1, VkImageLayout.DepthStencilAttachmentOptimal);
- subpass[SP_MODELS].AddPreservedReference (0);
-
- //compose
- subpass[SP_COMPOSE].AddColorReference (6, VkImageLayout.ColorAttachmentOptimal);
- subpass[SP_COMPOSE].AddInputReference (new VkAttachmentReference (2, VkImageLayout.ShaderReadOnlyOptimal),
- new VkAttachmentReference (3, VkImageLayout.ShaderReadOnlyOptimal),
- new VkAttachmentReference (4, VkImageLayout.ShaderReadOnlyOptimal),
- new VkAttachmentReference (5, VkImageLayout.ShaderReadOnlyOptimal));
- //tone mapping
- subpass[SP_TONE_MAPPING].AddColorReference ((samples == VkSampleCountFlags.SampleCount1) ? 0u : 2u, VkImageLayout.ColorAttachmentOptimal);
- subpass[SP_TONE_MAPPING].AddInputReference (new VkAttachmentReference (6, VkImageLayout.ShaderReadOnlyOptimal));
- if (samples != VkSampleCountFlags.SampleCount1)
- subpass[SP_TONE_MAPPING].AddResolveReference (0, VkImageLayout.ColorAttachmentOptimal);
-
- renderPass.AddSubpass (subpass);
-
- renderPass.AddDependency (Vk.SubpassExternal, SP_SKYBOX,
- VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.ColorAttachmentOutput,
- VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
- renderPass.AddDependency (SP_SKYBOX, SP_MODELS,
- VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
- VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
- renderPass.AddDependency (SP_MODELS, SP_COMPOSE,
- VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
- VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
- renderPass.AddDependency (SP_COMPOSE, SP_TONE_MAPPING,
- VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.FragmentShader,
- VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.ShaderRead);
- renderPass.AddDependency (SP_TONE_MAPPING, Vk.SubpassExternal,
- VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe,
- VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead);
-
-
- descriptorPool = new DescriptorPool (dev, 3,
- new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer, 2),
- new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler, 3),
- new VkDescriptorPoolSize (VkDescriptorType.InputAttachment, 6)
- );
-
- descLayoutMain = new DescriptorSetLayout (dev,
- new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
- new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer));
-
- descLayoutTextures = new DescriptorSetLayout (dev,
- new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
- new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
- );
-
- descLayoutGBuff = new DescriptorSetLayout (dev,
- new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//color + roughness
- new VkDescriptorSetLayoutBinding (1, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//emit + metal
- new VkDescriptorSetLayoutBinding (2, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//normals + AO
- new VkDescriptorSetLayoutBinding (3, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment),//Pos + depth
- new VkDescriptorSetLayoutBinding (4, VkShaderStageFlags.Fragment, VkDescriptorType.InputAttachment));//hdr
-
- dsMain = descriptorPool.Allocate (descLayoutMain);
- dsGBuff = descriptorPool.Allocate (descLayoutGBuff);
-
- GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, samples);
-
- if (samples != VkSampleCountFlags.SampleCount1) {
- cfg.multisampleState.sampleShadingEnable = true;
- cfg.multisampleState.minSampleShading = 0.5f;
- }
- cfg.Cache = pipelineCache;
- cfg.Layout = new PipelineLayout (dev, descLayoutMain, descLayoutTextures, descLayoutGBuff);
- cfg.Layout.AddPushConstants (
- new VkPushConstantRange (VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf<Matrix4x4> ()),
- new VkPushConstantRange (VkShaderStageFlags.Fragment, sizeof (int), 64)
- );
- cfg.RenderPass = renderPass;
- cfg.SubpassIndex = SP_MODELS;
- cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
- cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
- cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
- //cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
-
- cfg.AddVertexBinding<PbrModel.Vertex> (0);
- cfg.SetVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat, VkFormat.R32g32Sfloat);
-
- using (SpecializationInfo constants = new SpecializationInfo (
- new SpecializationConstant<float> (0, camera.NearPlane),
- new SpecializationConstant<float> (1, camera.FarPlane))) {
-
- cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/GBuffPbr.vert.spv");
- cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/GBuffPbr.frag.spv", constants);
-
- gBuffPipeline = new GraphicPipeline (cfg);
- }
-
- //COMPOSE PIPELINE
- cfg.blendAttachments.Clear ();
- cfg.blendAttachments.Add (new VkPipelineColorBlendAttachmentState (false));
- cfg.ResetShadersAndVerticesInfos ();
- cfg.SubpassIndex = SP_COMPOSE;
- cfg.Layout = gBuffPipeline.Layout;
- cfg.depthStencilState.depthTestEnable = false;
- cfg.depthStencilState.depthWriteEnable = false;
- cfg.AddShader (VkShaderStageFlags.Vertex, "shaders/FullScreenQuad.vert.spv");
- cfg.AddShader (VkShaderStageFlags.Fragment, "shaders/compose.frag.spv");
- composePipeline = new GraphicPipeline (cfg);
- //DEBUG DRAW use subpass of compose
- cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/show_gbuff.frag.spv");
- cfg.SubpassIndex = SP_COMPOSE;
- debugPipeline = new GraphicPipeline (cfg);
- //TONE MAPPING
- cfg.shaders[1] = new ShaderInfo (VkShaderStageFlags.Fragment, "shaders/tone_mapping.frag.spv");
- cfg.SubpassIndex = SP_TONE_MAPPING;
- //cfg.multisampleState.sampleShadingEnable = false;
- //cfg.multisampleState.rasterizationSamples = VkSampleCountFlags.SampleCount1;
+ renderer = new DeferredPbrRenderer (dev, swapChain, presentQueue, camera.NearPlane, camera.FarPlane);
- toneMappingPipeline = new GraphicPipeline (cfg);
-
- envCube = new EnvironmentCube (dsMain, gBuffPipeline.Layout, presentQueue, renderPass);
-
- matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels;
- uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices, true);
-
- string[] modelPathes = {
- "../data/models/DamagedHelmet/glTF/DamagedHelmet.gltf",
- "../data/models/Hubble.glb",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Avocado/glTF/Avocado.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BarramundiFish/glTF/BarramundiFish.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BoomBoxWithAxes/glTF/BoomBoxWithAxes.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Box/glTF/Box.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/EnvironmentTest/glTF/EnvironmentTest.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/MetalRoughSpheres/glTF/MetalRoughSpheres.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/OrientationTest/glTF/OrientationTest.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Buggy/glTF/Buggy.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/2CylinderEngine/glTF-Embedded/2CylinderEngine.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/FlightHelmet/glTF/FlightHelmet.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/GearboxAssy/glTF/GearboxAssy.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Lantern/glTF/Lantern.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/SciFiHelmet/glTF/SciFiHelmet.gltf",
- "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Sponza/glTF/Sponza.gltf",
- "/mnt/devel/vkChess/data/chess.gltf",
- "/home/jp/gltf/camaro/scene.gltf"
- };
-
- model = new PbrModel (presentQueue, modelPathes[1],
- descLayoutTextures,
- AttachmentType.Color,
- AttachmentType.PhysicalProps,
- AttachmentType.Normal,
- AttachmentType.AmbientOcclusion,
- AttachmentType.Emissive);
- //model = new Model (presentQueue, "../data/models/chess.gltf");
- //model = new Model (presentQueue, "../data/models/Sponza/glTF/Sponza.gltf");
- //model = new Model (dev, presentQueue, "../data/models/icosphere.gltf");
- //model = new Model (dev, presentQueue, cmdPool, "../data/models/cube.gltf");
- DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutMain);
- uboUpdate.Write (dev, dsMain,
- uboMats.Descriptor,
- envCube.irradianceCube.Descriptor,
- envCube.prefilterCube.Descriptor,
- envCube.lutBrdf.Descriptor,
- model.materialUBO.Descriptor);
-
- modelAABB = model.DefaultScene.AABB;
+ camera.Model = Matrix4x4.CreateScale (1f / Math.Max (Math.Max (renderer.modelAABB.Width, renderer.modelAABB.Height), renderer.modelAABB.Depth));
}
- void buildCommandBuffers () {
- for (int i = 0; i < swapChain.ImageCount; ++i) {
- cmds[i]?.Free ();
- cmds[i] = cmdPool.AllocateAndStart ();
- recordDraw (cmds[i], frameBuffers[i]);
- cmds[i].End ();
- }
+ void buildCommandBuffers () {
+ cmdPool.FreeCommandBuffers (cmds);
+ cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+ renderer.buildCommandBuffers (cmds);
}
- void recordDraw (CommandBuffer cmd, Framebuffer fb) {
- renderPass.Begin (cmd, fb);
-
- cmd.SetViewport (fb.Width, fb.Height);
- cmd.SetScissor (fb.Width, fb.Height);
-
- cmd.BindDescriptorSet (gBuffPipeline.Layout, dsMain);
-
- envCube.RecordDraw (cmd);
- renderPass.BeginSubPass (cmd);
- gBuffPipeline.Bind (cmd);
- model.Bind (cmd);
- model.DrawAll (cmd, gBuffPipeline.Layout);
-
- renderPass.BeginSubPass (cmd);
-
- cmd.BindDescriptorSet (composePipeline.Layout, dsGBuff, 2);
-
- if (currentDebugView == DebugView.none)
- composePipeline.Bind (cmd);
- else {
- debugPipeline.Bind (cmd);
- uint debugValue = (uint)currentDebugView - 1;
- debugValue += (uint)((envCube.debugFace << 8) + (envCube.debugMip << 16));
- cmd.PushConstant (debugPipeline.Layout, VkShaderStageFlags.Fragment, debugValue, (uint)Marshal.SizeOf<Matrix4x4> ());
- }
-
- cmd.Draw (3, 1, 0, 0);
-
- renderPass.BeginSubPass (cmd);
- toneMappingPipeline.Bind (cmd);
- cmd.Draw (3, 1, 0, 0);
-
- renderPass.End (cmd);
- }
#region update
public override void UpdateView () {
- camera.AspectRatio = (float)swapChain.Width / swapChain.Height;
-
- matrices.lightPos = lightPos;
-
- matrices.projection = camera.Projection;
- matrices.view = camera.View;
- matrices.model = camera.Model;
-
-
- matrices.camPos = new Vector4 (
- -camera.Position.Z * (float)Math.Sin (camera.Rotation.Y) * (float)Math.Cos (camera.Rotation.X),
- camera.Position.Z * (float)Math.Sin (camera.Rotation.X),
- camera.Position.Z * (float)Math.Cos (camera.Rotation.Y) * (float)Math.Cos (camera.Rotation.X),
- 0
- );
-
- uboMats.Update (matrices, (uint)Marshal.SizeOf<Matrices> ());
-
+ renderer.UpdateView (camera);
updateViewRequested = false;
}
#endregion
- void createGBuff () {
- gbColorRough?.Dispose ();
- gbEmitMetal?.Dispose ();
- gbN_AO?.Dispose ();
- gbPos?.Dispose ();
- hdrImg?.Dispose ();
-
- gbColorRough = new Image (dev, swapChain.ColorFormat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
- gbEmitMetal = new Image (dev, VkFormat.R8g8b8a8Unorm, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
- gbN_AO = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
- gbPos = new Image (dev, VkFormat.R16g16b16a16Sfloat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
- hdrImg = new Image (dev, hdrFormat, VkImageUsageFlags.InputAttachment | VkImageUsageFlags.ColorAttachment, VkMemoryPropertyFlags.DeviceLocal, swapChain.Width, swapChain.Height, VkImageType.Image2D, samples);
-
- gbColorRough.CreateView ();
- gbColorRough.CreateSampler ();
- gbColorRough.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
- gbEmitMetal.CreateView ();
- gbEmitMetal.CreateSampler ();
- gbEmitMetal.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
- gbN_AO.CreateView ();
- gbN_AO.CreateSampler ();
- gbN_AO.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
- gbPos.CreateView ();
- gbPos.CreateSampler ();
- gbPos.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
- hdrImg.CreateView ();
- hdrImg.CreateSampler ();
- hdrImg.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
-
- DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descLayoutGBuff);
- uboUpdate.Write (dev, dsGBuff, gbColorRough.Descriptor,
- gbEmitMetal.Descriptor,
- gbN_AO.Descriptor,
- gbPos.Descriptor,
- hdrImg.Descriptor);
- gbColorRough.SetName ("GBuffColorRough");
- gbEmitMetal.SetName ("GBuffEmitMetal");
- gbN_AO.SetName ("GBuffN");
- gbPos.SetName ("GBuffPos");
- hdrImg.SetName ("HDRimg");
- }
-
protected override void OnResize () {
UpdateView ();
-
- if (frameBuffers != null)
- for (int i = 0; i < swapChain.ImageCount; ++i)
- frameBuffers[i]?.Dispose ();
-
- createGBuff ();
-
- frameBuffers = new Framebuffer[swapChain.ImageCount];
-
- for (int i = 0; i < swapChain.ImageCount; ++i) {
- frameBuffers[i] = new Framebuffer (renderPass, swapChain.Width, swapChain.Height, new Image[] {
- swapChain.images[i], null, gbColorRough, gbEmitMetal, gbN_AO, gbPos, hdrImg});
- }
-
+ renderer.Resize ();
buildCommandBuffers ();
}
@@ -454,25 +70,25 @@ namespace deferred {
switch (key) {
case Key.F:
if (modifiers.HasFlag (Modifier.Shift)) {
- envCube.debugFace--;
- if (envCube.debugFace < 0)
- envCube.debugFace = 5;
+ renderer.envCube.debugFace--;
+ if (renderer.envCube.debugFace < 0)
+ renderer.envCube.debugFace = 5;
} else {
- envCube.debugFace++;
- if (envCube.debugFace > 5)
- envCube.debugFace = 0;
+ renderer.envCube.debugFace++;
+ if (renderer.envCube.debugFace > 5)
+ renderer.envCube.debugFace = 0;
}
rebuildBuffers = true;
break;
case Key.M:
if (modifiers.HasFlag (Modifier.Shift)) {
- envCube.debugMip--;
- if (envCube.debugMip < 0)
- envCube.debugMip = (int)envCube.prefilterCube.CreateInfo.mipLevels - 1;
+ renderer.envCube.debugMip--;
+ if (renderer.envCube.debugMip < 0)
+ renderer.envCube.debugMip = (int)renderer.envCube.prefilterCube.CreateInfo.mipLevels - 1;
} else {
- envCube.debugMip++;
- if (envCube.debugMip > envCube.prefilterCube.CreateInfo.mipLevels)
- envCube.debugMip = 0;
+ renderer.envCube.debugMip++;
+ if (renderer.envCube.debugMip > renderer.envCube.prefilterCube.CreateInfo.mipLevels)
+ renderer.envCube.debugMip = 0;
}
rebuildBuffers = true;
break;
@@ -486,60 +102,60 @@ namespace deferred {
case Key.Keypad7:
case Key.Keypad8:
case Key.Keypad9:
- currentDebugView = (DebugView)(int)key-320;
+ renderer.currentDebugView = (DeferredPbrRenderer.DebugView)(int)key-320;
rebuildBuffers = true;
break;
case Key.KeypadDivide:
- currentDebugView = DebugView.irradiance;
+ renderer.currentDebugView = DeferredPbrRenderer.DebugView.irradiance;
rebuildBuffers = true;
break;
case Key.Up:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos -= Vector4.UnitZ;
+ renderer.lightPos -= Vector4.UnitZ;
else
camera.Move (0, 0, 1);
break;
case Key.Down:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos += Vector4.UnitZ;
+ renderer.lightPos += Vector4.UnitZ;
else
camera.Move (0, 0, -1);
break;
case Key.Left:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos -= Vector4.UnitX;
+ renderer.lightPos -= Vector4.UnitX;
else
camera.Move (1, 0, 0);
break;
case Key.Right:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos += Vector4.UnitX;
+ renderer.lightPos += Vector4.UnitX;
else
camera.Move (-1, 0, 0);
break;
case Key.PageUp:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos += Vector4.UnitY;
+ renderer.lightPos += Vector4.UnitY;
else
camera.Move (0, 1, 0);
break;
case Key.PageDown:
if (modifiers.HasFlag (Modifier.Shift))
- lightPos -= Vector4.UnitY;
+ renderer.lightPos -= Vector4.UnitY;
else
camera.Move (0, -1, 0);
break;
case Key.F2:
if (modifiers.HasFlag (Modifier.Shift))
- matrices.exposure -= 0.3f;
+ renderer.matrices.exposure -= 0.3f;
else
- matrices.exposure += 0.3f;
+ renderer.matrices.exposure += 0.3f;
break;
case Key.F3:
if (modifiers.HasFlag (Modifier.Shift))
- matrices.gamma -= 0.1f;
+ renderer.matrices.gamma -= 0.1f;
else
- matrices.gamma += 0.1f;
+ renderer.matrices.gamma += 0.1f;
break;
case Key.F4:
if (camera.Type == Camera.CamType.FirstPerson)
@@ -549,7 +165,7 @@ namespace deferred {
Console.WriteLine ($"camera type = {camera.Type}");
break;
case Key.S:
- pipelineCache.Save ();
+ renderer.pipelineCache.Save ();
Console.WriteLine ($"Pipeline Cache saved.");
break;
default:
@@ -563,30 +179,7 @@ namespace deferred {
protected override void Dispose (bool disposing) {
if (disposing) {
if (!isDisposed) {
- dev.WaitIdle ();
- for (int i = 0; i < swapChain.ImageCount; ++i)
- frameBuffers[i]?.Dispose ();
-
- gbColorRough.Dispose ();
- gbEmitMetal.Dispose ();
- gbN_AO.Dispose ();
- gbPos.Dispose ();
- hdrImg.Dispose ();
-
- gBuffPipeline.Dispose ();
- composePipeline.Dispose ();
- toneMappingPipeline.Dispose ();
- debugPipeline.Dispose ();
-
- descLayoutMain.Dispose ();
- descLayoutTextures.Dispose ();
- descLayoutGBuff.Dispose ();
-
- uboMats.Dispose ();
- model.Dispose ();
- envCube.Dispose ();
-
- descriptorPool.Dispose ();
+ renderer.Dispose ();
}
}
diff --git a/samples/deferred/shaders/GBuffPbr.frag b/samples/deferred/shaders/GBuffPbr.frag
index 0a98717..c5708a0 100644
--- a/samples/deferred/shaders/GBuffPbr.frag
+++ b/samples/deferred/shaders/GBuffPbr.frag
@@ -45,19 +45,14 @@ layout (set = 0, binding = 0) uniform UBO {
mat4 projection;
mat4 model;
mat4 view;
- vec4 camPos;
- vec4 lightDir;
+ vec4 camPos;
float exposure;
float gamma;
float prefilteredCubeMipLevels;
float scaleIBLAmbient;
-#if DEBUG
- float debugViewInputs;
- float debugViewEquation;
-#endif
} ubo;
-layout (set = 0, binding = 4) uniform UBOMaterials {
+layout (set = 0, binding = 5) uniform UBOMaterials {
Material materials[16];
};
diff --git a/samples/deferred/shaders/GBuffPbr.vert b/samples/deferred/shaders/GBuffPbr.vert
index 76ee24b..aa526a0 100644
--- a/samples/deferred/shaders/GBuffPbr.vert
+++ b/samples/deferred/shaders/GBuffPbr.vert
@@ -9,8 +9,7 @@ layout (set = 0, binding = 0) uniform UBO {
mat4 projection;
mat4 model;
mat4 view;
- vec4 camPos;
- vec4 lightDir;
+ vec4 camPos;
float exposure;
float gamma;
float prefilteredCubeMipLevels;
diff --git a/samples/deferred/shaders/compose.frag b/samples/deferred/shaders/compose.frag
index 8dbf013..fc185a3 100644
--- a/samples/deferred/shaders/compose.frag
+++ b/samples/deferred/shaders/compose.frag
@@ -6,27 +6,22 @@ layout (set = 0, binding = 0) uniform UBO {
mat4 projection;
mat4 model;
mat4 view;
- vec4 camPos;
- vec4 lightPos;
+ vec4 camPos;
float exposure;
float gamma;
float prefilteredCubeMipLevels;
float scaleIBLAmbient;
-#if DEBUG
- float debugViewInputs;
- float debugViewEquation;
-#endif
} ubo;
-#define MAX_LIGHT 4
+layout (constant_id = 0) const uint NUM_LIGHTS = 1;
struct Light {
vec4 position;
vec4 color;
};
-layout (set = 0, binding = 5) uniform UBOLights {
- Light lights[MAX_LIGHT];
+layout (set = 0, binding = 4) uniform UBOLights {
+ Light lights[NUM_LIGHTS];
};
const float M_PI = 3.141592653589793;
@@ -171,56 +166,63 @@ void main()
vec3 specularEnvironmentR90 = vec3(1.0) * reflectance90;
vec3 n = subpassLoad(samplerN_AO, gl_SampleID).rgb;
- vec3 v = subpassLoad(samplerPos, gl_SampleID).rgb; // Vector from surface point to camera
- vec3 l = normalize(ubo.lightPos.xyz); // Vector from surface point to light
- vec3 h = normalize(l+v); // Half vector between both l and v
- vec3 reflection = -normalize(reflect(v, n));
- reflection.y *= -1.0f;
-
- float NdotL = clamp(dot(n, l), 0.001, 1.0);
- float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
- float NdotH = clamp(dot(n, h), 0.0, 1.0);
- float LdotH = clamp(dot(l, h), 0.0, 1.0);
- float VdotH = clamp(dot(v, h), 0.0, 1.0);
-
- PBRInfo pbrInputs = PBRInfo(
- NdotL,
- NdotV,
- NdotH,
- LdotH,
- VdotH,
- perceptualRoughness,
- metallic,
- specularEnvironmentR0,
- specularEnvironmentR90,
- alphaRoughness,
- diffuseColor,
- specularColor
- );
+ vec3 v = subpassLoad(samplerPos, gl_SampleID).rgb; // Vector from surface point to camera
+
+ vec3 colors = vec3(0);
+
+ for (int i=0; i<NUM_LIGHTS; i++) {
+
+ vec3 l = normalize(lights[i].position.xyz); // Vector from surface point to light
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
- // Calculate the shading terms for the microfacet specular shading model
- vec3 F = specularReflection(pbrInputs);
- float G = geometricOcclusion(pbrInputs);
- float D = microfacetDistribution(pbrInputs);
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
- const vec3 u_LightColor = vec3(1.0);
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
- // Calculation of analytical lighting contribution
- vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
- vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
- // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
- vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib);
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
- // Calculate lighting contribution from image based lighting source (IBL)
- color += getIBLContribution(pbrInputs, n, reflection);
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * lights[i].color.rgb * (diffuseContrib + specContrib);
+ // Calculate lighting contribution from image based lighting source (IBL)
+ colors += color + getIBLContribution(pbrInputs, n, reflection);
+
+ }
+ colors /= NUM_LIGHTS;
+
+
const float u_OcclusionStrength = 1.0f;
const float u_EmissiveFactor = 1.0f;
//AO is in the alpha channel of the normalAttachment
- color = mix(color, color * subpassLoad(samplerN_AO, gl_SampleID).a, u_OcclusionStrength);
- color += emissive;
+ colors = mix(colors, colors * subpassLoad(samplerN_AO, gl_SampleID).a, u_OcclusionStrength);
+ colors += emissive;
- outColor = vec4(color, baseColor.a);
+ outColor = vec4(colors, baseColor.a);
} \ No newline at end of file
diff --git a/samples/deferred/shaders/debug.vert b/samples/deferred/shaders/debug.vert
index 34a2df2..180e58e 100644
--- a/samples/deferred/shaders/debug.vert
+++ b/samples/deferred/shaders/debug.vert
@@ -12,8 +12,7 @@ layout (binding = 0) uniform UBO
{
mat4 projectionMatrix;
mat4 viewMatrix;
- mat4 modelMatrix;
- vec4 lightPos;
+ mat4 modelMatrix;
float gamma;
float exposure;
} ubo;
diff --git a/samples/deferred/shaders/tone_mapping.frag b/samples/deferred/shaders/tone_mapping.frag
index 9b8c94c..66f435d 100644
--- a/samples/deferred/shaders/tone_mapping.frag
+++ b/samples/deferred/shaders/tone_mapping.frag
@@ -6,8 +6,7 @@ layout (set = 0, binding = 0) uniform UBO {
mat4 projection;
mat4 model;
mat4 view;
- vec4 camPos;
- vec4 lightDir;
+ vec4 camPos;
float exposure;
float gamma;
} ubo;
diff --git a/vke/src/CommandPool.cs b/vke/src/CommandPool.cs
index 2099a51..4d21d4e 100644
--- a/vke/src/CommandPool.cs
+++ b/vke/src/CommandPool.cs
@@ -95,9 +95,16 @@ namespace CVKL {
return;
}
using (NativeList<VkCommandBuffer> nlCmds = new NativeList<VkCommandBuffer> ((uint)cmds.Length, (uint)cmds.Length)) {
- for (int i = 0; i < cmds.Length; i++)
- nlCmds[i] = cmds[i].Handle;
- vkFreeCommandBuffers (Dev.VkDev, handle, (uint)cmds.Length, nlCmds.Data);
+ int count = 0;
+ for (int i = 0; i < cmds.Length; i++) {
+ if (cmds[i] == null)
+ continue;
+ nlCmds[count] = cmds[i].Handle;
+ count++;
+ }
+ if (count == 0)
+ return;
+ vkFreeCommandBuffers (Dev.VkDev, handle, (uint)count, nlCmds.Data);
}
}
diff --git a/vke/src/Device.cs b/vke/src/Device.cs
index e66c28d..9c8700c 100644
--- a/vke/src/Device.cs
+++ b/vke/src/Device.cs
@@ -250,9 +250,10 @@ namespace CVKL {
protected virtual void Dispose (bool disposing) {
if (!disposedValue) {
- if (disposing) {
- // TODO: supprimer l'état managé (objets managés).
- }
+ if (disposing) {
+ resourceManager.Dispose ();
+ } else
+ System.Diagnostics.Debug.WriteLine ("Device disposed by Finalizer.");
vkDestroyDevice (dev, IntPtr.Zero);
@@ -260,17 +261,13 @@ namespace CVKL {
}
}
- // TODO: remplacer un finaliseur seulement si la fonction Dispose(bool disposing) ci-dessus a du code pour libérer les ressources non managées.
~Device() {
- // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
Dispose(false);
}
// Ce code est ajouté pour implémenter correctement le modèle supprimable.
public void Dispose () {
- // Ne modifiez pas ce code. Placez le code de nettoyage dans Dispose(bool disposing) ci-dessus.
Dispose (true);
- // TODO: supprimer les marques de commentaire pour la ligne suivante si le finaliseur est remplacé ci-dessus.
GC.SuppressFinalize(this);
}
#endregion
diff --git a/vke/src/Model.cs b/vke/src/Model.cs
index 0614108..280dc2a 100644
--- a/vke/src/Model.cs
+++ b/vke/src/Model.cs
@@ -75,6 +75,11 @@ namespace CVKL {
return new BoundingBox (mini, maxi, true);
}
+ public float Width => max.X - min.X;
+ public float Height => max.Y - min.Y;
+ public float Depth => max.Z - min.Z;
+
+ public Vector3 Center => new Vector3 (Width / 2f + min.X, Height / 2f + min.Y, Depth / 2f + min.Z);
public static BoundingBox operator +(BoundingBox bb1, BoundingBox bb2) {
return bb1.isValid ? bb2.isValid ? new BoundingBox (Vector3.Min (bb1.min, bb2.min), Vector3.Min (bb1.max, bb2.max),true) : bb1 : bb2.isValid ? bb2 : default(BoundingBox);