Skip to content

Commit d4e5754

Browse files
committed
merged rwmc, fix conflicts
2 parents 8b8fab0 + badb4a6 commit d4e5754

File tree

9 files changed

+598
-188
lines changed

9 files changed

+598
-188
lines changed

31_HLSLPathTracer/app_resources/hlsl/pathtracer.hlsl

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <nbl/builtin/hlsl/colorspace/encodeCIEXYZ.hlsl>
66
#include <nbl/builtin/hlsl/math/functions.hlsl>
77
#include <nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl>
8+
#include <nbl/builtin/hlsl/vector_utils/vector_traits.hlsl>
9+
#include <nbl/builtin/hlsl/concepts.hlsl>
810

911
#include "rand_gen.hlsl"
1012
#include "ray_gen.hlsl"
@@ -35,10 +37,33 @@ struct PathTracerCreationParams
3537
matrix<Scalar, 4, 4> invMVP;
3638
};
3739

38-
template<class RandGen, class RayGen, class Intersector, class MaterialSystem, /* class PathGuider, */ class NextEventEstimator>
40+
template<typename OutputTypeVec NBL_PRIMARY_REQUIRES(concepts::FloatingPointVector<OutputTypeVec>)
41+
struct DefaultAccumulator
42+
{
43+
using output_storage_type = OutputTypeVec;
44+
using this_t = DefaultAccumulator<OutputTypeVec>;
45+
output_storage_type accumulation;
46+
47+
static this_t create()
48+
{
49+
this_t retval;
50+
retval.accumulation = promote<OutputTypeVec, float32_t>(0.0f);
51+
52+
return retval;
53+
}
54+
55+
void addSample(uint32_t sampleCount, float32_t3 sample)
56+
{
57+
using ScalarType = typename vector_traits<OutputTypeVec>::scalar_type;
58+
ScalarType rcpSampleSize = 1.0 / (sampleCount);
59+
accumulation += (sample - accumulation) * rcpSampleSize;
60+
}
61+
};
62+
63+
template<class RandGen, class RayGen, class Intersector, class MaterialSystem, /* class PathGuider, */ class NextEventEstimator, class Accumulator>
3964
struct Unidirectional
4065
{
41-
using this_t = Unidirectional<RandGen, RayGen, Intersector, MaterialSystem, NextEventEstimator>;
66+
using this_t = Unidirectional<RandGen, RayGen, Intersector, MaterialSystem, NextEventEstimator, Accumulator>;
4267
using randgen_type = RandGen;
4368
using raygen_type = RayGen;
4469
using intersector_type = Intersector;
@@ -49,6 +74,7 @@ struct Unidirectional
4974
using vector3_type = vector<scalar_type, 3>;
5075
using monochrome_type = vector<scalar_type, 1>;
5176
using measure_type = typename MaterialSystem::measure_type;
77+
using output_storage_type = typename Accumulator::output_storage_type; // ?
5278
using sample_type = typename NextEventEstimator::sample_type;
5379
using ray_dir_info_type = typename sample_type::ray_dir_info_type;
5480
using ray_type = typename RayGen::ray_type;
@@ -255,40 +281,33 @@ struct Unidirectional
255281
}
256282

