From 56b8d83babf3246763f865164b0ed60b30b4ec0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Tue, 1 Jun 2021 16:29:24 +0200 Subject: [PATCH] DeferredShading demo: Add a skybox --- bin/resources/skybox.nzsl | 67 +++++++++++++++++++++++ examples/DeferredShading/main.cpp | 89 +++++++++++++++++++++++++++++-- 2 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 bin/resources/skybox.nzsl diff --git a/bin/resources/skybox.nzsl b/bin/resources/skybox.nzsl new file mode 100644 index 000000000..9d5b8660c --- /dev/null +++ b/bin/resources/skybox.nzsl @@ -0,0 +1,67 @@ +[layout(std140)] +struct ViewerData +{ + projectionMatrix: mat4, + invProjectionMatrix: mat4, + viewMatrix: mat4, + invViewMatrix: mat4, + viewProjMatrix: mat4, + invViewProjMatrix: mat4, + renderTargetSize: vec2, + invRenderTargetSize: vec2, + eyePosition: vec3 +} + +external +{ + [binding(1)] skybox: samplerCube +} + +struct VertOut +{ + [location(0)] uvw: vec3, + [builtin(position)] position: vec4 +} + +struct FragOut +{ + [location(0)] color: vec4, + [builtin(fragdepth)] depth: f32 +} + +[entry(frag)] +[depth_write(greater)] +fn main(input: VertOut) -> FragOut +{ + let output: FragOut; + output.color = skybox.Sample(input.uvw); + output.depth = 1.0; + + return output; +} + +external +{ + [binding(0)] viewerData: uniform +} + +struct VertIn +{ + [location(0)] position: vec3 +} + +[entry(vert)] +fn main(input: VertIn) -> VertOut +{ + // Set translation part to zero + let rotationMat = viewerData.viewMatrix; + rotationMat[3][0] = 0.0; + rotationMat[3][1] = 0.0; + rotationMat[3][2] = 0.0; + + let output: VertOut; + output.position = viewerData.projectionMatrix * rotationMat * vec4(input.position, 1.0); + output.uvw = vec3(input.position.xy * -1.0, input.position.z); + + return output; +} diff --git a/examples/DeferredShading/main.cpp b/examples/DeferredShading/main.cpp index 08d7636f4..e0f926d3c 100644 --- a/examples/DeferredShading/main.cpp +++ b/examples/DeferredShading/main.cpp @@ -108,6 +108,7 @@ int main() texParams.renderDevice = device; texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB; + // Plane Nz::MeshParams meshPrimitiveParams; meshPrimitiveParams.storage = Nz::DataStorage::Software; @@ -119,8 +120,49 @@ int main() std::shared_ptr planeMeshGfx = std::make_shared(*planeMesh); + // Skybox meshPrimitiveParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ); + std::shared_ptr cubeMesh = std::make_shared(); + cubeMesh->CreateStatic(); + cubeMesh->BuildSubMesh(Nz::Primitive::Box(Nz::Vector3f::Unit(), Nz::Vector3ui(0), Nz::Matrix4f::Scale({ 1.f, -1.f, 1.f })), meshPrimitiveParams); + cubeMesh->SetMaterialCount(1); + + std::shared_ptr cubeMeshGfx = std::make_shared(*cubeMesh); + + Nz::RenderPipelineLayoutInfo pipelineLayoutInfo; + auto& uboBinding = pipelineLayoutInfo.bindings.emplace_back(); + uboBinding.index = 0; + uboBinding.shaderStageFlags = Nz::ShaderStageType::Vertex; + uboBinding.type = Nz::ShaderBindingType::UniformBuffer; + + auto& textureBinding = pipelineLayoutInfo.bindings.emplace_back(); + textureBinding.index = 1; + textureBinding.shaderStageFlags = Nz::ShaderStageType::Fragment; + textureBinding.type = Nz::ShaderBindingType::Texture; + + std::shared_ptr skyboxPipelineLayout = device->InstantiateRenderPipelineLayout(std::move(pipelineLayoutInfo)); + + Nz::RenderPipelineInfo skyboxPipelineInfo; + skyboxPipelineInfo.depthBuffer = true; + skyboxPipelineInfo.depthCompare = Nz::RendererComparison::Equal; + skyboxPipelineInfo.faceCulling = true; + skyboxPipelineInfo.cullingSide = Nz::FaceSide::Front; + skyboxPipelineInfo.pipelineLayout = skyboxPipelineLayout; + skyboxPipelineInfo.shaderModules.push_back(device->InstantiateShaderModule(Nz::ShaderStageType::Fragment | Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraShader, resourceDir / "skybox.nzsl", {})); + skyboxPipelineInfo.vertexBuffers.push_back({ + 0, + meshPrimitiveParams.vertexDeclaration + }); + + std::shared_ptr skyboxPipeline = device->InstantiateRenderPipeline(std::move(skyboxPipelineInfo)); + + Nz::TextureParams skyboxTexParams; + skyboxTexParams.renderDevice = device; + + std::shared_ptr skyboxTexture = Nz::Texture::LoadCubemapFromFile(resourceDir / "skybox-space.png", skyboxTexParams); + + // Cone mesh std::shared_ptr coneMesh = std::make_shared(); coneMesh->CreateStatic(); coneMesh->BuildSubMesh(Nz::Primitive::Cone(1.f, 1.f, 16, Nz::Matrix4f::Rotate(Nz::EulerAnglesf(90.f, 0.f, 0.f))), meshPrimitiveParams); @@ -436,7 +478,28 @@ int main() bool viewerUboUpdate = true; - Nz::BakedFrameGraph bakedGraph = [&]{ + std::shared_ptr textureSampler = device->InstantiateTextureSampler({}); + + std::shared_ptr skyboxShaderBinding = skyboxPipelineLayout->AllocateShaderBinding(); + skyboxShaderBinding->Update({ + { + 0, + Nz::ShaderBinding::UniformBufferBinding { + viewerDataUBO.get(), + 0, viewerDataUBO->GetSize() + } + }, + { + 1, + Nz::ShaderBinding::TextureBinding { + skyboxTexture.get(), + textureSampler.get() + } + } + }); + + Nz::BakedFrameGraph bakedGraph = [&] + { Nz::FrameGraph graph; colorTexture = graph.AddAttachment({ @@ -544,7 +607,26 @@ int main() lightingPass.SetClearColor(lightingPass.AddOutput(backbuffer), Nz::Color::Black); lightingPass.SetDepthStencilInput(depthBuffer); lightingPass.SetDepthStencilOutput(depthBuffer); - //lightingPass.SetDepthStencilInput(depthBuffer); + + Nz::FramePass& forwardPass = graph.AddPass("Forward pass"); + forwardPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder) + { + builder.SetScissor(Nz::Recti{ 0, 0, int(offscreenWidth), int(offscreenHeight) }); + builder.SetViewport(Nz::Recti{ 0, 0, int(offscreenWidth), int(offscreenHeight) }); + + builder.BindShaderBinding(*skyboxShaderBinding); + + builder.BindIndexBuffer(cubeMeshGfx->GetIndexBuffer(0).get()); + builder.BindVertexBuffer(0, cubeMeshGfx->GetVertexBuffer(0).get()); + builder.BindPipeline(*skyboxPipeline); + + builder.DrawIndexed(static_cast(cubeMeshGfx->GetIndexCount(0))); + }); + + forwardPass.AddInput(backbuffer); + forwardPass.AddOutput(backbuffer); + forwardPass.SetDepthStencilInput(depthBuffer); + forwardPass.SetDepthStencilOutput(depthBuffer); graph.SetBackbufferOutput(backbuffer); @@ -553,8 +635,6 @@ int main() bakedGraph.Resize(offscreenWidth, offscreenHeight); - std::shared_ptr textureSampler = device->InstantiateTextureSampler({}); - for (std::size_t i = 0; i < MaxPointLight; ++i) { @@ -787,7 +867,6 @@ int main() Nz::Vector3f position = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, elapsedTime * 45.f * rotationSpeed, 0.f)) * spotLight.position; Nz::Vector3f direction = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, elapsedTime * 90.f * rotationSpeed, 0.f)) * spotLight.direction; - Nz::AccessByOffset(lightDataPtr, colorOffset) = Nz::Vector3f(spotLight.color.r / 255.f, spotLight.color.g / 255.f, spotLight.color.b / 255.f); Nz::AccessByOffset(lightDataPtr, positionOffset) = position; Nz::AccessByOffset(lightDataPtr, directionOffset) = direction;