【发布时间】:2021-06-29 07:40:45
【问题描述】:
我有一个带有简单着色器的 OpenGL 应用,它可以在具有 API 30 的 Android Studio 中的模拟器设备上运行良好,但在我自己的硬件设备 (API 30) 上却不能。
问题出在片段着色器中。这是代码:
#version 100
precision highp float;
struct DirLight {
int on;
vec3 direction;
vec3 ambientColor;
vec3 diffuseColor;
vec3 specularColor;
float specularExponent;
sampler2D shadowMap;
mat4 shadowVPMatrix;
int shadowEnabled;
};
struct PointLight {
int on;
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambientColor;
vec3 diffuseColor;
vec3 specularColor;
float specularExponent;
sampler2D shadowMap;
mat4 shadowVPMatrix;
int shadowEnabled;
};
#define MAX_NUM_POINT_LIGHTS 8
uniform DirLight uDirLight;
uniform PointLight uPointLights[MAX_NUM_POINT_LIGHTS];
uniform int uNumPointLights;
uniform vec3 uViewPos;
uniform sampler2D uTexture;
uniform int uIsTextured;
varying vec4 vColor;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec2 vTexCoords;
const vec4 bitShifts = vec4(1.0 / (256.0*256.0*256.0), 1.0 / (256.0*256.0), 1.0 / 256.0, 1.0);
vec4 getColor(){
if (uIsTextured != 0){
return texture2D(uTexture,vTexCoords);
}
return vColor;
}
float unpack(vec4 color){
return dot(color, bitShifts);
}
// return 0.0 if in shadow.
// return 1.0 if not in shadow.
float calcShadow(sampler2D shadowMap, vec4 positionFromLight, int shadowEnabled){
if (shadowEnabled == 0){
return 1.0;
}
vec3 positionFromLight3 = positionFromLight.xyz / positionFromLight.w;
positionFromLight3 = (positionFromLight3 + 1.0) / 2.0;
float closestFragmentZ = unpack(texture2D(shadowMap, positionFromLight3.xy));
float currentFragmentZ = positionFromLight3.z;
return float(closestFragmentZ > currentFragmentZ);
}
float diffuseLighting(vec3 normal, vec3 lightDir){
return max(dot(normal, lightDir), 0.0);
}
float specularLighting(vec3 normal, vec3 lightDir, vec3 viewDir, float specularExponent){
vec3 reflectDir = reflect(-lightDir, normal);
return pow(max(dot(viewDir, reflectDir), 0.0), specularExponent);
}
vec4 calcDirLight(vec3 normal, vec3 viewDir){
vec3 lightDir = normalize(-uDirLight.direction);
float diff = diffuseLighting(normal, lightDir);
float spec = specularLighting(normal, lightDir, viewDir, uDirLight.specularExponent);
vec4 color = getColor();
vec4 ambient = vec4(uDirLight.ambientColor, 1.0) * color;
vec4 diffuse = vec4(uDirLight.diffuseColor * diff, 1.0) * color;
vec4 specular = vec4(uDirLight.specularColor * spec, 1.0) * vec4(0.5,0.5,0.5,1.0);
return ambient + (diffuse + specular) * calcShadow(uDirLight.shadowMap, uDirLight.shadowVPMatrix * vPosition, uDirLight.shadowEnabled);
}
float calcAttenuation(PointLight pointLight, float distance){
return 1.0 / (pointLight.constant + pointLight.linear * distance + pointLight.quadratic * (distance * distance));
}
vec4 calcPointLight(PointLight pointLight, vec3 normal, vec3 viewDir){
vec3 d = pointLight.position - vec3(vPosition);
vec3 lightDir = normalize(d);
float diff = diffuseLighting(normal, lightDir);
float spec = specularLighting(normal, lightDir, viewDir, pointLight.specularExponent);
float distance = length(d);
float attenuation = calcAttenuation(pointLight,distance);
vec4 color = getColor();
vec4 ambient = vec4(pointLight.ambientColor, 1.0) * color;
vec4 diffuse = vec4(pointLight.diffuseColor * diff, 1.0) * color;
vec4 specular = vec4(pointLight.specularColor * spec, 1.0) * vec4(0.5,0.5,0.5,1.0);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return ambient + (diffuse + specular) * calcShadow(pointLight.shadowMap, pointLight.shadowVPMatrix * vPosition, pointLight.shadowEnabled);
}
void main() {
vec3 normal = normalize(vNormal);
vec3 viewDir = normalize(uViewPos - vec3(vPosition));
vec4 result = vec4(0.0);
if (uDirLight.on == 1){
result = calcDirLight(normal, viewDir);
}
for (int i = 0; i < uNumPointLights; i++){
if (uPointLights[i].on == 1){
result += calcPointLight(uPointLights[i], normal, viewDir);
}
}
gl_FragColor = result;
}
当我在我的设备上运行应用程序时,logcat 显示以下几行
2021-06-24 17:49:14.032 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: Build Config : S P 10.0.7 AArch64
2021-06-24 17:49:14.032 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
2021-06-24 17:49:14.036 2061-2096/com.outofbound.rhinoengine I/AdrenoGLES-0: PFP: 0x016ee190, ME: 0x00000000
2021-06-24 17:49:14.040 2061-2061/com.outofbound.rhinoengine D/SurfaceView: UPDATE null, mIsCastMode = false
2021-06-24 17:49:14.074 2061-2102/com.outofbound.rhinoengine I/AdrenoGLES-0: ERROR: 0:101: 'viewDir' : undeclared identifier
ERROR: 0:101: 'specularLighting' : no matching overloaded function found
ERROR: 2 compilation errors. No code generated.
2021-06-24 17:49:14.075 2061-2102/com.outofbound.rhinoengine I/AdrenoGLES-0: ERROR: 0:101: 'viewDir' : undeclared identifier
ERROR: 0:101: 'specularLighting' : no matching overloaded function found
ERROR: 2 compilation errors. No code generated.
2021-06-24 17:49:15.316 2061-2085/com.outofbound.rhinoengine W/System: A resource failed to call close.
但是如果我只是在 main() 函数中将 viewDir 重命名为 v
void main() {
vec3 normal = normalize(vNormal);
vec3 v = normalize(uViewPos - vec3(vPosition));
vec4 result = vec4(0.0);
if (uDirLight.on == 1){
result = calcDirLight(normal, v);
}
for (int i = 0; i < uNumPointLights; i++){
if (uPointLights[i].on == 1){
result += calcPointLight(uPointLights[i], normal, v);
}
}
gl_FragColor = result;
}
上面的错误消失了,但应用程序仍然无法显示黑屏。 有什么建议吗?
【问题讨论】:
-
尝试将精度设置为中等
标签: android opengl-es opengl-es-2.0