257283
// Li
258-
measure_type getMeasure(uint32_t numSamples, uint32_t depth, NBL_CONST_REF_ARG(scene_type) scene)
284+
void sampleMeasure(uint32_t sampleIndex, uint32_t maxDepth, NBL_CONST_REF_ARG(scene_type) scene, NBL_REF_ARG(Accumulator) accumulator)
259285
{
260-
measure_type Li = (measure_type)0.0;
261-
scalar_type meanLumaSq = 0.0;
262-
for (uint32_t i = 0; i < numSamples; i++)
286+
//scalar_type meanLumaSq = 0.0;
287+
vector3_type uvw = rand3d(0u, sampleIndex, randGen.rng()); // TODO: take from scramblebuf?
288+
ray_type ray = rayGen.generate(uvw);
289+
290+
// bounces
291+
bool hit = true;
292+
bool rayAlive = true;
293+
for (int d = 1; (d <= maxDepth) && hit && rayAlive; d += 2)
263294
{
264-
vector3_type uvw = rand3d(0u, i, randGen.rng()); // TODO: take from scramblebuf?
265-
ray_type ray = rayGen.generate(uvw);
266-
267-
// bounces
268-
bool hit = true;
269-
bool rayAlive = true;
270-
for (int d = 1; (d <= depth) && hit && rayAlive; d += 2)
271-
{
272-
ray.intersectionT = numeric_limits<scalar_type>::max;
273-
ray.objectID = intersector_type::traceRay(ray, scene);
295+
ray.intersectionT = numeric_limits<scalar_type>::max;
296+
ray.objectID = intersector_type::traceRay(ray, scene);
274297

275-
hit = ray.objectID.id != -1;
276-
if (hit)
277-
rayAlive = closestHitProgram(1, i, ray, scene);
278-
}
279-
if (!hit)
280-
missProgram(ray);
281-
282-
measure_type accumulation = ray.payload.accumulation;
283-
scalar_type rcpSampleSize = 1.0 / (i + 1);
284-
Li += (accumulation - Li) * rcpSampleSize;
298+
hit = ray.objectID.id != -1;
299+
if (hit)
300+
rayAlive = closestHitProgram(1, sampleIndex, ray, scene);
301+
}
302+
if (!hit)
303+
missProgram(ray);
285304

286-
// TODO: visualize high variance
305+
const uint32_t sampleCount = sampleIndex + 1;
306+
accumulator.addSample(sampleCount, ray.payload.accumulation);
287307

288-
// TODO: russian roulette early exit?
289-
}
308+
// TODO: visualize high variance
290309

291-
return Li;
310+
// TODO: russian roulette early exit?
292311
}
293312

294313
NBL_CONSTEXPR_STATIC_INLINE uint32_t MAX_DEPTH_LOG2 = 4u;

31_HLSLPathTracer/app_resources/hlsl/present.frag.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ using namespace nbl::hlsl;
1010
using namespace ext::FullScreenTriangle;
1111

1212
// binding 0 set 0
13-
[[vk::combinedImageSampler]] [[vk::binding(0, 0)]] Texture2D texture;
13+
[[vk::combinedImageSampler]] [[vk::binding(0, 0)]] Texture2DArray texture;
1414
[[vk::combinedImageSampler]] [[vk::binding(0, 0)]] SamplerState samplerState;
1515

1616
[[vk::location(0)]] float32_t4 main(SVertexAttributes vxAttr) : SV_Target0
1717
{
18-
return float32_t4(texture.Sample(samplerState, vxAttr.uv).rgb, 1.0f);
18+
return float32_t4(texture.Sample(samplerState, float3(vxAttr.uv, 0)).rgb, 1.0f);
1919
}

31_HLSLPathTracer/app_resources/hlsl/render.comp.hlsl

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,31 @@
3535
#define LIGHT_COUNT 1
3636
#define BXDF_COUNT 7
3737

38-
#include "render_common.hlsl"
38+
#include <render_common.hlsl>
39+
#include <rwmc_global_settings_common.hlsl>
40+
41+
#ifdef RWMC_ENABLED
42+
#include <nbl/builtin/hlsl/rwmc/CascadeAccumulator.hlsl>
43+
#include <render_rwmc_common.hlsl>
44+
#endif
45+
46+
#ifdef RWMC_ENABLED
47+
[[vk::push_constant]] RenderRWMCPushConstants pc;
48+
#else
49+
[[vk::push_constant]] RenderPushConstants pc;
50+
#endif
51+
52+
[[vk::combinedImageSampler]] [[vk::binding(0, 2)]] Texture2D<float3> envMap; // unused
53+
[[vk::combinedImageSampler]] [[vk::binding(0, 2)]] SamplerState envSampler;
54+
55+
[[vk::binding(1, 2)]] Buffer<uint3> sampleSequence;
56+
57+
[[vk::combinedImageSampler]] [[vk::binding(2, 2)]] Texture2D<uint2> scramblebuf; // unused
58+
[[vk::combinedImageSampler]] [[vk::binding(2, 2)]] SamplerState scrambleSampler;
59+
60+
[[vk::image_format("rgba16f")]] [[vk::binding(0)]] RWTexture2DArray<float32_t4> outImage;
61+
[[vk::image_format("rgba16f")]] [[vk::binding(1)]] RWTexture2DArray<float32_t4> cascade;
62+
3963
#include "pathtracer.hlsl"
4064

