0

实现 PhongModel 着色时。镜面反射项出现在几何体的两侧。使用半向量计算镜面反射项。

在前面的输出图像中,它似乎计算正确。光在相机后面,物体在相机前面。

[光……相机……物体]

但是当去另一边时,即使没有漫反射项,我仍然会得到一些镜面反射,我不确定我是否应该这样做。在下面的图片中,物体和灯光都在相机前面,灯光在物体后面。

[相机……物体……光]

我想也许镜面反射应该乘以符号(fLDotN)?但结果似乎并不好。一般是怎么处理的?

我的猜测是我是

光照均匀位置在相机空间中设置:

vec3 ptLightPos_CS=vec3(matLookAt*vec4(ptLightPos, 1));

具有法线和半向量的结果图像: Phong Specular+Diffuse Results

顶点着色器

// Input layouts
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexCoord;
in vec3 vertexTangent;
in vec3 vertexBitangent;

// Output layouts

// Uniform variables
uniform VertexUniforms
{
    mat4 uniform_Projection;
    mat4 uniform_ModelView;
    mat4 uniform_NormalMatrix;
};

// In variables

// Out variables
out vec2 vs_uv;
out vec3 vs_normal;
out vec3 vs_tangent;
out vec3 vs_bitangent;
out vec3 vs_pos;
// Global variables

/*************/

void main()
{
    // Convert the vertex to clip space
    vec3 vcPos=vec3(uniform_ModelView*vec4(vertexPosition, 1.0f));
    vec4 vertexProj = uniform_Projection * vec4(vcPos, 1.0f);

    ///--- Tangent space
    vs_normal=normalize(vec3(uniform_NormalMatrix * vec4(vertexNormal, 0)));
    vs_tangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexTangent, 0)));
    vs_bitangent=normalize(vec3(uniform_NormalMatrix * vec4(vertexBitangent, 0)));

    ///---
    vs_pos=vcPos;

    // UV
    vs_uv=vertexTexCoord;

    gl_Position = vertexProj;   
}

片段着色器

// Output layouts
out vec4 outColor;

// Uniform variables
uniform vec3 uniform_v3LightDiffuseColor;
uniform vec3 uniform_v3LightSpecularColor;
uniform sampler2D uniform_tDiffuse;
uniform sampler2D uniform_tNormal;
uniform vec3 uniform_v3LightPos;

// In variables
in vec2 vs_uv;
in vec3 vs_normal;
in vec3 vs_tangent;
in vec3 vs_bitangent;
in vec3 vs_pos;
// Out variables

// Global variables

/*************/
#define PI 3.141592

void main()
{   
    const vec3 T=normalize(vs_tangent);
    const vec3 B=normalize(vs_bitangent);
    const vec3 N=normalize(vs_normal);
    const mat3 mTBN=mat3(T, B, N);  
    vec3 vNormal=mTBN*((texture2D(uniform_tNormal, vs_uv).xyz*2.0-1.0));    
    vNormal=normalize(vNormal);

    const vec3 vEye=normalize(-vs_pos);
    const vec3 vLightDir=normalize(uniform_v3LightPos-vs_pos);
    const vec3 vLightDiffuse=vec3(0.5,0.5,0.5);//uniform_v3LightDiffuseColor;
    const vec3 vLightSpecular=vec3(0.5,0.5,0.5);//uniform_v3LightSpecularColor;
    const vec3 vMatDiffuse=vec3(0.5,0.5,0.5);//texture2D(uniform_tDiffuse, vs_uv).xyz;
    const vec3 vMatSpecular=vMatDiffuse;
    const float fMatSpecularPower=0.8;
    const float fLDotN=max(dot(vLightDir, vNormal), 0);

    //-- Diffuse
    float fDiffuseContrib = fLDotN;

    //-- Specular
    vec3 v3HalfVect=normalize(vEye+vLightDir);
    float fSpecularContrib=pow(clamp(dot(v3HalfVect, vNormal), 0.0, 1.0), fMatSpecularPower);
    vec3 vDiffuse=fDiffuseContrib*vMatDiffuse*vLightDiffuse;
    vec3 vSpecular=fSpecularContrib*vMatSpecular*vLightSpecular;

    vec3 vcFinal=vDiffuse+vSpecular;    
    outColor = vec4(vcFinal, 1);    

    //outColor = vec4(vNormal.xyz, 1);
    //outColor = vec4(vEye.xyz, 1);
    //outColor = vec4(vLightDir.xyz, 1);
    //outColor = vec4(v3HalfVect.xyz, 1);
}
4

1 回答 1

0

您不计算镜面反射if (dot(vNormal, vLightDir) < 0)并将其设置为 0。

于 2016-01-14T07:57:14.950 回答