Falcor
Falcor copied to clipboard
Custom Intersection Shader.
I'm trying to use custom intersection shaders in Falcor 3.2.2. Initially, my goal is to call a function in my intersection shaders that perform triangle or procedural intersection based on a material ID value. I know a much better design would be creating hit groups for each case, but my initial objective is to circumvent the current inflexibility in Falcor's shader table.
For that purpose, I've changed the descriptor type in struct HitProgramDesc
, inside RtStateObjectHelper.h, from D3D12_HIT_GROUP_TYPE_TRIANGLES to D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE:
HitProgramDesc(ID3DBlobPtr pAhsBlob, const std::wstring& ahsExportName,
ID3DBlobPtr pChsBlob, const std::wstring& chsExportName,
ID3DBlobPtr pIntersectionBlob, const std::wstring& intersectionExportName,
const std::wstring& name):
anyHitShader(pAhsBlob, ahsExportName),
closestHitShader(pChsBlob, chsExportName),
intersectionShader(pIntersectionBlob, intersectionExportName),
exportName(name)
{
desc.IntersectionShaderImport = pIntersectionBlob ? intersectionShader.exportName.c_str() : nullptr;
desc.AnyHitShaderImport = pAhsBlob ? anyHitShader.exportName.c_str() : nullptr;
desc.ClosestHitShaderImport = pChsBlob ? closestHitShader.exportName.c_str() : nullptr;
desc.HitGroupExport = exportName.c_str();
// CHANGED THIS LINE
desc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE;
//
subobject.Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
subobject.pDesc = &desc;
}
That allowed me to create hit groups with intersection shaders and to compile them properly (syntax errors are correctly reported by Falcor). I'm doing this in a custom version of the GGXGloballlumination class, from the PathTracer sample:
namespace {
// Shader files
const char* kFileRayGen = "GGXGIRayGen.slang";
const char* kFileIntersection = "Intersection.slang";
const std::array<const char*, 3> kRayNames =
{
"GGXGIShadowRay",
"GGXGIIndirectRay",
"ReflectionRay"
};
// Entry-point names
const char* kEntryPointRayGen = "GGXGlobalIllumRayGen";
};
void GGXGlobalIllumination::initialize(RenderContext* pContext, const RenderData* pRenderData)
{
mpBlackHDR = Texture::create2D(128, 128, ResourceFormat::RGBA32Float, 1u, 1u, nullptr, Resource::BindFlags::ShaderResource | Resource::BindFlags::RenderTarget);
pContext->clearRtv(mpBlackHDR->getRTV().get(), vec4(0.0f, 0.0f, 0.0f, 1.0f));
mpState = RtState::create();
mpState->setMaxTraceRecursionDepth(mMaxPossibleRayDepth);
RtProgram::Desc desc;
desc.addShaderLibrary(kFileRayGen);
desc.setRayGen(kEntryPointRayGen);
for (int i = 0; i < kRayNames.size(); ++i)
{
std::string shaderFile = kRayNames[i];
shaderFile.append(".slang");
desc.addShaderLibrary(shaderFile);
std::string entryMiss = kRayNames[i];
entryMiss += "Miss";
desc.addMiss(i, entryMiss);
std::string entryClosestHit = kRayNames[i];
entryClosestHit += "ClosestHit";
std::string entryAnyHit = kRayNames[i];
entryAnyHit += "AnyHit";
std::string entryIntersection = kRayNames[i];
entryIntersection += "Intersection";
desc.addHitGroup(i, entryClosestHit, entryAnyHit, entryIntersection);
}
However, even though Falcor compiles my intersection shaders properly, it is not using them at runtime. It is behaving like it is using the built-in triangle intersection shader instead. I've tested this by passing intersection shaders without any computation at all and the result is the same.
Another question is if intersection shaders are supported in 4.0.