4165
using namespace nbl;
@@ -59,15 +83,15 @@ NBL_CONSTEXPR ext::PTPolygonMethod POLYGON_METHOD = ext::PPM_SOLID_ANGLE;
5983

6084
int32_t2 getCoordinates()
6185
{
62-
uint32_t width, height;
63-
outImage.GetDimensions(width, height);
86+
uint32_t width, height, imageArraySize;
87+
outImage.GetDimensions(width, height, imageArraySize);
6488
return int32_t2(glsl::gl_GlobalInvocationID().x % width, glsl::gl_GlobalInvocationID().x / width);
6589
}
6690

6791
float32_t2 getTexCoords()
6892
{
69-
uint32_t width, height;
70-
outImage.GetDimensions(width, height);
93+
uint32_t width, height, imageArraySize;
94+
outImage.GetDimensions(width, height, imageArraySize);
7195
int32_t2 iCoords = getCoordinates();
7296
return float32_t2(float(iCoords.x) / width, 1.0 - float(iCoords.y) / height);
7397
}
@@ -97,7 +121,14 @@ using raygen_type = ext::RayGen::Basic<ray_type>;
97121
using intersector_type = ext::Intersector::Comprehensive<ray_type, light_type, bxdfnode_type>;
98122
using material_system_type = ext::MaterialSystem::System<diffuse_bxdf_type, conductor_bxdf_type, dielectric_bxdf_type>;
99123
using nee_type = ext::NextEventEstimator::Estimator<scene_type, ray_type, sample_t, aniso_interaction, ext::IntersectMode::IM_PROCEDURAL, LIGHT_TYPE, POLYGON_METHOD>;
100-
using pathtracer_type = ext::PathTracer::Unidirectional<randgen_type, raygen_type, intersector_type, material_system_type, nee_type>;
124+
125+
#ifdef RWMC_ENABLED
126+
using accumulator_type = rwmc::CascadeAccumulator<float32_t3, CascadeCount>;
127+
#else
128+
using accumulator_type = ext::PathTracer::DefaultAccumulator<float32_t3>;
129+
#endif
130+
131+
using pathtracer_type = ext::PathTracer::Unidirectional<randgen_type, raygen_type, intersector_type, material_system_type, nee_type, accumulator_type>;
101132

