Phong - 半矢量镜面双面

时间:2016-01-14 06:17:41

标签: c++ glsl phong specular pixel-shading

实现PhongModel着色时。 Specular术语出现在几何体的两侧。镜面术语是使用半矢量计算的。

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

[光......相机......对象]

但是当走向另一边时,即使没有漫反复的术语,我仍然会得到一些镜面反射,我不确定应该这样。在照片后面的照片中,物体和光线都在相机前面,光线在物体后面。

[相机...对象...光]

我认为也许镜面乘以符号(fLDotN)?但结果似乎并不好。通常如何处理?

我的猜测是我

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

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

带法线和半矢量的结果图像: Phong Specular+Diffuse Results

VertexShader

// 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;   
}

FragmentShader

// 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);
}

1 个答案:

答案 0 :(得分:0)

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