Skip to content

Commit e7d4670

Browse files
committed
fixed light sampling nee
1 parent 4d3e046 commit e7d4670

File tree

4 files changed

+86
-55
lines changed

4 files changed

+86
-55
lines changed

31_HLSLPathTracer/app_resources/glsl/common.glsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//#define VISUALIZE_HIGH_VARIANCE
88

99
// debug
10-
//#define NEE_ONLY
10+
#define NEE_ONLY 1
1111

1212
layout(set = 2, binding = 0) uniform sampler2D envMap;
1313
layout(set = 2, binding = 1) uniform usamplerBuffer sampleSequence;

31_HLSLPathTracer/app_resources/hlsl/material_system.hlsl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct Material
2323
DIELECTRIC
2424
};
2525

26-
NBL_CONSTEXPR_STATIC_INLINE uint32_t DataSize = 32;
26+
NBL_CONSTEXPR_STATIC_INLINE uint32_t DataSize = 1;
2727

2828
uint32_t type : 2;
2929
uint32_t unused : 30; // possible space for flags
@@ -66,7 +66,7 @@ struct System
6666
case Material::Type::DIFFUSE:
6767
{
6868
diffuseBxDF.init(cparams);
69-
return cparams.albedo * (measure_type)diffuseBxDF.eval(params);
69+
return (measure_type)diffuseBxDF.eval(params);
7070
}
7171
break;
7272
case Material::Type::CONDUCTOR:
@@ -123,8 +123,13 @@ struct System
123123

124124
quotient_pdf_type quotient_and_pdf(NBL_CONST_REF_ARG(Material) material, NBL_CONST_REF_ARG(create_params_t) cparams, NBL_CONST_REF_ARG(params_t) params)
125125
{
126+
127+
const bool transmissive = material.type == Material::Type::DIELECTRIC;
128+
const float clampedNdotV = math::conditionalAbsOrMax<float>(transmissive, params.uNdotV, 0.0);
129+
const float clampedNdotL = math::conditionalAbsOrMax<float>(transmissive, params.uNdotL, 0.0);
130+
126131
const float minimumProjVectorLen = 0.00000001;
127-
if (params.NdotV > minimumProjVectorLen && params.NdotL > minimumProjVectorLen)
132+
if (clampedNdotV > minimumProjVectorLen && clampedNdotL > minimumProjVectorLen)
128133
{
129134
switch(material.type)
130135
{
@@ -147,10 +152,10 @@ struct System
147152
}
148153
break;
149154
default:
150-
return quotient_pdf_type::create((measure_type)0.0, numeric_limits<float>::infinity);
155+
return quotient_pdf_type::create((measure_type)0.0, 0.0);
151156
}
152157
}
153-
return quotient_pdf_type::create((measure_type)0.0, numeric_limits<float>::infinity);
158+
return quotient_pdf_type::create((measure_type)0.0, 0.0);
154159
}
155160

156161
DiffuseBxDF diffuseBxDF;

