Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e106cd0
Merge branch 'master' into ris_bxdfs
keptsecret Mar 20, 2026
dcac12e
refactor changes in method names in concepts
keptsecret Mar 23, 2026
ebb025b
Merge branch 'master' into ris_bxdfs
keptsecret Mar 24, 2026
4da04ee
fixes from changes to projected solid angle tri
keptsecret Mar 24, 2026
25e2b43
ray stores depth, nee gets depth from ray
keptsecret Mar 24, 2026
b2a0938
nee deferredPdf is deferredWeight
keptsecret Mar 24, 2026
770899c
refactor bxdfs have cache type
keptsecret Mar 24, 2026
8694bdd
fixes to bxdf unit tests
keptsecret Mar 25, 2026
4bdd81c
refactor eval returns value_and_weight type
keptsecret Mar 25, 2026
5d53317
refactor eval use value_and_weight type
keptsecret Mar 25, 2026
789a88c
refactor use quotient_weight type
keptsecret Mar 26, 2026
ee0c4ab
merge master
keptsecret Mar 27, 2026
89eb0fa
change remaining method names with pdf to weight
keptsecret Mar 27, 2026
88a01d2
avoid division by 0
keptsecret Mar 27, 2026
5d64bab
refactor regular bxdf don't take cache for eval
keptsecret Mar 27, 2026
9b5cbc3
fix change in owen sampler
keptsecret Mar 31, 2026
bd79b76
fixes some flickering by constraining scramblebuf coord
keptsecret Mar 31, 2026
b72cc0f
avoid creating pathtracer struct every loop for persistent wg mode
keptsecret Mar 31, 2026
f17d9ac
flip intersect normals when intersect from backface, adjust tolerance…
keptsecret Apr 3, 2026
21334ea
merge master, fix conflicts (except render.comp.hlsl needs modificati…
keptsecret Apr 17, 2026
2065829
move changes to render.comp.hlsl to new merge
keptsecret Apr 17, 2026
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
53 changes: 36 additions & 17 deletions 31_HLSLPathTracer/app_resources/hlsl/compute_render_scene_impl.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ RenderPushConstants getRenderPushConstants()
}

template<NEEPolygonMethod PPM>
void tracePixel(int32_t2 coords)
void tracePixel(NBL_REF_ARG(typename SVariantTypes<PPM>::pathtracer_type) pathtracer, int32_t2 coords)
{
const RenderPushConstants renderPushConstants = getRenderPushConstants();
using variant_types = SVariantTypes<PPM>;

uint32_t width, height, imageArraySize;
::outImage.GetDimensions(width, height, imageArraySize);
Expand All @@ -72,8 +71,6 @@ void tracePixel(int32_t2 coords)
return;
}

typename variant_types::pathtracer_type pathtracer;

uint2 scrambleDim;
::scramblebuf.GetDimensions(scrambleDim.x, scrambleDim.y);
const float32_t2 pixOffsetParam = float32_t2(1.0, 1.0) / float32_t2(scrambleDim);
Expand All @@ -86,24 +83,15 @@ void tracePixel(int32_t2 coords)
NDC.z = 1.0;
}

scene_type scene;
scene.updateLight(renderPushConstants.getLightMatrix());

using variant_types = SVariantTypes<PPM>;
typename variant_types::raygen_type rayGen;
rayGen.pixOffsetParam = pixOffsetParam;
rayGen.camPos = camPos;
rayGen.NDC = NDC;
rayGen.invMVP = renderPushConstants.invMVP;

pathtracer.scene = scene;
pathtracer.randGen.pSampleBuffer = renderPushConstants.pSampleSequence;
const uint32_t2 scrambleCoord = uint32_t2(coords.x & 511, coords.y & 511);
pathtracer.randGen.rng = Xoroshiro64Star::construct(scramblebuf[coords].rg);
pathtracer.randGen.sequenceSamplesLog2 = renderPushConstants.sequenceSampleCountLog2;
pathtracer.nee.lights = lights;
pathtracer.materialSystem.bxdfs = bxdfs;
pathtracer.bxdfPdfThreshold = 0.0001;
pathtracer.lumaContributionThreshold = hlsl::dot(colorspace::scRGBtoXYZ[1], colorspace::eotf::sRGB(hlsl::promote<spectral_t>(1.0 / 255.0)));
pathtracer.spectralTypeToLumaCoeffs = colorspace::scRGBtoXYZ[1];

