我正在尝试制作一个将置换贴图用于3d效果的应用程序。在Flash中,可以使用位移过滤器来完成它,如下所示:http://flashflex.com/pixel-bender-displacement-map-fakes-3d-effect-update/。很少有应用程序可以在iPhone上做到这一点,例如:www.youtube.com/watch?v = NvCHHUN8nnE
我想知道他们如何执行此操作。
我正在尝试使用此处描述的基于位移图的技术:www.cocos2d-iphone.org/forum/topic/11659,但是即时执行似乎很慢。
任何指针将不胜感激。
谢谢
最佳答案
在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。但是,这种方式只能获得与视图无关的静态位移。为了获得真实的位移,需要generate texture tangents and bitangents包含对象空间中纹理轴的方向(一个棘手的概念,请阅读文章)。有了它们之后,您所需要做的就是对象空间眼位置(可以通过将顶点位置乘以顶点着色器中的modelview-projection inverse来计算),并将其投影在切线/双切线矢量上,可以按顺序调制位移取决于视图:
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);
}
这应该可以解决问题...(请注意,我写的是从头开始的,所以如果有任何错误,请不要犹豫地发表评论)
编辑:而且有错误,我将参数顺序交换到texture2D(采样器排在第一位)。