Skip to content

Gbuffer rendered by rasterization #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Scenes specific tweaks are stored in the *SceneSettings* struct.

## Render passes
### GBuffer
GBuffer rendering is the first pass. It is generated by raytracing. Should normally be done by rasterization to save time but last time i tried it was crashing. See GBuffer.cpp.
GBuffer rendering is the first pass, it is generated by rasterization. This is faster than tracing primary rays. See GBuffer.cpp.

### RIS
Resampled Importance Sampling is performed as described in paper. See RISPass.cpp
Expand Down
96 changes: 62 additions & 34 deletions Source/Samples/Restir/GBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,77 +14,105 @@ void GBuffer::init(ref<Device> pDevice, ref<Scene> pScene, uint32_t width, uint3
mHeight = height;

createTextures();
compilePrograms();
compileProgram();
}

void GBuffer::createTextures()
{
mCurrentPositionWsTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mPreviousPositionWsTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mCurrentNormalWsTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mPreviousNormalWsTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mAlbedoTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mSpecularTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::RGBA32Float, 1, 1, nullptr, ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
mWidth,
mHeight,
ResourceFormat::RGBA32Float,
1,
1,
nullptr,
ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource | ResourceBindFlags::UnorderedAccess
);

mDepthTexture = mpDevice->createTexture2D(
mWidth, mHeight, ResourceFormat::D32Float, 1, 1, nullptr, ResourceBindFlags::DepthStencil
);
}

void GBuffer::compilePrograms()
void GBuffer::compileProgram()
{
auto shaderModules = mpScene->getShaderModules();
auto typeConformances = mpScene->getTypeConformances();

auto defines = mpScene->getSceneDefines();

ProgramDesc rtProgDesc;
rtProgDesc.addShaderModules(shaderModules);
rtProgDesc.addShaderLibrary("Samples/Restir/GBuffer.slang");
rtProgDesc.addTypeConformances(typeConformances);
rtProgDesc.setMaxTraceRecursionDepth(1);

rtProgDesc.setMaxPayloadSize(24);
ProgramDesc rasterProgDesc;
rasterProgDesc.addShaderModules(shaderModules);
rasterProgDesc.addShaderLibrary("Samples/Restir/GBuffer.slang").vsEntry("vsMain").psEntry("psMain");
rasterProgDesc.addTypeConformances(typeConformances);

ref<RtBindingTable> sbt = RtBindingTable::create(1, 1, mpScene->getGeometryCount());
sbt->setRayGen(rtProgDesc.addRayGen("rayGen"));
sbt->setMiss(0, rtProgDesc.addMiss("primaryMiss"));
auto primary = rtProgDesc.addHitGroup("primaryClosestHit", "primaryAnyHit");

sbt->setHitGroup(0, mpScene->getGeometryIDs(Scene::GeometryType::TriangleMesh), primary);

mpRaytraceProgram = Program::create(mpDevice, rtProgDesc, defines);
mpRtVars = RtProgramVars::create(mpDevice, mpRaytraceProgram, sbt);
mpRasterPass = RasterPass::create(mpDevice, rasterProgDesc, defines);
mpFbo = Fbo::create(mpDevice);
}

void GBuffer::render(RenderContext* pRenderContext)
{
FALCOR_PROFILE(pRenderContext, "GBuffer::render");

auto var = mpRtVars->getRootVar();

var["PerFrameCB"]["viewportDims"] = float2(mWidth, mHeight);
var["PerFrameCB"]["sampleIndex"] = mSampleIndex++;
mpFbo->attachColorTarget(mCurrentPositionWsTexture, 0u);
mpFbo->attachColorTarget(mCurrentNormalWsTexture, 1u);
mpFbo->attachColorTarget(mAlbedoTexture, 2u);
mpFbo->attachColorTarget(mSpecularTexture, 3u);
mpFbo->attachDepthStencilTarget(mDepthTexture);

var["gPositionWs"] = mCurrentPositionWsTexture;
var["gNormalWs"] = mCurrentNormalWsTexture;
var["gAlbedo"] = mAlbedoTexture;
var["gSpecular"] = mSpecularTexture;
pRenderContext->clearFbo(mpFbo.get(), float4(0), 1.f, 0, FboAttachmentType::All);

mpScene->raytrace(pRenderContext, mpRaytraceProgram.get(), mpRtVars, uint3(mWidth, mHeight, 1));
mpRasterPass->getState()->setFbo(mpFbo);
mpScene->rasterize(pRenderContext, mpRasterPass->getState().get(), mpRasterPass->getVars().get());
}

} // namespace Restir
Expand Down
8 changes: 5 additions & 3 deletions Source/Samples/Restir/GBuffer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "Singleton.h"
#include "Core/Pass/RasterPass.h"

