I’m trying to integrate VXGI into my game engine. I followed the documentation, but nothing is shown at the output. Here is the code:
void TestApplication::NvidiaVXGIInit()
{
VXGI::Status::Enum status;
rendererInterface = new NVRHI::RendererInterfaceD3D11(&giErrorCallback, m_DX11DeviceContext);
VXGI::GIParameters giParams = {};
giParams.errorCallback = &giErrorCallback;
giParams.rendererInterface = rendererInterface;
VXGI::VFX_VXGI_CreateGIObject(giParams, &giObject);
VXGI::ShaderCompilerParameters scParams = {};
scParams.errorCallback = &giErrorCallback;
scParams.d3dCompilerDLLName = "D3DCompiler_47.dll";
VXGI::VFX_VXGI_CreateShaderCompiler(scParams, &shaderCompiler);
ID3DBlob* vsD3dBlob = m_PointLightVertexShader->GetBlob();
VXGI::IBlob* gsBlob;
status = shaderCompiler->compileVoxelizationGeometryShaderFromVS(&gsBlob, vsD3dBlob->GetBufferPointer(), vsD3dBlob->GetBufferSize());
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
VXGI::IBlob* psBlob;
//status = shaderCompiler->compileVoxelizationDefaultPixelShader(&psBlob);
//if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
std::ifstream t("src/VoxelizationPixelShader.hlsl");
std::stringstream psSource;
psSource << t.rdbuf();
VXGI::ShaderResources userShaderCodeResources = {};
userShaderCodeResources.constantBufferCount = 1;
userShaderCodeResources.constantBufferSlots[0] = 0;
userShaderCodeResources.textureCount = 5;
userShaderCodeResources.textureSlots[0] = 0;
userShaderCodeResources.textureSlots[1] = 1;
userShaderCodeResources.textureSlots[2] = 2;
userShaderCodeResources.textureSlots[3] = 3;
userShaderCodeResources.textureSlots[4] = 4;
userShaderCodeResources.samplerCount = 2;
userShaderCodeResources.samplerSlots[0] = 0;
userShaderCodeResources.samplerSlots[1] = 1;
status = shaderCompiler->compileVoxelizationPixelShader(&psBlob, psSource.str().c_str(), psSource.str().size(), "PSMain", userShaderCodeResources);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
status = giObject->loadUserDefinedShaderSet(&gsShaderSet, gsBlob->getData(), gsBlob->getSize());
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
status = giObject->loadUserDefinedShaderSet(&psShaderSet, psBlob->getData(), psBlob->getSize());
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
VXGI::VoxelizationParameters vParams = {};
vParams.mapSize = VXGI::uint3(g_nMapSize);
vParams.enableMultiBounce = g_bEnableMultiBounce;
vParams.persistentVoxelData = !g_bEnableMultiBounce;
vParams.useEmittanceInterpolation = g_bEnableMultiBounce;
status = giObject->validateVoxelizationParameters(vParams);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
status = giObject->setVoxelizationParameters(vParams);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
status = giObject->createBasicTracer(&basicViewTracer, shaderCompiler);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
}
void TestApplication::NvidiaVXGIVoxelization()
{
VXGI::Status::Enum status;
VXGI::UpdateVoxelizationParameters uvParams = {};
glm::vec3 camPos = cameras[SelectedCamera].GetPosition();
glm::vec3 frontVec = cameras[SelectedCamera].GetFrontVector();
glm::vec3 caVec = camPos + frontVec * g_fVoxelSize * float(g_nMapSize) * 0.25f;
uvParams.clipmapAnchor = VXGI::float3(caVec.x, caVec.y, caVec.z);
uvParams.indirectIrradianceMapTracingParameters.irradianceScale = g_fMultiBounceScale;
uvParams.indirectIrradianceMapTracingParameters.useAutoNormalization = true;
uvParams.indirectIrradianceMapTracingParameters.lightLeakingAmount = VXGI::LightLeakingAmount::MODERATE;
uvParams.finestVoxelSize = g_fVoxelSize;
bool performOpacityVoxelization = false;
bool performEmittanceVoxelization = false;
status = giObject->prepareForVoxelization(uvParams, performOpacityVoxelization, performEmittanceVoxelization);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
//giObject->voxelizeTestScene({0.f, 0.f, 0.f}, 5.f, shaderCompiler);
if (performOpacityVoxelization)
{
std::cout << "Voxelizing...\n";
VXGI::VoxelizationViewParameters vvParams;
giObject->getVoxelizationViewParameters(vvParams);
memcpy(&voxelizationViewMatrix, &vvParams.viewMatrix, sizeof(vvParams.viewMatrix));
memcpy(&voxelizationProjMatrix, &vvParams.projectionMatrix, sizeof(vvParams.projectionMatrix));
VXGI::MaterialInfo matInfo = {};
matInfo.geometryShader = gsShaderSet;
matInfo.pixelShader = psShaderSet;
status = giObject->getVoxelizationState(matInfo, true, *drawCallState);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
RenderSceneForVoxelization(drawCallState);
rendererInterface->clearState();
}
status = giObject->finalizeVoxelization();
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
}
void TestApplication::NvidiaVXGIConeTracing()
{
VXGI::Status::Enum status;
basicViewTracer->beginFrame();
VXGI::BasicDiffuseTracingParameters bdtParams = {};
VXGI::IBasicViewTracer::InputBuffers inputBuffers = {};
bdtParams.enableTemporalReprojection = g_bTemporalFiltering;
bdtParams.enableTemporalJitter = g_bTemporalFiltering;
bdtParams.quality = g_fQuality;
bdtParams.directionalSamplingRate = g_fSamplingRate;
bdtParams.irradianceScale = g_fDiffuseScale;
auto depthSRV = gBuffer->GetShaderResourceView(2);
auto normalSRV = gBuffer->GetShaderResourceView(1);
ID3D11Resource* depthRes;
depthSRV->GetResource(&depthRes);
ID3D11Resource* normalRes;
normalSRV->GetResource(&normalRes);
inputBuffers.gbufferDepth = rendererInterface->getHandleForTexture(depthRes);
inputBuffers.gbufferNormal = rendererInterface->getHandleForTexture(normalRes);
inputBuffers.gbufferViewport = NVRHI::Viewport((float)texWidth, (float)texHeight);
inputBuffers.preViewTranslation = VXGI::float3(0.f);
glm::mat4 gBufferProjMat = glm::perspectiveFovLH(XM_PIDIV4, (FLOAT)texWidth, (FLOAT)texHeight, 0.01f, 100.f);
glm::mat4 gBufferViewMat = cameras[SelectedCamera].GetViewMatrix();
memcpy(&inputBuffers.viewMatrix, &gBufferViewMat, sizeof(gBufferViewMat));
memcpy(&inputBuffers.projMatrix, &gBufferProjMat, sizeof(gBufferProjMat));
NVRHI::TextureHandle indirectDiffuse = nullptr;
NVRHI::TextureHandle indirectConfidence = nullptr;
status = basicViewTracer->computeDiffuseChannelBasic(bdtParams, inputBuffers, nullptr, indirectDiffuse, indirectConfidence);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
if (indirectDiffuse && indirectConfidence)
{
std::cout << "Cone tracing...\n";
indirectSRV = rendererInterface->getSRVForTexture(indirectDiffuse);
confidenceSRV = rendererInterface->getSRVForTexture(indirectConfidence);
}
}
void TestApplication::RenderSceneForVoxelization(NVRHI::DrawCallState* state)
{
VXGI::Status::Enum status;
const UINT SRV_SLOT_DIFFUSE_TEXTURE = 0;
const UINT SRV_SLOT_SHADOW_MAP = 4;
LightCB lightCb;
lightCb.lightPos = glm::vec4(cameras[1].GetPosition().x, cameras[1].GetPosition().y, cameras[1].GetPosition().z, 1.f);
lightCb.conLinQuad[0] = lightProps.constant;
lightCb.conLinQuad[1] = lightProps.linear;
lightCb.conLinQuad[2] = lightProps.quadratic;
lightCb.lightColor = { lightProps.color[0], lightProps.color[1], lightProps.color[2] };
lightCb.lightViewMat = glm::transpose(cameras[1].GetViewMatrix());
lightCb.lightProjMat = glm::transpose(lightProjMat);
lightCb.bias = m_ShadowMapBias;
lightCb.lightVP = glm::transpose(lightProjMat * cameras[1].GetViewMatrix());
lightCb.cubeView[0] = glm::transpose(m_PointLightDepthCaptureViews[0]);
lightCb.cubeView[1] = glm::transpose(m_PointLightDepthCaptureViews[1]);
lightCb.cubeView[2] = glm::transpose(m_PointLightDepthCaptureViews[2]);
lightCb.cubeView[3] = glm::transpose(m_PointLightDepthCaptureViews[3]);
lightCb.cubeView[4] = glm::transpose(m_PointLightDepthCaptureViews[4]);
lightCb.cubeView[5] = glm::transpose(m_PointLightDepthCaptureViews[5]);
lightCb.cubeProj = glm::transpose(lightProjMat);
lightCb.camPos = cameras[SelectedCamera].GetPosition();
rendererInterface->writeConstantBuffer(m_pGlobalCBuffer, &lightCb, sizeof(lightCb));
auto translate = props[1].translation;
auto rotate = props[1].rotation;
auto scale = props[1].scale;
ConstantBuffer cb;
auto modelMat = glm::mat4(1.f);
modelMat = glm::translate(modelMat, glm::vec3(translate[0], translate[1], translate[2]));
modelMat = glm::rotate(modelMat, glm::radians(rotate[0]), glm::vec3(1.f, 0.f, 0.f));
modelMat = glm::rotate(modelMat, glm::radians(rotate[1]), glm::vec3(0.f, 1.f, 0.f));
modelMat = glm::rotate(modelMat, glm::radians(rotate[2]), glm::vec3(0.f, 0.f, 1.f));
modelMat = glm::scale(modelMat, glm::vec3(scale[0], scale[1], scale[2]));
cb.modelMat = glm::transpose(modelMat);
cb.viewMat = glm::transpose(voxelizationViewMatrix);
cb.projMat = glm::transpose(voxelizationProjMatrix);
cb.normalMat = glm::inverse(modelMat);
cb.viewProjMatInv = glm::transpose(glm::inverse(voxelizationProjMatrix * voxelizationViewMatrix));
rendererInterface->writeConstantBuffer(m_pGlobalCBufferMatrixes, &cb, sizeof(cb));
NVRHI::BindConstantBuffer(state->VS, 0, m_pGlobalCBufferMatrixes);
NVRHI::BindConstantBuffer(state->VS, 1, m_pGlobalCBuffer);
state->inputLayout = m_pInputLayout;
state->primType = NVRHI::PrimitiveType::TRIANGLE_LIST;
state->indexBufferFormat = NVRHI::Format::R32_UINT;
state->indexBuffer = m_IndexBuffer;
state->vertexBufferCount = 1;
state->vertexBuffers[0].buffer = m_VertexBuffer;
state->vertexBuffers[0].slot = 0;
state->vertexBuffers[0].stride = sizeof(Vertex);
state->VS.shader = m_pDefaultVS;
rendererInterface->beginRenderingPass();
status = giObject->beginVoxelizationDrawCallGroup();
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
UINT numMeshes = models[1]->GetNumMeshes();
std::vector<NVRHI::DrawArguments> drawCalls;
ID3D11Resource* shadowmapRes;
m_PointLightDepthSRV->GetResource(&shadowmapRes);
m_ShadowMap = rendererInterface->getHandleForTexture(shadowmapRes);
for (UINT i = 0; i < numMeshes; ++i)
{
VXGI::MaterialInfo materialInfo{};
materialInfo.geometryShader = gsShaderSet;
materialInfo.pixelShader = psShaderSet;
status = giObject->getVoxelizationState(materialInfo, true, *voxelizationState);
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
state->GS = voxelizationState->GS;
state->PS = voxelizationState->PS;
state->renderState = voxelizationState->renderState;
state->renderState.rasterState.frontCounterClockwise = true;
Mesh& mesh = models[1]->GetMeshes()[i];
ID3D11Resource* diffuseRes;
auto diffuseSRV = ((DX11Texture2D*)mesh.GetAlbedoTexture().get())->GetSRV();
diffuseSRV->GetResource(&diffuseRes);
m_DiffuseTexture = rendererInterface->getHandleForTexture(diffuseRes);
NVRHI::BindTexture(state->PS, SRV_SLOT_SHADOW_MAP, m_ShadowMap, false, NVRHI::Format::R32_FLOAT);
NVRHI::BindSampler(state->PS, 0, m_pDefaultSamplerState);
NVRHI::BindSampler(state->PS, 1, m_pComparisonSamplerState);
NVRHI::BindConstantBuffer(state->PS, 0, m_pGlobalCBuffer);
NVRHI::BindTexture(state->PS, SRV_SLOT_DIFFUSE_TEXTURE, m_DiffuseTexture, false);
NVRHI::DrawArguments args;
args.vertexCount = mesh.GetNumVertices();
args.startIndexLocation = models[1]->GetIndexOffset(i);
args.startVertexLocation = models[1]->GetVertexOffset(i);
drawCalls.push_back(args);
}
if (!drawCalls.empty())
{
rendererInterface->drawIndexed(*state, &drawCalls[0], uint32_t(drawCalls.size()));
}
status = giObject->endVoxelizationDrawCallGroup();
if (status != 0) std::cout << "Something went wrong. Status: " << status << '\n';
rendererInterface->endRenderingPass();
}