我正在嘗試編寫一個簡單的陰影映射引擎,它使用兩個分離且不同的着色器,分別使用OpenGL和LWJGL。它完全使用VAO/VBO。相機旋轉時出現問題。就像陰影旋轉兩倍於相機一樣。OpenGL陰影映射雙着色器
我首先在原點創建一個簡單的立方體,並在立方體下面創建一個2D平面。
[代碼由於省略以長度]
我然後創建一個「太陽」(可移動一段時間內),它使用正投影來創建陰影圖。
光源投影矩陣(接近爲1,遠爲100):
lightMatrixStore.getProjectionMatrix().m00 = 1;
lightMatrixStore.getProjectionMatrix().m11 = 1;
lightMatrixStore.getProjectionMatrix().m22 = -2f/(100-1);
lightMatrixStore.getProjectionMatrix().m23 = -((100+1f)/(100-1f));
lightMatrixStore.getProjectionMatrix().m33 = 1;
lightMatrixStore.getProjectionMatrix().m32 = 0;
設置幀緩衝器/渲染/質地:
depthTextureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL14.GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.5f);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, (ByteBuffer) null
);
glBindTexture(GL_TEXTURE_2D, 0);
shadowMapWidth = 2048;
shadowMapHeight = 768*2;
rboId = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, shadowMapWidth, shadowMapHeight);
fboId = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTextureId, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
int fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fboStatus != GL_FRAMEBUFFER_COMPLETE) {
System.err.print("Framebuffer error " + fboStatus + " : " + gluErrorString(glGetError()));
}
陰影圖頂點着色器:
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;
out vec4 pass_Color;
out vec2 pass_TextureCoord;
void main(void) {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;
pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}
和陰影貼圖着色器:
#version 150 core
uniform sampler2D texture_diffuse;
in vec4 pass_Color;
in vec2 pass_TextureCoord;
out vec4 out_Color;
void main(void) {
out_Color = pass_Color;
}
該程序從光線的角度呈現場景並創建陰影貼圖,然後第二個渲染通道進行環境光照,鏡面光照和陰影嘗試。
最後的頂點着色器:
#version 150 core
varying vec4 varyingVertex;
varying vec4 projectionVertex;
varying vec3 varyingNormal;
varying vec3 varyingPosition;
varying vec4 shadowCoord;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 lightViewMatrix;
uniform mat4 lightProjectionMatrix;
in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;
in vec3 in_Normal;
out vec4 pass_Color;
out vec2 pass_TextureCoord;
void main() {
varyingVertex = in_Position;
varyingNormal = in_Normal;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_Position;
varyingPosition = gl_Position;
pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
shadowCoord = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0) * lightProjectionMatrix * lightViewMatrix * inverse(viewMatrix) * modelMatrix * in_Position;
}
最後片段着色器:
#version 150
uniform sampler2D ShadowMap;
varying vec4 varyingVertex;
varying vec4 projectionVertex;
varying vec3 varyingNormal;
varying vec3 varyingPosition;
varying vec4 shadowCoord;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec4 pass_Color;
in vec2 pass_TextureCoord;
out vec4 out_Color;
void main() {
vec3 vertexPosition = (modelMatrix * viewMatrix * varyingVertex).xyz;
vec3 surfaceNormal = normalize((mat3(1) * varyingNormal).xyz);
vec3 lightDirection = normalize(gl_LightSource[0].position.xyz - vertexPosition);
float diffuseLightIntensity = max(0, dot(surfaceNormal, lightDirection));
out_Color.rgb = diffuseLightIntensity * pass_Color.rgb;
out_Color += gl_LightModel.ambient;
vec3 reflectionDirection = normalize(reflect(-lightDirection, surfaceNormal));
float specular = max(0.0, dot(surfaceNormal, reflectionDirection));
if (diffuseLightIntensity != 0) {
float fspecular = pow(specular, 128);
out_Color += fspecular;
}
vec4 shadowCoordinateWdivide = shadowCoord/shadowCoord.w ;
shadowCoordinateWdivide.z += 0.0005;
float distanceFromLight = texture2D(ShadowMap,shadowCoordinateWdivide.st).z;
float shadow = 1.0;
if (shadowCoord.w > 0.0)
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0 ;
out_Color = shadow * out_Color;
}
我得承認,我覺得我是一個有點超過我的頭,當談到了解整個過程,已經從各種來源拼湊起來。這個問題似乎很簡單,但我無法弄清楚。
以下是圖像:
不旋轉:
旋轉的:
編輯:
更改陰影貼圖片段着色器:
#version 150 core
layout(location=0) out float fragmentdepth;
void main(void) {
fragmentdepth = gl_FragCoord.z;
}
這是什麼語言? –
它使用Java(LWJGL) – Chris
好吧。我在問,因爲沒有語言標籤。我注意到有人添加了** c **標籤,我發現這是不正確的。這就是你不包含語言標籤時所得到的結果。 ;) –