diff --git a/README.md b/README.md index 65ca911..070953f 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/Source/Samples/Restir/GBuffer.cpp b/Source/Samples/Restir/GBuffer.cpp index d1472b5..65867d0 100644 --- a/Source/Samples/Restir/GBuffer.cpp +++ b/Source/Samples/Restir/GBuffer.cpp @@ -14,77 +14,105 @@ void GBuffer::init(ref pDevice, ref 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 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 diff --git a/Source/Samples/Restir/GBuffer.h b/Source/Samples/Restir/GBuffer.h index 4d1f515..1eb8b75 100644 --- a/Source/Samples/Restir/GBuffer.h +++ b/Source/Samples/Restir/GBuffer.h @@ -1,6 +1,7 @@ #pragma once #include "Singleton.h" +#include "Core/Pass/RasterPass.h" namespace Restir { @@ -30,7 +31,7 @@ class GBuffer private: void createTextures(); - void compilePrograms(); + void compileProgram(); Falcor::ref mpDevice; Falcor::ref mpScene; @@ -43,12 +44,13 @@ class GBuffer Falcor::ref mAlbedoTexture; Falcor::ref mSpecularTexture; + Falcor::ref mDepthTexture; Falcor::ref mCurrentNormalWsTexture; Falcor::ref mPreviousNormalWsTexture; - Falcor::ref mpRaytraceProgram; - Falcor::ref mpRtVars; + Falcor::ref mpRasterPass; + Falcor::ref mpFbo; uint32_t mSampleIndex = 0u; }; diff --git a/Source/Samples/Restir/GBuffer.slang b/Source/Samples/Restir/GBuffer.slang index c27a340..a2c5544 100644 --- a/Source/Samples/Restir/GBuffer.slang +++ b/Source/Samples/Restir/GBuffer.slang @@ -1,87 +1,52 @@ -import Scene.Raytracing; -import Utils.Sampling.TinyUniformSampleGenerator; +import Scene.Raster; import Rendering.Lights.LightHelpers; -RWTexture2D gPositionWs; -RWTexture2D gNormalWs; -RWTexture2D gAlbedo; -RWTexture2D 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); -} -