Texture Tile in Shader

I turn to the vertex shader texture (glsl) 2: from the screen and less, normalmap. Normal map scales to screen size. Therefore, if the first texture is 1152Γ—864 pixels, and the normal map is 256Γ—256 , it will be reduced from size to larger.

How can I make it tiled? For instance. make it 256Γ—256 and cut through the whole texture.


UPD

For example, my main (large) texture is displayed as follows:

 [0.17, 0.61, 0.33, 0.83] 

Instead:

 [0, 0, 1, 1] 

Thus, my normal texture is also displayed for the first coordinates. Therefore, I see a small rectangle with a display. How can I display it in a shader for full size?

+4
source share
1 answer

it will scale from it to a larger size.

No, it certainly will not. This is a common misunderstanding regarding textures. Textures are nothing more than fancy lookup tables. Textures do not β€œscale” relative to each other; it's just a matter of what texture coordinates you use.

In all likelihood, what you are doing uses the same texture coordinate for the screen texture as your normal map. Since we are most likely talking about normalized texture coordinates, this means that you are matching the same range [0, 1] with both of them.

To get the effect you're talking about, you need to calculate the texture coordinates for your regular texture, which do what you need. Therefore, if you have a texture coordinate related to the screen texture, you must convert it to the space you want in for a normal texture.

There are several ways to do this. The manual way is to calculate the ratio of texture sizes to each other in the CPU, and then transfer it to the shader. Using the numbers you indicated, the aspect ratio will be:

 (1152.0/256.0, 864.0/256.0) = (4.5, 3.375). 

Make sure this is done in floating point math. Having done this, just pass it in a uniform and multiply the coordinates of the texture by this ratio in the shader before fetching:

 uniform vec2 textureRatio; void main() { //Get the texture coordinate. vec4 screenTexColor = texture(screenTex, texCoord); vec2 normTexCoord = textureRatio * texCoord; vec4 normalValue = texture(normalTex, normTexCoord); //Do something with these. } 

The automatic way in GLSL is to do this directly in the shader. This requires GLSL 1.30 or higher. Basically, you use the available language functions to calculate the relationship:

 void main() { //Get the texture coordinate. vec2 textureRatio = textureSize(screenTex) / textureSize(normalTex); vec4 screenTexColor = texture(screenTex, texCoord); vec2 normTexCoord = textureRatio * texCoord; vec4 normalValue = texture(normalTex, normTexCoord); //Do something with these. } 

In both cases, I assume that your GL_TEXTURE_WRAP_S / T is set to GL_REPEAT with the appropriate texture or sampler parameters.

Remember that calculating the relation to the processor and transferring it as homogeneous is likely to be faster than calculating it in the shader. Especially for flash shaders that will run a lot.

+6
source

All Articles