31_HLSLPathTracer/app_resources/hlsl/next_event_estimator.hlsl

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,18 @@ struct Estimator
6363
break;
6464
case PST_RECTANGLE:
6565
{
66-
vector3_type offset = vector3_type(asfloat(event.data[2]), asfloat(event.data[3]), asfloat(event.data[4]));
67-
vector3_type edge0 = vector3_type(asfloat(event.data[5]), asfloat(event.data[6]), asfloat(event.data[7]));
68-
vector3_type edge1 = vector3_type(asfloat(event.data[8]), asfloat(event.data[9]), asfloat(event.data[10]));
66+
const vector3_type offset = vector3_type(
67+
bit_cast<float32_t>(event.data[2]),
68+
bit_cast<float32_t>(event.data[3]),
69+
bit_cast<float32_t>(event.data[4]));
70+
const vector3_type edge0 = vector3_type(
71+
bit_cast<float32_t>(event.data[5]),
72+
bit_cast<float32_t>(event.data[6]),
73+
bit_cast<float32_t>(event.data[7]));
74+
const vector3_type edge1 = vector3_type(
75+
bit_cast<float32_t>(event.data[8]),
76+
bit_cast<float32_t>(event.data[9]),
77+
bit_cast<float32_t>(event.data[10]));
6978
Shape<PST_RECTANGLE> rect = Shape<PST_RECTANGLE>::create(offset, edge0, edge1, event.data[11]);
7079
pdf *= rect.template deferredPdf<ray_type>(ray);
7180
}
@@ -115,8 +124,12 @@ struct Estimator
115124
{
116125
case PST_SPHERE:
117126
{
118-
vector3_type position = vector3_type(asfloat(event.data[2]), asfloat(event.data[3]), asfloat(event.data[4]));
119-
Shape<PST_SPHERE> sphere = Shape<PST_SPHERE>::create(position, asfloat(event.data[5]), event.data[6]);
127+
const vector3_type position = vector3_type(
128+
bit_cast<float32_t>(event.data[2]),
129+
bit_cast<float32_t>(event.data[3]),
130+
bit_cast<float32_t>(event.data[4]));
131+
Shape<PST_SPHERE> sphere = Shape<PST_SPHERE>::create(position, bit_cast<float32_t>(event.data[5]), event.data[6]);
132+
120133
const vector3_type sampleL = sphere.template generate_and_pdf<interaction_type>(pdf, newRayMaxT, origin, interaction, isBSDF, xi);
121134
const vector3_type V = interaction.isotropic.V.getDirection();
122135
const scalar_type VdotL = nbl::hlsl::dot<vector3_type>(V, sampleL);
@@ -127,10 +140,20 @@ struct Estimator
127140
break;
128141
case PST_TRIANGLE:
129142
{
130-
vector3_type vertex0 = vector3_type(asfloat(event.data[2]), asfloat(event.data[3]), asfloat(event.data[4]));
131-
vector3_type vertex1 = vector3_type(asfloat(event.data[5]), asfloat(event.data[6]), asfloat(event.data[7]));
132-
vector3_type vertex2 = vector3_type(asfloat(event.data[8]), asfloat(event.data[9]), asfloat(event.data[10]));
143+
const vector3_type vertex0 = vector3_type(
144+
bit_cast<float32_t>(event.data[2]),
145+
bit_cast<float32_t>(event.data[3]),
146+
bit_cast<float32_t>(event.data[4]));
147+
const vector3_type vertex1 = vector3_type(
148+
bit_cast<float32_t>(event.data[5]),
149+
bit_cast<float32_t>(event.data[6]),
150+
bit_cast<float32_t>(event.data[7]));
151+
const vector3_type vertex2 = vector3_type(
152+
bit_cast<float32_t>(event.data[8]),
153+
bit_cast<float32_t>(event.data[9]),
154+
bit_cast<float32_t>(event.data[10]));
133155
Shape<PST_TRIANGLE> tri = Shape<PST_TRIANGLE>::create(vertex0, vertex1, vertex2, event.data[11]);
156+
134157
const vector3_type sampleL = tri.template generate_and_pdf<interaction_type>(pdf, newRayMaxT, origin, interaction, isBSDF, xi);
135158
const vector3_type V = interaction.isotropic.V.getDirection();
136159
const scalar_type VdotL = nbl::hlsl::dot<vector3_type>(V, sampleL);
@@ -141,10 +164,20 @@ struct Estimator
141164
break;
142165
case PST_RECTANGLE:
143166
{
144-
vector3_type offset = vector3_type(asfloat(event.data[2]), asfloat(event.data[3]), asfloat(event.data[4]));
145-
vector3_type edge0 = vector3_type(asfloat(event.data[5]), asfloat(event.data[6]), asfloat(event.data[7]));
146-
vector3_type edge1 = vector3_type(asfloat(event.data[8]), asfloat(event.data[9]), asfloat(event.data[10]));
167+
const vector3_type offset = vector3_type(
168+
bit_cast<float32_t>(event.data[2]),
169+
bit_cast<float32_t>(event.data[3]),
170+
bit_cast<float32_t>(event.data[4]));
171+
const vector3_type edge0 = vector3_type(
172+
bit_cast<float32_t>(event.data[5]),
173+
bit_cast<float32_t>(event.data[6]),
174+
bit_cast<float32_t>(event.data[7]));
175+
const vector3_type edge1 = vector3_type(
176+
bit_cast<float32_t>(event.data[8]),
177+
bit_cast<float32_t>(event.data[9]),
178+
bit_cast<float32_t>(event.data[10]));
147179
Shape<PST_RECTANGLE> rect = Shape<PST_RECTANGLE>::create(offset, edge0, edge1, event.data[11]);
180+
148181
const vector3_type sampleL = rect.template generate_and_pdf<interaction_type>(pdf, newRayMaxT, origin, interaction, isBSDF, xi);
149182
const vector3_type V = interaction.isotropic.V.getDirection();
150183
const scalar_type VdotL = nbl::hlsl::dot<vector3_type>(V, sampleL);
@@ -154,7 +187,7 @@ struct Estimator
154187
}
155188
break;
156189
default:
157-
pdf = numeric_limits<float>::infinity;
190+
pdf = bit_cast<float>(numeric_limits<float>::infinity);
158191
break;
159192
}
160193

31_HLSLPathTracer/app_resources/hlsl/pathtracer.hlsl

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct Unidirectional
9999

100100
scalar_type getLuma(NBL_CONST_REF_ARG(vector3_type) col)
101101
{
102-
return nbl::hlsl::dot(nbl::hlsl::transpose(colorspace::scRGBtoXYZ)[1], col);
102+
return hlsl::dot<vector3_type>(hlsl::transpose(colorspace::scRGBtoXYZ)[1], col);
103103
}
104104

105105
// TODO: probably will only work with procedural shapes, do the other ones
@@ -123,8 +123,8 @@ struct Unidirectional
123123
bsdfLightIDs = scene.getBsdfLightIDs(objectID);
124124
vector3_type N = scene.getNormal(objectID, intersection);
125125
N = nbl::hlsl::normalize(N);
126-
typename isotropic_type::ray_dir_info_type V;
127-
V.direction = nbl::hlsl::normalize(-ray.direction);
126+
ray_dir_info_type V;
127+
V.direction = -ray.direction;
128128
isotropic_type iso_interaction = isotropic_type::create(V, N);
129129
interaction = anisotropic_type::create(iso_interaction);
130130
}
@@ -143,8 +143,6 @@ struct Unidirectional
143143
ray.payload.accumulation += nee.deferredEvalAndPdf(_pdf, scene.lights[lightID], ray, scene.toNextEvent(lightID)) * throughput / (1.0 + _pdf * _pdf * ray.payload.otherTechniqueHeuristic);
144144
}
145145

