Skip to content

Commit

Permalink
wip render sky pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelarius committed Mar 29, 2024
1 parent dc8ec13 commit e8a41c1
Show file tree
Hide file tree
Showing 6 changed files with 482 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ set(WGSL_SHADER_FILES
reference_path_tracer.wgsl
texture_blit.wgsl
hybrid_renderer_gbuffer_pass.wgsl
hybrid_renderer_debug_pass.wgsl)
hybrid_renderer_debug_pass.wgsl
hybrid_renderer_sky_pass.wgsl)

set(SHADER_SOURCE_HEADER_FILE src/pt/shader_source.hpp)

Expand Down
217 changes: 214 additions & 3 deletions src/pt/hybrid_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ HybridRenderer::HybridRenderer(
mGbufferBindGroupLayout(),
mGbufferBindGroup(),
mGbufferPass(gpuContext, rendererDesc),
mDebugPass()
mDebugPass(),
mSkyPass(gpuContext)
{
{
const std::array<WGPUTextureFormat, 1> depthFormats{
Expand Down Expand Up @@ -170,7 +171,8 @@ HybridRenderer::~HybridRenderer()
void HybridRenderer::render(
const GpuContext& gpuContext,
const WGPUTextureView textureView,
const glm::mat4& viewProjectionMat)
const glm::mat4& viewProjectionMat,
const Sky& sky)
{
wgpuDeviceTick(gpuContext.device);

Expand All @@ -190,7 +192,7 @@ void HybridRenderer::render(
mAlbedoTextureView,
mNormalTextureView);

mDebugPass.render(mGbufferBindGroup, encoder, textureView);
mSkyPass.render(gpuContext, sky, encoder, textureView);

const WGPUCommandBuffer cmdBuffer = [encoder]() {
const WGPUCommandBufferDescriptor cmdBufferDesc{
Expand Down Expand Up @@ -1020,4 +1022,213 @@ void HybridRenderer::DebugPass::resize(const GpuContext& gpuContext, const Exten
wgpuQueueWriteBuffer(
gpuContext.queue, mUniformBuffer.ptr(), 0, &uniformData.x, sizeof(Extent2<float>));
}

HybridRenderer::SkyPass::SkyPass(const GpuContext& gpuContext)
: mCurrentSky{},
mVertexBuffer{
gpuContext.device,
"Sky vertex buffer",
GpuBufferUsage::Vertex | GpuBufferUsage::CopyDst,
std::span<const float[2]>(quadVertexData)},
mSkyStateBuffer{
gpuContext.device,
"Sky state buffer",
GpuBufferUsage::ReadOnlyStorage | GpuBufferUsage::CopyDst,
sizeof(AlignedSkyState)},
mSkyStateBindGroup{},
mPipeline(nullptr)
{
{
const AlignedSkyState skyState{mCurrentSky};
wgpuQueueWriteBuffer(
gpuContext.queue, mSkyStateBuffer.ptr(), 0, &skyState, sizeof(AlignedSkyState));
}

const GpuBindGroupLayout skyStateBindGroupLayout{
gpuContext.device,
"Sky state bind group layout",
mSkyStateBuffer.bindGroupLayoutEntry(0, WGPUShaderStage_Fragment, sizeof(AlignedSkyState))};

mSkyStateBindGroup = GpuBindGroup{
gpuContext.device,
"Sky state bind group",
skyStateBindGroupLayout.ptr(),
mSkyStateBuffer.bindGroupEntry(0)};

{
// Pipeline layout

const WGPUBindGroupLayout bindGroupLayouts[] = {skyStateBindGroupLayout.ptr()};

const WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
.nextInChain = nullptr,
.label = "Sky pass pipeline layout",
.bindGroupLayoutCount = std::size(bindGroupLayouts),
.bindGroupLayouts = bindGroupLayouts,
};

const WGPUPipelineLayout pipelineLayout =
wgpuDeviceCreatePipelineLayout(gpuContext.device, &pipelineLayoutDesc);

// Vertex layout

const WGPUVertexAttribute vertexAttributes[] = {WGPUVertexAttribute{
.format = WGPUVertexFormat_Float32x2,
.offset = 0,
.shaderLocation = 0,
}};

const WGPUVertexBufferLayout vertexBufferLayout{
.arrayStride = sizeof(float[2]),
.stepMode = WGPUVertexStepMode_Vertex,
.attributeCount = std::size(vertexAttributes),
.attributes = vertexAttributes,
};

// Shader module

const WGPUShaderModule shaderModule = [&gpuContext]() -> WGPUShaderModule {
const WGPUShaderModuleWGSLDescriptor wgslDesc = {
.chain =
WGPUChainedStruct{
.next = nullptr,
.sType = WGPUSType_ShaderModuleWGSLDescriptor,
},
.code = HYBRID_RENDERER_SKY_PASS_SOURCE,
};

const WGPUShaderModuleDescriptor moduleDesc{
.nextInChain = &wgslDesc.chain,
.label = "Sky pass shader",
};

return wgpuDeviceCreateShaderModule(gpuContext.device, &moduleDesc);
}();
NLRS_ASSERT(shaderModule != nullptr);

// Fragment state

const WGPUBlendState blendState{
.color =
WGPUBlendComponent{
.operation = WGPUBlendOperation_Add,
.srcFactor = WGPUBlendFactor_One,
.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha,
},
.alpha =
WGPUBlendComponent{
.operation = WGPUBlendOperation_Add,
.srcFactor = WGPUBlendFactor_Zero,
.dstFactor = WGPUBlendFactor_One,
},
};

const WGPUColorTargetState colorTargets[] = {WGPUColorTargetState{
.nextInChain = nullptr,
.format = Window::SWAP_CHAIN_FORMAT,
.blend = &blendState,
.writeMask = WGPUColorWriteMask_All}};

const WGPUFragmentState fragmentState{
.nextInChain = nullptr,
.module = shaderModule,
.entryPoint = "fsMain",
.constantCount = 0,
.constants = nullptr,
.targetCount = std::size(colorTargets),
.targets = colorTargets,
};

// Pipeline

const WGPURenderPipelineDescriptor pipelineDesc{
.nextInChain = nullptr,
.label = "Sky pass render pipeline",
.layout = pipelineLayout,
.vertex =
WGPUVertexState{
.nextInChain = nullptr,
.module = shaderModule,
.entryPoint = "vsMain",
.constantCount = 0,
.constants = nullptr,
.bufferCount = 1,
.buffers = &vertexBufferLayout,
},
.primitive =
WGPUPrimitiveState{
.nextInChain = nullptr,
.topology = WGPUPrimitiveTopology_TriangleList,
.stripIndexFormat = WGPUIndexFormat_Undefined,
.frontFace = WGPUFrontFace_CCW,
.cullMode = WGPUCullMode_Back,
},
.depthStencil = nullptr,
.multisample =
WGPUMultisampleState{
.nextInChain = nullptr,
.count = 1,
.mask = ~0u,
.alphaToCoverageEnabled = false,
},
.fragment = &fragmentState,
};

mPipeline = wgpuDeviceCreateRenderPipeline(gpuContext.device, &pipelineDesc);
wgpuPipelineLayoutRelease(pipelineLayout);
}
}

HybridRenderer::SkyPass::~SkyPass()
{
renderPipelineSafeRelease(mPipeline);
mPipeline = nullptr;
}

void HybridRenderer::SkyPass::render(
const GpuContext& gpuContext,
const Sky& sky,
const WGPUCommandEncoder cmdEncoder,
const WGPUTextureView textureView)
{
if (mCurrentSky != sky)
{
mCurrentSky = sky;
const AlignedSkyState skyState{sky};
wgpuQueueWriteBuffer(
gpuContext.queue, mSkyStateBuffer.ptr(), 0, &skyState, sizeof(AlignedSkyState));
}

const WGPURenderPassEncoder renderPass = [cmdEncoder, textureView]() -> WGPURenderPassEncoder {
const WGPURenderPassColorAttachment colorAttachment{
.nextInChain = nullptr,
.view = textureView,
.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED,
.resolveTarget = nullptr,
.loadOp = WGPULoadOp_Clear,
.storeOp = WGPUStoreOp_Store,
.clearValue = WGPUColor{0.0, 0.0, 0.0, 1.0},
};

const WGPURenderPassDescriptor renderPassDesc{
.nextInChain = nullptr,
.label = "Sky pass render pass",
.colorAttachmentCount = 1,
.colorAttachments = &colorAttachment,
.depthStencilAttachment = nullptr,
.occlusionQuerySet = nullptr,
.timestampWrites = nullptr,
};

return wgpuCommandEncoderBeginRenderPass(cmdEncoder, &renderPassDesc);
}();
NLRS_ASSERT(renderPass != nullptr);

wgpuRenderPassEncoderSetPipeline(renderPass, mPipeline);
wgpuRenderPassEncoderSetBindGroup(renderPass, 0, mSkyStateBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetVertexBuffer(
renderPass, 0, mVertexBuffer.ptr(), 0, mVertexBuffer.byteSize());
wgpuRenderPassEncoderDraw(renderPass, 6, 1, 0, 0);
wgpuRenderPassEncoderEnd(renderPass);
}
} // namespace nlrs
34 changes: 33 additions & 1 deletion src/pt/hybrid_renderer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "aligned_sky_state.hpp"
#include "gpu_bind_group.hpp"
#include "gpu_bind_group_layout.hpp"
#include "gpu_buffer.hpp"
Expand Down Expand Up @@ -43,7 +44,11 @@ class HybridRenderer
HybridRenderer(HybridRenderer&&) = delete;
HybridRenderer& operator=(HybridRenderer&&) = delete;

void render(const GpuContext&, WGPUTextureView, const glm::mat4& viewProjectionMatrix);
void render(
const GpuContext&,
WGPUTextureView,
const glm::mat4& viewProjectionMatrix,
const Sky&);
void resize(const GpuContext&, const Extent2u&);

private:
Expand Down Expand Up @@ -124,6 +129,32 @@ class HybridRenderer
void resize(const GpuContext&, const Extent2u&);
};

struct SkyPass
{
private:
Sky mCurrentSky;
GpuBuffer mVertexBuffer;
GpuBuffer mSkyStateBuffer;
GpuBindGroup mSkyStateBindGroup;
WGPURenderPipeline mPipeline;

public:
SkyPass(const GpuContext&);
~SkyPass();

SkyPass(const SkyPass&) = delete;
SkyPass& operator=(const SkyPass&) = delete;

SkyPass(SkyPass&&) = delete;
SkyPass& operator=(SkyPass&&) = delete;

void render(
const GpuContext& gpuContext,
const Sky& sky,
WGPUCommandEncoder cmdEncoder,
WGPUTextureView textureView);
};

WGPUTexture mDepthTexture;
WGPUTextureView mDepthTextureView;
WGPUTexture mAlbedoTexture;
Expand All @@ -134,5 +165,6 @@ class HybridRenderer
GpuBindGroup mGbufferBindGroup;
GbufferPass mGbufferPass;
DebugPass mDebugPass;
SkyPass mSkyPass;
};
} // namespace nlrs
Loading

0 comments on commit e8a41c1

Please sign in to comment.