码迷,mamicode.com
首页 > 移动开发 > 详细

Bump mapping的GLSL实现 [转]

时间:2014-06-25 13:43:39      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   http   tar   

原文 http://www.cnblogs.com/CGDeveloper/archive/2008/07/03/1234206.html

 

如果物体表面细节很多,我们可以不断的精细化物体的几何数据,但是这样会产生大量的Lighting & Transformation等计算,
为了实现丰富真实的物体表面,除了贴上一般纹理之外,往往还使用Bump mapping(凹凸纹理)技术。
Bump mapping并没有增加物体的几何复杂度,它只是在计算物体的光照效果时作了“弊”,不使用物体本身的法向量,而是
使用了经过处理的法向量。如果这样的法向量使用normal map,我们可以使用GLSL实现凹凸效果。
首先,因为没有改变对象的几何形状,所以bump mapping的实现是在FS之中进行的,因此光照计算就必须在FS之中进行。
由于normal map之中的法向量是在SURFACE_LOCAL COORDINATE SPACE,所以用于光照计算的光源的方向和视向都
必须变换到同一空间进行光照计算。也就是说,必须使用所谓TBN矩阵的逆矩阵对光源的方向和视向进行变换,转换之后的值
作为varying传入到FS之中。
对于三角形mesh而言,TBN的一种计算方法如下:

