Skip to content

Hlsl path tracer#224

Open
devshgraphicsprogramming wants to merge 196 commits intomasterfrom
hlsl_path_tracer
Open

Hlsl path tracer#224
devshgraphicsprogramming wants to merge 196 commits intomasterfrom
hlsl_path_tracer

Conversation

@devshgraphicsprogramming
Copy link
Member

@devshgraphicsprogramming devshgraphicsprogramming commented Nov 3, 2025

@keptsecret after you merge master again, you'll probably have the UI mess up and show changed from the merge commit, so close and reopen again

TODO

  • 4 unresolved conversations from RWMC #218, check if done

Comment on lines +390 to +392
if (hlsl::isinf(pdf))
{
retval.quotient_pdf = quotient_pdf_type::create(hlsl::promote<spectral_type>(0.0), 0.0);
Copy link
Member Author

Choose a reason for hiding this comment

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

@keptsecret you need a very good comment to justify this, because normally thats a point light

So write something about PDF being inf when SolidAngle is 0, so the quotient of finite area emission would be 0 due to division by int

also comment that the "PDF" getting returned is really a thing for a MIS weight

ray_dir_info_t V;
V.setDirection(-ray.direction);
interaction_type interaction = interaction_type::create(V, N);
interaction.luminosityContributionHint = hlsl::normalize(colorspace::scRGBtoXYZ[1] * ray.getPayloadThroughput());
Copy link
Member Author

Choose a reason for hiding this comment

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

this is a good default, just rmemeber that our Unidirectional PT will overwrite it anyway

Comment on lines +60 to +74
using spectral_t = vector<float, 3>;
using bxdfnode_type = BxDFNode<spectral_t>;

static const bxdfnode_type bxdfs[SceneBase::SCENE_BXDF_COUNT] = {
bxdfnode_type::create(MaterialType::DIFFUSE, false, float2(0,0), spectral_t(0.8,0.8,0.8)),
bxdfnode_type::create(MaterialType::DIFFUSE, false, float2(0,0), spectral_t(0.8,0.4,0.4)),
bxdfnode_type::create(MaterialType::DIFFUSE, false, float2(0,0), spectral_t(0.4,0.8,0.4)),
bxdfnode_type::create(MaterialType::CONDUCTOR, false, float2(0,0), spectral_t(1.02,1.02,1.3), spectral_t(1.0,1.0,2.0)),
bxdfnode_type::create(MaterialType::CONDUCTOR, false, float2(0,0), spectral_t(1.02,1.3,1.02), spectral_t(1.0,2.0,1.0)),
bxdfnode_type::create(MaterialType::CONDUCTOR, false, float2(0.15,0.15), spectral_t(1.02,1.3,1.02), spectral_t(1.0,2.0,1.0)),
bxdfnode_type::create(MaterialType::DIELECTRIC, false, float2(0.0625,0.0625), spectral_t(1,1,1), spectral_t(1.4,1.45,1.5)),
bxdfnode_type::create(MaterialType::IRIDESCENT_CONDUCTOR, false, 0.0, 505.0, spectral_t(1.39,1.39,1.39), spectral_t(1.2,1.2,1.2), spectral_t(0.5,0.5,0.5)),
bxdfnode_type::create(MaterialType::IRIDESCENT_DIELECTRIC, false, 0.0, 400.0, spectral_t(1.7,1.7,1.7), spectral_t(1.0,1.0,1.0), spectral_t(0,0,0)),
bxdfnode_type::create(MaterialType::EMISSIVE, LightEminence)
};
Copy link
Member Author

Choose a reason for hiding this comment

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

erm, shouldn't the table of bxdfs be in the material system and not the scene ?


NBL_CONSTEXPR_STATIC_INLINE uint32_t SCENE_SPHERE_COUNT = 10u;
NBL_CONSTEXPR_STATIC_INLINE uint32_t SCENE_LIGHT_COUNT = 1u;
NBL_CONSTEXPR_STATIC_INLINE uint32_t SCENE_BXDF_COUNT = 10u;
Copy link
Member Author

Choose a reason for hiding this comment

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

material system ?

Copy link
Member Author

Choose a reason for hiding this comment

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

the BXDF count that is

Comment on lines +192 to +200
ray_dir_info_type L;
L.makeInvalid();
return sample_type::create(L, hlsl::promote<vector3_type>(0.0));
}
}

ray_dir_info_type L;
L.makeInvalid();
return sample_type::create(L, hlsl::promote<vector3_type>(0.0));
Copy link
Member Author

Choose a reason for hiding this comment

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

put a break in the switch, or remove the unreachable code after the switch

Comment on lines +187 to +189
return iridescentDielectricBxDF.generate(interaction, u, _cache);
}
break;
Copy link
Member Author

Choose a reason for hiding this comment

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

if you return from a case label, you don't need to break, Clang actually warns you about that in C++

Comment on lines +259 to +263
DiffuseBxDF diffuseBxDF;
ConductorBxDF conductorBxDF;
DielectricBxDF dielectricBxDF;
IridescentConductorBxDF iridescentConductorBxDF;
IridescentDielectricBxDF iridescentDielectricBxDF;
Copy link
Member Author

Choose a reason for hiding this comment

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

compiler and perf will hate you because these are live variables.

I think I have a solution for this

Copy link
Member Author

@devshgraphicsprogramming devshgraphicsprogramming Feb 25, 2026

Choose a reason for hiding this comment

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

see Devsh-Graphics-Programming/Nabla#991 (comment)

Basically make the "cache" more generic, and instead of it just being an aniso cache, also slap the BxDF in there so it doesn't need to be live state here.

Obviously this means some very light weight serialization to emulate a union

I wish we could have KHR_shader_untyped_pointers that work on any storage class, then unions would be easy
KhronosGroup/Vulkan-Docs#2684

}
else
{
retval.quotient_pdf = quotient_pdf_type::create(1.0, 0.0);
Copy link
Member Author

Choose a reason for hiding this comment

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

why when the sample is invalid or below the hemisphere are you returning 1 for the quotient?

}

light_type lights[scene_type::SCENE_LIGHT_COUNT];
uint32_t lightCount;
Copy link
Member Author

Choose a reason for hiding this comment

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

make it a constant, not a variable, will speed us up a lot

Copy link
Member Author

Choose a reason for hiding this comment

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

basically remove it and use scene_type::SCENE_LIGHT_COUNT in its place

Comment on lines +390 to +397
if (hlsl::isinf(pdf))
{
retval.quotient_pdf = quotient_pdf_type::create(hlsl::promote<spectral_type>(0.0), 0.0);
return retval;
}

if (retval.sample_.getNdotL() > numeric_limits<scalar_type>::min && retval.sample_.isValid())
{
Copy link
Member Author

Choose a reason for hiding this comment

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

also you could join the failure cases if you write enough comments

if (pdf < Inf && NdotL > min && retval.sample_.isValid())

normally you'd have to do conditionalMaxOrAbs(NdotL,0.0f,isBSDF) > min because BSDFs should receive light from the backside, and its only in this scene that they can't because the scene has watertight geometry everywhere

Copy link
Member Author

Choose a reason for hiding this comment

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

P.S. do you even need to check if the sample is valid, I thought invalid samples produce NaN or 0

so I guess first check if the pdf is non-zero and finite (with comment about finiteness being due to area lights) and the NdotL (with a comment)

then create the sample and do the rest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants