2013-08-26 4 views
0

Я делаю пиксельный шейдер освещения в GLSL. На рисунке изображена сетка кубов, в которой, в зависимости от того, какой порядок они нарисованы, стороны, которые должны быть затенены, отображаются поверх других. Это не проблема, когда я переключаюсь на настройку освещения фиксированной функции opengl. Что вызывает его, как его исправить?GLSL - Как избежать дублирования многоугольников?

what it looks like

вершинные шейдеры:

varying vec4 ecPos; 
varying vec3 normal; 

void main() 
{ 

gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 

/* first transform the normal into eye space and normalize the result */ 
normal = normalize(gl_NormalMatrix * gl_Normal); 

/* compute the vertex position in camera space. */ 
ecPos = gl_ModelViewMatrix * gl_Vertex; 


gl_Position = ftransform(); 

} 

пиксельный шейдер:

varying vec4 ecPos; 
varying vec3 normal; 

uniform sampler2D tex; 
uniform vec2 resolution; 

void main() 
{ 
vec3 n,halfV,lightDir; 
float NdotL,NdotHV; 

vec4 color = gl_LightModel.ambient; 
vec4 texC = texture2D(tex,gl_TexCoord[0].st) * gl_LightSource[0].diffuse; 

float att, dist; 

/* a fragment shader can't write a verying variable, hence we need 
a new variable to store the normalized interpolated normal */ 
n = normalize(normal); 

// Compute the ligt direction 
lightDir = vec3(gl_LightSource[0].position-ecPos); 

/* compute the distance to the light source to a varying variable*/ 
dist = length(lightDir); 


/* compute the dot product between normal and ldir */ 
NdotL = max(dot(n,normalize(lightDir)),0.0); 

if (NdotL > 0.0) { 

    att = 1.0/(gl_LightSource[0].constantAttenuation + 
      gl_LightSource[0].linearAttenuation * dist + 
      gl_LightSource[0].quadraticAttenuation * dist * dist); 
    color += att * (texC * NdotL + gl_LightSource[0].ambient); 


    halfV = normalize(gl_LightSource[0].halfVector.xyz); 
    NdotHV = max(dot(n,halfV),0.0); 
    color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess); 

} 


gl_FragColor = color; 
} 

Шейдеры в основном модифицированные версии этих http://www.lighthouse3d.com/tutorials/glsl-tutorial/point-light-per-pixel/

+0

Извините, «за пиксельное освещение». – everling

ответ

5

Ну вы, вероятно, забыл включить GL_DEPTH_TEST.

Вы должны позвонить glEnable(GL_DEPTH_TEST);, что позволило OpenGL проверить глубину различных примитивов. Поэтому, когда OpenGL рендерит, он не будет случайным образом отображать вещи поверх других вещей, которые на самом деле должны быть позади!

http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml

+2

или ОП забыл выделить буфер глубины с тем же результатом. – Bahbar

Смежные вопросы