Shadow mapping with wrong results (HLSL, Shader model 3.0) - visual-c++

(Sorry for my bad English.)
I'm new to Stack Overflow and writing a 3D game application with MS Visual C++ 2015 compiler, Direct3D 9 and HLSL(Shader model 3.0).
I've implemented a deferred rendering logic with 4 render target textures.
I stored depth values of pixels in a render target texture and created a shadow map. Here are the results. (All meshes have black color because the meshes have small size and close to the camera. The far plane distance value is 1000.0f.)
The depth texture and the shadow map.
I rendered a full screen quad with shadow mapping shaders and outputted shadows with red color to confirm the shader is working correctly.
But, It seems that the shaders output wrong results. The shadow map texture output repeats on the mesh surfaces.
https://www.youtube.com/watch?v=1URGgoCR6Zc
Here is the shadow mapping vertex shader to draw the quad.
struct VsInput {
float4 position : POSITION0;
};
struct VsOutput {
float4 position : POSITION0;
float4 cameraViewRay : TEXCOORD0;
};
float4x4 matInverseCameraViewProjection;
float4 cameraWorldPosition;
float farDistance;
VsOutput vs_main(VsInput input) {
VsOutput output = (VsOutput)0;
output.position = input.position;
output.cameraViewRay = mul(float4(input.position.xy, 1.0f, 1.0f) * farDistance, matInverseCameraViewProjection);
output.cameraViewRay /= output.cameraViewRay.w;
output.cameraViewRay.xyz -= cameraWorldPosition.xyz;
return output;
}
And here is the shadow mapping pixel shader to draw the quad.
struct PsInput {
float2 screenPosition : VPOS;
float4 viewRay : TEXCOORD0;
};
struct PsOutput {
float4 color : COLOR0;
};
texture depthMap;
texture shadowMap;
sampler depthMapSampler = sampler_state {
Texture = (depthMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
sampler shadowMapSampler = sampler_state {
Texture = (shadowMap);
AddressU = CLAMP;
AddressV = CLAMP;
MagFilter = POINT;
MinFilter = POINT;
MipFilter = POINT;
};
//float4x4 matCameraView;
float4x4 matLightView;
float4x4 matLightProjection;
float4 cameraWorldPosition;
float4 lightWorldPosition;
float2 halfPixel;
float epsilon;
float farDistance;
PsOutput ps_main(PsInput input) {
PsOutput output = (PsOutput)0;
output.color.a = 1.0f;
//Reconstruct the world position using the view-space linear depth value.
float2 textureUv = input.screenPosition * halfPixel * 2.0f - halfPixel;
float viewDepth = tex2D(depthMapSampler, textureUv).r;
float3 eye = input.viewRay.xyz * viewDepth;
float4 worldPosition = float4((eye + cameraWorldPosition.xyz), 1.0f);
//Test if the reconstructed world position has right coordinate values.
//output.color = mul(worldPosition, matCameraView).z / farDistance;
float4 positionInLightView = mul(worldPosition, matLightView);
float lightDepth = positionInLightView.z / farDistance;
float4 positionInLightProjection = mul(positionInLightView, matLightProjection);
positionInLightProjection /= positionInLightProjection.w;
//If-statement doesn't work???
float condition = positionInLightProjection.x >= -1.0f;
condition *= positionInLightProjection.x <= 1.0f;
condition *= positionInLightProjection.y >= -1.0f;
condition *= positionInLightProjection.y <= 1.0f;
condition *= positionInLightProjection.z >= 0.0f;
condition *= positionInLightProjection.z <= 1.0f;
condition *= positionInLightProjection.w > 0.0f;
float2 shadowMapUv = float2(
positionInLightProjection.x * 0.5f + 0.5f,
-positionInLightProjection.y * 0.5f + 0.5f
);
//If-statement doesn't work???
float condition2 = shadowMapUv.x >= 0.0f;
condition2 *= shadowMapUv.x <= 1.0f;
condition2 *= shadowMapUv.y >= 0.0f;
condition2 *= shadowMapUv.y <= 1.0f;
float viewDepthInShadowMap = tex2D(
shadowMapSampler,
shadowMapUv
).r;
output.color.r = lightDepth > viewDepthInShadowMap + epsilon;
output.color.r *= condition;
output.color.r *= condition2;
return output;
}
It seems that the uv for the shadow map has some wrong values, but i can't figure out what's the real problem.
Many thanks for any help.
EDIT : I've updated the shader codes. I decided to use view-space linear depth and confirmed that the world position has right value. I really don't understand why the shadow map coordinate values have wrong values...

It really looks like you are using a wrong bias. Google up "Shadow Acne" and you should find your answer to your problem. Also the resolution of the shadowmap could be a problem.

I found the solution.
The first problem was that the render target texture had wrong texture format. I should have used D3DFMT_R32F. (I had used D3DFMT_A8R8G8B8.)
And i added these lines in my shadow mapping pixel shader.
//Reconstruct the world position using the view-space linear depth value.
float2 textureUv = input.screenPosition * halfPixel * 2.0f - halfPixel;
float4 viewPosition = float4(input.viewRay.xyz * tex2D(depthMapSampler, textureUv).r, 1.0f);
float4 worldPosition = mul(viewPosition, matInverseCameraView);
...
//If-statement doesn't work???
float condition = positionInLightProjection.x >= -1.0f;
condition *= positionInLightProjection.x <= 1.0f;
condition *= positionInLightProjection.y >= -1.0f;
condition *= positionInLightProjection.y <= 1.0f;
condition *= positionInLightProjection.z >= 0.0f;
condition *= positionInLightProjection.z <= 1.0f;
condition *= viewPosition.z < farDistance;
The last line was the key and solved my second problem. The 'farDistance' is the far plane distance of the camera frustum. I'm still trying to understand why that is needed.

You can use saturate to clamp the positionInLightProjection and compare it against the unsaturated variable. This way you can verify that positionInLightProjection is within 0..1.
if ((saturate(positionInLightProjection.x) == positionInLightProjection.x) && (saturate(positionInLightProjection.y) == positionInLightProjection.y)) {
// we are in the view of light
// todo: compare depth values from shadow map and current scene depth
} else {
// this is shadow for sure!
}

Related

How to implement linear interpolation when stretching a texture in HLSL?

This is the pixel shader code:
sampler s0 : register(s0);
float4 main(float2 tex : TEXCOORD0) : COLOR
{
tex.x=tex.x/8 +0.25;
float4 l = tex2D(s0, tex);
return l;
}
When running the above code I get the following:
I tried changing the sampler state filter without success:
sampler s0 : register(s0) = sampler_state
{
Texture = (s0);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
I tried cubic filtering but is very expensive:
sampler s0;
float c0;
float c1;
#define sp(a, b) float4 a = tex2D(s0, float2(coord + b * fx * c1.x, tex.y));
float4 main(float2 tex : TEXCOORD0) : COLOR
{
float coord = (tex.x/2)*c0; // assign the output position, normalized to texture width in pixels
float t = frac(coord); // calculate the difference between the output pixel and the original surrounding two pixels
// adjust sampling matrix to put the output pixel on Q2+.25
float fx;
if(t > .5) {
coord = (coord-t+1.5)*c1; fx = -1;
} else {
coord = (coord-t+0.5)*c1; fx = 1;
}
sp(P0, -2)
sp(P1, -1)
sp(P2, 0)
sp(P3, 1)
sp(P4, 2) // original pixels
return (P0 + P2*216 + P3*66 - P1*18 - P4*9)/256; // output interpolated value
}
Thanks.
Most likely you need to specify 'MipFilter = LINEAR' in your sampler desc, and you need to make sure you are supplying a texture with mipmaps...

Is there a faked antialiasing algorithm using the depth buffer?

Lately I implemented the FXAA algorithm into my OpenGL application. I haven't understand this algorithm completely by now but I know that it uses contrast data of the final image to selectively apply blurring. As a post processing effect that makes sense. B since I use deferred shading in my application I already have a depth texture of the scene. Using that it might be much easier and more precise to find edges for applying blur there.
So is there a known antialiasing algorithm using the depth texture instead of the final image to find the edges? By fakes I mean an antialiasing algorithm based on a pixel basis instead of a vertex basis.
After some research I found out that my idea is widely used already in deferred renderers. I decided to post this answer because I came up with my own implementation which I want to share with the community.
Based on the gradient changes of the depth and the angle changes of the normals, there is blurring applied to the pixel.
// GLSL fragment shader
#version 330
in vec2 coord;
out vec4 image;
uniform sampler2D image_tex;
uniform sampler2D position_tex;
uniform sampler2D normal_tex;
uniform vec2 frameBufSize;
void depth(out float value, in vec2 offset)
{
value = texture2D(position_tex, coord + offset / frameBufSize).z / 1000.0f;
}
void normal(out vec3 value, in vec2 offset)
{
value = texture2D(normal_tex, coord + offset / frameBufSize).xyz;
}
void main()
{
// depth
float dc, dn, ds, de, dw;
depth(dc, vec2( 0, 0));
depth(dn, vec2( 0, +1));
depth(ds, vec2( 0, -1));
depth(de, vec2(+1, 0));
depth(dw, vec2(-1, 0));
float dvertical = abs(dc - ((dn + ds) / 2));
float dhorizontal = abs(dc - ((de + dw) / 2));
float damount = 1000 * (dvertical + dhorizontal);
// normals
vec3 nc, nn, ns, ne, nw;
normal(nc, vec2( 0, 0));
normal(nn, vec2( 0, +1));
normal(ns, vec2( 0, -1));
normal(ne, vec2(+1, 0));
normal(nw, vec2(-1, 0));
float nvertical = dot(vec3(1), abs(nc - ((nn + ns) / 2.0)));
float nhorizontal = dot(vec3(1), abs(nc - ((ne + nw) / 2.0)));
float namount = 50 * (nvertical + nhorizontal);
// blur
const int radius = 1;
vec3 blur = vec3(0);
int n = 0;
for(float u = -radius; u <= +radius; ++u)
for(float v = -radius; v <= +radius; ++v)
{
blur += texture2D(image_tex, coord + vec2(u, v) / frameBufSize).rgb;
n++;
}
blur /= n;
// result
float amount = mix(damount, namount, 0.5);
vec3 color = texture2D(image_tex, coord).rgb;
image = vec4(mix(color, blur, min(amount, 0.75)), 1.0);
}
For comparison, this is the scene without any anti-aliasing.
This is the result with anti-aliasing applied.
You may need to view the images at their full resolution to judge the effect. In my view the result is adequate for the simple implementation. The best thing is that there are nearly no jagged artifacts when the camera moves.

OpenGL Shadow Volume Difference On Debian and Win7,Ubuntu

In windows7 with latest opengl and in Ubuntu 12.04 with freeglut3 app, I can draw shadows correctly by using shadow volume method. However, when I run my code on an older version of Debian GNU/Linux 6.0.6, shadows do not be drawn correctly and unfortunately I am supposed to draw these shadows :(
I think I have culling problem because when I draw colored shadow volume I can see the volume correctly. However, culling of front and back faces of volume create a problem and shadow could not be drawn. I see nothing about shadows.
Here is my casting shadow code:
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_STENCIL_TEST);
glColorMask(0, 0, 0, 0);
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
// first pass, stencil operation decreases stencil value
glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
for (int i = 0; i < triangles.size(); ++i)
if (triangles[i]->visible)
for (int j = 0; j < 3; ++j)
{
Triangle *k = triangles[i]->neigh[j];
if ((k == NULL) || (!k->visible))
{
// here we have an edge, we must draw a polygon
p1 = triangles[i]->p[j];
p2 = triangles[i]->p[(j+1)%3];
//calculate the length of the vector
v1.x = (p1.x - wlp[0])*100;
v1.y = (p1.y - wlp[1])*100;
v1.z = (p1.z - wlp[2])*100;
v2.x = (p2.x - wlp[0])*100;
v2.y = (p2.y - wlp[1])*100;
v2.z = (p2.z - wlp[2])*100;
//draw the polygon
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p1.x + v1.x, p1.y + v1.y, p1.z + v1.z);
glVertex3f(p2.x, p2.y, p2.z);
glVertex3f(p2.x + v2.x, p2.y + v2.y, p2.z + v2.z);
glEnd();
}
}
// second pass, stencil operation increases stencil value
glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
for (int i = 0; i < triangles.size(); ++i)
if (triangles[i]->visible)
for (int j = 0; j < 3; ++j)
{
Triangle *k = triangles[i]->neigh[j];
if ((k == NULL) || (!k->visible))
{
// here we have an edge, we must draw a polygon
p1 = triangles[i]->p[j];
p2 = triangles[i]->p[(j+1)%3];
//calculate the length of the vector
v1.x = (p1.x - wlp[0])*100;
v1.y = (p1.y - wlp[1])*100;
v1.z = (p1.z - wlp[2])*100;
v2.x = (p2.x - wlp[0])*100;
v2.y = (p2.y - wlp[1])*100;
v2.z = (p2.z - wlp[2])*100;
//draw the polygon
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p1.x + v1.x, p1.y + v1.y, p1.z + v1.z);
glVertex3f(p2.x, p2.y, p2.z);
glVertex3f(p2.x + v2.x, p2.y + v2.y, p2.z + v2.z);
glEnd();
}
}
glFrontFace(GL_CCW);
glColorMask(1, 1, 1, 1);
//draw a shadowing rectangle covering the entire screen
glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glLoadIdentity();
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-1, 1,-1);
glVertex3f(-1,-1,-1);
glVertex3f( 1, 1,-1);
glVertex3f( 1,-1,-1);
glEnd();
glPopMatrix();
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
glDisable(GL_STENCIL_TEST);
glShadeModel(GL_SMOOTH);
glPopMatrix();
and here is my initialization:
glEnable(GL_DEPTH_TEST); // Enable depth Buffering
glEnable(GL_COLOR_MATERIAL); // Enable color tracking
glEnable(GL_NORMALIZE); // Enables vector normalization (optional)
glClearColor( 0.4f, 0.4f, 0.8f, 1.0f ); // Set initial value of color buffer (Set background color also)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glDepthFunc(GL_LEQUAL);
// Lighting initialization
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT1, GL_POSITION , light.position); //Set position.
glLightfv(GL_LIGHT1, GL_AMBIENT , light.ambient); //Set ambient light.
glLightfv(GL_LIGHT1, GL_DIFFUSE , light.diffuse); //Set diffuse component.
glLightfv(GL_LIGHT1, GL_SPECULAR , light.specular); //Set specular component.
glEnable(GL_LIGHT1);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat.ambient); // Set Material Ambience
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat.diffuse); // Set Material Diffuse
glMaterialfv(GL_FRONT, GL_SPECULAR, mat.specular); // Set Material Specular
glCullFace(GL_BACK); // Set Culling Face To Back Face
glEnable(GL_CULL_FACE); // Enable Culling
glClearColor(0.1f, 1.0f, 0.5f, 1.0f); // Set Clear Color (Greenish Color)
// Initialize camera
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
glLoadIdentity(); // Clear current matrix to identity matrix
gluPerspective(80, 1 , 0.5 , 1000000); // Set projection of camera (You can modify the arguments if needed.)
glMatrixMode(GL_MODELVIEW);
Make sure the mode you pass to glutInitDisplayMode() includes GLUT_STENCIL, otherwise you may not get a stencil buffer.