102133
static const ext::Shape<ext::PST_SPHERE> spheres[SPHERE_COUNT] = {
103134
ext::Shape<ext::PST_SPHERE>::create(float3(0.0, -100.5, -1.0), 100.0, 0u, light_type::INVALID_ID),
@@ -130,7 +161,7 @@ static const ext::Shape<ext::PST_RECTANGLE> rectangles[1];
130161
#endif
131162

132163
static const light_type lights[LIGHT_COUNT] = {
133-
light_type::create(spectral_t(30.0,25.0,15.0),
164+
light_type::create(LightEminence,
134165
#ifdef SPHERE_LIGHT
135166
8u,
136167
#else
@@ -155,11 +186,22 @@ static const ext::Scene<light_type, bxdfnode_type> scene = ext::Scene<light_type
155186
lights, LIGHT_COUNT, bxdfs, BXDF_COUNT
156187
);
157188

158-
[numthreads(WorkgroupSize, 1, 1)]
189+
RenderPushConstants retireveRenderPushConstants()
190+
{
191+
#ifdef RWMC_ENABLED
192+
return pc.renderPushConstants;
193+
#else
194+
return pc;
195+
#endif
196+
}
197+
198+
[numthreads(RenderWorkgroupSize, 1, 1)]
159199
void main(uint32_t3 threadID : SV_DispatchThreadID)
160200
{
161-
uint32_t width, height;
162-
outImage.GetDimensions(width, height);
201+
const RenderPushConstants renderPushConstants = retireveRenderPushConstants();
202+
203+
uint32_t width, height, imageArraySize;
204+
outImage.GetDimensions(width, height, imageArraySize);
163205
#ifdef PERSISTENT_WORKGROUPS
164206
uint32_t virtualThreadIndex;
165207
[loop]
@@ -181,10 +223,10 @@ void main(uint32_t3 threadID : SV_DispatchThreadID)
181223
#endif
182224
}
183225

184-
if (((pc.depth - 1) >> MAX_DEPTH_LOG2) > 0 || ((pc.sampleCount - 1) >> MAX_SAMPLES_LOG2) > 0)
226+
if (((renderPushConstants.depth - 1) >> MAX_DEPTH_LOG2) > 0 || ((renderPushConstants.sampleCount - 1) >> MAX_SAMPLES_LOG2) > 0)
185227
{
186228
float32_t4 pixelCol = float32_t4(1.0,0.0,0.0,1.0);
187-
outImage[coords] = pixelCol;
229+
outImage[uint3(coords.x, coords.y, 0)] = pixelCol;
188230
#ifdef PERSISTENT_WORKGROUPS
189231
continue;
190232
#else
@@ -204,19 +246,33 @@ void main(uint32_t3 threadID : SV_DispatchThreadID)
204246

205247
float4 NDC = float4(texCoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
206248
{
207-
float4 tmp = mul(pc.invMVP, NDC);
249+
float4 tmp = mul(renderPushConstants.invMVP, NDC);
208250
ptCreateParams.camPos = tmp.xyz / tmp.w;
209251
NDC.z = 1.0;
210252
}
211253

212254
ptCreateParams.NDC = NDC;
213-
ptCreateParams.invMVP = pc.invMVP;
255+
ptCreateParams.invMVP = renderPushConstants.invMVP;
214256

215257
pathtracer_type pathtracer = pathtracer_type::create(ptCreateParams);
216258

217-
float32_t3 color = pathtracer.getMeasure(pc.sampleCount, pc.depth, scene);
218-
float32_t4 pixCol = float32_t4(color, 1.0);
219-
outImage[coords] = pixCol;
259+
#ifdef RWMC_ENABLED
260+
accumulator_type accumulator = accumulator_type::create(pc.splattingParameters);
261+
#else
262+
accumulator_type accumulator = accumulator_type::create();
263+
#endif
264+
// path tracing loop
265+
for(int i = 0; i < renderPushConstants.sampleCount; ++i)
266+
pathtracer.sampleMeasure(i, renderPushConstants.depth, scene, accumulator);
267+
268+
#ifdef RWMC_ENABLED
269+
for (uint32_t i = 0; i < CascadeCount; ++i)
270+
cascade[uint3(coords.x, coords.y, i)] = float32_t4(accumulator.accumulation.data[i], 1.0f);
271+
#else
272+
outImage[uint3(coords.x, coords.y, 0)] = float32_t4(accumulator.accumulation, 1.0);
273+
#endif
274+
275+
220276

221277
#ifdef PERSISTENT_WORKGROUPS
222278
}
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
#ifndef _NBL_HLSL_PATHTRACER_RENDER_COMMON_INCLUDED_
22
#define _NBL_HLSL_PATHTRACER_RENDER_COMMON_INCLUDED_
3+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
34

4-
struct SPushConstants
5+
#ifndef __HLSL_VERSION
6+
#include "matrix4SIMD.h"
7+
#endif
8+
9+
struct RenderPushConstants
510
{
11+
#ifdef __HLSL_VERSION
612
float32_t4x4 invMVP;
13+
#else
14+
nbl::hlsl::float32_t4x4 invMVP;
15+
#endif
716
int sampleCount;
817
int depth;
918
};
1019

11-
[[vk::push_constant]] SPushConstants pc;
12-
13-
[[vk::combinedImageSampler]][[vk::binding(0, 2)]] Texture2D<float3> envMap; // unused
14-
[[vk::combinedImageSampler]][[vk::binding(0, 2)]] SamplerState envSampler;
15-
16-
[[vk::binding(1, 2)]] Buffer<uint3> sampleSequence;
17-
18-
[[vk::combinedImageSampler]][[vk::binding(2, 2)]] Texture2D<uint2> scramblebuf; // unused
19-
[[vk::combinedImageSampler]][[vk::binding(2, 2)]] SamplerState scrambleSampler;
20-
21-
[[vk::image_format("rgba16f")]][[vk::binding(0, 0)]] RWTexture2D<float32_t4> outImage;
20+
NBL_CONSTEXPR nbl::hlsl::float32_t3 LightEminence = nbl::hlsl::float32_t3(30.0f, 25.0f, 15.0f);
21+
NBL_CONSTEXPR uint32_t RenderWorkgroupSize = 512u;
2222

2323
#endif
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef _NBL_HLSL_PATHTRACER_RENDER_RWMC_COMMON_INCLUDED_
2+
#define _NBL_HLSL_PATHTRACER_RENDER_RWMC_COMMON_INCLUDED_
3+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
4+
#include "nbl/builtin/hlsl/rwmc/SplattingParameters.hlsl"
5+
#include "render_common.hlsl"
6+
7+
#ifndef __HLSL_VERSION
8+
#include "matrix4SIMD.h"
9+
#endif
10+
11+
struct RenderRWMCPushConstants
12+
{
13+
RenderPushConstants renderPushConstants;
14+
nbl::hlsl::rwmc::SplattingParameters splattingParameters;
15+
};
16+
17+
#endif
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <nbl/builtin/hlsl/rwmc/resolve.hlsl>
2+
#include "resolve_common.hlsl"
3+
#include "rwmc_global_settings_common.hlsl"
4+
#ifdef PERSISTENT_WORKGROUPS
5+
#include "nbl/builtin/hlsl/math/morton.hlsl"
6+
#endif
7+
8+
[[vk::push_constant]] ResolvePushConstants pc;
9+
[[vk::image_format("rgba16f")]] [[vk::binding(0)]] RWTexture2DArray<float32_t4> outImage;
10+
[[vk::image_format("rgba16f")]] [[vk::binding(1)]] RWTexture2DArray<float32_t4> cascade;
11+
12+
using namespace nbl;
13+
using namespace hlsl;
14+
15+
int32_t2 getImageExtents()
16+
{
17+
uint32_t width, height, imageArraySize;
18+
outImage.GetDimensions(width, height, imageArraySize);
19+
return int32_t2(width, height);
20+
}
21+
22+
[numthreads(ResolveWorkgroupSizeX, ResolveWorkgroupSizeY, 1)]
23+
void main(uint32_t3 threadID : SV_DispatchThreadID)
24+
{
25+
const int32_t2 coords = int32_t2(threadID.x, threadID.y);
26+
const int32_t2 imageExtents = getImageExtents();
27+
if (coords.x >= imageExtents.x || coords.y >= imageExtents.y)
28+
return;
29+
30+
using ResolveAccessorAdaptorType = rwmc::ResolveAccessorAdaptor<float>;
31+
using ResolverType = rwmc::Resolver<ResolveAccessorAdaptorType, float32_t3>;
32+
ResolveAccessorAdaptorType accessor;
33+
accessor.cascade = cascade;
34+
ResolverType resolve = ResolverType::create(pc.resolveParameters);
35+
36+
float32_t3 color = resolve(accessor, int16_t2(coords.x, coords.y));
37+
38+
//float32_t3 color = rwmc::reweight<rwmc::ResolveAccessorAdaptor<float> >(pc.resolveParameters, cascade, coords);
39+
40+
outImage[uint3(coords.x, coords.y, 0)] = float32_t4(color, 1.0f);
41+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef _NBL_HLSL_PATHTRACER_RESOLVE_COMMON_INCLUDED_
2+
#define _NBL_HLSL_PATHTRACER_RESOLVE_COMMON_INCLUDED_
3+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
4+
#include "nbl/builtin/hlsl/rwmc/ResolveParameters.hlsl"
5+
6+
struct ResolvePushConstants
7+
{
8+
uint32_t sampleCount;
9+
nbl::hlsl::rwmc::ResolveParameters resolveParameters;
10+
};
11+
12+
NBL_CONSTEXPR uint32_t ResolveWorkgroupSizeX = 32u;
13+
NBL_CONSTEXPR uint32_t ResolveWorkgroupSizeY = 16u;
14+
15+
#endif

0 commit comments

Comments
 (0)