146-
return false; // emissive only
147-
148146
const uint32_t bsdfID = glsl::bitfieldExtract(bsdfLightIDs, 0, 16);
149147
if (bsdfID == bxdfnode_type::INVALID_ID)
150148
return false;
@@ -163,9 +161,9 @@ struct Unidirectional
163161
// thresholds
164162
const scalar_type bxdfPdfThreshold = 0.0001;
165163
const scalar_type lumaContributionThreshold = getLuma(colorspace::eotf::sRGB<vector3_type>((vector3_type)1.0 / 255.0)); // OETF smallest perceptible value
166-
const vector3_type throughputCIE_Y = nbl::hlsl::transpose(colorspace::sRGBtoXYZ)[1] * throughput; // TODO: this only works if spectral_type is dim 3
164+
const vector3_type throughputCIE_Y = hlsl::transpose(colorspace::sRGBtoXYZ)[1] * throughput; // TODO: this only works if spectral_type is dim 3
167165
const measure_type eta = bxdf.params.ior0 / bxdf.params.ior1; // assume it's real, not imaginary?
168-
const scalar_type monochromeEta = nbl::hlsl::dot(throughputCIE_Y, eta) / (throughputCIE_Y.r + throughputCIE_Y.g + throughputCIE_Y.b); // TODO: imaginary eta?
166+
const scalar_type monochromeEta = hlsl::dot<vector3_type>(throughputCIE_Y, eta) / (throughputCIE_Y.r + throughputCIE_Y.g + throughputCIE_Y.b); // TODO: imaginary eta?
169167

170168
// sample lights
171169
const scalar_type neeProbability = 1.0; // BSDFNode_getNEEProb(bsdf);
@@ -185,7 +183,6 @@ struct Unidirectional
185183
// but if we allowed non-watertight transmitters (single water surface), it would make sense just to apply this line by itself
186184
anisocache_type _cache;
187185
validPath = validPath && anisocache_type::template compute<ray_dir_info_type, ray_dir_info_type>(_cache, interaction, nee_sample, monochromeEta);
188-
bxdf.params.A = nbl::hlsl::max(bxdf.params.A, vector<scalar_type, 2>(0,0));
189186
bxdf.params.eta = monochromeEta;
190187

191188
if (neeContrib_pdf.pdf < numeric_limits<scalar_type>::max)
@@ -231,7 +228,7 @@ struct Unidirectional
231228
}
232229