#if PATH_TRACER_USE_RWMC
accumulator_type accumulator = accumulator_type::create(::pc.splattingParameters);
Expand Down Expand Up @@ -133,7 +121,23 @@ void runLinear(uint32_t3 threadID)
{
uint32_t width, height, imageArraySize;
::outImage.GetDimensions(width, height, imageArraySize);
tracePixel<PPM>(int32_t2(threadID.x % width, threadID.x / width));

const RenderPushConstants renderPushConstants = getRenderPushConstants();
scene_type scene;
scene.updateLight(renderPushConstants.getLightMatrix());

using variant_types = SVariantTypes<PPM>;
typename variant_types::pathtracer_type pathtracer;
pathtracer.scene = scene;
pathtracer.randGen.sequenceSamplesLog2 = renderPushConstants.sequenceSampleCountLog2;
pathtracer.randGen.pSampleBuffer = renderPushConstants.pSampleSequence;
pathtracer.nee.lights = lights;
pathtracer.materialSystem.bxdfs = bxdfs;
pathtracer.bxdfPdfThreshold = 0.0001;
pathtracer.lumaContributionThreshold = hlsl::dot(colorspace::scRGBtoXYZ[1], colorspace::eotf::sRGB(hlsl::promote<spectral_t>(1.0 / 255.0)));
pathtracer.spectralTypeToLumaCoeffs = colorspace::scRGBtoXYZ[1];

tracePixel<PPM>(pathtracer, int32_t2(threadID.x % width, threadID.x / width));
}
#endif

Expand All @@ -146,14 +150,29 @@ void runPersistent()
const uint32_t numWorkgroupsX = width / RenderWorkgroupSizeSqrt;
const uint32_t numWorkgroupsY = height / RenderWorkgroupSizeSqrt;

const RenderPushConstants renderPushConstants = getRenderPushConstants();
scene_type scene;
scene.updateLight(renderPushConstants.getLightMatrix());

using variant_types = SVariantTypes<PPM>;
typename variant_types::pathtracer_type pathtracer;
pathtracer.scene = scene;
pathtracer.randGen.sequenceSamplesLog2 = renderPushConstants.sequenceSampleCountLog2;
pathtracer.randGen.pSampleBuffer = renderPushConstants.pSampleSequence;
pathtracer.nee.lights = lights;
pathtracer.materialSystem.bxdfs = bxdfs;
pathtracer.bxdfPdfThreshold = 0.0001;
pathtracer.lumaContributionThreshold = hlsl::dot(colorspace::scRGBtoXYZ[1], colorspace::eotf::sRGB(hlsl::promote<spectral_t>(1.0 / 255.0)));
pathtracer.spectralTypeToLumaCoeffs = colorspace::scRGBtoXYZ[1];

[loop]
for (uint32_t wgBase = glsl::gl_WorkGroupID().x; wgBase < numWorkgroupsX * numWorkgroupsY; wgBase += glsl::gl_NumWorkGroups().x)
{
const int32_t2 wgCoords = int32_t2(wgBase % numWorkgroupsX, wgBase / numWorkgroupsX);
morton::code<true, 32, 2> mc;
mc.value = glsl::gl_LocalInvocationIndex().x;
const int32_t2 localCoords = _static_cast<int32_t2>(mc);
tracePixel<PPM>(wgCoords * int32_t2(RenderWorkgroupSizeSqrt, RenderWorkgroupSizeSqrt) + localCoords);
tracePixel<PPM>(pathtracer, wgCoords * int32_t2(RenderWorkgroupSizeSqrt, RenderWorkgroupSizeSqrt) + localCoords);
}
}
#endif
Expand Down
9 changes: 7 additions & 2 deletions 31_HLSLPathTracer/app_resources/hlsl/example_common.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct Ray

// mutable
scalar_type intersectionT;
uint16_t depth;

payload_type payload;
using spectral_type = typename payload_type::spectral_type;
Expand Down Expand Up @@ -133,6 +134,7 @@ struct Ray

void setT(scalar_type t) { intersectionT = t; }
scalar_type getT() NBL_CONST_MEMBER_FUNC { return intersectionT; }
void setDepth(uint16_t d) { depth = d; }

spectral_type getPayloadThroughput() NBL_CONST_MEMBER_FUNC { return payload.throughput; }
};
Expand All @@ -154,6 +156,7 @@ struct Ray<Payload, PPM_APPROX_PROJECTED_SOLID_ANGLE>

// mutable
scalar_type intersectionT;
uint16_t depth;

payload_type payload;
using spectral_type = typename payload_type::spectral_type;
Expand Down Expand Up @@ -202,6 +205,7 @@ struct Ray<Payload, PPM_APPROX_PROJECTED_SOLID_ANGLE>

void setT(scalar_type t) { intersectionT = t; }
scalar_type getT() NBL_CONST_MEMBER_FUNC { return intersectionT; }
void setDepth(uint16_t d) { depth = d; }

