Phong - 半矢量镜面镜面

Phong - Half Vector Specular both sides

本文关键字:Phong      更新时间:2023-10-16

实现PhongModel着色时。镜面反射项显示在几何图形的两侧。镜面反射项是使用半向量计算的。

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

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

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

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

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

我的猜测是我是

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

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

具有法线和半向量的结果图像:蓬镜面反射+漫反射结果

顶点着色器

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

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