Gölge Haritaları: Gerçekçi Işık Hesaplama Adım Adım

Gölge haritası, ışık kaynağının bakış açısından sahneyi bir doku olarak render etmek ve daha sonra piksellerin ışığa göre gölgede olup olmadığını kontrol etmek için kullanılan bir tekniktir. Gerçekçi gölgeler oluşturmanın en yaygın yöntemidir.

Temel fikir şu: ışığın gözünden baktığında bir pikselin ne kadar uzakta olduğunu kaydedersin. Sonra sahneyi normal kameradan render ederken, her piksel için ışığa olan mesafeyi hesaplar ve gölge haritasında saklanan değerle karşılaştırırsın. Eğer piksel ışıktan daha uzaksa, gölgededir.

Adım 1: Derinlik Haritası Oluştur

İlk olarak ışık kaynağının konumundan sahneyi render edersin. Normalde renk render etmek yerine, her pikselin ışıktan ne kadar uzak olduğunu (derinlik değerini) kaydedersin.

1// GLSL - Derinlik haritası vertex shader
2uniform mat4 lightSpaceMatrix;
3
4void main()
5{
6gl_Position = lightSpaceMatrix * vec4(aPosition, 1.0);
7}

Fragment shader sadece derinlik değerini kaydeder; OpenGL bunu otomatik olarak yapar.

Adım 2: Gölge Haritasını Kullan

Asıl render geçişinde, her piksel için ışık uzayında konumunu hesapla, gölge haritasından o konumdaki derinliği oku ve karşılaştır:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1// GLSL - Gölge hesaplama fragment shader
2uniform sampler2D shadowMap;
3uniform mat4 lightSpaceMatrix;
4
5float shadowCalculation(vec4 fragPosLightSpace)
6{
7vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
8projCoords = projCoords * 0.5 + 0.5; // NDC'den [0,1] aralığına
9
10float closestDepth = texture(shadowMap, projCoords.xy).r;
11float currentDepth = projCoords.z;
12
13float shadow = currentDepth > closestDepth? 1.0: 0.0;
14return shadow;
15}

Eğer piksel ışıktan daha uzaksa (currentDepth > closestDepth), gölge değeri 1 olur; aksi halde 0.

Adım 3: Yumuşatma (Soft Shadows)

Sert kenarları yumuşatmak için gölge haritasının çevresindeki değerleri örnekle:

1float shadow = 0.0;
2vec2 texelSize = 1.0 / textureSize(shadowMap, 0);
3
4for(int x = -1; x <= 1; ++x)
5for(int y = -1; y <= 1; ++y)
6{
7float pcfDepth = texture(shadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
8shadow += currentDepth > pcfDepth? 1.0: 0.0;
9}
10shadow /= 9.0; // Ortalama gölge değeri

Bu, 3x3 piksel çevresi kontrol ederek gölge kenarlarını yumuşatır.

Pratik Çıktı

Sahneyi render ettiğinde, ışık kaynağının arkasındaki nesneler gölge içinde kalır; aydınlık alanlar normal renkle gösterilir. Gölge kenarları pürüzsüz ve doğal görünür.

Gölge haritaları hızlı ve ölçeklenebilir; birden fazla ışık için aynı yöntemi tekrarla. Bknz: Sahne Optimizasyonu: Culling ve LOD Sistemleri Pratik Uygulaması - performans için culling stratejileri.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz