2

我有一个片段着色器,可以进行视差映射和照明计算。我已经设法将问题追溯到纹理和/或照明计算的采样,所以我只会发布代码以保持简短:

// sample maps
vec3 albedo = texture2D(u_albedo_texture_1, p_texc).rgb;
vec3 ao = texture2D(u_ambientocclusion_texture, v_texcoord).rgb - 0.5; // ambient occlusion
vec3 normalT = texture2D(u_normalmap_texture, p_texc).rgb * 2.0 - 1.0; // tangent space normal

vec4 normalW = vec4(normalize(TBN * normalT).xyz, 1.0); // world space normal

vec3 color = vec3(0.0);
vec3 ambient = textureCube(u_cubemap_texture, -normalW.xyz).rgb; // get ambient lighting from cubemap
color += ambient * ao;

float d = length(light_vector);
float atten = 1.0 / dot(light_attenuation, vec3(1.0, d, d * d)); // compute attenuation of point light

// diffuse term
float ndotl = max(dot(normalW.xyz, light_vector), 0.0);
color += atten * ndotl * light_diffuse.rgb * albedo;

// specular term
float hdotn = max(0.0, dot(half_vector, normalW.xyz));
color += atten * ((shininess + 8.0) / 8.0 * 3.1416) * light_specular.rgb * p_ks * pow(hdotn, shininess);

gl_FragColor = vec4(color.rgb, 1.0);

我有这个代码在其他着色器中工作,但是在视差映射着色器中它只是丢弃了像素,我不明白为什么。因此,它不是显示对象,而是简单地丢弃像素,并且对象根本不显示。没有错误或凌乱的颜色,什么都没有。

我设法将问题追溯到反照率和环境采样颜色。它们都被正确采样。如果我打印出来

gl_FragColor = vec4(ambient.rgb, 1.0);

或者

gl_FragColor = vec4(albedo.rgb, 1.0);

它们都可以正确显示,但是如果我尝试用两种颜色做某事,像素就会被丢弃。以下都不起作用:

gl_FragColor = vec4(ambient + albedo, 1.0);
gl_FragColor = vec4(ambient * albedo, 1.0);
gl_FragColor = vec4(ambient.r, albedo.g, ambient.b, 1.0);

环境是从立方体贴图中采样的,反照率是从 2D 纹理中采样的。我有其他用于环境光遮蔽和法线贴图的采样器,它们可以工作,它们也可以与环境光或反照率结合使用。所以环境 + ao 有效,反照率 + ao 有效。

所以,这是我的问题,我不知道是什么原因造成的。就像我说的,我在另一个着色器中有相同的代码,并且那个代码有效。

值得一提的是,它在 OpenGL ES 2.0 的 PowerVR 模拟器上运行。GPU是nVidia GT220。也可以随意指出我的代码中的其他错误,比如低效的东西。如有必要,我将发布完整的片段着色器代码。对不起,很长的帖子:P

解决了

哇,不敢相信原因如此愚蠢,但我完全错过了它。基本上,我忘记为该特定模型加载立方体贴图,并且它没有发送到着色器。不过,它到底是如何对某些东西进行采样的呢?我的意思是,它是单独工作的,那么纹理单元采样了什么?先前处理后遗留在缓存中的立方体贴图?

4

1 回答 1

0

不过,它到底是如何对某些东西进行采样的呢?

通常,当我的着色器没有产生所需的结果但看起来很“正常”时,这是因为着色器编译丢弃了它(我在某处犯了错误)并决定改用“固定管道”着色器......

于 2011-09-05T18:44:34.637 回答