在着色器中平铺纹理

发布于 2024-11-17 02:35:37 字数 422 浏览 2 评论 0原文

我传递给顶点着色器 (glsl) 2 个纹理:来自屏幕和较小的法线贴图。 法线贴图根据屏幕尺寸进行缩放。因此,如果第一个纹理是 1152×864 像素,法线贴图是 256×256,它将从其大小缩放到更大。

我怎样才能让它平铺呢?例如,将其大小设置为256×256并平铺所有纹理。


UPD

例如,我的主要(大)纹理是这样映射的:

[0.17, 0.61, 0.33, 0.83]

而不是:

[0, 0, 1, 1]

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

I'm passing to vertex shader (glsl) 2 textures: from the screen and smaller, normalmap.
Normalmap is scaled for the screen size. So if first texture is 1152×864 pixels and normalmap is 256×256, it will be scaled from it's size to bigger.

How can I make it tiled? E.g. make it size as 256×256 and tile through all the texture.


UPD:

For example, my main (big) texture is mapped like this:

[0.17, 0.61, 0.33, 0.83]

Instead of:

[0, 0, 1, 1]

This way my normal texture is mapped for the first coordinates too. So I see a small mapped rectangle of it. How can I map it in shader for the full size?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏爱你一生 2024-11-24 02:35:37

它将从原来的大小缩放到更大。

不,肯定不会。这是对纹理的常见误解。纹理只不过是花哨的查找表。纹理之间并不是相对“缩放”的;这只是您使用什么纹理坐标的问题。

您所做的很可能是使用与法线贴图相同的屏幕纹理纹理坐标。由于我们可能正在讨论标准化纹理坐标,这意味着您将相同的 [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 上计算比率并将其作为统一传递可能比在着色器中计算速度更快。特别是对于片段着色器,它将运行大量的操作。

it will be scaled from it's size to bigger.

No, it most certainly will not. This is a common misunderstanding about textures. Textures are nothing more than fancy look-up tables. Textures are not "scaled" relative to one another; it is merely a question of what texture coordinates you use.

In all likelihood, what you are doing is using the same texture coordinate for the screen texture as your normal map. Since we're likely talking about normalized texture coordinates, this means that you're mapping the same [0, 1] range to both of them.

To get the effect you're talking about, you need to compute texture coordinates for your normal texture that do what you need them to do. So if you have a texture coordinate that is relative to the screen texture, you must transform it into the space you want it in for the normal texture.

There are a couple of ways to do it. The manual way is to compute the ratio of the textures' sizes to one another on the CPU, then pass it to the shader. Using the numbers you've given, the size ratios would be:

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

Make sure that this is done in floating-point math. Once done, simply pass this along in a uniform and multiply the texture coordinates by this ratio in the shader before sampling:

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 better. Basically, you use the available features of the language to compute the ratio:

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 of these cases, I'm assuming that your GL_TEXTURE_WRAP_S/T are set to GL_REPEAT with appropriate texture or sampler parameters.

Do note that computing the ratio on the CPU and passing it as a uniform will likely be faster than computing it in the shader. Particularly for fragment shaders, which will be run a very great deal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文