我目前正在iOS上的Open GL ES 2.0中实现聚光灯。我的所有光照计算都是在世界空间中完成的(即我将世界空间坐标传递给着色器)。
我在场景中水平放置了一个地板网格(非常好的镶嵌),并在(0,250,0)处放置了一个光源,即直线。在我的着色器中,我将光线硬编码直接指向下方(0,-1,0)。在这种情况下,聚光灯锥不起作用。然而,当我在某一点向上抬起地板位置(在y轴上,越靠近光线)时,聚光灯“出现”。此外,就在它出现之前,一个奇怪的“镜像”轮廓出现在地板上,在某个阈值处,有一些明显的渲染错误(下面第四张图片)
查看以下相册中的屏幕截图,排列的地板越接近每个图像的光线。最终图像显示它正常工作
此外 - 这些屏幕是在ipad mini上拍摄的,但在xCode iOS模拟器上它完美运行!!
同样在“收盘”范围内,所有基本的phong计算都按预期工作。
关于可能导致问题的任何想法?
这是我的片段着色器:
// Fragment shader
precision highp float;
uniform mediump vec4 u_mat_diffuse;
uniform mediump vec4 u_mat_ambient;
uniform mediump float u_mat_specular;
uniform mediump float u_mat_shininess;
uniform mediump vec3 u_light_color;
uniform mediump float u_light_intensity;
uniform mediump vec3 u_light_spot_dir;
uniform mediump float u_light_spot_cutoff;
uniform mediump vec3 u_light_pos;
uniform mediump vec3 u_camera_eye;
varying mediump vec3 v_light_dir;
varying mediump vec3 v_normal;
varying mediump vec3 v_pos;
void main(void)
{
//normalize all first - v-pos is the vertex world position
//all uniforms are in world position
mediump vec3 E = normalize(u_camera_eye - v_pos);
mediump vec3 L = normalize(u_light_pos - v_pos);
mediump vec3 N = normalize(v_normal);
mediump vec3 light_direction = vec3(0.0, -1.0, 0.0); //light direction
mediump vec3 D = normalize(light_direction);
highp vec4 finalColor = vec4(0.0, 0.0, 0.0, 1.0);
//simple lambert
highp float ndotl = max(dot(N, L), 0.0);
highp vec3 DiffuseColor = vec3(1.0, 1.0, 1.0) * ndotl;
if (dot(-L, D) > 0.9)
{
finalColor += vec4(DiffuseColor, 1.0) * vec4(1.0, 0.0, 0.0, 1.0);
}
gl_FragColor = finalColor ;
}
编辑:如果我将finalColor设置为固定值(即不使用漫反射术语),那么它可以工作!所以扩散项的计算方式有问题
解决:
答案是使着色器中的相关矢量和矩阵都具有高精度(highp)。
答案 0 :(得分:0)
答案是使着色器中的相关矢量和矩阵都具有高精度(highp)。