<p>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.</p>
<p>Also, assuming texture coordinates tc are mapped to a single texture map (0,1).</p>
<p>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.</p>
<p>tc.y doesn't change till tile 8 which then gets 1024/8192 added to it until tile 16 and so forth.</p>
<p>So the tile specific texture coords would be</p>
<pre><code>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;
</code></pre>
<p>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.</p>
<p>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.</p>
<p>Then it computes the normalized offsets for x and y and adds them to get the grid specific location.</p>

CC BY-SA 4.0
2021-10-05T17:13:03.930Z
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
H3XXX
CC BY-SA 4.0
2021-10-05T17:32:30.377Z
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.
pmw1234
CC BY-SA 4.0
2021-10-05T16:14:53.817Z
2021-10-05T16:20:14.347Z
2021-10-05T16:20:14.347Z
pmw1234
<p>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:</p>
<pre><code>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);
</code></pre>
<p>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:</p>
<pre><code>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;
</code></pre>
<p>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.</p>

CC BY-SA 4.0
2021-10-05T14:39:09.653Z
8192x8192? This would be 16 shadow maps but the text says side by side, could you please clarify?
pmw1234
CC BY-SA 4.0
2021-10-05T15:31:52.803Z
@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
H3XXX
CC BY-SA 4.0
2021-10-05T15:48:55.040Z
shouldn't tile size be 8192/8 ? (or just plain 1024)
pmw1234
CC BY-SA 4.0
2021-10-05T15:55:04.507Z
Also, is this code working with normalized texture coordinates or unnormalized texture coordinates?
pmw1234
CC BY-SA 4.0
2021-10-05T16:10:31.043Z
@pmw1234 The textures coordinates are normalized
H3XXX
<3d><hlsl><uv-mapping><directx>
Calculating UV coordinates for sampling texture atlas
H3XXX
# Calculating UV coordinates for sampling texture atlas

(Asked by: username_0 on 2021-10-05)

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.

**Tags:** 3d, hlsl, uv-mapping, directx

> **Comments:**
> **username_1**: 8192x8192? This would be 16 shadow maps but the text says side by side, could you please clarify?  
> **username_0**: @username_1 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  
> **username_1**: shouldn't tile size be 8192/8 ? (or just plain 1024)  
> **username_1**: Also, is this code working with normalized texture coordinates or unnormalized texture coordinates?  
> **username_0**: @username_1 The textures coordinates are normalized  

---

## 1 answers

### Answer by username_1 on 2021-10-05. Score: 1 | Accepted answer

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.

> **Comments:**
> **username_0**: 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  
> **username_1**: 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.  

---