DirectX 11: text output, using your own font texture

I'm learning DirectX, using the book "Sherrod A., Jones W. - Beginning DirectX 11 Game Programming - 2011" Now I'm exploring the 4th chapter about drawing text.
Please, help we to fix my function, that I'm using to draw a string on the screen. I've already loaded font texture and in the function I create some sprites with letters and define texture coordinates for them. This compiles correctly, but doesn't draw anything. What's wrong?
bool DirectXSpriteGame :: DrawString(char* StringToDraw, float StartX, float StartY)
{
//VAR
HRESULT D3DResult; //The result of D3D functions
int i; //Counters
const int IndexA = static_cast<char>('A'); //ASCII index of letter A
const int IndexZ = static_cast<char>('Z'); //ASCII index of letter Z
int StringLenth = strlen(StringToDraw); //Lenth of drawing string
float ScreenCharWidth = static_cast<float>(LETTER_WIDTH) / static_cast<float>(SCREEN_WIDTH); //Width of the single char on the screen(in %)
float ScreenCharHeight = static_cast<float>(LETTER_HEIGHT) / static_cast<float>(SCREEN_HEIGHT); //Height of the single char on the screen(in %)
float TexelCharWidth = 1.0f / static_cast<float>(LETTERS_NUM); //Width of the char texel(in the texture %)
float ThisStartX; //The start x of the current letter, drawingh
float ThisStartY; //The start y of the current letter, drawingh
float ThisEndX; //The end x of the current letter, drawing
float ThisEndY; //The end y of the current letter, drawing
int LetterNum; //Letter number in the loaded font
int ThisLetter; //The current letter
D3D11_MAPPED_SUBRESOURCE MapResource; //Map resource
VertexPos* ThisSprite; //Vertecies of the current sprite, drawing
//VAR
//Clamping string, if too long
if(StringLenth > LETTERS_NUM)
{
StringLenth = LETTERS_NUM;
}
//Mapping resource
D3DResult = _DeviceContext -> Map(_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MapResource);
if(FAILED(D3DResult))
{
throw("Failed to map resource");
}
ThisSprite = (VertexPos*)MapResource.pData;
for(i = 0; i < StringLenth; i++)
{
//Creating geometry for the letter sprite
ThisStartX = StartX + ScreenCharWidth * static_cast<float>(i);
ThisStartY = StartY;
ThisEndX = ThisStartX + ScreenCharWidth;
ThisEndY = StartY + ScreenCharHeight;
ThisSprite[0].Position = XMFLOAT3(ThisEndX, ThisEndY, 1.0f);
ThisSprite[1].Position = XMFLOAT3(ThisEndX, ThisStartY, 1.0f);
ThisSprite[2].Position = XMFLOAT3(ThisStartX, ThisStartY, 1.0f);
ThisSprite[3].Position = XMFLOAT3(ThisStartX, ThisStartY, 1.0f);
ThisSprite[4].Position = XMFLOAT3(ThisStartX, ThisEndY, 1.0f);
ThisSprite[5].Position = XMFLOAT3(ThisEndX, ThisEndY, 1.0f);
ThisLetter = static_cast<char>(StringToDraw[i]);
//Defining the letter place(number) in the font
if(ThisLetter < IndexA || ThisLetter > IndexZ)
{
//Invalid character, the last character in the font, loaded
LetterNum = IndexZ - IndexA + 1;
}
else
{
LetterNum = ThisLetter - IndexA;
}
//Unwraping texture on the geometry
ThisStartX = TexelCharWidth * static_cast<float>(LetterNum);
ThisStartY = 0.0f;
ThisEndY = 1.0f;
ThisEndX = ThisStartX + TexelCharWidth;
ThisSprite[0].TextureCoords = XMFLOAT2(ThisEndX, ThisEndY);
ThisSprite[1].TextureCoords = XMFLOAT2(ThisEndX, ThisStartY);
ThisSprite[2].TextureCoords = XMFLOAT2(ThisStartX, ThisStartY);
ThisSprite[3].TextureCoords = XMFLOAT2(ThisStartX, ThisStartY);
ThisSprite[4].TextureCoords = XMFLOAT2(ThisStartX, ThisEndY);
ThisSprite[5].TextureCoords = XMFLOAT2(ThisEndX, ThisEndY);
ThisSprite += VERTEX_IN_RECT_NUM;
}
for(i = 0; i < StringLenth; i++, ThisSprite -= VERTEX_IN_RECT_NUM);
_DeviceContext -> Unmap(_vertexBuffer, 0);
_DeviceContext -> Draw(VERTEX_IN_RECT_NUM * StringLenth, 0);
return true;
}
Although the piece of code constructing the Vertex Array seems correct to me at first glance, it seems like you are trying to Draw your vertices with a Shader which has not been set yet !
It is difficult to precisely answer you without looking at the whole code, but I can guess that you will need to do something like that :
1) Create Vertex and Pixel Shaders by compiling them first from their respective buffers
2) Create the Input Layout description, which describes the Input Buffers that will be read by the Input Assembler stage. It will have to match your VertexPos structure and your shader structure.
3) Set the Shader parameters.
4) Only now you can Set Shader rendering parameters : Set the InputLayout, as well as the Vertex and Pixel Shaders that will be used to render your triangles by something like :
_DeviceContext -> Unmap(_vertexBuffer, 0);
_DeviceContext->IASetInputLayout(myInputLayout);
_DeviceContext->VSSetShader(myVertexShader, NULL, 0); // Set Vertex shader
_DeviceContext->PSSetShader(myPixelShader, NULL, 0); // Set Pixel shader
_DeviceContext -> Draw(VERTEX_IN_RECT_NUM * StringLenth, 0);
This link should help you achieve what you want to do : http://www.rastertek.com/dx11tut12.html
Also, I recommend you to set an IndexBuffer and to use the method DrawIndexed to render your triangles for performance reasons : It will allow the graphics adapter to store vertices in a vertex cache, allowing recently-used vertex to be fetched from the cache instead of reading it from the vertex buffer.
More about this concern can be found on MSDN : http://msdn.microsoft.com/en-us/library/windows/desktop/bb147325(v=vs.85).aspx
Hope this helps!
P.S : Also, don't forget to release the resources after using them by calling Release().

