@@ -124,6 +124,20 @@ size_t Froxelizer::getFroxelBufferByteCount(FEngine::DriverApi& driverApi) noexc
124124 return std::min (FROXEL_BUFFER_MAX_ENTRY_COUNT * sizeof (FroxelEntry), targetSize);
125125}
126126
127+ View::FroxelConfigurationInfo Froxelizer::getFroxelConfigurationInfo () const noexcept {
128+ return { uint8_t (getFroxelCountX ()),
129+ uint8_t (getFroxelCountY ()),
130+ uint8_t (getFroxelCountZ ()),
131+ mViewport .width ,
132+ mViewport .height ,
133+ mFroxelDimension ,
134+ mZLightFar ,
135+ mLinearizer [0 ],
136+ mProjection ,
137+ mClipTransform
138+ };
139+ }
140+
127141Froxelizer::Froxelizer (FEngine& engine)
128142 : mArena (" froxel" , PER_FROXELDATA_ARENA_SIZE),
129143 mZLightNear (FROXEL_FIRST_SLICE_DEPTH),
@@ -198,10 +212,14 @@ void Froxelizer::setProjection(const mat4f& projection,
198212bool Froxelizer::prepare (
199213 FEngine::DriverApi& driverApi, RootArenaScope& rootArenaScope,
200214 filament::Viewport const & viewport,
201- const mat4f& projection, float const projectionNear, float const projectionFar) noexcept {
215+ const mat4f& projection, float const projectionNear, float const projectionFar,
216+ float4 const & clipTransform) noexcept {
202217 setViewport (viewport);
203218 setProjection (projection, projectionNear, projectionFar);
204219
220+ // Only for debugging
221+ mClipTransform = clipTransform;
222+
205223 bool uniformsNeedUpdating = false ;
206224 if (UTILS_UNLIKELY (mDirtyFlags )) {
207225 uniformsNeedUpdating = update ();
@@ -361,8 +379,10 @@ bool Froxelizer::update() noexcept {
361379 getFroxelBufferEntryCount (), viewport);
362380
363381 mFroxelDimension = froxelDimension;
364- mClipToFroxelX = (0 .5f * float (viewport.width )) / float (froxelDimension.x );
365- mClipToFroxelY = (0 .5f * float (viewport.height )) / float (froxelDimension.y );
382+ // note: because froxelDimension is a power-of-two and viewport is an integer, mClipFroxel
383+ // is an exact value (which is not true for 1/mClipToFroxelX, btw)
384+ mClipToFroxelX = float (viewport.width ) / float (2 * froxelDimension.x );
385+ mClipToFroxelY = float (viewport.height ) / float (2 * froxelDimension.y );
366386
367387 uniformsNeedUpdating = true ;
368388
@@ -408,8 +428,7 @@ bool Froxelizer::update() noexcept {
408428 }
409429
410430 // for the inverse-transformation (view-space z to z-slice)
411- mLinearizer = 1 .0f / linearizer;
412- mZLightFar = zLightFar;
431+ mLinearizer = { linearizer, 1 .0f / linearizer };
413432
414433 mParamsZ [0 ] = 0 ; // updated when camera changes
415434 mParamsZ [1 ] = 0 ; // updated when camera changes
@@ -466,7 +485,7 @@ bool Froxelizer::update() noexcept {
466485 // ==> i = log2(z_screen * (far/near)) * (-1/linearizer) + zcount
467486 mParamsZ [0 ] = mZLightFar / Pw;
468487 mParamsZ [1 ] = 0 .0f ;
469- mParamsZ [2 ] = -mLinearizer ;
488+ mParamsZ [2 ] = -mLinearizer [ 1 ] ;
470489 } else {
471490 // orthographic projection
472491 // z_view = (1 - z_screen) * (near - far) - near
@@ -476,7 +495,7 @@ bool Froxelizer::update() noexcept {
476495 // Pw = far / (far - near)
477496 mParamsZ [0 ] = -1 .0f / (Pz * mZLightFar ); // -(far-near) / mZLightFar
478497 mParamsZ [1 ] = Pw / (Pz * mZLightFar ); // far / mZLightFar
479- mParamsZ [2 ] = mLinearizer ;
498+ mParamsZ [2 ] = mLinearizer [ 1 ] ;
480499 }
481500 uniformsNeedUpdating = true ;
482501 }
@@ -507,7 +526,7 @@ size_t Froxelizer::findSliceZ(float const z) const noexcept {
507526
508527 // This whole function is now branch-less.
509528
510- int s = int ( fast::log2 (-z / mZLightFar ) * mLinearizer + float (mFroxelCountZ ) );
529+ int s = int ( fast::log2 (-z / mZLightFar ) * mLinearizer [ 1 ] + float (mFroxelCountZ ) );
511530
512531 // there are cases where z can be negative here, e.g.:
513532 // - the light is visible, but its center is behind the camera
0 commit comments