Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Nelarius committed May 26, 2024
1 parent ff29b58 commit f88e4f4
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 232 deletions.
2 changes: 1 addition & 1 deletion src/common/extent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ constexpr float aspectRatio(const Extent2<T>& extent) noexcept
template<typename T>
constexpr T area(const Extent2<T>& extent) noexcept
{
return static_cast<float>(extent.x) * static_cast<float>(extent.y);
return static_cast<T>(extent.x) * static_cast<float>(extent.y);
}

template<typename T>
Expand Down
125 changes: 23 additions & 102 deletions src/pt/deferred_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,11 +1342,6 @@ DeferredRenderer::LightingPass::LightingPass(
std::span<const VertexAttributes> sceneVertexAttributes,
std::span<const Texture> sceneBaseColorTextures)
: mCurrentSky{},
mVertexBuffer{
gpuContext.device,
"Sky vertex buffer",
{GpuBufferUsage::Vertex, GpuBufferUsage::CopyDst},
std::span<const float[2]>(quadVertexData)},
mSkyStateBuffer{
gpuContext.device,
"Sky state buffer",
Expand Down Expand Up @@ -1526,39 +1521,6 @@ DeferredRenderer::LightingPass::LightingPass(
{
// Pipeline layout

const WGPUBindGroupLayout bindGroupLayouts[] = {
skyStateBindGroupLayout.ptr(),
uniformBindGroupLayout.ptr(),
gbufferBindGroupLayout.ptr(),
bvhBindGroupLayout.ptr()};

const WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
.nextInChain = nullptr,
.label = "Lighting 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 =
Expand All @@ -1578,82 +1540,45 @@ DeferredRenderer::LightingPass::LightingPass(
}();
NLRS_ASSERT(shaderModule != nullptr);

// Fragment state
const WGPUBindGroupLayout bindGroupLayouts[] = {
skyStateBindGroupLayout.ptr(),
uniformBindGroupLayout.ptr(),
gbufferBindGroupLayout.ptr(),
bvhBindGroupLayout.ptr()};

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 WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
.nextInChain = nullptr,
.label = "Lighting pass pipeline layout",
.bindGroupLayoutCount = std::size(bindGroupLayouts),
.bindGroupLayouts = bindGroupLayouts,
};

const WGPUColorTargetState colorTargets[] = {WGPUColorTargetState{
.nextInChain = nullptr,
.format = Window::SWAP_CHAIN_FORMAT,
.blend = &blendState,
.writeMask = WGPUColorWriteMask_All}};
const WGPUPipelineLayout pipelineLayout =
wgpuDeviceCreatePipelineLayout(gpuContext.device, &pipelineLayoutDesc);

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

// Pipeline

const WGPURenderPipelineDescriptor pipelineDesc{
const WGPUComputePipelineDescriptor pipelineDesc{
.nextInChain = nullptr,
.label = "Lighting pass render pipeline",
.label = "Lighting pass compute 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,
.compute = computeStageDesc,
};

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

DeferredRenderer::LightingPass::~LightingPass()
{
renderPipelineSafeRelease(mPipeline);
computePipelineSafeRelease(mPipeline);
mPipeline = nullptr;
}

Expand All @@ -1662,7 +1587,6 @@ DeferredRenderer::LightingPass::LightingPass(LightingPass&& other) noexcept
if (this != &other)
{
mCurrentSky = other.mCurrentSky;
mVertexBuffer = std::move(other.mVertexBuffer);
mSkyStateBuffer = std::move(other.mSkyStateBuffer);
mSkyStateBindGroup = std::move(other.mSkyStateBindGroup);
mUniformBuffer = std::move(other.mUniformBuffer);
Expand All @@ -1686,7 +1610,6 @@ DeferredRenderer::LightingPass& DeferredRenderer::LightingPass::operator=(
if (this != &other)
{
mCurrentSky = other.mCurrentSky;
mVertexBuffer = std::move(other.mVertexBuffer);
mSkyStateBuffer = std::move(other.mSkyStateBuffer);
mSkyStateBindGroup = std::move(other.mSkyStateBindGroup);
mUniformBuffer = std::move(other.mUniformBuffer);
Expand All @@ -1698,7 +1621,7 @@ DeferredRenderer::LightingPass& DeferredRenderer::LightingPass::operator=(
mTextureBuffer = std::move(other.mTextureBuffer);
mBlueNoiseBuffer = std::move(other.mBlueNoiseBuffer);
mBvhBindGroup = std::move(other.mBvhBindGroup);
renderPipelineSafeRelease(mPipeline);
computePipelineSafeRelease(mPipeline);
mPipeline = other.mPipeline;
other.mPipeline = nullptr;
mFrameCount = other.mFrameCount;
Expand Down Expand Up @@ -1763,13 +1686,11 @@ void DeferredRenderer::LightingPass::render(
}();
NLRS_ASSERT(renderPass != nullptr);

wgpuRenderPassEncoderSetPipeline(renderPass, mPipeline);
wgpuRenderPassEncoderSetBindGroup(renderPass, 0, mSkyStateBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPass, 1, mUniformBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPass, 2, gbufferBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetBindGroup(renderPass, 3, mBvhBindGroup.ptr(), 0, nullptr);
wgpuRenderPassEncoderSetVertexBuffer(
renderPass, 0, mVertexBuffer.ptr(), 0, mVertexBuffer.byteSize());

wgpuRenderPassEncoderDraw(renderPass, 6, 1, 0, 0);

gui.render(renderPass);
Expand Down Expand Up @@ -1829,7 +1750,7 @@ DeferredRenderer::ResolvePass::ResolvePass(

const WGPUPipelineLayoutDescriptor pipelineLayoutDesc{
.nextInChain = nullptr,
.label = "Lighting pass pipeline layout",
.label = "Resolve pass pipeline layout",
.bindGroupLayoutCount = std::size(bindGroupLayouts),
.bindGroupLayouts = bindGroupLayouts,
};
Expand Down Expand Up @@ -1866,7 +1787,7 @@ DeferredRenderer::ResolvePass::ResolvePass(

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

return wgpuDeviceCreateShaderModule(gpuContext.device, &moduleDesc);
Expand Down
29 changes: 14 additions & 15 deletions src/pt/deferred_renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,21 +159,20 @@ class DeferredRenderer
struct LightingPass
{
private:
Sky mCurrentSky = Sky{};
GpuBuffer mVertexBuffer = GpuBuffer{};
GpuBuffer mSkyStateBuffer = GpuBuffer{};
GpuBindGroup mSkyStateBindGroup = GpuBindGroup{};
GpuBuffer mUniformBuffer = GpuBuffer{};
GpuBindGroup mUniformBindGroup = GpuBindGroup{};
GpuBuffer mBvhNodeBuffer = GpuBuffer{};
GpuBuffer mPositionAttributesBuffer = GpuBuffer{};
GpuBuffer mVertexAttributesBuffer = GpuBuffer{};
GpuBuffer mTextureDescriptorBuffer = GpuBuffer{};
GpuBuffer mTextureBuffer = GpuBuffer{};
GpuBuffer mBlueNoiseBuffer = GpuBuffer{};
GpuBindGroup mBvhBindGroup = GpuBindGroup{};
GpuBindGroup mAccumulationBindGroup = GpuBindGroup{};
WGPURenderPipeline mPipeline = nullptr;
Sky mCurrentSky = Sky{};
GpuBuffer mSkyStateBuffer = GpuBuffer{};
GpuBindGroup mSkyStateBindGroup = GpuBindGroup{};
GpuBuffer mUniformBuffer = GpuBuffer{};
GpuBindGroup mUniformBindGroup = GpuBindGroup{};
GpuBuffer mBvhNodeBuffer = GpuBuffer{};
GpuBuffer mPositionAttributesBuffer = GpuBuffer{};
GpuBuffer mVertexAttributesBuffer = GpuBuffer{};
GpuBuffer mTextureDescriptorBuffer = GpuBuffer{};
GpuBuffer mTextureBuffer = GpuBuffer{};
GpuBuffer mBlueNoiseBuffer = GpuBuffer{};
GpuBindGroup mBvhBindGroup = GpuBindGroup{};
GpuBindGroup mAccumulationBindGroup = GpuBindGroup{};
WGPUComputePipeline mPipeline = nullptr;

std::uint32_t mFrameCount = 0;

Expand Down
79 changes: 25 additions & 54 deletions src/pt/deferred_renderer_lighting_pass.wgsl
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
struct VertexInput {
@location(0) position: vec2f,
}

struct VertexOutput {
@builtin(position) position: vec4f,
@location(0) texCoord: vec2f,
}

@vertex
fn vsMain(in: VertexInput) -> VertexOutput {
let uv = 0.5 * in.position + vec2f(0.5);
var out: VertexOutput;
out.position = vec4f(in.position, 0.0, 1.0);
out.texCoord = vec2f(uv.x, 1.0 - uv.y);

return out;
}

struct SkyState {
params: array<f32, 27>,
skyRadiances: array<f32, 3>,
Expand All @@ -32,23 +13,6 @@ struct Uniforms {
frameCount: u32,
}

@group(0) @binding(0) var<storage, read> skyState: SkyState;

@group(1) @binding(0) var<uniform> uniforms: Uniforms;

@group(2) @binding(0) var gbufferAlbedo: texture_2d<f32>;
@group(2) @binding(1) var gbufferNormal: texture_2d<f32>;
@group(2) @binding(2) var gbufferDepth: texture_depth_2d;

@group(3) @binding(0) var<storage, read> bvhNodes: array<BvhNode>;
@group(3) @binding(1) var<storage, read> positionAttributes: array<Positions>;
@group(3) @binding(2) var<storage, read> vertexAttributes: array<VertexAttributes>;
@group(3) @binding(3) var<storage, read> textureDescriptors: array<TextureDescriptor>;
@group(3) @binding(4) var<storage, read> textures: array<u32>;
@group(3) @binding(5) var<storage, read> blueNoise: BlueNoise;

@group(4) @binding(0) var<storage, read_write> accumulationBuffer: array<array<f32, 3>>;

struct Aabb {
min: vec3f,
max: vec3f,
Expand Down Expand Up @@ -114,12 +78,30 @@ const SOLAR_INV_PDF = 2f * PI * (1f - SOLAR_COS_THETA_MAX);
const T_MIN = 0.001f;
const T_MAX = 10000f;

@fragment
fn fsMain(in: VertexOutput) -> @location(0) vec4f {
var color = vec3f(0.0, 0.0, 0.0);
@group(0) @binding(0) var<storage, read> skyState: SkyState;

@group(1) @binding(0) var<uniform> uniforms: Uniforms;

@group(2) @binding(0) var gbufferAlbedo: texture_2d<f32>;
@group(2) @binding(1) var gbufferNormal: texture_2d<f32>;
@group(2) @binding(2) var gbufferDepth: texture_depth_2d;

@group(3) @binding(0) var<storage, read> bvhNodes: array<BvhNode>;
@group(3) @binding(1) var<storage, read> positionAttributes: array<Positions>;
@group(3) @binding(2) var<storage, read> vertexAttributes: array<VertexAttributes>;
@group(3) @binding(3) var<storage, read> textureDescriptors: array<TextureDescriptor>;
@group(3) @binding(4) var<storage, read> textures: array<u32>;
@group(3) @binding(5) var<storage, read> blueNoise: BlueNoise;

@group(4) @binding(0) var<storage, read_write> sampleBuffer: array<array<f32, 3>>;


let uv = in.texCoord;
let textureIdx = vec2u(floor(uv * uniforms.framebufferSize));
@compute @workgroup_size(64, 64)
fn main(@builtin(global_invocation_id) globalInvocationId: vec3<u32>) {
let uv = vec2f(GlobalInvocationID.xy) / uniforms.framebufferSize;
let textureIdx = globalInvocationId.xy;

var color = vec3f(0.0, 0.0, 0.0);
let depthSample = textureLoad(gbufferDepth, textureIdx, 0);
if depthSample == 0.0 {
let world = worldFromUv(uv, depthSample);
Expand All @@ -142,9 +124,8 @@ fn fsMain(in: VertexOutput) -> @location(0) vec4f {
color = surfaceColor(coord, offsetPosition(position, decodedNormal), decodedNormal, albedo);
}

let rgb = acesFilmic(uniforms.exposure * color);
let srgb = pow(rgb, vec3(1f / 2.2f));
return vec4(srgb, 1f);
let sampleBufferIdx = textureIdx.y * u32(uniforms.framebufferSize.x) + textureIdx.x;
sampleBuffer[sampleBufferIdx] = color;
}

@must_use
Expand Down Expand Up @@ -253,16 +234,6 @@ fn skyRadiance(theta: f32, gamma: f32, channel: u32) -> f32 {
return r * radianceDist + solarRadiance;
}

@must_use
fn acesFilmic(x: vec3f) -> vec3f {
let a = 2.51f;
let b = 0.03f;
let c = 2.43f;
let d = 0.59f;
let e = 0.14f;
return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
}

@must_use
fn sampleSolarDiskDirection(u: vec2f, cosThetaMax: f32, direction: vec3f) -> vec3f {
let v = directionInCone(u, cosThetaMax);
Expand Down
Loading

0 comments on commit f88e4f4

Please sign in to comment.