WebGL 变形位置为空

Luc*_*ore 2 null shader lighting webgl

我正在学习 WebGL,而且我对 Stack Overflow 也很陌生。如果我做错了什么,很抱歉。我的问题是照明不太好用。我想我隔离了这个问题。我的一些制服位置是空的。

在寻找解决方案时,我发现如果不使用变量,编译器会优化它们。但是它们用于我的着色器中!所以我不知道还有什么可能出错。

这是我正在使用的着色器,下面我报告哪些变量为空。同样有趣的是,只有其中一些为空,我无法弄清楚为什么它们不同。对我的着色器的任何帮助都会让我非常感激。

<script id="shader-f-textcol-per_frag_light" type="x-shader/x-fragment">
 precision mediump float;

 varying vec2 vTextureCoord;
 varying vec3 vTransformedNormal;
 varying vec4 vPosition;
 varying vec4 vColor;

 uniform bool uUseAmbientLight;
 uniform bool uUseSpecLight;
 uniform bool uUseDirectLight;
 uniform bool uUsePointLight;

 uniform int  uMode;

 uniform float uMaterialShine;
 uniform float uAlpha;

 uniform vec3 uAmbientColor;

 uniform vec3 uPointLightingLocation;
 uniform vec3 uPointLightingColor;

 uniform vec3 uDirectLightingDirection;
 uniform vec3 uDirectLightingColor;

 uniform sampler2D uSampler;

 void main(void) {

   vec3 ambientColor = uAmbientColor;
   vec3 lightWeighting = vec3(1.0,1.0,1.0);

   vec3 normal = normalize(vTransformedNormal);    
   vec3 lightDirection = normalize(uPointLightingLocation - vPosition.xyz);

   float directionalLightWeighting = 0.0;
   float specularLightWeighting = 0.0;
   float pointLightWeighting = 0.0;

   if(!uUseAmbientLight)
   {
       ambientColor = vec3(0.0,0.0,0.0);
   }
   if(uUseDirectLight)
   {
       directionalLightWeighting = max(dot(normal, uDirectLightingDirection), 0.0);
   }
   if(uUsePointLight)
   {
       float pointLightWeighting = max(dot(normal, lightDirection), 0.0);

       float specularLightWeighting = 0.0;
       if (uUseSpecLight) {
           vec3 eyeDirection = normalize(-vPosition.xyz);
           vec3 reflectionDirection = reflect(-lightDirection, normal);

           specularLightWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), uMaterialShine);
       }
   }

   lightWeighting = ambientColor + uDirectLightingColor * directionalLightWeighting + uPointLightingColor  * pointLightWeighting + uPointLightingColor  * specularLightWeighting;

   vec4 fragmentColor;
   if (uMode == 0) 
   {
       fragmentColor = vColor;
   }
   else if (uMode == 1)
   {
       fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
   }
   else 
   {
        fragmentColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;
   }

   gl_FragColor = vec4(fragmentColor.rgb * lightWeighting, fragmentColor.a*uAlpha);

  }
 </script>

 <script id="shader-v-textcol-per_frag_light" type="x-shader/x-vertex">
 attribute vec3 aVertexPosition;
 attribute vec3 aVertexNormal;
 attribute vec4 aVertexColor;
 attribute vec2 aTextureCoord;

 uniform mat4 uMVMatrix;
 uniform mat4 uPMatrix;
 uniform mat3 uNMatrix;

 varying vec2 vTextureCoord;
 varying vec3 vTransformedNormal;
 varying vec4 vPosition;
 varying vec4 vColor;

 void main(void) {
   vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
   gl_Position = uPMatrix * vPosition;
   vTextureCoord = aTextureCoord;
   vTransformedNormal = uNMatrix * aVertexNormal;
   vColor = aVertexColor;
    }
   </script> 
Run Code Online (Sandbox Code Playgroud)

这是制服的印刷品。只有与点照明和镜面高光相关的那些是空的。

     uMaterialShine null
     uUseSpecularLight null
     uUseAmbientLight [object WebGLUniformLocation]
     uUsePointLight null
     uUseDirectLight [object WebGLUniformLocation]
     uAmbientColor [object WebGLUniformLocation]
     uPointLightingLocation null
     uPointLightingColor null
     uAmbientColor [object WebGLUniformLocation]
     uDirectLighting [object WebGLUniformLocation]
     uDirectLightingDirection [object WebGLUniformLocation]
     uAlpha [object WebGLUniformLocation]
Run Code Online (Sandbox Code Playgroud)

gma*_*man 7

您的着色器中不使用这些制服。大多数司机会优化这些制服,因此他们不会有位置。

正是由于这个原因,gl.uniform???使用null位置调用是无操作的,因此在编辑着色器时,如果您的代码查找已优化代码设置的制服,则制服不会开始产生错误。

// even if the uniform does not exist this code 
// will not generate an error.
var locationOfMissingLocation = gl.getUniformLocation(prg, "foobar");
...
gl.uniform4f(locationOfMissingLocation, r, g, b, a);
Run Code Online (Sandbox Code Playgroud)

您应该设计您的代码,使其无论是否存在统一(或属性)都能正常工作。这样,当您调试和注释掉着色器的某些部分以找出问题所在时,您的程序仍然可以运行。