我传递给顶点着色器(glsl)2个纹理:从屏幕和较小的法线贴图。
Normalmap按屏幕大小缩放。因此,如果第一个纹理是1152×864
像素而法线贴图是256×256
,那么它将从它的大小缩放到更大。
如何让它平铺?例如。将其大小设为256×256
并平铺所有纹理。
UPD :
例如,我的主(大)纹理映射如下:
[0.17, 0.61, 0.33, 0.83]
而不是:
[0, 0, 1, 1]
这样我的普通纹理也会映射到第一个坐标。所以我看到了一个小的映射矩形。如何在着色器中将其映射为完整尺寸?
答案 0 :(得分:6)
它将从它的大小缩放到更大。
不,它肯定不会。这是对纹理的常见误解。纹理只不过是花哨的查找表。纹理不是相对于彼此“缩放”的;它只是你使用什么纹理坐标的问题。
很可能,你正在做的是使用与普通地图相同的纹理坐标作为屏幕纹理。由于我们可能正在讨论规范化纹理坐标,这意味着您将相同的[0,1]范围映射到它们两者。
要获得您正在谈论的效果,您需要计算正常纹理的纹理坐标,以满足您的需要。因此,如果您具有相对于屏幕纹理的纹理坐标,则必须将其转换为您想要的空间以用于普通纹理。
有几种方法可以做到这一点。手动方式是在CPU上计算纹理大小的比例,然后将其传递给着色器。使用您给出的数字,大小比率为:
(1152.0/256.0, 864.0/256.0) = (4.5, 3.375).
确保这是在浮点数学中完成的。完成后,只需将其传递给均匀,然后在采样前将纹理坐标乘以着色器中的此比率:
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.
}
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.
}
在这两种情况下,我假设您的GL_TEXTURE_WRAP_S / T设置为GL_REPEAT,并带有适当的纹理或采样器参数。
请注意,计算CPU上的比率并将其作为统一传递可能比在着色器中计算它更快。特别是片段着色器,它将运行非常多。