也许在 OpenGL ES 2.0 中实现置换贴图的最简单方法也可能是最快的。您需要两个纹理,一个包含颜色(常规纹理)和一个置换贴图。当正常采样常规纹理时,您的片段着色器将如下所示:
uniform sampler2D myTexture;
varying vec2 texcoords;
void main()
{
gl_FragColor = texture2D(myTexture, texcoords);
}
这是非常简单的事情。现在,要实现位移贴图,您需要:
uniform sampler2D myTexture;
uniform sampler2D myDisplacementMap;
varying vec2 texcoords;
void main()
{
vec2 displacement = 0.1 * texture2D(myDisplacementMap, texcoords).rg;
gl_FragColor = texture2D(myTexture, texcoords + displacement);
}
这也很简单。您还有另一个纹理,其中红色和绿色用作位移的 x 和 y。然而,通过这种方式,您只能获得静态的、与视图无关的位移。为了获得真实的位移,需要生成纹理切线和双切线 http://www.terathon.com/code/tangent.html其中包含对象空间中纹理轴的方向(一个棘手的概念,请阅读文章)。拥有它们后,您所需要的只是对象空间眼睛位置(可以通过将顶点位置乘以顶点着色器中的模型视图投影逆来计算),并且通过将其投影到切线/双切线向量上,您可以按顺序调制位移依赖于视图:
attribute vec3 position, tangent, bitangent;
attribute vec2 texcoord;
varying vec2 texcoords;
varying vec3 eye_dir, tan, bitan;
uniform matrix4f modelviewProjectionMatrix;
uniform matrix4f modelviewProjectionMatrixInverse;
void main()
{
gl_Position = modelviewProjectionMatrix * vec4(position, 1.0);
tan = tangent;
bitan = bitangent;
texcoords = texcoord;
}
(那是顶点着色器),这里是片段着色器:
uniform sampler2D myTexture;
uniform sampler2D myDisplacementMap;
varying vec2 texcoords;
varying vec3 eye_dir, tan, bitan;
void main()
{
vec2 eyen = normalize(eye_dir);
vec2 modulation = vec2(dot(eyen, normalize(tan)), dot(eyen, normalize(bitan)));
vec2 displacement = 0.1 * texture2D(myDisplacementMap, texcoords).rg * modulation;
gl_FragColor = texture2D(myTexture, texcoords + displacement);
}
这应该可以解决问题......(请注意,我是从头开始写的,所以如果有任何错误,请随时发表评论)
EDIT:并且出现错误,我将参数顺序交换为texture2D(采样器先行)。