在着色器中的平铺纹理

Max*_*rai 5 shader textures glsl

我传递给顶点着色器(glsl)2纹理:从屏幕和较小的法线贴图.Normalmap按屏幕大小缩放.因此,如果第一个纹理是1152×864像素而法线贴图是256×256,那么它将从它的大小缩放到更大.

我怎样才能平铺?例如,将其大小设置为256×256并覆盖所有纹理.


UPD:

例如,我的主(大)纹理映射如下:

[0.17, 0.61, 0.33, 0.83]
Run Code Online (Sandbox Code Playgroud)

代替:

[0, 0, 1, 1]
Run Code Online (Sandbox Code Playgroud)

这样我的普通纹理也会映射到第一个坐标.所以我看到了一个小的映射矩形.如何在着色器中将其映射为完整尺寸?

Nic*_*las 6

它将从它的大小缩放到更大.

不,它肯定不会.这是对纹理的常见误解.纹理只不过是花哨的查找表.纹理不是相对于彼此"缩放"的; 它只是你使用什么纹理坐标的问题.

很有可能,你正在做的是使用与普通地图相同的纹理坐标作为屏幕纹理.由于我们可能正在讨论规范化纹理坐标,这意味着您将相同的[0,1]范围映射到它们两者.

要获得您正在谈论的效果,您需要为正常纹理计算纹理坐标,以满足您的需要.因此,如果您具有相对于屏幕纹理的纹理坐标,则必须将其转换为所需的空间以用于普通纹理.

有几种方法可以做到这一点.手动方式是在CPU上计算纹理大小的比例,然后将其传递给着色器.使用您给出的数字,大小比率为:

(1152.0/256.0, 864.0/256.0) = (4.5, 3.375).
Run Code Online (Sandbox Code Playgroud)

确保这是在浮点数学中完成的.完成后,只需将其沿均匀传递并在采样前将着色器中的纹理坐标乘以此比率:

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.
}
Run Code Online (Sandbox Code Playgroud)

GLSL中的自动方式是直接在着色器中执行此操作.这需要GLSL 1.30或更高.基本上,您使用该语言的可用功能来计算比率:

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.
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我假设您的GL_TEXTURE_WRAP_S/T设置为GL_REPEAT,并带有适当的纹理或采样器参数.

请注意,计算CPU上的比率并将其作为统一传递可能比在着色器中计算它更快.特别是片段着色器,它将运行非常多.