2012-06-13 16 views
7

Bir yükseklik haritası oluşturan ve daha sonra OpenGL ile bir ağ olarak görüntüleyen bir programım var. Aydınlatma eklemeye çalıştığımda, örgüyi örten garip kare şekillerle sonuçlanır. Bazı bölgelerde diğerlerinden daha dikkat çekicidirler, fakat her zaman oradadırlar.Garip kare aydınlatma eserleri OpenGL

Dörtlü bir ağ kullanıyordum, ancak bir üçgen ağa geçtikten sonra hiçbir şey değişmedi. Hepsi aynı etkiyle, köşe normallerini hesaplamak için en az üç farklı yöntem kullandım. Işığı el ile gölgelendiricilerle yapıyordum, ancak OpenGL aydınlatma sistemini kullanırken hiçbir şey değişmiyor. ben kullandım sadece kod olmasa da

int i; 
for (i = 0; i < NINDEX; i += 3) { 
    vec v[3]; 
    v[0] = verts[faces[i + 0]]; 
    v[1] = verts[faces[i + 1]]; 
    v[2] = verts[faces[i + 2]]; 

    vec v1 = vec_sub(v[1], v[0]); 
    vec v2 = vec_sub(v[2], v[0]); 

    vec n = vec_norm(vec_cross(v2, v1)); 

    norms[faces[i + 0]] = vec_add(norms[faces[i + 0]], n); 
    norms[faces[i + 1]] = vec_add(norms[faces[i + 1]], n); 
    norms[faces[i + 2]] = vec_add(norms[faces[i + 2]], n); 
} 

for (i = 0; i < NVERTS; i++) { 
    norms[i] = vec_norm(norms[i]); 
} 

, bu yüzden de şüphe:

Benim son Normal üreten kodu (bakan bir verts içine endekslerinin dizisi, köşe dizidir) problemin sebebidir.

Beraber örgü çizmek:

Ve şu anda herhangi bir gölgelendiricileri kullanmıyorum.

Buna neden olabilir?

DÜZENLEME: ekran görüntüleri daha kapsamlı kümesi: sonuncusu için

shader kodu

olduğunu

Vertex:

varying vec3 lightvec, normal; 

void main() { 
    vec3 lightpos = vec3(0, 0, 100); 
    vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex); 
    normal = gl_NormalMatrix * gl_Normal; 

    lightvec = normalize(lightpos - v); 

    gl_Position = ftransform(); 
} 

Fragment:

varying vec3 lightvec, normal; 

void main(void) { 
    float l = dot(lightvec, normal); 
    gl_FragColor = vec4(l, l, l, 1); 
} 
+0

Aynı sahnenin iki ekran görüntüsünü, biri tel çerçeveli ve diğeri olmadan kaydeder misiniz? –

+0

"Norms" sıfır başlatıldı mı? İlk önce sıfırlamadan vektörlerinizin içine biriktiriyorsunuz, ancak programda başka bir yerde sorun çıkmaması durumunda. – genpfault

+0

, gölgelendiricide normal öznitelikler için düzgün enterpolasyon kullanıyor musunuz? Belki biraz 'düz' için geçiş, sorunun yerelleştirilmesine yardımcı olabilir. Ayrıca, OpenGL aydınlatma benim için çok yorucu olma eğilimindedir - genellikle kendim yazdığım koddan daha eminim. –

cevap

1

ben olmayan shader sürümleri için kesin bir cevabım yok, ama piksel aydınlatma başına yapıyoruz eğer eklemek istedim fragman shader'ınız, muhtemelen fragman gölgelendiricisindeki normal ve lightvec'i normalleştirmelisiniz.

Bunu yapmazsanız, birim uzunlukta olmazlar (iki normalleştirilmiş vektör arasında doğrusal bir enterpolasyon mutlaka normalleştirilmez). Bu, gölgelendirici versiyonunda gördüğünüz eserlerin bazılarını açıklayabilir, çünkü nokta ürününün büyüklüğü, görüntünüze benzeyen köşelerden uzaklığın bir fonksiyonu olarak değişecektir.

DÜZENLEME: Başka bir düşünce, gölgelendirici olmayan sürümü oluştururken ağın eşit olmayan bir ölçeklemesini (farklı x, y, z) yapıyor musunuz? Eğer ölçeklendirirseniz, ya normal ölçekleri ters ölçek faktörü ile değiştirmeniz ya da glEnable(GL_NORMALIZE)'u ayarlamanız gerekir.Daha fazlası için buraya bakınız: Çok gibi, parça gölgelendirici normal normalleştirmek yapmalı ya http://www.lighthouse3d.com/tutorials/glsl-tutorial/normalization-issues/

2

:

varying vec3 lightvec, normal; 

void main(void) { 
    vec3 normalNormed = normalize(normal); 
    float l = dot(lightvec, normalNormed); 
    gl_FragColor = vec4(l, l, l, 1); 
} 

Bu olsa pahalı olabilir. Bu durumda da, yön ışıkları ile çalışacak olan, tepe ışıklandırması kullanmaktır. Yani, bu onu düzeltir umut

varying float light; 

void main(void) { 
    float l = light; 
    gl_FragColor = vec4(l, l, l, 1); 
} 

vertex shader

varying float lightItensity; 

void main() { 
    vec3 lightpos = vec3(0, 0, 100); 
    vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex); 
    normal = gl_NormalMatrix * gl_Normal; 

    lightvec = normalize(lightpos - v); 

    lightItensity = dot(normal, lightvec); 

    gl_Position = ftransform(); 
} 

ışık değerini hesaplamak ve parça gölgelendirici kullanmak, bunları yapmazsa bana bildirin.

DÜZENLEME: yani daha üçgenler ekleyin yardımcı olmazsa

: İşte küçük bir diyagram büyük olasılıkla olduğunu açıklayan

enter image description here

EDIT2 oluyor. Yükseklik haritanızın değerlerini yorumlayın ve aralarında bazı köşeler ekleyin.

Alternatif olarak, düzenleme düzeninizi değiştirmeyi deneyin. Örneğin, benzer bir eşkenar üçgen ağ yapısı, eserler daha az belirgin hale getirebilir.

enter image description here

Sen heightmap bazı interpolasyon yapmak gerekecektir.

Aksi halde hiç bir fikrim yok .. İyi şanslar!

+0

Teşekkürler, ama maalesef zaten böyle bir şey yapmayı denedim. Problemin benim grafik kartımda olup olmadığını merak etmeye başlıyorum (1.5 yaşında Intel entegre çip). – sigill

+0

Kesinlikle şüphe ediyorum. Gölgelendirici kodu, destekleyen herhangi bir grafik kartında aynı şekilde yürütülmelidir. – Hannesh