0

我目前正在 iOS 上的 Open GL ES 2.0 中实现聚光灯。我所有的照明计算都是在世界空间中完成的(即我将世界空间坐标传递给着色器)。

我在场景中水平放置了一个地板网格(非常好的镶嵌),并在 (0,250,0) 处放置了一个光源,即直接向上。在我的着色器中,我将灯光硬编码为直接指向下方 (0,-1,0)。在这种情况下,聚光灯锥不起作用。但是,当我将地板位置向上提升(在 y 轴上,靠近灯光)时,聚光灯会在某个点“出现”。此外,就在它出现之前,地板上出现了一个奇怪的锥形“镜像”轮廓,并且在一定的阈值下,存在一些明显的渲染错误(下图第四张)

请参阅以下相册中的屏幕截图,每张图片都以地板越来越接近光线的方式排列。最终图像显示它工作正常

http://imgur.com/a/cKOll

此外 - 这些屏幕是在 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)。

4

1 回答 1

0

答案是在着色器中使相关向量和矩阵都具有高精度(highp)。

于 2013-04-07T21:25:52.707 回答