Help to understand Pixelate effect

I'm new a HLSL and I'm trying to understand a pixelate sample. However, I haven't been able to find a reference about how a couple of operations are. Here is the shader example:
//--------------------------------------------------------------------------------------
//
// WPF ShaderEffect HLSL -- PixelateEffect
//
//--------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
// Shader constant register mappings (scalars - float, double, Point, Color, Point3D, etc.)
//-----------------------------------------------------------------------------------------
float HorizontalPixelCounts : register(C0);
float VerticalPixelCounts : register(C1);
//--------------------------------------------------------------------------------------
// Sampler Inputs (Brushes, including ImplicitInput)
//--------------------------------------------------------------------------------------
sampler2D implicitInputSampler : register(S0);
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(float2 uv : TEXCOORD) : COLOR
{
float2 brickCounts = { HorizontalPixelCounts, VerticalPixelCounts };
float2 brickSize = 1.0 / brickCounts;
// Offset every other row of bricks
float2 offsetuv = uv;
bool oddRow = floor(offsetuv.y / brickSize.y) % 2.0 >= 1.0;
if (oddRow)
{
offsetuv.x += brickSize.x / 2.0;
}
float2 brickNum = floor(offsetuv / brickSize);
float2 centerOfBrick = brickNum * brickSize + brickSize / 2;
float4 color = tex2D(implicitInputSampler, centerOfBrick);
return color;
}
I haven't been able to understand what computation is happening in:
float2 brickNum = floor(offsetuv / brickSize);
I'm not sure what how to compute the division between the two vectors, and also I don't know how to compute the floor of a vector. (I'm assuming that division of two float2 returns a float2).
Any idea?
HLSL operators and functions often work with structures like float2 which has an x and y.
The division inside the floor returns a float2 where the x and y are the result of dividing the x with x and y with y. And floor will return a float2 where the x and y of the result are the floored value of the x and y of the input (the result of the division).
The same is true for float3 and other similar structures.

Resources