Opengl GLSL phong着色器的奇怪镜面反射结果

Opengl GLSL phong着色器的奇怪镜面反射结果,opengl,glsl,phong,specular,Opengl,Glsl,Phong,Specular,我正在尝试在GLSL中实现phong着色,但镜面反射组件存在一些问题 绿色灯光是镜面反射组件。点光源在平面上方以圆形传播。镜面反射高光始终向内指向Y轴,光线围绕Y轴旋转,并向漫反射扇出,如图所示。它看起来一点也不受相机位置的影响,我也不知道我哪里出了问题 顶点着色器代码: #version 330 core /* * Phong Shading with with Point Light (Quadratic Attenutation) */ //Input vertex data layo

我正在尝试在GLSL中实现phong着色,但镜面反射组件存在一些问题

绿色灯光是镜面反射组件。点光源在平面上方以圆形传播。镜面反射高光始终向内指向Y轴,光线围绕Y轴旋转,并向漫反射扇出,如图所示。它看起来一点也不受相机位置的影响,我也不知道我哪里出了问题

顶点着色器代码:

#version 330 core

/*
* Phong Shading with with Point Light (Quadratic Attenutation)
*/

//Input vertex data
layout(location = 0) in vec3 vertexPosition_modelSpace;
layout(location = 1) in vec2 vertexUVs;
layout(location = 2) in vec3 vertexNormal_modelSpace;

//Output Data; will be interpolated for each fragment
out vec2 uvCoords;

out vec3 vertexPosition_cameraSpace;
out vec3 vertexNormal_cameraSpace;

//Uniforms
uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
uniform mat3 normalTransformMatrix;


void main()
{
    vec3 normal = normalize(vertexNormal_modelSpace);

    //Set vertices in clip space
    gl_Position = mvpMatrix * vec4(vertexPosition_modelSpace, 1);

    //Set output for UVs
    uvCoords = vertexUVs;

    //Convert vertex and normal into eye space
    vertexPosition_cameraSpace = mat3(mvMatrix) * vertexPosition_modelSpace;    
    vertexNormal_cameraSpace = normalize(normalTransformMatrix * normal);

}
片段着色器代码:

#version 330 core

in vec2 uvCoords;

in vec3 vertexPosition_cameraSpace;
in vec3 vertexNormal_cameraSpace;

//out
out vec4 fragColor;

//uniforms
uniform sampler2D diffuseTex;
uniform vec3 lightPosition_cameraSpace;

void main()
{
    const float materialAmbient = 0.025;    //a touch of ambient

    const float materialDiffuse = 0.65;
    const float materialSpec = 0.35;  

    const float lightPower = 2.0;
    const float specExponent = 2;

    //--------------Set Colors and determine vectors needed for shading-----------------           

    //reflection colors- NOTE- diffuse and ambient reflections will use the texture color
    const vec3 colorSpec = vec3(0,1,0); //Green spec color
    vec3 diffuseColor = texture2D(diffuseTex, uvCoords).rgb;    //Get color from the texture at fragment

    const vec3 lightColor = vec3(1,1,1);        //White light

    //Re-normalize normal vectors : after interpolation they make not be unit length any longer
    vec3 normVertexNormal_cameraSpace = normalize(vertexNormal_cameraSpace);

    //Set camera vec
    vec3 viewVec_cameraSpace = normalize(-vertexPosition_cameraSpace);  //Since its view space, camera at origin

    //Set light vec
    vec3 lightVec_cameraSpace = normalize(lightPosition_cameraSpace - vertexPosition_cameraSpace);

    //Set reflect vect
    vec3 reflectVec_cameraSpace = normalize(reflect(-lightVec_cameraSpace, normVertexNormal_cameraSpace));      //reflect function requires incident vec; from light to vertex

    //----------------Find intensity of each component---------------------

    //Determine Light Intensity
    float distance = abs(length(lightPosition_cameraSpace - vertexPosition_cameraSpace));
    float lightAttenuation = 1.0/( (distance > 0) ? (distance * distance) : 1 );    //Quadratic

    vec3 lightIntensity = lightPower * lightAttenuation * lightColor;

    //Determine Ambient Component
    vec3 ambientComp = materialAmbient * diffuseColor * lightIntensity;

    //Determine Diffuse Component
    float lightDotNormal = max( dot(lightVec_cameraSpace, normVertexNormal_cameraSpace), 0.0 );
    vec3 diffuseComp = materialDiffuse *  diffuseColor * lightDotNormal * lightIntensity;

    vec3 specComp = vec3(0,0,0);
    //Determine Spec Component
    if(lightDotNormal > 0.0)
    {
        float reflectDotView = max( dot(reflectVec_cameraSpace, viewVec_cameraSpace), 0.0 );
        specComp = materialSpec *  colorSpec * pow(reflectDotView, specExponent) * lightIntensity;
    }

    //Add Ambient + Diffuse + Spec
    vec3 phongFragRGB = ambientComp + 
          diffuseComp + 
          specComp;  

    //----------------------Putting it together-----------------------

    //Out Frag color
    fragColor = vec4(  phongFragRGB, 1);
}
只需注意,在顶点着色器中看到的normalTransformMatrix是模型视图矩阵的逆转置

我正在设置一个从顶点位置到灯光、到摄影机和反射向量的向量,所有这些都在摄影机空间中。对于漫反射计算,我取光向量和法向量的点积,对于镜面反射分量,我取反射向量和视图向量的点积。也许我对算法有一些基本的误解

起初我认为问题可能是我没有在插值后对进入片段着色器的法线进行规格化,但是添加一条线进行规格化不会影响图像。我不知道该去哪里找

我知道网站上有很多关于phong着色的问题,但每个人似乎都有一个有点不同的问题。如果有人知道我哪里出了问题,请告诉我。感谢您的帮助


编辑:好了,现在开始工作了!正如jozxyqk在下面建议的那样,我需要对顶点位置执行mat4*vec4操作,否则会丢失平移信息。当我第一次进行更改时,我得到了奇怪的结果,直到我意识到我在OpenGL代码中对lightPosition_cameraSpace犯了相同的错误,然后我将其传递给着色器。错误是我将视图矩阵向下转换为mat3进行计算,而不是将灯光位置向量设置为vec4。一旦我编辑了这些线的着色器似乎工作正常!谢谢你的帮助,jozxqk

我可以看到两个看起来不对劲的部分

vertexPosition\u cameraSpace=mat3mvMatrix*vertexPosition\u模型空间应为mat4/vec4x,y,z,1乘法,否则它将忽略模型视图矩阵的平移部分。
二,。距离使用相对于摄影机的灯光位置,而不是顶点。请改用lightVec_cameraSpace。编辑:当我尝试得到一个场景时,错过了重复计算

Hmm,其中对象的照明取决于从对象到摄影机的距离。当我把相机拉开时,物体变黑了。