着色器纹理总是朝向相机[英] Shader Texture Always Facing The Camera

本文是小编为大家收集整理的关于着色器纹理总是朝向相机的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有这个基本的着色器,尽管我遇到了一些麻烦,这确实使我感到困扰!

我正在使用片段着色器应用纹理,但是我移动或旋转相机,脸上的纹理将始终面对相机(我添加了一个gif图像).

.

 gif

因此,正如您在上面的图像上看到的那样,纹理一直朝相机面对相机,同样,如果我移开近距离,它将保持比例.

我正在尝试实现我可以四处走动的,并且质地将根据面部和顶点保持其位置,旋转和缩放,而不是按照相机进行的.

这是所需的结果,尽管使用不弃用的方法glVertex2f和glTexCoord2f,这与我想要的结果相同,尽管通过着色器,但我想我的问题是计算质地上正确的紫外线坐标.

所需结果
(来源: gyazo.com )

重要的我想使用着色器来实现这一目标,以便我可以对实际纹理的颜色进行更改. (例如,使其成为黑白).

这是我当前的顶点和片段着色器代码.

顶点着色器代码

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

片段着色器代码

uniform vec2 size;
uniform sampler2D texture;

void main() {
    gl_FragColor = texture2D(texture, gl_FragCoord.xy / size.xy);
}

碎片着色器中的uniform vec2 size;是施加纹理的面部本身的宽度和高度. uniform sampler2D texture;当然是草质地.

推荐答案

这样做是因为您已经编程了.您直接从片段的坐标中得出了TexCoord.如果您希望纹理"坚持几何形状",则需要定义几何图形和纹理空间之间的映射.通常,这是通过每个顶点的2D纹理坐标属性来完成的 - 就像固定功能管道对您提到的glTexCoord2f()所做的那样.

在您的特定情况下(假设主机程序仍然指定了TexCoords,您使用gl_Vertex的顶点位置的剥夺方式),您可以让GL插入每个片段的TexCoords,并使用这些片段访问这些纹理,并在片段着色器:

顶点着色器代码

varying vec2 vTexCoord;

void main() {
    vTexCoord = gl_MultiTexCoord0.st;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

片段着色器代码

uniform sampler2D texture;
varying vec2 vTexCoord;

void main() {
    gl_FragColor = texture2D(texture, vTexCoord);
}

我建议切换到通用顶点属性和更现代的GLSL版本.

本文地址:https://www.itbaoku.cn/post/2091118.html

问题描述

I have this basic shader, though I ran into some trouble which really bugs me!

I'm applying the texture using the fragment shader though however I move or rotate the camera, the texture on the face will always be facing the camera (I've added a GIF image as an example).

gif

So as you can see on the image above the texture keeps facing the camera, also if I move away of closer it will keep its scale.

I'm trying to achive that I can move around and the texture will keep it's position, rotation and scale according to the face and vertices, and not according to the camera as it is doing now.

Here is the desired result, though using the deprecated methods glVertex2f and the glTexCoord2f which is the same result I want though through shaders, I guess my problem is calculating the correct UV coordinates on the texture.

desired result
(source: gyazo.com)

Important I want to achive this using shaders so I can make/calculate changes into the colors of the actual texture. (For instance make it a black and white).

Here is my current Vertex & Fragment Shader Code.

Vertex Shader Code

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader Code

uniform vec2 size;
uniform sampler2D texture;

void main() {
    gl_FragColor = texture2D(texture, gl_FragCoord.xy / size.xy);
}

The uniform vec2 size; within the fragment shader, is the width and height of the face itself where the texture is applied on. The uniform sampler2D texture; is of course the grass texture itself.

推荐答案

It does that because that is whay you've programmed. You derive the texcoords directly from the coordinates of the fragment. If you want the texture to "stick to the geometry", you need to define a mapping between your geometry and texture space. Usually, this is done through a 2D texture coordinate attribute per vertex - just as the fixed function pipeline did with the glTexCoord2f() you mentioned.

In your specific case, (assuming the host program still specifies texcoords the same deprectaed way you are using for vertex positions with gl_Vertex), you could let the GL interpolate the texcoords per fragment and use these to access the texture in the fragment shader:

Vertex Shader Code

varying vec2 vTexCoord;

void main() {
    vTexCoord = gl_MultiTexCoord0.st;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader Code

uniform sampler2D texture;
varying vec2 vTexCoord;

void main() {
    gl_FragColor = texture2D(texture, vTexCoord);
}

I would suggest to switch to generic vertex attributen, and more modern GLSL versions, though.