233230
quotient_pdf_type bsdf_quotient_pdf = materialSystem.quotient_and_pdf(material, bxdf.params, params);
234-
bsdf_quotient_pdf.quotient *= throughput;
231+
bsdf_quotient_pdf.quotient *= bxdf.albedo * throughput;
235232
neeContrib_pdf.quotient *= bsdf_quotient_pdf.quotient;
236233
const scalar_type otherGenOverChoice = bsdf_quotient_pdf.pdf * rcpChoiceProb;
237234
// const scalar_type otherGenOverLightAndChoice = otherGenOverChoice / bsdf_quotient_pdf.pdf;
@@ -268,30 +265,30 @@ struct Unidirectional
268265
{
269266
params = params_type::template create<sample_type, isotropic_type>(bsdf_sample, iso_interaction, bxdf::BCM_MAX);
270267
}
271-
else if (!isBSDF && bxdf.materialType != ext::MaterialSystem::Material::DIFFUSE)
272-
{
273-
if (bxdf.params.is_aniso)
274-
params = params_type::template create<sample_type, anisotropic_type, anisocache_type>(bsdf_sample, interaction, _cache, bxdf::BCM_MAX);
275-
else
276-
{
277-
isocache_type isocache = _cache.iso_cache;
278-
params = params_type::template create<sample_type, isotropic_type, isocache_type>(bsdf_sample, iso_interaction, isocache, bxdf::BCM_MAX);
279-
}
280-
}
281-
else if (isBSDF && bxdf.materialType == ext::MaterialSystem::Material::DIFFUSE)
282-
{
283-
params = params_type::template create<sample_type, isotropic_type>(bsdf_sample, iso_interaction, bxdf::BCM_ABS);
284-
}
285-
else if (isBSDF && bxdf.materialType != ext::MaterialSystem::Material::DIFFUSE)
286-
{
287-
if (bxdf.params.is_aniso)
288-
params = params_type::template create<sample_type, anisotropic_type, anisocache_type>(bsdf_sample, interaction, _cache, bxdf::BCM_ABS);
289-
else
290-
{
291-
isocache_type isocache = _cache.iso_cache;
292-
params = params_type::template create<sample_type, isotropic_type, isocache_type>(bsdf_sample, iso_interaction, isocache, bxdf::BCM_ABS);
293-
}
294-
}
268+
// else if (!isBSDF && bxdf.materialType != ext::MaterialSystem::Material::DIFFUSE)
269+
// {
270+
// if (bxdf.params.is_aniso)
271+
// params = params_type::template create<sample_type, anisotropic_type, anisocache_type>(bsdf_sample, interaction, _cache, bxdf::BCM_MAX);
272+
// else
273+
// {
274+
// isocache_type isocache = _cache.iso_cache;
275+
// params = params_type::template create<sample_type, isotropic_type, isocache_type>(bsdf_sample, iso_interaction, isocache, bxdf::BCM_MAX);
276+
// }
277+
// }
278+
// else if (isBSDF && bxdf.materialType == ext::MaterialSystem::Material::DIFFUSE)
279+
// {
280+
// params = params_type::template create<sample_type, isotropic_type>(bsdf_sample, iso_interaction, bxdf::BCM_ABS);
281+
// }
282+
// else if (isBSDF && bxdf.materialType != ext::MaterialSystem::Material::DIFFUSE)
283+
// {
284+
// if (bxdf.params.is_aniso)
285+
// params = params_type::template create<sample_type, anisotropic_type, anisocache_type>(bsdf_sample, interaction, _cache, bxdf::BCM_ABS);
286+
// else
287+
// {
288+
// isocache_type isocache = _cache.iso_cache;
289+
// params = params_type::template create<sample_type, isotropic_type, isocache_type>(bsdf_sample, iso_interaction, isocache, bxdf::BCM_ABS);
290+
// }
291+
// }
295292

296293
// the value of the bsdf divided by the probability of the sample being generated
297294
quotient_pdf_type bsdf_quotient_pdf = materialSystem.quotient_and_pdf(material, bxdf.params, params);
@@ -353,11 +350,7 @@ struct Unidirectional
353350

354351
hit = ray.objectID.id != -1;
355352
if (hit)
356-
{
357-
// float pp = float(ray.objectID.id) / 10.0;
358-
// ray.payload.accumulation = measure_type(pp, 1.0-pp, 0.3);
359353
rayAlive = closestHitProgram(1, i, ray, scene);
360-
}
361354

362355
}
363356
if (!hit)

0 commit comments

Comments
 (0)