Gölgelendiricileri kullanarak OpenGL'de ilk kez temel gölge haritalama uyguladım ve bazı sorunlarla karşılaşıyorum. Aşağıda, oluşturulan sahnemin bir örneğini görebilirsiniz:
Takip ettiğim gölge eşleme işlemi, ışığı bakış açısından bir Görünüm Matrisi ile normal oluşturma için kullanılan projeksiyon ve model matrislerini kullanarak sahneyi çerçeve arabelleğine oluşturmamdır.
İkinci geçişte, yukarıdaki MVP matrisini ışık bakış açısından, pozisyonu ışık boşluğuna dönüştüren köşe gölgelendiricisine gönderirim. Parça gölgelendirici perspektif bölünür ve konumu doku koordinatlarına değiştirir.
İşte tepe gölgelendiricim,
#version 150 core
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 MVPMatrix;
uniform mat4 lightMVP;
uniform float scale;
in vec3 in_Position;
in vec3 in_Normal;
in vec2 in_TexCoord;
smooth out vec3 pass_Normal;
smooth out vec3 pass_Position;
smooth out vec2 TexCoord;
smooth out vec4 lightspace_Position;
void main(void){
pass_Normal = NormalMatrix * in_Normal;
pass_Position = (ModelViewMatrix * vec4(scale * in_Position, 1.0)).xyz;
lightspace_Position = lightMVP * vec4(scale * in_Position, 1.0);
TexCoord = in_TexCoord;
gl_Position = MVPMatrix * vec4(scale * in_Position, 1.0);
}
Ve parça gölgelendiricim,
#version 150 core
struct Light{
vec3 direction;
};
uniform Light light;
uniform sampler2D inSampler;
uniform sampler2D inShadowMap;
smooth in vec3 pass_Normal;
smooth in vec3 pass_Position;
smooth in vec2 TexCoord;
smooth in vec4 lightspace_Position;
out vec4 out_Color;
float CalcShadowFactor(vec4 lightspace_Position){
vec3 ProjectionCoords = lightspace_Position.xyz / lightspace_Position.w;
vec2 UVCoords;
UVCoords.x = 0.5 * ProjectionCoords.x + 0.5;
UVCoords.y = 0.5 * ProjectionCoords.y + 0.5;
float Depth = texture(inShadowMap, UVCoords).x;
if(Depth < (ProjectionCoords.z + 0.001)) return 0.5;
else return 1.0;
}
void main(void){
vec3 Normal = normalize(pass_Normal);
vec3 light_Direction = -normalize(light.direction);
vec3 camera_Direction = normalize(-pass_Position);
vec3 half_vector = normalize(camera_Direction + light_Direction);
float diffuse = max(0.2, dot(Normal, light_Direction));
vec3 temp_Color = diffuse * vec3(1.0);
float specular = max( 0.0, dot( Normal, half_vector) );
float shadowFactor = CalcShadowFactor(lightspace_Position);
if(diffuse != 0 && shadowFactor > 0.5){
float fspecular = pow(specular, 128.0);
temp_Color += fspecular;
}
out_Color = vec4(shadowFactor * texture(inSampler, TexCoord).xyz * temp_Color, 1.0);
}
Sorunlardan biri resimde gördüğünüz gibi kendi kendine gölgeleme, sandığın kendi üzerine kendi gölge atması var. Ne denedim çokgen ofset (yani glEnable (POLYGON_OFFSET_FILL), glPolygonOffset (GLfloat, GLfloat)) etkinleştirmek ama çok değişmedi. Parça gölgelendiricide gördüğünüz gibi, 0.001 statik ofset değerini koydum, ancak çok kullanışlı olmayan daha arzu edilen efektler elde etmek için ışığın mesafesine bağlı olarak değeri değiştirmek zorundayım. Ayrıca çerçeveciye dönüştürdüğümde ön yüz toplama kullanmayı denedim, bu çok fazla değişmedi.
Diğer sorun, Işığın görüş frustumunun dışındaki piksellerin gölgeli olması. Gölgeleme yapabilmesi gereken tek nesne sandıktır. Sanırım daha uygun projeksiyon seçmeli ve matrisleri görüntülemeliyim, ama bunu nasıl yapacağımdan emin değilim. Ortografik bir projeksiyon seçmem gereken bazı yaygın uygulamalar nelerdir?
Biraz dolaşmaktan, bu sorunların o kadar da önemsiz olmadığını anlıyorum. Herkes bu sorunlara uygulamak kolay çözüm var mı? Bana bazı ek ipuçları verebilir misiniz?
Kodum hakkında daha fazla bilgiye ihtiyacınız olup olmadığını lütfen bana sorun.
İşte sandığın yakın planının gölge eşlemeli ve eşlemesiz karşılaştırması. Kendi kendine gölgeleme daha görünür.