2012-03-20 98 views
16

基於像素的照明是許多OpenGL應用程序中的常見問題,因爲標準OpenGL照明質量非常差。通用GLSL照明着色器

我想使用GLSL程序在我的OpenGL程序中使用基於像素的照明,而不是每個頂點。只是散射照明,但至少具有霧,紋理和紋理。

我開始與this shader

texture.vert:

varying vec3 position; 
varying vec3 normal; 

void main(void) 
{ 
    gl_Position  = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_FrontColor  = gl_Color; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    normal  = normalize(gl_NormalMatrix * gl_Normal); 
    position  = vec3(gl_ModelViewMatrix * gl_Vertex); 
} 

texture.frag:

uniform sampler2D Texture0; 
uniform int ActiveLights; 

varying vec3 position; 
varying vec3 normal; 

void main(void) 
{ 
    vec3 lightDir; 
    float attenFactor; 
    vec3 eyeDir   = normalize(-position); // camera is at (0,0,0) in ModelView space 
    vec4 lightAmbientDiffuse = vec4(0.0,0.0,0.0,0.0); 
    vec4 lightSpecular  = vec4(0.0,0.0,0.0,0.0);  

    // iterate all lights 
    for (int i=0; i<ActiveLights; ++i) 
    { 
    // attenuation and light direction 
    if (gl_LightSource[i].position.w != 0.0) 
    { 
     // positional light source 
     float dist = distance(gl_LightSource[i].position.xyz, position); 
     attenFactor = 1.0/(gl_LightSource[i].constantAttenuation + 
        gl_LightSource[i].linearAttenuation * dist + 
        gl_LightSource[i].quadraticAttenuation * dist * dist); 
     lightDir = normalize(gl_LightSource[i].position.xyz - position); 
    }  
    else 
    {   
     // directional light source   
     attenFactor = 1.0;   
     lightDir = gl_LightSource[i].position.xyz;  
    }  
    // ambient + diffuse   
    lightAmbientDiffuse  += gl_FrontLightProduct[i].ambient*attenFactor;  
    lightAmbientDiffuse  += gl_FrontLightProduct[i].diffuse * max(dot(normal, lightDir), 0.0) * attenFactor; 
    // specular  
    vec3 r  = normalize(reflect(-lightDir, normal)); 
    lightSpecular += gl_FrontLightProduct[i].specular * 
        pow(max(dot(r, eyeDir), 0.0), gl_FrontMaterial.shininess) * 
        attenFactor; 
    }  
    // compute final color  
    vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy);  
    gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular; 

    float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; // Intensität berechnen 
    fog  = clamp(fog, 0.0, 1.0);     // Beschneiden 
    gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog);   // Nebelfarbe einmischen 
} 

評論是德國,因爲它是這個地方代碼被髮布了德國網站,對不起。

但是所有這些着色器都會讓所有的東西都變得很黑。根本沒有照明效果 - 但是着色器代碼編譯。如果我只在片段着色器中使用GL_LIGHT0,那麼它似乎可行,但只適用於面向相機的多邊形和我的地板多邊形,它們非常黑暗。此外,RGBA紋理顯示沒有透明度。 我對模型視圖矩陣使用標準glRotate/Translate,對我的多邊形使用glVertex/Normal。除了在非常大的表面上看起來醜陋這一事實,OpenGL照明效果很好。我三重檢查了我的法線,他們很好。

上面的代碼有什麼問題嗎? 或 告訴我爲什麼這個實際任務沒有通用照明着色器(基於點的距離衰減燈:如果你願意的話) - 不應該只有一個正確的方法來做到這一點嗎?我不想碰/正常/視差/香椿/模糊/任何效果。我只想讓我的燈光在更大的多邊形下表現更好。

我發現的所有教程僅適用於當相機處於與對象正交的0,0,0時照明單個對象。以上是唯一發現的,至少看起來像我想做的事情。

+1

顯而易見的第一:你是否綁定了一個採樣器,你的紋理座標和法線是否正確,如果將gl_FragColor設置爲固定顏色,是否顯示幾何?對於着色器,我發現通過一次只使用一個特徵並添加一些小特徵,在沒有能夠進入和追蹤它們的情況下,我可以更容易地理解它們:p。 – Robinson 2012-03-20 10:37:09

+0

採樣器是TEXTURE_2D,它綁定了渲染的多邊形。紋理座標是正確的,因爲普通的openGL燈具完美無瑕。法線是完美的(如前所述)。是的,它會在將gl_FragColor設置爲固定顏色或僅設置texColor時顯示幾何圖形。 – Rock 2012-03-20 12:55:36

回答

10

我強烈建議您閱讀 this article怎麼看標準ADS閃電GLSL.That內做的是GL 4.0,但不是一個問題,以適應您的版本:

而且您可以在視圖操作(攝像頭)的空間,以便DON「T否定眼睛矢量:

vec3 eyeDir = normalize(-position); 

我有非常類似的問題,以你的,因爲我也否定了眼睛矢量忘記了它轉化爲視圖space.Your漫射和鏡面計算似乎是在當前情況下也是錯誤的。在你的地方,我根本不會使用來自固定管道的數據erwise在着色器中做什麼要點? 這裏是計算在每個片段ADS點閃電漫射和鏡面的方法:

void ads(int lightIndex,out vec3 ambAndDiff, out vec3 spec) 
{ 


vec3 s = vec3(lights[lightIndex].Position - posOut) ; 
vec3 v = normalize(posOut.xyz); 
vec3 n = normalize(normOut); 
vec3 h = normalize(v+s) ;// half vector (read in the web on what it is) 


    vec3 diffuse = ((Ka+ lights[lightIndex].Ld) * Kd * max(0.0,dot(n, v))) ; 
    spec = Ks * pow(max(0.0, dot(n,h)), Shininess) ; 


ambAndDiff = diffuse ; 

/// Ka-material ambient factor 
/// Kd-material diffuse factor 
/// Ks-material specular factor. 
/// lights[lightIndex].Ld-lights diffuse factor;you may also add La and Ls if you want to have even more control of the light shading. 
} 

而且我也不會用你這裏有衰減公式建議你,這是很難control.If要增加基於光線半徑的衰減 there is this nice blog post: