Shader在iOS上看起来很糟糕但在Windows上很好

Ben*_*Ben 0 opengl glsl ios opengl-es-2.0 glsles

我正在为Windows和iOS开发跨平台渲染器.对于一个示例应用程序,我编写了一个在两个平台上都没有问题的着色器(Windows上的着色器版本"#version 120"和iOS上的"#version 100").

接下来我添加了两个光源,在iOS上,奇怪的事情开始发生.我改变了我的代码几次,但它从未向我展示预期的结果(使用只有一个灯光的着色器渲染火炬,这就是为什么它在iOS上看起来很好).

(1)有时一切都是一种颜色:

在此输入图像描述

(2)有时它看起来很糟糕:

在此输入图像描述

在Windows上,它看起来像我期望它看起来:

在此输入图像描述

有谁知道为什么我的着色器在iOS上这样做?

这是(2)的片段着色器:

//Light
uniform mediump float  numLights;
//L0
uniform mediump vec4   lightPosition_0;
uniform mediump vec3   lightColor_0;
uniform mediump float  lightIntensity_0;
uniform mediump float  lightAttenuation_0;
//L1
/*same as for light 0 */
//L2
/*same as for light 0 */

uniform mediump vec3    ambientColor;

uniform mediump vec3 Ka;
uniform mediump vec3 Kd;
uniform mediump vec3 Ks;

uniform sampler2D NormalMap;
uniform sampler2D DiffuseMap;
uniform sampler2D SpecularMap;

varying highp vec4 texCoordVarying;

varying highp vec4 posWorldSpace;       // pos in View Space

varying highp vec3 tangentSurface2light_0;
varying highp vec3 tangentSurface2light_1;
varying highp vec3 tangentSurface2light_2;

void main()
{
    //normal based on normal map
    highp vec3 normalNormalMap = normalize(texture2D(NormalMap, texCoordVarying.st).xyz *2.0 - 1.0);

    //ambient light
    highp vec3 ambient  = clamp(ambientColor + Ka, 0.0, 1.0);

    //diffuse light
    highp vec3 diffuse;

    // light 0
    if(numLights >= 1.0)
    {
        //light intensity based on distance from light to object
        highp float distance = distance(posWorldSpace, lightPosition_0);
        highp float intensityBasedOnDist = lightIntensity_0/(lightAttenuation_0*distance*distance);
        intensityBasedOnDist = clamp(intensityBasedOnDist, 0.0, 1.0);

        //light intensity based on angle between normal and light vector
        highp float intensity = max(dot(normalNormalMap,tangentSurface2light_0), 0.0) ;
        intensity = clamp(intensity, 0.0, 1.0);

        //diffuse light
        diffuse  += lightColor_0 * intensity * intensityBasedOnDist;
    }
    // light 1
    if(numLights >= 2.0)
    {
        /*same as for light 0 */
    }
    // light 2
    if(numLights >= 3.0)
    {
       /*same as for light 0 */
    }

    diffuse = diffuse * Kd * texture2D(DiffuseMap, texCoordVarying.st).xyz;

    gl_FragColor = vec4(clamp(ambient + diffuse, 0.0, 1.0), 1.0);
}
Run Code Online (Sandbox Code Playgroud)

我做了很多东西或者是高级的.当我把它变成高速时,它有时几乎看起来是正确的,但现在甚至连那个技巧似乎都没有帮助......

Pod*_*kiy 5

  1. 您不得使用未初始化的变量.查看漫反射变量,向未初始化变量添加值.只需更换:

    highp vec3 diffuse;
    
    Run Code Online (Sandbox Code Playgroud)

    有:

    highp vec3 diffuse = vec3(0,0,0);
    
    Run Code Online (Sandbox Code Playgroud)

    如果使用未初始化的变量,则行为可能因驱动程序而异.

  2. 尽可能避免if语句.对于您的情况,最好为一个,两个和三个灯创建三个单独的着色器.您可以使用预处理器来保留单个源文件.