0
$\begingroup$

I have an 8192x8192 texture atlas that contains 1024x1024 shadow maps aligned side by side. I'm trying to calculate the uv coordinates so that I can sample each shadow map appropriately based on the 'shadowIndex' of my light. With a single non-atlas shadowmap I can easily calculate the uv coordinates like this:

tc.x = lightViewPosition.x / lightViewPosition.w / 2.0f + 0.5f;
tc.y = -lightViewPosition.y / lightViewPosition.w / 2.0f + 0.5f;

shadowFactor += shadowMap.SampleCmpLevelZero(SampleComp, tc, lightDepthValue);

How can I replicate the same thing while also factoring in an offset for sampling the correct shadow map from the atlas? I tried this:

tc.x = lightViewPosition.x / lightViewPosition.w / 2.0f + 0.5f;
tc.y = -lightViewPosition.y / lightViewPosition.w / 2.0f + 0.5f;

float tileSize = 1024.0f / 8.0f;
float tileOffset = tileSize * lights[i].shadowIndex;

tc += frac((tc - tileOffset) / tileSize) * tileSize + tileOffset;

But this does not work correctly. Additionally I have to consider that the y (V) coordinate should not be affected while the shadow index isn't a multiple of 8 because there are 8 shadow maps per row. Any ideas? Thanks.

$\endgroup$
5
  • $\begingroup$ 8192x8192? This would be 16 shadow maps but the text says side by side, could you please clarify? $\endgroup$
    – pmw1234
    Oct 5 '21 at 14:39
  • $\begingroup$ @pmw1234 They are aligned side by side in each row is what I meant. If there was more than 8 then the subsequent shadowmaps will be put on the next row $\endgroup$
    – H3XXX
    Oct 5 '21 at 15:31
  • $\begingroup$ shouldn't tile size be 8192/8 ? (or just plain 1024) $\endgroup$
    – pmw1234
    Oct 5 '21 at 15:48
  • $\begingroup$ Also, is this code working with normalized texture coordinates or unnormalized texture coordinates? $\endgroup$
    – pmw1234
    Oct 5 '21 at 15:55
  • $\begingroup$ @pmw1234 The textures coordinates are normalized $\endgroup$
    – H3XXX
    Oct 5 '21 at 16:10
1
$\begingroup$

Assuming normalized texture coordinates and a grid of 8x8 (which is 64 tiles not 16 like I said in the comments) then tileOffset will need to be a vec2 for the x and y offsets.

Also, assuming texture coordinates tc are mapped to a single texture map (0,1).

Then the new texture coordinates for tile 0,0 are tc = (tc*vec2(1024,1024))/vec2(8192,8192); For tile 1 the texture coordinates would added 1024/8192 to the tc.x, tile two would add 2048/8192 to tc.x and so forth up to tile 8.

tc.y doesn't change till tile 8 which then gets 1024/8192 added to it until tile 16 and so forth.

So the tile specific texture coords would be

tc = (tc*vec2(1024,1024))/vec2(8192,8192);
tc.x += ((lights[i].shadowIndex % 8) * 1024)/8192.0;
tc.y += ((lights[i].shadowIndex / 8) * 1024)/8192.0;

Where the %8 and /8 are indicating integer modulus and division. This is just psudo code and I was using the upper left corner as 0,0 but the idea is the same for other origins.

Edit: The code is converting normalized coordinates to unnormalized coordinates for a texture map size of 1024x1024. Then converting that to normalized coordinates for a texture maps size of 8192x8192.

Then it computes the normalized offsets for x and y and adds them to get the grid specific location.

$\endgroup$
3
  • $\begingroup$ Thanks for your answer. This seems to work but only for the shadowmap that is at index 0, a light with a shadowmap index of 1 for example will not produce correct shadows until it's index becomes 0 (for example if the first light is deleted). I'll accept your answer anyway maybe I'll figure it out. $\endgroup$
    – H3XXX
    Oct 5 '21 at 16:56
  • $\begingroup$ Changing the code to tc.y += (0 * 1024.0) / 8192.0; has fixed it, looks like some kind of issue with the tiling in the 'y' direction $\endgroup$
    – H3XXX
    Oct 5 '21 at 17:13
  • 1
    $\begingroup$ The bit of code (lights[i].shadowIndex / 8) might be computing a floating point value instead of an integer value which would give an incorrect result by scewing everything by some small floating point offset. $\endgroup$
    – pmw1234
    Oct 5 '21 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.