Soru OpenGL Phong shader'ım neden düz bir gölgelendirici gibi davranıyor?


Son birkaç haftadır OpenGL'yi öğreniyorum ve bir Phong gölgelendiricisini uygulamakta zorlanıyorum. Kullandığım her şeye rağmen vertexler arasında interpolasyon yapmıyor gibi görünüyor. smooth eleme. Burada bir şey mi eksik? Kredinin vadesi geldiğinde kredi vermek için, köşe ve parça gölgelendiricilerin kodları, OpenGL SuperBible Beşinci baskı. Bu kitabı kesinlikle tavsiye ederim!

Vertex Shader:

#version 330
in vec4 vVertex;
in vec3 vNormal;
uniform mat4 mvpMatrix;  // mvp = ModelViewProjection
uniform mat4 mvMatrix; // mv = ModelView
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;

void main(void) {
 vVaryingNormal = normalMatrix * vNormal;
 vec4 vPosition4 = mvMatrix * vVertex;
 vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
 vVaryingLightDir = normalize(vLightPosition - vPosition3);
 gl_Position = mvpMatrix * vVertex;
}

Fragman Shader:

#version 330
out vec4 vFragColor;
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;

void main(void) {
 float diff = max(0.0, dot(normalize(vVaryingNormal), normalize(vVaryingLightDir)));
 vFragColor = diff * diffuseColor;
 vFragColor += ambientColor;
 vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir),normalize(vVaryingNormal)));
 float spec = max(0.0, dot(normalize(vVaryingNormal), vReflection));

 if(diff != 0) {
   float fSpec = pow(spec, 32.0);
   vFragColor.rgb += vec3(fSpec, fSpec, fSpec);
 }

}

Vikipedi'nin bu (genel alan) resmi tam olarak ne tür bir görüntü aldığımı ve neyi amaçladığımı gösteriyor - "düz" görüntü alıyorum ama "Phong" görüntüsünü istiyorum.

Herhangi bir yardım büyük takdir edilecektir. Teşekkür ederim!

düzenleme: Bir fark yaratırsa, PyOpenGL 3.0.1 ve Python 2.6 kullanıyorum.

edit2:

Çözüm

Problemin geometri ile olduğu ortaya çıktı; Kos haklıydı. Bu problemi Blender modellerine sahip olan herkes için Kos, bunu yaptıklarına işaret etti. Edit->Faces->Set Smooth hile yapar. Wings 3D'nin "kutudan çıktı" olduğunu keşfettim.


44
2018-01-16 02:20


Menşei


Aynı çözüm benim için çalıştı. Çok teşekkür ederim. - Vinod


Cevaplar:


Hmm ... Normal olanı enterpolasyon yapıyorsun. varying değişken, bu yüzden fragman shader normal piksel başına doğru piksel almalıdır.

Sol görüntüde sonucu aldığınızın tek açıklaması (düşünebilirim) Belirli bir yüzdeki her fragman, sonuçta aynı normali alır.. Aşağıdaki gibi bir parça gölgelendirici ile onaylayabilirsiniz:

void main() {
   vFragColor = normalize(vVaryingNormal);
}

Durum buysa, soru şu: Neden? Köşe gölgelendirici Tamam görünüyor.

Yani belkide yanlış bir şey var. geometri? Gölgeye gönderdiğiniz veriler nedir? Sadece yüz yüze değil, her bir köşe başı değerlerini doğru hesapladığınızdan emin misiniz?

normals

Turuncu çizgiler diyagonal yüzün normalleridir, kırmızı çizgiler yatay yüzün normalleridir.

Verileriniz yukarıdaki görüntü gibi görünüyorsa, doğru bir gölgelendirici ile bile düz gölgelendirme elde edersiniz. Alt görüntüde olduğu gibi köşe başına doğru normal değerlere sahip olduğunuzdan emin olun. (Bir küre için hesaplamak gerçekten çok basittir.)


48
2018-01-16 14:00



Sadece @Kos'un "bir küre için hesaplanması gerçekten basit" ile ne anlama geldiğini belirtmek isteriz: Kökte bir birim yarıçap küre durumunda, normal, köşe konumuyla aynıdır. - datenwolf
Kod snippet'inizi denedim ve renk enterpolasyonu olmadı, bu yüzden bunun geometri ile ilgili bir problem olduğunu tahmin ediyorum. Kullandığım küre aslında Blender'dan Wavefront OBJ dosya formatına aktarıldı. Normal değerler Blender'da doğru görünüyor, ama dışarı çıktıklarından emin olmak için yapabileceğim bir şey var mı? - Jonba
Hmm ... Bu garip. Yaptın mı Edit->Faces->Set Smooth ihracattan önce Blender'da? - Kos
Bu mükemmel çalıştı! Ayrıca, Wings 3D'nin herhangi bir düzleştirme belirtmek zorunda kalmadan iyi oynayan normalleri dışa aktardığını görüyorum. - Jonba
Bazen bazen bir sonuç istersiniz, bazen diğerini istersiniz - nerede kontrol edeceğinizi bilmek iyidir. Ama Blender'da neden pürüzsüz görüneceğini bilmiyorum. önce Bunu sen mi ayarladın? - Kos


Bu cevaba ek olarak, burada normallerinizi görselleştirmenize izin veren basit bir geometri gölgelendiricisi var. Öznitelik konumlarınıza ve matrislerinizi nasıl göndereceğinize bağlı olarak, gereken köşe gölgelendiricisini gerektiği gibi değiştirin.

Ama ilk olarak, arkadaşımızın Stanford tavşasından dev bir tavşan kafasının resminin bir örneği!

normals for the Stanford bunny

Büyük uyarı: normal normal bir matris yerine normallleri modelleme matrisi ile dönüştürmeyi bıraktığımı unutmayın. Model görünümünüz düzgün olmayan ölçekleme içeriyorsa, bu düzgün çalışmayacaktır. Ayrıca, normallerinizin uzunluğu doğru olmayacak, ancak sadece yönlerini kontrol etmek istediğinizde önemsiz.

Vertex shader:

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 normal;
layout(location = 2) in mat4 mv;

out Data
{
    vec4 position;
    vec4 normal;
    vec4 color;
    mat4 mvp;
} vdata;

uniform mat4 projection;

void main()
{
    vdata.mvp = projection * mv;
    vdata.position = position;
    vdata.normal = normal;
}

Geometri gölgelendirici:

#version 330
layout(triangles) in;
layout(line_strip, max_vertices = 6) out;

in Data
{
    vec4 position;
    vec4 normal;
    vec4 color;
    mat4 mvp;
} vdata[3];

out Data
{
    vec4 color;
} gdata;

void main()
{
    const vec4 green = vec4(0.0f, 1.0f, 0.0f, 1.0f);
    const vec4 blue = vec4(0.0f, 0.0f, 1.0f, 1.0f);

    for (int i = 0; i < 3; i++)
    {
        gl_Position = vdata[i].mvp * vdata[i].position;
        gdata.color = green;
        EmitVertex();

        gl_Position = vdata[i].mvp * (vdata[i].position + vdata[i].normal);
        gdata.color = blue;
        EmitVertex();

        EndPrimitive();
    }
}

Parça gölgelendiricisi:

#version 330

in Data
{
    vec4 color;
} gdata;

out vec4 outputColor;

void main()
{
    outputColor = gdata.color;
}

64
2018-02-28 14:18



Ne kadar serin! - Kos