-
Notifications
You must be signed in to change notification settings - Fork 69
Env map importance sampling #969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b99ae6e
b9537ea
a737173
64349db
e44fcf4
9b29dfd
9be65a0
3e03467
34d1385
06ae3e4
16ecb52
8d682b9
890f7c6
f99c63b
3ff2791
76ef536
ef773fd
b9467fe
3682604
ac1e2f3
baca1cf
f12b797
0957aed
1b35d34
665bb8d
b522b4f
3e51c69
c72d305
5ee2ce7
867868c
1a66157
d4b8105
8853738
6bde489
756fbb0
8d64a19
70d8423
2842d29
a51848c
58c9c13
fa94ac2
8494124
b273d87
3bc0e57
1dadf92
f19cbe9
fde2bba
81cae21
733a4ab
ba6be93
f04d98b
df2bfc3
4930e25
05b862a
d50b50f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| +1 −1 | CMakeLists.txt | |
| +1 −1 | icd/VkICD_mock_icd.json.in | |
| +456 −542 | icd/generated/function_declarations.h | |
| +682 −761 | icd/generated/function_definitions.h | |
| +816 −1,050 | icd/generated/vk_typemap_helper.h | |
| +2 −2 | scripts/known_good.json | |
| +1 −1 | tests/icd/mock_icd_tests.cpp | |
| +11 −3 | vulkaninfo/CMakeLists.txt | |
| +1 −160 | vulkaninfo/generated/vulkaninfo.hpp | |
| +6 −11 | vulkaninfo/vulkaninfo.cpp |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| // Copyright (C) 2018-2025 - DevSH Graphics Programming Sp. z O.O. | ||
| // This file is part of the "Nabla Engine". | ||
| // For conditions of distribution and use, see copyright notice in nabla.h | ||
|
|
||
| #ifndef _NBL_BUILTIN_HLSL_SAMPLING_HIERARCHICAL_IMAGE_INCLUDED_ | ||
| #define _NBL_BUILTIN_HLSL_SAMPLING_HIERARCHICAL_IMAGE_INCLUDED_ | ||
|
|
||
| #include <nbl/builtin/hlsl/sampling/basic.hlsl> | ||
| #include <nbl/builtin/hlsl/sampling/warp.hlsl> | ||
| #include <nbl/builtin/hlsl/sampling/hierarchical_image/accessors.hlsl> | ||
| #include <nbl/builtin/hlsl/cpp_compat/intrinsics.hlsl> | ||
|
|
||
| namespace nbl | ||
| { | ||
| namespace hlsl | ||
| { | ||
| namespace sampling | ||
| { | ||
|
|
||
| template <typename ScalarT, typename LuminanceAccessorT | ||
| NBL_PRIMARY_REQUIRES( | ||
| is_scalar_v<ScalarT> && | ||
| hierarchical_image::LuminanceReadAccessor<LuminanceAccessorT, ScalarT> | ||
| ) | ||
|
Comment on lines
+20
to
+24
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a bool for whether the accessor is corner sampled or not |
||
| struct LuminanceMapSampler | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this one is actually the HierarchicalLuminanceSampler |
||
| { | ||
| using scalar_type = ScalarT; | ||
| using vector2_type = vector<scalar_type, 2>; | ||
| using vector4_type = vector<scalar_type, 4>; | ||
|
|
||
| LuminanceAccessorT _map; | ||
| uint32_t2 _mapSize; | ||
| uint32_t2 _lastWarpPixel; | ||
| bool _aspect2x1; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. store these instead float32_t2 rcpMapSize;
uint16_t mip2x1 : 15;
uint16_t aspect2x1 : 1; |
||
|
|
||
| static LuminanceMapSampler<ScalarT, LuminanceAccessorT> create(NBL_CONST_REF_ARG(LuminanceAccessorT) lumaMap, uint32_t2 mapSize, bool aspect2x1, uint32_t2 warpSize) | ||
| { | ||
| LuminanceMapSampler<ScalarT, LuminanceAccessorT> result; | ||
| result._map = lumaMap; | ||
| result._mapSize = mapSize; | ||
| result._lastWarpPixel = warpSize - uint32_t2(1, 1); | ||
| result._aspect2x1 = aspect2x1; | ||
| return result; | ||
| } | ||
|
|
||
| static bool choseSecond(scalar_type first, scalar_type second, NBL_REF_ARG(scalar_type) xi) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefix with |
||
| { | ||
| // numerical resilience against IEEE754 | ||
| scalar_type dummy = scalar_type(0); | ||
| PartitionRandVariable<scalar_type> partition; | ||
| partition.leftProb = scalar_type(1) / (scalar_type(1) + (second / first)); | ||
| return partition(xi, dummy); | ||
| } | ||
|
|
||
| vector2_type binarySearch(const uint32_t2 coord) | ||
| { | ||
| // We use _lastWarpPixel here for corner sampling | ||
| float32_t2 xi = float32_t2(coord)/ _lastWarpPixel; | ||
| uint32_t2 p = uint32_t2(0, 0); | ||
| const uint32_t2 mip2x1 = findMSB(_mapSize.y); | ||
|
Comment on lines
+55
to
+60
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to be able to use this as a sampler, I also need a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you also wouldn't store
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are you using a uint32_t2 to store this, its a uint16_t at most, its a scalar quantity Also should be precomputed |
||
|
|
||
| if (_aspect2x1) { | ||
| // do one split in the X axis first cause penultimate full mip would have been 2x1 | ||
| p.x = choseSecond(_map.texelFetch(uint32_t2(0, 0), mip2x1), _map.texelFetch(uint32_t2(1, 0), mip2x1), xi.x) ? 1 : 0; | ||
| } | ||
|
|
||
| for (int i = mip2x1 - 1; i >= 0; i--) | ||
| { | ||
| p <<= 1; | ||
| const vector4_type values = _map.texelGather(p, i); | ||
| scalar_type wx_0, wx_1; | ||
| { | ||
| const scalar_type wy_0 = values[3] + values[2]; | ||
| const scalar_type wy_1 = values[1] + values[0]; | ||
| if (choseSecond(wy_0, wy_1, xi.y)) | ||
| { | ||
| p.y |= 1; | ||
| wx_0 = values[0]; | ||
| wx_1 = values[1]; | ||
| } | ||
| else | ||
| { | ||
| wx_0 = values[3]; | ||
| wx_1 = values[2]; | ||
| } | ||
| } | ||
| if (choseSecond(wx_0, wx_1, xi.x)) | ||
| p.x |= 1; | ||
|
Comment on lines
+87
to
+88
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw you can get the PDF of the finally chosen texel as metadata if on the final call to (obvioulsy if |
||
| } | ||
|
|
||
|
|
||
| // If we don`t add xi, the sample will clump to the lowest corner of environment map texel. We add xi to simulate uniform distribution within a pixel and make the sample continuous. This is why we compute the pdf not from the normalized luminance of the texel, instead from the reciprocal of the Jacobian. | ||
| const vector2_type directionUV = (vector2_type(p.x, p.y) + xi) / vector2_type(_mapSize); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if your spheremap or octahedral maps are corner sampled, the edge pixels need special treatment Essentially whenever your X or Y coordinate is an edge coordinate, you'd need to weight their luma contribution down by 50% and also change how the remaining
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then you'd actually rescale that final UV from [0.5/size,1-0.5/size] to [0,1] before outputting it in the warpmap |
||
| return directionUV; | ||
| } | ||
|
|
||
| matrix<scalar_type, 4, 2> sampleUvs(uint32_t2 sampleCoord) NBL_CONST_MEMBER_FUNC | ||
| { | ||
| const vector2_type dir0 = binarySearch(sampleCoord + vector2_type(0, 1)); | ||
| const vector2_type dir1 = binarySearch(sampleCoord + vector2_type(1, 1)); | ||
| const vector2_type dir2 = binarySearch(sampleCoord + vector2_type(1, 0)); | ||
| const vector2_type dir3 = binarySearch(sampleCoord); | ||
| return matrix<scalar_type, 4, 2>( | ||
| dir0, | ||
| dir1, | ||
| dir2, | ||
| dir3 | ||
| ); | ||
| } | ||
|
Comment on lines
+97
to
+109
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure that
|
||
| }; | ||
|
|
||
| template <typename ScalarT, typename LuminanceAccessorT, typename HierarchicalSamplerT, typename PostWarpT | ||
| NBL_PRIMARY_REQUIRES(is_scalar_v<ScalarT> && | ||
| concepts::accessors::GenericReadAccessor<LuminanceAccessorT, ScalarT, float32_t2> && | ||
| hierarchical_image::HierarchicalSampler<HierarchicalSamplerT, ScalarT> && | ||
| concepts::Warp<PostWarpT>) | ||
| struct HierarchicalImage | ||
|
Comment on lines
+112
to
+117
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be called WarpmapSampler or something like that |
||
| { | ||
| using scalar_type = ScalarT; | ||
| using vector2_type = vector<ScalarT, 2>; | ||
| using vector3_type = vector<ScalarT, 3>; | ||
| using vector4_type = vector<ScalarT, 4>; | ||
| LuminanceAccessorT _lumaMap; | ||
| HierarchicalSamplerT _warpMap; | ||
| uint32_t2 _warpSize; | ||
| uint32_t2 _lastWarpPixel; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you actually only need to store the |
||
| scalar_type _rcpAvgLuma; | ||
|
|
||
| static HierarchicalImage create(NBL_CONST_REF_ARG(LuminanceAccessorT) lumaMap, NBL_CONST_REF_ARG(HierarchicalSamplerT) warpMap, uint32_t2 warpSize, scalar_type avgLuma) | ||
| { | ||
| HierarchicalImage<ScalarT, LuminanceAccessorT, HierarchicalSamplerT, PostWarpT> result; | ||
| result._lumaMap = lumaMap; | ||
| result._warpMap = warpMap; | ||
| result._warpSize = warpSize; | ||
| result._lastWarpPixel = warpSize - uint32_t2(1, 1); | ||
| result._rcpAvgLuma = ScalarT(1.0) / avgLuma; | ||
| return result; | ||
| } | ||
|
|
||
| vector2_type inverseWarp_and_deferredPdf(NBL_REF_ARG(scalar_type) pdf, vector3_type direction) NBL_CONST_MEMBER_FUNC | ||
| { | ||
| vector2_type envmapUv = PostWarpT::inverseWarp(direction); | ||
| scalar_type luma; | ||
| _lumaMap.get(envmapUv, luma); | ||
| pdf = (luma * _rcpAvgLuma) * PostWarpT::backwardDensity(direction); | ||
| return envmapUv; | ||
| } | ||
|
|
||
| scalar_type deferredPdf(vector3_type direction) NBL_CONST_MEMBER_FUNC | ||
| { | ||
| vector2_type envmapUv = PostWarpT::inverseWarp(direction); | ||
| scalar_type luma; | ||
| _lumaMap.get(envmapUv, luma); | ||
| return luma * _rcpAvgLuma * PostWarpT::backwardDensity(direction); | ||
| } | ||
|
|
||
| vector3_type generate_and_pdf(NBL_REF_ARG(scalar_type) pdf, NBL_REF_ARG(vector2_type) uv, vector2_type xi) NBL_CONST_MEMBER_FUNC | ||
|
Comment on lines
+140
to
+157
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make it conform to #1001 's ResamplableSampler |
||
| { | ||
| const vector2_type texelCoord = xi * float32_t2(_lastWarpPixel); | ||
|
|
||
| matrix<scalar_type, 4, 2> uvs = _warpMap.sampleUvs(uint32_t2(texelCoord)); | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warpmap should convert you from [0,1] normalized xi to its own texels,the |
||
| const vector2_type interpolant = frac(texelCoord); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make the |
||
|
|
||
| const vector2_type xDiffs[] = { | ||
| uvs[2] - uvs[3], | ||
| uvs[1] - uvs[0] | ||
| }; | ||
| const vector2_type yVals[] = { | ||
| xDiffs[0] * interpolant.x + uvs[3], | ||
| xDiffs[1] * interpolant.x + uvs[0] | ||
| }; | ||
| const vector2_type yDiff = yVals[1] - yVals[0]; | ||
| uv = yDiff * interpolant.y + yVals[0]; | ||
|
|
||
| const WarpResult<vector3_type> warpResult = PostWarpT::warp(uv); | ||
|
|
||
| const scalar_type detInterpolJacobian = determinant(matrix<scalar_type, 2, 2>( | ||
| lerp(xDiffs[0], xDiffs[1], interpolant.y), // first column dFdx | ||
| yDiff // second column dFdy | ||
| )) * _lastWarpPixel.x * _lastWarpPixel.y; | ||
|
|
||
| pdf = abs(warpResult.density / detInterpolJacobian); | ||
|
|
||
| return warpResult.dst; | ||
| } | ||
| }; | ||
|
Comment on lines
+112
to
+187
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. separate file, also struct needs better name like WarpMap sampler |
||
|
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #ifndef _NBL_BUILTIN_HLSL_HIERARCHICAL_IMAGE_ACCESSORS_INCLUDED_ | ||
| #define _NBL_BUILTIN_HLSL_CONCEPTS_ACCESSORS_HIERARCHICAL_IMAGE_INCLUDED_ | ||
|
|
||
| #include "nbl/builtin/hlsl/concepts/accessors/generic_shared_data.hlsl" | ||
|
|
||
| namespace nbl | ||
| { | ||
| namespace hlsl | ||
| { | ||
| namespace sampling | ||
| { | ||
| namespace hierarchical_image | ||
| { | ||
| // declare concept | ||
| #define NBL_CONCEPT_NAME LuminanceReadAccessor | ||
| #define NBL_CONCEPT_TPLT_PRM_KINDS (typename)(typename) | ||
| #define NBL_CONCEPT_TPLT_PRM_NAMES (U)(ScalarT) | ||
| // not the greatest syntax but works | ||
| #define NBL_CONCEPT_PARAM_0 (a,U) | ||
| #define NBL_CONCEPT_PARAM_1 (coord,uint32_t2) | ||
| #define NBL_CONCEPT_PARAM_2 (level,uint32_t) | ||
| // start concept | ||
| NBL_CONCEPT_BEGIN(3) | ||
| // need to be defined AFTER the concept begins | ||
| #define a NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 | ||
| #define coord NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 | ||
| #define level NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 | ||
| NBL_CONCEPT_END( | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((a.template texelFetch(coord,level)) , ::nbl::hlsl::is_same_v, ScalarT)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((a.template texelGather(coord,level)) , ::nbl::hlsl::is_same_v, vector<ScalarT, 4>)) | ||
| ); | ||
| #undef level | ||
| #undef coord | ||
| #undef a | ||
| #include <nbl/builtin/hlsl/concepts/__end.hlsl> | ||
|
Comment on lines
+14
to
+35
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you merge latest path tracer branch, you can forego this concept in lieu of a LoadableImage with Components=1 and add a GatherableImage with all the other accessors , see #969 (comment) |
||
|
|
||
| // sampleUvs return 4 UVs in a square to calculate the jacobian matrix | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace "to calculate the jacobian matrix" with "for manual bilinear interpolation with differentiability" |
||
| // declare concept | ||
| #define NBL_CONCEPT_NAME HierarchicalSampler | ||
| #define NBL_CONCEPT_TPLT_PRM_KINDS (typename)(typename) | ||
| #define NBL_CONCEPT_TPLT_PRM_NAMES (HierarchicalSamplerT)(ScalarT) | ||
| // not the greatest syntax but works | ||
| #define NBL_CONCEPT_PARAM_0 (sampler,HierarchicalSamplerT) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sampler is a reserved keyword in HLSL |
||
| #define NBL_CONCEPT_PARAM_1 (coord,vector<uint32_t, 2>) | ||
| // start concept | ||
| NBL_CONCEPT_BEGIN(2) | ||
| // need to be defined AFTER the concept begins | ||
| #define sampler NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 | ||
| #define coord NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 | ||
| NBL_CONCEPT_END( | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sampler.template sampleUvs(coord)) , ::nbl::hlsl::is_same_v, matrix<ScalarT, 4, 2>)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. signature should be |
||
| ); | ||
| #undef sampler | ||
| #undef coord | ||
| #include <nbl/builtin/hlsl/concepts/__end.hlsl> | ||
|
|
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #ifndef _NBL_HLSL_SAMPLING_HIERARCHICAL_IMAGE_COMMON_INCLUDED_ | ||
| #define _NBL_HLSL_SAMPLING_HIERARCHICAL_IMAGE_COMMON_INCLUDED_ | ||
|
|
||
| #include "nbl/builtin/hlsl/cpp_compat.hlsl" | ||
|
|
||
| namespace nbl | ||
| { | ||
| namespace hlsl | ||
| { | ||
| namespace sampling | ||
| { | ||
| namespace hierarchical_image | ||
| { | ||
|
|
||
| struct SLumaGenPushConstants | ||
| { | ||
| float32_t3 lumaRGBCoefficients; | ||
| uint32_t2 lumaMapResolution; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can use |
||
| }; | ||
|
|
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| #include "common.hlsl" | ||
|
|
||
| using namespace nbl; | ||
| using namespace nbl::hlsl; | ||
| using namespace nbl::hlsl::sampling::hierarchical_image; | ||
|
|
||
| [[vk::push_constant]] SLumaGenPushConstants pc; | ||
|
|
||
| [[vk::binding(0, 0)]] Texture2D<float32_t4> envMap; | ||
| [[vk::binding(1, 0)]] RWTexture2D<float32_t> outImage; | ||
|
Comment on lines
+9
to
+10
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this assumes a 2D map and not a cubemap/layered thing, use layered images instead |
||
|
|
||
| [numthreads(WORKGROUP_DIM, WORKGROUP_DIM, 1)] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imho don't pass a define, and hardcode to 16x16 (but obviously leave a cosntexpr in a shared header so the c++ can be in-sync) |
||
| [shader("compute")] | ||
| void main(uint32_t3 threadID : SV_DispatchThreadID) | ||
| { | ||
| if (all(threadID < pc.lumaMapResolution)) | ||
| { | ||
|
|
||
| const float uv_y = (float(threadID.y) + float(0.5f)) / pc.lumaMapResolution.y; | ||
| const float32_t3 envMapSample = envMap.Load(float32_t3(threadID.xy, 0)); | ||
| const float32_t luma = hlsl::dot(envMapSample, pc.lumaRGBCoefficients) * sin(numbers::pi<float32_t> * uv_y); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this assumes a spherical warp
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. generalize |
||
|
|
||
| outImage[threadID.xy] = luma; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #include "nbl/builtin/hlsl/sampling/hierarchical_image.hlsl" | ||
|
|
||
| [[vk::binding(0, 0)]] Texture2D<float32_t> lumaMap; | ||
|
|
||
| [[vk::binding(1, 0)]] RWTexture2D<float32_t2> outImage; | ||
|
|
||
| using namespace nbl; | ||
| using namespace nbl::hlsl; | ||
| using namespace nbl::hlsl::sampling; | ||
|
|
||
| struct LuminanceAccessor | ||
| { | ||
| float32_t texelFetch(uint32_t2 coord, uint32_t level) | ||
| { | ||
| return lumaMap.Load(uint32_t3(coord, level)); | ||
| } | ||
|
|
||
| float32_t4 texelGather(uint32_t2 coord, uint32_t level) | ||
| { | ||
| return float32_t4( | ||
| lumaMap.Load(uint32_t3(coord, level), uint32_t2(0, 1)), | ||
| lumaMap.Load(uint32_t3(coord, level), uint32_t2(1, 1)), | ||
| lumaMap.Load(uint32_t3(coord, level), uint32_t2(1, 0)), | ||
| lumaMap.Load(uint32_t3(coord, level), uint32_t2(0, 0)) | ||
| ); | ||
|
Comment on lines
+20
to
+25
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw OOB reads using texelFetch are undefined, asser that |
||
|
|
||
| } | ||
| }; | ||
|
|
||
| [numthreads(WORKGROUP_DIM, WORKGROUP_DIM, 1)] | ||
| [shader("compute")] | ||
| void main(uint32_t3 threadID : SV_DispatchThreadID) | ||
| { | ||
| LuminanceAccessor luminanceAccessor; | ||
| uint32_t lumaMapWidth, lumaMapHeight; | ||
|
|
||
| lumaMap.GetDimensions(lumaMapWidth, lumaMapHeight); | ||
|
|
||
| using LuminanceSampler = LuminanceMapSampler<float32_t, LuminanceAccessor>; | ||
|
|
||
| LuminanceSampler luminanceSampler = | ||
| LuminanceSampler::create(luminanceAccessor, uint32_t2(lumaMapWidth, lumaMapHeight), lumaMapWidth != lumaMapHeight, uint32_t2(lumaMapWidth, lumaMapHeight)); | ||
|
Comment on lines
+41
to
+42
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we passing the |
||
|
|
||
| uint32_t2 pixelCoord = threadID.xy; | ||
|
|
||
| outImage[pixelCoord] = luminanceSampler.binarySearch(pixelCoord); | ||
|
|
||
|
Comment on lines
+44
to
+47
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you need to handle OOB, I can have a 4x4 sphere map, but my workgroup is 16x16 |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer an extension, dont need the option