vector3_type getPayloadThroughput() NBL_CONST_MEMBER_FUNC { return payload.throughput; }
};
Expand Down Expand Up @@ -234,7 +238,7 @@ struct Light
template<typename T>
struct Tolerance
{
NBL_CONSTEXPR_STATIC_INLINE T INTERSECTION_ERROR_BOUND_LOG2 = -8.0;
NBL_CONSTEXPR_STATIC_INLINE T INTERSECTION_ERROR_BOUND_LOG2 = -12.0;

static T __common(uint16_t depth)
{
Expand Down Expand Up @@ -700,7 +704,8 @@ struct PTIsoConfiguration<LS,Interaction,Spectrum NBL_PARTIAL_REQ_BOT(CONF_ISO)
using anisotropic_interaction_type = PTAnisotropicInteraction<isotropic_interaction_type>;
using sample_type = LS;
using spectral_type = Spectrum;
using quotient_pdf_type = sampling::quotient_and_pdf<spectral_type, scalar_type>;
using quotient_weight_type = sampling::quotient_and_pdf<spectral_type, scalar_type>;
using value_weight_type = sampling::value_and_weight<spectral_type, scalar_type>;
};

template<class LS, class Interaction, class MicrofacetCache, class Spectrum NBL_STRUCT_CONSTRAINABLE>
Expand Down
37 changes: 21 additions & 16 deletions 31_HLSLPathTracer/app_resources/hlsl/material_system.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ struct MaterialSystem
using measure_type = typename DiffuseBxDF::spectral_type;
using sample_type = typename DiffuseBxDF::sample_type;
using ray_dir_info_type = typename sample_type::ray_dir_info_type;
using quotient_pdf_type = typename DiffuseBxDF::quotient_pdf_type;
using quotient_weight_type = typename DiffuseBxDF::quotient_weight_type;
using value_weight_type = typename DiffuseBxDF::value_weight_type;
using anisotropic_interaction_type = typename DiffuseBxDF::anisotropic_interaction_type;
using isotropic_interaction_type = typename anisotropic_interaction_type::isotropic_interaction_type;
using anisocache_type = typename ConductorBxDF::anisocache_type;
Expand Down Expand Up @@ -133,34 +134,36 @@ struct MaterialSystem
}
}

measure_type eval(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
value_weight_type evalAndWeight(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction)
{
cache_type _cache = getCacheFromSampleInteraction(matID, _sample, interaction);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the cache to test the functions without the special overload

MaterialType matType = (MaterialType)bxdfs[matID.id].materialType;
switch(matType)
{
case MaterialType::DIFFUSE:
{
return bxdfs[matID.id].albedo * _cache.diffuseBxDF.eval(_sample, interaction.isotropic);
value_weight_type ret = _cache.diffuseBxDF.evalAndWeight(_sample, interaction.isotropic);
ret._value *= bxdfs[matID.id].albedo;
return ret;
}
case MaterialType::CONDUCTOR:
{
return _cache.conductorBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.conductorBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::DIELECTRIC:
{
return _cache.dielectricBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.dielectricBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_CONDUCTOR:
{
return _cache.iridescentConductorBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentConductorBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_DIELECTRIC:
{
return _cache.iridescentDielectricBxDF.eval(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentDielectricBxDF.evalAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
default:
return hlsl::promote<measure_type>(0.0);
return value_weight_type::create(0.0, 0.0);
}
}

Expand All @@ -172,7 +175,8 @@ struct MaterialSystem
{
case MaterialType::DIFFUSE:
{
return _cache.diffuseBxDF.generate(interaction, u.xy);
typename diffuse_op_type::isocache_type dummycache;
return _cache.diffuseBxDF.generate(interaction, u.xy, dummycache);
}
case MaterialType::CONDUCTOR:
{
Expand Down Expand Up @@ -230,7 +234,7 @@ struct MaterialSystem
}
}

quotient_pdf_type quotient_and_pdf(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(cache_type) _cache)
quotient_weight_type quotientAndWeight(material_id_type matID, NBL_CONST_REF_ARG(sample_type) _sample, NBL_CONST_REF_ARG(anisotropic_interaction_type) interaction, NBL_REF_ARG(cache_type) _cache)
{
const float minimumProjVectorLen = 0.00000001; // TODO: still need this check?
if (interaction.getNdotV(bxdf::BxDFClampMode::BCM_ABS) > minimumProjVectorLen && _sample.getNdotL(bxdf::BxDFClampMode::BCM_ABS) > minimumProjVectorLen)
Expand All @@ -240,31 +244,32 @@ struct MaterialSystem
{
case MaterialType::DIFFUSE:
{
quotient_pdf_type ret = _cache.diffuseBxDF.quotient_and_pdf(_sample, interaction.isotropic);
typename diffuse_op_type::isocache_type dummycache;
quotient_weight_type ret = _cache.diffuseBxDF.quotientAndWeight(_sample, interaction.isotropic, dummycache);
Comment on lines +247 to +248
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave comment why

ret._quotient *= bxdfs[matID.id].albedo;
return ret;
}
case MaterialType::CONDUCTOR:
{
return _cache.conductorBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.conductorBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::DIELECTRIC:
{
return _cache.dielectricBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.dielectricBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_CONDUCTOR:
{
return _cache.iridescentConductorBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentConductorBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
case MaterialType::IRIDESCENT_DIELECTRIC:
{
return _cache.iridescentDielectricBxDF.quotient_and_pdf(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
return _cache.iridescentDielectricBxDF.quotientAndWeight(_sample, interaction.isotropic, _cache.aniso_cache.iso_cache);
}
default:
break;
}
}
return quotient_pdf_type::create(hlsl::promote<measure_type>(0.0), 0.0);
return quotient_weight_type::create(0.0, 0.0);
}

bool hasEmission(material_id_type matID)
Expand Down
Loading