bubuko.com,布布扣void FindInvTBN(Vertor3f Vertices[3], Vector2f TexCoords[3], Vector3f & InvNormal,
bubuko.com,布布扣                  Vector3f & InvBinormal, Vector3f & InvTangent) 
bubuko.com,布布扣  {
bubuko.com,布布扣                /* Calculate the vectors from the current vertex
bubuko.com,布布扣                   to the two other vertices in the triangle */
bubuko.com,布布扣  
bubuko.com,布布扣                Vector3f v2v1 = Vertices[0- Vertices[2];
bubuko.com,布布扣                Vector3f v3v1 = Vertices[1- Vertices[2];
bubuko.com,布布扣  
bubuko.com,布布扣                //Calculate the “direction” of the triangle based on texture coordinates.
bubuko.com,布布扣  
bubuko.com,布布扣                // Calculate c2c1_T and c2c1_B
bubuko.com,布布扣                float c2c1_T = TexCoords[0].x() - TexCoords[2].x();
bubuko.com,布布扣                float c2c1_B = TexCoords[0].y() - TexCoords[2].y();
bubuko.com,布布扣  
bubuko.com,布布扣                // Calculate c3c1_T and c3c1_B
bubuko.com,布布扣                float c3c1_T = TexCoords[1].x() - TexCoords[2].x();
bubuko.com,布布扣                float c3c1_B = TexCoords[1].y() - TexCoords[2].y();
bubuko.com,布布扣  
bubuko.com,布布扣                //Look at the references for more explanation for this one.
bubuko.com,布布扣                float fDenominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B;  
bubuko.com,布布扣                /*ROUNDOFF here is a macro that sets a value to 0.0f if the value is a very small
bubuko.com,布布扣                  value, such as > -0.001f and < 0.001. */
bubuko.com,布布扣 
bubuko.com,布布扣                /* EDIT by c programmer: you should NEVER perform an equality test against a floating point value, even if
bubuko.com,布布扣                   your macro has set fDenominator to 0.0f.  The comparison can still fail.  The code needs fixed.
bubuko.com,布布扣                   Instead you should check if fDenominator is within an epsilon value of 0.0f. */
bubuko.com,布布扣 
bubuko.com,布布扣                if (ROUNDOFF(fDenominator) == 0.0f
bubuko.com,布布扣                {
bubuko.com,布布扣                       /* We won‘t risk a divide by zero, so set the tangent matrix to the
bubuko.com,布布扣                          identity matrix */
bubuko.com,布布扣                        InvTangent = Vector3f(1.0f0.0f0.0f);
bubuko.com,布布扣                        InvBinormal = Vector3f(0.0f1.0f0.0f);
bubuko.com,布布扣                        InvNormal = Vector3f(0.0f0.0f1.0f);
bubuko.com,布布扣                }
bubuko.com,布布扣                else
bubuko.com,布布扣                {            
bubuko.com,布布扣                        // Calculate the reciprocal value once and for all (to achieve speed)
bubuko.com,布布扣                        float fScale1 = 1.0f / fDenominator;
bubuko.com,布布扣  
bubuko.com,布布扣                        /* Time to calculate the tangent, binormal, and normal.
bubuko.com,布布扣                           Look at Søren’s article for more information. */
bubuko.com,布布扣                        Vector3f T, B, N;
bubuko.com,布布扣                        T = Vector3f((c3c1_B * v2v1.x() - c2c1_B * v3v1.x()) * fscale1,
bubuko.com,布布扣                                     (c3c1_B * v2v1.y() - c2c1_B * v3v1.y()) * fScale1,
bubuko.com,布布扣                                     (c3c1_B * v2v1.z() - c2c1_B * v3v1.z()) * fScale1);
bubuko.com,布布扣  
bubuko.com,布布扣                        B = Vector3f((-c3c1_T * v2v1.x() + c2c1_T * v3v1.x()) * fScale1,                                     (-c3c1_T * v2v1.y() + c2c1_T * v3v1.y()) * fScale1,                                     (-c3c1_T * v2v1.z() + c2c1_T * v3v1.z()) * fScale1);                          N = T%B; //Cross product!  /*This is where programmers should break up the function to smooth the tangent, binormal and    normal values. */    //Look at “Derivation of the Tangent Space Matrix” for more information.                          float fScale2 = 1.0f / ((T.x() * B.y() * N.z() - T.z() * B.y() * N.x()) +                                                 (B.x() * N.y() * T.z() - B.z() * N.y() * T.x()) +                                                 (N.x() * T.y() * B.z() - N.z() * T.y() * B.x()));                        InvTangent.set((B%N).x() * fScale2,                                       ((-1.0f * N)%T).x() * fScale2,                                       (T%B).x() * fScale2);                        InvTangent.normalize();                          InvBinormal.set(((-1.0f *B)%N).y() * fScale2,                                        (N%T).y() * fScale2,                                        ((-1.0f * T)%B).y() * fScale2);                        InvBinormal.normalize();                          InvNormal.set((B%N).z() * fScale2,                                      ((-1.0f * N)%T).z() * fScale2,                                      (T%B).z() * fScale2);                        InvNormal.normalize();              }

上述计算中可以只计算T。
相应的VS如下:

bubuko.com,布布扣varying vec3 LightDir;
bubuko.com,布布扣varying vec3 EyeDir;
bubuko.com,布布扣
bubuko.com,布布扣attribute vec3 Tangent;
bubuko.com,布布扣
bubuko.com,布布扣void main()
bubuko.com,布布扣{
bubuko.com,布布扣    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
bubuko.com,布布扣    gl_TexCoord[0= gl_MultiTexCoord0;
bubuko.com,布布扣
bubuko.com,布布扣    // 眼坐标系下的TBN
bubuko.com,布布扣    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
bubuko.com,布布扣    vec3 t = normalize(gl_NormalMatrix * Tangent);
bubuko.com,布布扣    vec3 b = cross(n, t);
bubuko.com,布布扣    mat3 TBN = mat3(t, b, n);
bubuko.com,布布扣    
bubuko.com,布布扣    vec4 pos = gl_ModelViewMatrix * gl_Vertex;
bubuko.com,布布扣    vec3 epos = vec3(pos)/pos.w;
bubuko.com,布布扣    
bubuko.com,布布扣    vec3 v = gl_LightSource[0].position.xyz - epos;
bubuko.com,布布扣    v = v * TBN;
bubuko.com,布布扣    LightDir = normalize(v);
bubuko.com,布布扣
bubuko.com,布布扣    v = -epos * TBN;
bubuko.com,布布扣    EyeDir = normalize(v);
bubuko.com,布布扣}


相应的FS如下:

bubuko.com,布布扣uniform sampler2D BumpTex;
bubuko.com,布布扣uniform sampler2D DecalTex;
bubuko.com,布布扣
bubuko.com,布布扣varying vec3 LightDir;
bubuko.com,布布扣varying vec3 EyeDir;
bubuko.com,布布扣
bubuko.com,布布扣void main() 
bubuko.com,布布扣{
bubuko.com,布布扣    vec3 BumpNorm = vec3(texture2D(BumpTex, gl_TexCoord[0].xy));
bubuko.com,布布扣    BumpNorm = (BumpNorm -0.5* 2.0;
bubuko.com,布布扣    
bubuko.com,布布扣    vec4 DecalCol = texture2D(DecalTex, gl_TexCoord[0].xy);
bubuko.com,布布扣    
bubuko.com,布布扣    float NdotL = max(dot(BumpNorm, LightDir), 0.0);
bubuko.com,布布扣    
bubuko.com,布布扣    vec3 h = normalize(LightDir+EyeDir);
bubuko.com,布布扣    float NdotH = max(dot(BumpNorm, h), 0.0);
bubuko.com,布布扣    
bubuko.com,布布扣    vec3 diffuse = vec3(NdotL * gl_LightSource[0].diffuse * DecalCol);
bubuko.com,布布扣    vec3 specular = vec3(pow(NdotH, 6* gl_LightSource[0].specular);
bubuko.com,布布扣    
bubuko.com,布布扣    gl_FragColor = vec4(diffuse + specular, 1.0);
bubuko.com,布布扣}
bubuko.com,布布扣

Bump mapping的GLSL实现 [转],布布扣,bubuko.com

Bump mapping的GLSL实现 [转]

标签:style   class   blog   code   http   tar   

原文地址:http://www.cnblogs.com/mazhenyu/p/3806629.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!