我想在GLSL中實現phong着色,但是在高光組件上存在一些問題。來自GLSL phong着色器的奇怪鏡面反射結果
綠光是鏡面反射分量。光線(點光源)在飛機上方以圓形行進。鏡面高光始終指向光軸旋轉的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操作或丟失翻譯信息。當我第一次做出改變時,我得到了奇怪的結果,直到我意識到在我將它傳遞給着色器之前,我在lightPosition_cameraSpace的OpenGL代碼中犯了同樣的錯誤(錯誤是我將視圖矩陣轉換爲mat3用於計算而不是將光位置矢量設置爲vec4)。一旦我編輯了這些線,着色器看起來工作正常!感謝您的幫助,jozxqk!
嗯,當我試圖讓我有一個場景,其中對象的照明取決於從物體到相機的距離。當我將相機拉開時,物體變黑。 – StackAttack
確定它的工作!看到我上面的編輯。 – StackAttack