0

我使用 Android Open GL ES2.0 Java API 编写了一个 3D 渲染程序。它在我运行 Android 3.1 的 Xoom 上运行良好。

我正在尝试在 Android 版本分别为 4.0.3 和 4.2 的 HTC Evo 3D 和三星 Galaxy S4 上运行它。没有显示渲染。GLSurface View 上的黑色窗口。Logcat 显示错误消息“无法编译着色器 35633(35632):”和“E/Adreno200-ES20(15586): <__load_uniform_int:258>: GL_INVALID_OPERATION”

从 3.1 到 4.0 的哪些变化导致着色器无法编译?

该程序显示月球绕地球运行。它实现了由类似于太阳的光引起的动态阴影。它还实现了由地球海洋表面上的光引起的镜面反射光。

地球顶点着色器:

attribute vec4 aPosition;   
attribute vec3 aNormal;   
attribute vec2 aTextureCoord;   

varying mediump vec2 vTextureCoord;   
varying lowp vec4 colorVarying1;
varying lowp vec4 colorVarying2;
varying vec4 vPosition;    
varying vec3 nPos;
varying vec3 vNormal;

uniform vec3 uLight1Position;   
uniform vec4 uLight1Color;
uniform vec3 uLight2Position;   
uniform vec4 uLight2Color;
uniform mat4 uMVPMatrix;
uniform vec4 uAmbientLight;

void main() {   
  vTextureCoord.x = aTextureCoord.x;   
  vTextureCoord.y = aTextureCoord.y;   
  vNormal = normalize(aNormal);  

  vPosition = aPosition;
  nPos = aPosition.xyz / aPosition.w;
  float nDotVP1 = max(0.0, dot(vNormal, normalize(uLight1Position - nPos)));  
  float nDotVP2 = max(0.0, dot(vNormal, normalize(uLight2Position - nPos)));  

  vec4 diffuse1 = uLight1Color * nDotVP1;
  colorVarying1 = diffuse1;
  colorVarying2 = uLight2Color * nDotVP2;
  gl_Position = uMVPMatrix * aPosition;

};

以下是地球片段着色器。

precision highp float;

const vec4 bitShifts = vec4(1.0 / (256.0 * 256.0 * 256.0),
                1.0 / (256.0 * 256.0),
                1.0 / 256.0,
                1.0);

varying lowp vec4 colorVarying1; 
varying lowp vec4 colorVarying2; 
varying mediump vec2 vTextureCoord; 
varying vec4 vPosition;
varying vec3 vNormal;
varying vec3 nPos;

uniform sampler2D sTexture;  
uniform sampler2D sCloudTexture;  
uniform sampler2D sDepthMapLight1;  
uniform sampler2D sDepthMapLight2;  

uniform float uHeightOfLight1Frustum;
uniform float uHeightOfLight2Frustum;
uniform vec3 uLight1Position;   
uniform vec4 uLight1Color;
uniform vec3 uLight2Position;   
uniform vec4 uLight2Color;
uniform mat4 uLight1MVPMatrix;   
uniform mat4 uLight2MVPMatrix;   
uniform vec4 uAmbientLight;
uniform vec3 uEyePosition;
uniform vec4 uCenterOfSphere;


float unpack(vec4 rgba){
  return dot(rgba, bitShifts);
};

void main() { 
  vec4 surfaceColor;
  vec4 cloudColor; 
  vec3 incoming1 = nPos - uLight1Position;
  vec3 reflected1 = normalize(reflect(incoming1, vNormal));
  vec3 incoming2 = nPos - uLight2Position;
  vec3 reflected2 = normalize(reflect(incoming2, vNormal));
  vec3 posToEye = normalize(uEyePosition - nPos);

  float shininess = 60.0;
  vec4 specular1 = uLight1Color * 5.0 * pow(max(0.0, dot(reflected1,posToEye)), shininess);
  vec4 specular2 = uLight2Color * 5.0 * pow(max(0.0, dot(reflected2,posToEye)), shininess);
  surfaceColor=texture2D(sTexture, vTextureCoord);
  if(surfaceColor.x > surfaceColor.z || surfaceColor.y > surfaceColor.z)
    specular1 = vec4(0.0, 0.0, 0.0, 0.0);

  cloudColor=texture2D(sCloudTexture, vTextureCoord);
  vec4 depth1Un = uLight1MVPMatrix * vPosition;
  vec3 depth1 = depth1Un.xyz / depth1Un.w;
  vec4 depth2Un = uLight2MVPMatrix * vPosition;
  vec3 depth2 = depth2Un.xyz / depth2Un.w;

  depth1.z = length(vPosition.xyz - uLight1Position) / uHeightOfLight1Frustum;
  depth2.z = length(vPosition.xyz - uLight2Position) / uHeightOfLight2Frustum;
  vec2 coord1 = vec2((depth1.x+1.0)/2.0, (depth1.y+1.0)/2.0);
  vec2 coord2 = vec2((depth2.x+1.0)/2.0, (depth2.y+1.0)/2.0);

  vec4 moveToCenter = uCenterOfSphere * 0.01 + vPosition * 0.99;
  vec4 depthShifted1Un = uLight1MVPMatrix * moveToCenter;
  vec3 depthShifted1 = depthShifted1Un.xyz / depthShifted1Un.w;
  vec4 depthShifted2Un = uLight2MVPMatrix * moveToCenter;
  vec3 depthShifted2 = depthShifted2Un.xyz / depthShifted2Un.w;

  vec2 coordShifted1 = vec2((depthShifted1.x+1.0)/2.0, (depthShifted1.y+1.0)/2.0);
  vec2 coordShifted2 = vec2((depthShifted2.x+1.0)/2.0, (depthShifted2.y+1.0)/2.0);

  float shadow1 = 1.0;
  float shadowDepth1 = unpack(texture2D(sDepthMapLight1, coord1));
  float shadowDepthShifted1 = unpack(texture2D(sDepthMapLight1, coordShifted1));
  if ( depth1.z >= shadowDepthShifted1 * 1.02 ){
       shadow1 = 0.0;
  }

  float shadow2 = 1.0;    
  float shadowDepth2 = unpack(texture2D(sDepthMapLight2, coord2));
  float shadowDepthShifted2 = unpack(texture2D(sDepthMapLight2, coordShifted2));
  if ( depth2.z >= shadowDepthShifted2 * 1.02 ){
       shadow2 = 0.0;
  }

  vec4 totalLight4 = (colorVarying1 + specular1) * shadow1 + uAmbientLight;

  if(cloudColor[0]>0.3) {
    cloudColor[3]=0.5;  
    gl_FragColor=(cloudColor*1.3 + surfaceColor*.4) * totalLight4; 
  } else {
  gl_FragColor = surfaceColor * totalLight4;
  }
};
4

1 回答 1

1

因为您的着色器使用了大量的制服,您可能会用完某些 GPU 的可用制服向量。您应该检查这些设备的GL_MAX_VERTEX_UNIFORM_VECTORS和上的值。GL_MAX_FRAGMENT_UNIFORM_VECTORS

另外,请注意文字实际上采用统一向量,即使 2 个具有相同值的文字实际上也使用 2 个统一。所以你的着色器使用了相当多的隐式制服。

您可以在此问题中找到更详细的信息:Declaring constants instead of literals in vertex shader。标准做法,还是不必要的严谨?

于 2013-11-13T07:54:10.123 回答