namespace Restir
{
Expand Down Expand Up @@ -30,7 +31,7 @@ class GBuffer

private:
void createTextures();
void compilePrograms();
void compileProgram();

Falcor::ref<Falcor::Device> mpDevice;
Falcor::ref<Falcor::Scene> mpScene;
Expand All @@ -43,12 +44,13 @@ class GBuffer

Falcor::ref<Falcor::Texture> mAlbedoTexture;
Falcor::ref<Falcor::Texture> mSpecularTexture;
Falcor::ref<Falcor::Texture> mDepthTexture;

Falcor::ref<Falcor::Texture> mCurrentNormalWsTexture;
Falcor::ref<Falcor::Texture> mPreviousNormalWsTexture;

Falcor::ref<Falcor::Program> mpRaytraceProgram;
Falcor::ref<Falcor::RtProgramVars> mpRtVars;
Falcor::ref<Falcor::RasterPass> mpRasterPass;
Falcor::ref<Falcor::Fbo> mpFbo;

uint32_t mSampleIndex = 0u;
};
Expand Down
85 changes: 25 additions & 60 deletions Source/Samples/Restir/GBuffer.slang
Original file line number Diff line number Diff line change
@@ -1,87 +1,52 @@
import Scene.Raytracing;
import Utils.Sampling.TinyUniformSampleGenerator;
import Scene.Raster;
import Rendering.Lights.LightHelpers;

RWTexture2D<float4> gPositionWs;
RWTexture2D<float4> gNormalWs;
RWTexture2D<float4> gAlbedo;
RWTexture2D<float4> gSpecular;

cbuffer PerFrameCB
VSOut vsMain(VSIn vIn)
{
float2 viewportDims;
uint sampleIndex;
};
return defaultVS(vIn);
}

struct PrimaryRayData
struct GBufferPSOut
{
bool dummy;
float4 positionWs : SV_TARGET0;
float4 normalWs : SV_TARGET1;
float4 albedo : SV_TARGET2;
float4 specular : SV_TARGET3;
};

[shader("miss")]
void primaryMiss(inout PrimaryRayData hitData)
GBufferPSOut psMain(VSOut vsOut, uint triangleIndex : SV_PrimitiveID) : SV_TARGET
{
uint2 launchIndex = DispatchRaysIndex().xy;
gPositionWs[launchIndex].w = 0.0f;
}
GBufferPSOut psOut = {};

[shader("closesthit")]
void primaryClosestHit(inout PrimaryRayData hitData, BuiltInTriangleIntersectionAttributes attribs)
{
// Get the hit-point data.
float3 rayDirW = WorldRayDirection();
float hitT = RayTCurrent();
uint triangleIndex = PrimitiveIndex();
const float3 faceNormal = gScene.getFaceNormalW(vsOut.instanceID, triangleIndex);
const VertexData v = prepareVertexData(vsOut, faceNormal);
const let lod = ImplicitLodTextureSampler();

// Prepare the shading data.
const GeometryInstanceID instanceID = getGeometryInstanceID();
VertexData v = getVertexData(instanceID, triangleIndex, attribs);
uint materialID = gScene.getMaterialID(instanceID);
ShadingData sd = gScene.materials.prepareShadingData(v, materialID, -rayDirW);
const float3 viewDir = normalize(gScene.camera.getPosition() - v.posW);
const ShadingData sd = prepareShadingData(vsOut, triangleIndex, viewDir);

// Create material instance and query its properties.
let lod = ExplicitLodTextureSampler(0.f);
let mi = gScene.materials.getMaterialInstance(sd, lod);
let bsdfProperties = mi.getProperties(sd);

// The launch index.
const uint2 launchIndex = DispatchRaysIndex().xy;

// Write the ws position.
{
gPositionWs[launchIndex] = float4(sd.posW, 1.f);
psOut.positionWs = float4(sd.posW, 1.f);
}
// Write the ws normal.

// Write the ws normal and hit distance.
{
gNormalWs[launchIndex] = float4(sd.faceN, hitT);
psOut.normalWs = float4(sd.faceN, length(gScene.camera.getPosition() - sd.posW));
}

// Write the albedo.
// Write the albedo and material id.
{
gAlbedo[launchIndex] = float4(bsdfProperties.diffuseReflectionAlbedo, materialID);
psOut.albedo = float4(bsdfProperties.diffuseReflectionAlbedo, vsOut.materialID);
}

// Write the specular.
// Write the specular and roughness.
{
gSpecular[launchIndex] = float4(bsdfProperties.specularReflectionAlbedo, bsdfProperties.roughness);
psOut.specular = float4(bsdfProperties.specularReflectionAlbedo, bsdfProperties.roughness);
}
}

[shader("anyhit")]
void primaryAnyHit(inout PrimaryRayData rayData, BuiltInTriangleIntersectionAttributes attribs)
{
return psOut;
}

[shader("raygeneration")]
void rayGen()
{
uint3 launchIndex = DispatchRaysIndex();
if (any(launchIndex.xy > (uint2)viewportDims))
return;

const RayDesc ray = gScene.camera.computeRayPinhole(launchIndex.xy, viewportDims).toRayDesc();

PrimaryRayData hitData;
TraceRay(gScene.rtAccel, 0 /*rayFlags*/, 0xFF, 0 /* ray index*/, rayTypeCount, 0, ray, hitData);
}