9
9
#include " ../../ext/MitsubaLoader/CMitsubaLoader.h"
10
10
#include < irr/video/IGPUVirtualTexture.h>
11
11
12
+ #define USE_ENVMAP
13
+
12
14
using namespace irr ;
13
15
using namespace core ;
14
16
17
19
#define _IRR_COMPUTE_LIGHTING_DEFINED_
18
20
19
21
#include <irr/builtin/glsl/format/decode.glsl>
22
+ #include <irr/builtin/glsl/random/xoroshiro.glsl>
20
23
21
24
struct SLight
22
25
{
@@ -29,6 +32,15 @@ layout (set = 2, binding = 0, std430) readonly restrict buffer Lights
29
32
SLight lights[];
30
33
};
31
34
layout(set = 2, binding = 1) uniform sampler2D envMap;
35
+ layout(set = 2, binding = 2) uniform usamplerBuffer sampleSequence;
36
+ layout(set = 2, binding = 3) uniform usampler2D scramblebuf;
37
+
38
+ vec2 rand2d(in uint _sample, inout irr_glsl_xoroshiro64star_state_t scramble_state)
39
+ {
40
+ uvec2 seqVal = texelFetch(sampleSequence,int(_sample)).xy;
41
+ seqVal ^= uvec2(irr_glsl_xoroshiro64star(scramble_state),irr_glsl_xoroshiro64star(scramble_state));
42
+ return vec2(seqVal)*uintBitsToFloat(0x2f800004u);
43
+ }
32
44
33
45
vec2 SampleSphericalMap(in vec3 v)
34
46
{
@@ -40,41 +52,60 @@ vec2 SampleSphericalMap(in vec3 v)
40
52
41
53
vec3 irr_computeLighting(inout irr_glsl_IsotropicViewSurfaceInteraction out_interaction, in mat2 dUV)
42
54
{
55
+ irr_glsl_xoroshiro64star_state_t scramble_start_state = textureLod(scramblebuf,gl_FragCoord.xy/VIEWPORT_SZ,0).rg;
56
+
43
57
vec3 emissive = irr_glsl_decodeRGB19E7(InstData.data[InstanceIndex].emissive);
44
58
45
59
vec3 color = vec3(0.0);
46
- /*
60
+
61
+ #ifdef USE_ENVMAP
47
62
instr_stream_t gcs = getGenChoiceStream();
48
- const int N = 100;
49
- for (int i = 0; i < N; ++i)
63
+ for (int i = 0; i < SAMPLE_COUNT; ++i)
50
64
{
51
- vec3 rem;
52
- vec2 rand;//TODO
53
- vec3 L = runGeneratorChoiceStream(gcs, rand, rem);
65
+ irr_glsl_xoroshiro64star_state_t scramble_state = scramble_start_state;
66
+
67
+ instr_stream_t gcs = getGenChoiceStream();
68
+ instr_stream_t rnps = getRemAndPdfStream();
69
+
70
+ vec2 rand = rand2d(i,scramble_state);//TODO has to be 3d
71
+ float pdf;
72
+ runGenerateAndRemainderStream(gcs, rnps, rand, pdf);
73
+
54
74
vec2 uv = SampleSphericalMap(L);
55
75
color += rem*textureLod(envMap, uv, 0.0).xyz;
56
76
}
57
- */
77
+ color /= float(SAMPLE_COUNT);
78
+ #endif
79
+
58
80
irr_glsl_BSDFIsotropicParams params;
59
- for (int i = 0; i < 13 ; ++i)
81
+ for (int i = 0; i < LIGHT_COUNT ; ++i)
60
82
{
61
83
SLight l = lights[i];
62
84
vec3 L = l.position-WorldPos;
63
85
params.L = L;
64
- #define INTENSITY 0.01 //ehh might want to render to hdr fbo and do tonemapping
65
- color += irr_bsdf_cos_eval(params, out_interaction, dUV)*l.intensity*INTENSITY / dot(L,L);
86
+ const float intensityScale = LIGHT_INTENSITY_SCALE; //ehh might want to render to hdr fbo and do tonemapping
87
+ color += irr_bsdf_cos_eval(params, out_interaction, dUV)*l.intensity*intensityScale / dot(L,L);
66
88
}
67
89
68
90
return color+emissive;
69
91
}
70
92
)" ;
71
- static core::smart_refctd_ptr<asset::ICPUSpecializedShader> createModifiedFragShader (const asset::ICPUSpecializedShader* _fs)
93
+ static core::smart_refctd_ptr<asset::ICPUSpecializedShader> createModifiedFragShader (const asset::ICPUSpecializedShader* _fs, uint32_t viewport_w, uint32_t viewport_h, uint32_t lightCnt, uint32_t smplCnt, float intensityScale )
72
94
{
73
95
const asset::ICPUShader* unspec = _fs->getUnspecialized ();
74
96
assert (unspec->containsGLSL ());
75
97
76
98
std::string glsl = reinterpret_cast <const char *>( unspec->getSPVorGLSL ()->getPointer () );
77
- glsl.insert (glsl.find (" #ifndef _IRR_COMPUTE_LIGHTING_DEFINED_" ), GLSL_COMPUTE_LIGHTING);
99
+ std::string extra = " \n #define VIEWPORT_SZ vec2(" + std::to_string (viewport_w)+" ," +std::to_string (viewport_h)+" )" +
100
+ " \n #define LIGHT_COUNT " + std::to_string (lightCnt) +
101
+ " \n #define SAMPLE_COUNT " + std::to_string (smplCnt) +
102
+ " \n #define LIGHT_INTENSITY_SCALE " + std::to_string (intensityScale) +
103
+ #ifdef USE_ENVMAP
104
+ " \n #define USE_ENVMAP" +
105
+ #endif
106
+ GLSL_COMPUTE_LIGHTING;
107
+
108
+ glsl.insert (glsl.find (" #ifndef _IRR_COMPUTE_LIGHTING_DEFINED_" ), extra);
78
109
79
110
// auto* f = fopen("fs.glsl","w");
80
111
// fwrite(glsl.c_str(), 1, glsl.size(), f);
@@ -244,7 +275,7 @@ int main()
244
275
245
276
core::smart_refctd_ptr<asset::ICPUDescriptorSetLayout> ds2layout;
246
277
{
247
- asset::ICPUDescriptorSetLayout::SBinding bnd[2 ];
278
+ asset::ICPUDescriptorSetLayout::SBinding bnd[4 ];
248
279
bnd[0 ].binding = 0u ;
249
280
bnd[0 ].count = 1u ;
250
281
bnd[0 ].samplers = nullptr ;
@@ -260,39 +291,30 @@ int main()
260
291
bnd[1 ].stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
261
292
bnd[1 ].type = asset::EDT_COMBINED_IMAGE_SAMPLER;
262
293
263
- ds2layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bnd, bnd + 2 );
294
+ bnd[2 ].binding = 2u ;
295
+ bnd[2 ].count = 1u ;
296
+ bnd[2 ].samplers = nullptr ;
297
+ bnd[2 ].stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
298
+ bnd[2 ].type = asset::EDT_UNIFORM_TEXEL_BUFFER;
299
+
300
+ samplerParams = { ISampler::ETC_CLAMP_TO_EDGE, ISampler::ETC_CLAMP_TO_EDGE, ISampler::ETC_CLAMP_TO_EDGE, ISampler::ETBC_INT_OPAQUE_BLACK, ISampler::ETF_NEAREST, ISampler::ETF_NEAREST, ISampler::ESMM_NEAREST, 0u , false , ECO_ALWAYS };
301
+ auto smplr_int = core::make_smart_refctd_ptr<asset::ICPUSampler>(samplerParams);
302
+ bnd[3 ].binding = 3u ;
303
+ bnd[3 ].count = 1u ;
304
+ bnd[3 ].samplers = &smplr_int;
305
+ bnd[3 ].stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
306
+ bnd[3 ].type = asset::EDT_COMBINED_IMAGE_SAMPLER;
307
+
308
+ ds2layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bnd, bnd + 4 );
264
309
}
265
310
266
311
// gather all meshes into core::vector and modify their pipelines
267
- core::unordered_set<const asset::ICPURenderpassIndependentPipeline*> modifiedPipelines;
268
- core::unordered_map<core::smart_refctd_ptr<asset::ICPUSpecializedShader>, core::smart_refctd_ptr<asset::ICPUSpecializedShader>> modifiedShaders;
269
312
core::vector<core::smart_refctd_ptr<asset::ICPUMesh>> cpumeshes;
270
313
cpumeshes.reserve (meshes.getSize ());
271
314
for (auto it = meshes.getContents ().begin (); it != meshes.getContents ().end (); ++it)
272
315
{
273
316
cpumeshes.push_back (core::smart_refctd_ptr_static_cast<asset::ICPUMesh>(std::move (*it)));
274
- // modify pipeline layouts with our custom DS2 layout (DS2 will be used for lights buffer)
275
- for (uint32_t i = 0u ; i < cpumeshes.back ()->getMeshBufferCount (); ++i)
276
- {
277
- auto * pipeline = cpumeshes.back ()->getMeshBuffer (i)->getPipeline ();
278
- if (modifiedPipelines.find (pipeline)==modifiedPipelines.end ())
279
- {
280
- // if (!pipeline->getLayout()->getDescriptorSetLayout(2u))
281
- pipeline->getLayout ()->setDescriptorSetLayout (2u , core::smart_refctd_ptr (ds2layout));
282
- auto * fs = pipeline->getShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT);
283
- auto found = modifiedShaders.find (core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs));
284
- if (found != modifiedShaders.end ())
285
- pipeline->setShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT, found->second .get ());
286
- else {
287
- auto newfs = createModifiedFragShader (fs);
288
- modifiedShaders.insert ({ core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs),newfs});
289
- pipeline->setShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT, newfs.get ());
290
- }
291
- modifiedPipelines.insert (pipeline);
292
- }
293
- }
294
317
}
295
- modifiedShaders.clear ();
296
318
297
319
core::smart_refctd_ptr<asset::ICPUDescriptorSet> cpuds0;
298
320
{
@@ -370,7 +392,35 @@ int main()
370
392
}
371
393
}
372
394
373
- constexpr uint32_t MAX_INSTANCES = 512u ;
395
+ constexpr uint32_t ENVMAP_SAMPLE_COUNT = 64u ;
396
+ constexpr float LIGHT_INTENSITY_SCALE = 0 .01f ;
397
+
398
+ core::unordered_set<const asset::ICPURenderpassIndependentPipeline*> modifiedPipelines;
399
+ core::unordered_map<core::smart_refctd_ptr<asset::ICPUSpecializedShader>, core::smart_refctd_ptr<asset::ICPUSpecializedShader>> modifiedShaders;
400
+ for (auto & mesh : cpumeshes)
401
+ {
402
+ // modify pipeline layouts with our custom DS2 layout (DS2 will be used for lights buffer)
403
+ for (uint32_t i = 0u ; i < mesh->getMeshBufferCount (); ++i)
404
+ {
405
+ auto * pipeline = mesh->getMeshBuffer (i)->getPipeline ();
406
+ if (modifiedPipelines.find (pipeline) == modifiedPipelines.end ())
407
+ {
408
+ // if (!pipeline->getLayout()->getDescriptorSetLayout(2u))
409
+ pipeline->getLayout ()->setDescriptorSetLayout (2u , core::smart_refctd_ptr (ds2layout));
410
+ auto * fs = pipeline->getShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT);
411
+ auto found = modifiedShaders.find (core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs));
412
+ if (found != modifiedShaders.end ())
413
+ pipeline->setShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT, found->second .get ());
414
+ else {
415
+ auto newfs = createModifiedFragShader (fs, params.WindowSize .Width , params.WindowSize .Height , lights.size (), ENVMAP_SAMPLE_COUNT, LIGHT_INTENSITY_SCALE);
416
+ modifiedShaders.insert ({ core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs),newfs });
417
+ pipeline->setShaderAtStage (asset::ICPUSpecializedShader::ESS_FRAGMENT, newfs.get ());
418
+ }
419
+ modifiedPipelines.insert (pipeline);
420
+ }
421
+ }
422
+ }
423
+ modifiedShaders.clear ();
374
424
375
425
core::aabbox3df sceneBound;
376
426
auto gpumeshes = driver->getGPUObjectsFromAssets (cpumeshes.data (), cpumeshes.data ()+cpumeshes.size ());
@@ -424,11 +474,63 @@ int main()
424
474
driver->updateDescriptorSets (1u , &write, 0u , nullptr );
425
475
}
426
476
477
+ smart_refctd_ptr<video::IGPUBufferView> gpuSequenceBufferView;
478
+ {
479
+ constexpr uint32_t MaxSamples = ENVMAP_SAMPLE_COUNT;
480
+
481
+ auto sampleSequence = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof (uint32_t ) * MaxSamples*2u );
482
+
483
+ core::OwenSampler sampler (1u , 0xdeadbeefu );
484
+
485
+ auto out = reinterpret_cast <uint32_t *>(sampleSequence->getPointer ());
486
+ for (uint32_t i = 0 ; i < MaxSamples*2u ; i++)
487
+ {
488
+ out[i] = sampler.sample (i&1u , i>>1 );
489
+ }
490
+ auto gpuSequenceBuffer = driver->createFilledDeviceLocalGPUBufferOnDedMem (sampleSequence->getSize (), sampleSequence->getPointer ());
491
+ gpuSequenceBufferView = driver->createGPUBufferView (gpuSequenceBuffer.get (), asset::EF_R32G32_UINT);
492
+ }
493
+
494
+ smart_refctd_ptr<video::IGPUImageView> gpuScrambleImageView;
495
+ {
496
+ video::IGPUImage::SCreationParams imgParams;
497
+ imgParams.flags = static_cast <asset::IImage::E_CREATE_FLAGS>(0u );
498
+ imgParams.type = asset::IImage::ET_2D;
499
+ imgParams.format = asset::EF_R32G32_UINT;
500
+ imgParams.extent = {params.WindowSize .Width ,params.WindowSize .Height ,1u };
501
+ imgParams.mipLevels = 1u ;
502
+ imgParams.arrayLayers = 1u ;
503
+ imgParams.samples = asset::IImage::ESCF_1_BIT;
504
+
505
+ video::IGPUImage::SBufferCopy region;
506
+ region.imageExtent = imgParams.extent ;
507
+ region.imageSubresource .layerCount = 1u ;
508
+
509
+ constexpr auto ScrambleStateChannels = 2u ;
510
+ const auto renderPixelCount = imgParams.extent .width *imgParams.extent .height ;
511
+ core::vector<uint32_t > random (renderPixelCount*ScrambleStateChannels);
512
+ {
513
+ core::RandomSampler rng (0xbadc0ffeu );
514
+ for (auto & pixel : random)
515
+ pixel = rng.nextSample ();
516
+ }
517
+ auto buffer = driver->createFilledDeviceLocalGPUBufferOnDedMem (random.size ()*sizeof (uint32_t ),random.data ());
518
+
519
+ video::IGPUImageView::SCreationParams viewParams;
520
+ viewParams.flags = static_cast <video::IGPUImageView::E_CREATE_FLAGS>(0u );
521
+ viewParams.image = driver->createFilledDeviceLocalGPUImageOnDedMem (std::move (imgParams),buffer.get (),1u ,®ion);
522
+ viewParams.viewType = video::IGPUImageView::ET_2D;
523
+ viewParams.format = asset::EF_R32G32_UINT;
524
+ viewParams.subresourceRange .levelCount = 1u ;
525
+ viewParams.subresourceRange .layerCount = 1u ;
526
+ gpuScrambleImageView = driver->createGPUImageView (std::move (viewParams));
527
+ }
528
+
427
529
auto gpuds2layout = driver->getGPUObjectsFromAssets (&ds2layout.get (), &ds2layout.get ()+1 )->front ();
428
530
auto gpuds2 = driver->createGPUDescriptorSet (std::move (gpuds2layout));
429
531
{
430
- video::IGPUDescriptorSet::SDescriptorInfo info[2 ];
431
- video::IGPUDescriptorSet::SWriteDescriptorSet w[2 ];
532
+ video::IGPUDescriptorSet::SDescriptorInfo info[4 ];
533
+ video::IGPUDescriptorSet::SWriteDescriptorSet w[4 ];
432
534
w[0 ].arrayElement = 0u ;
433
535
w[0 ].binding = 0u ;
434
536
w[0 ].count = 1u ;
@@ -451,7 +553,25 @@ int main()
451
553
info[1 ].image .sampler = nullptr ;
452
554
info[1 ].desc = std::move (gpuEnvmapImageView);
453
555
454
- driver->updateDescriptorSets (2u , w, 0u , nullptr );
556
+ w[2 ].arrayElement = 0u ;
557
+ w[2 ].binding = 2u ;
558
+ w[2 ].count = 1u ;
559
+ w[2 ].descriptorType = asset::EDT_UNIFORM_TEXEL_BUFFER;
560
+ w[2 ].dstSet = gpuds2.get ();
561
+ w[2 ].info = info+2 ;
562
+ info[2 ].desc = gpuSequenceBufferView;
563
+
564
+ w[3 ].arrayElement = 0u ;
565
+ w[3 ].binding = 3u ;
566
+ w[3 ].count = 1u ;
567
+ w[3 ].descriptorType = asset::EDT_COMBINED_IMAGE_SAMPLER;
568
+ w[3 ].dstSet = gpuds2.get ();
569
+ w[3 ].info = info+3 ;
570
+ info[3 ].image .imageLayout = asset::EIL_UNDEFINED;
571
+ info[3 ].image .sampler = nullptr ;// imm sampler is present
572
+ info[3 ].desc = gpuScrambleImageView;
573
+
574
+ driver->updateDescriptorSets (4u , w, 0u , nullptr );
455
575
}
456
576
457
577
// camera and viewport
@@ -561,6 +681,7 @@ int main()
561
681
uint64_t lastFPSTime = 0 ;
562
682
float lastFastestMeshFrameNr = -1 .f ;
563
683
684
+ constexpr uint32_t MAX_INSTANCES = 512u ;
564
685
core::vector<core::matrix4SIMD> uboData (MAX_INSTANCES);
565
686
while (device->run () && receiver.keepOpen ())
566
687
{
0 commit comments