【问题标题】:Reflection Mapping in OpenGL ESOpenGL ES 中的反射映射
【发布时间】:2014-12-23 11:04:50
【问题描述】:

我正在尝试在 OpenGL ES 2.0 中为“球体”实现反射映射。 我已经完成了天空盒。 对于球体渲染,我使用的反射着色器是:

环境映射(球体)顶点着色器::

precision highp float;
uniform mat4    u_mvMatrix; // ModelView Matrix
uniform mat4    u_mvpMatrix; // ModelViewProjection Matrix

attribute vec4 a_position;
attribute vec3 a_envmapNormal;

varying vec3 v_eyecoordEyeReflection;

vec3 v_eyecoordPosition;
vec3 v_eyecoordNormal;

void main()
 {
    // position and normal in model coordinates
    vec4 modelCoordPosition = a_position;
    vec3 modelCoordNormal   = a_envmapNormal;

    // Calculate position in eye space
    v_eyecoordPosition = vec3(u_mvMatrix * modelCoordPosition);

    // Calculate and normalize eye space normal
    vec3 eyecoordNormal    = vec3(u_mvMatrix * vec4(modelCoordNormal, 0.0));
    v_eyecoordNormal        = normalize(eyecoordNormal);
    // Calculate reflection vector
    v_eyecoordEyeReflection = reflect(v_eyecoordPosition, v_eyecoordNormal);

    gl_Position = u_mvpMatrix * a_position;
}

环境映射(球体)片段着色器

precision highp float;
uniform lowp samplerCube baseCubeMapTexture;
varying vec3 v_eyecoordEyeReflection;

void main()
{
    gl_FragColor  = textureCube(baseCubeMapTexture, v_eyecoordEyeReflection);
}

但我没有得到正确的输出。 当球体旋转时,纹理没有变化。

着色器中的错误是什么?



谢谢安东... 我使用了你的着色器代码。 但我得到的是白色球体。

球体法线的计算方法是:

    #define ANGLE_STEP      ((2.0f * OGLES_PI) / ((float) NUM_OF_SLICES))
    for ( iCnti = 0; iCnti < NUM_OF_PARALLELS + 1; iCnti++ )    {
        for ( iCntj = 0; iCntj < NUM_OF_SLICES + 1; iCntj++ )   {
            pSphereNormals[iNormalIndex + 0] = sin(ANGLE_STEP * (FLOAT) iCnti )* sin (ANGLE_STEP *(FLOAT)iCntj);
            pSphereNormals[iNormalIndex + 1] = cos(ANGLE_STEP * (FLOAT) iCnti );
            pSphereNormals[iNormalIndex + 2] = sin(ANGLE_STEP * (FLOAT) iCnti )* cos (ANGLE_STEP *(FLOAT)iCntj);
            iNormalIndex += 3;
        }
    }

我的视图矩阵“matViewMatrix”源自 (http://www.learnopengles.com/tag/linmath-h/mat4x4_look_at()) MyCameraLookAt(matViewMatrix, 0.0f, 0.0f, -2.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

InvViewMat 的逆矩阵是 //inverse() 函数取自http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp

    InvViewMat[0][0] = -1.000000   InvViewMat[1][0] = -0.000000   InvViewMat[2][0] = 0.000000    InvViewMat[3][0] = -0.000000
    InvViewMat[0][1] = -0.000000   InvViewMat[1][1] = 1.000000    InvViewMat[2][1] = -0.000000   InvViewMat[3][1] = -0.000000
    InvViewMat[0][2] =  0.000000   InvViewMat[1][2] = -0.000000   InvViewMat[2][2] = -1.000000   InvViewMat[3][2] = -2.000000
    InvViewMat[0][3] = -0.000000   InvViewMat[1][3] = 0.000000    InvViewMat[2][3] = 0.000000    InvViewMat[3][3] = 1.000000

我的矩阵值或任何计算有问题吗?

【问题讨论】:

    标签: reflection opengl-es shader


    【解决方案1】:

    如果您有一个以相机原点(眼睛空间)为中心的球体,那么无论您如何旋转它,眼睛空间中的位置和法线在屏幕上的任何位置都将始终相同。这就是球体的定义——每个顶点到中心的距离(半径)相同。

    您实际上需要在 世界空间 中执行此操作(该位置会随着您旋转球体而变化)。

    现在,这带来了一个问题 - 您只有一个 ModelView 矩阵(从对象空间转换到眼睛空间)。您需要拆分模型和视图矩阵来执行此操作,并且为方便起见,您应该将视图矩阵的逆矩阵传递给 GLSL。

    下面是一个修改后的顶点着色器,可以满足你的需要:

    precision highp float;
    uniform mat4    u_vInvMatrix; // Inverse View Matrix -- NEW
    uniform mat4    u_mvMatrix;   // ModelView Matrix
    uniform mat4    u_mvpMatrix;  // ModelViewProjection Matrix
    
    attribute vec4 a_position;
    attribute vec3 a_envmapNormal;
    
    //varying vec3 v_eyecoordEyeReflection; // YOU DO NOT WANT EYE-SPACE
    varying vec3 v_worldReflection;         // Use world-space instead -- MODIFIED
    
    vec3 v_eyecoordPosition;
    vec3 v_eyecoordNormal;
    
    void main()
     {
        // position and normal in model coordinates
        vec4 modelCoordPosition = a_position;
        vec3 modelCoordNormal   = a_envmapNormal;
    
        // Calculate position in eye space
        v_eyecoordPosition   = vec3(u_mvMatrix * modelCoordPosition);
    
        // Calculate and normalize eye space normal
        vec3 eyecoordNormal  = vec3(u_mvMatrix * vec4(modelCoordNormal, 0.0));
        v_eyecoordNormal     = normalize(eyecoordNormal);
    
        // Calculate reflection vector (eye-space)
        vec3 eyeReflection   = reflect(v_eyecoordPosition, v_eyecoordNormal);
    
        // Transform the reflection into world-space -- NEW
        v_worldReflection    = vec3 (u_vInvMatrix * vec4 (eyeReflection, 0.0f));
    
        gl_Position = u_mvpMatrix * a_position;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多