Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OpenGL ES 2.0/3.0中的各向异性照明。黑色人工制品_Android_Opengl Es_Shader_Artifacts_Opengl Es 3.0 - Fatal编程技术网

Android OpenGL ES 2.0/3.0中的各向异性照明。黑色人工制品

Android OpenGL ES 2.0/3.0中的各向异性照明。黑色人工制品,android,opengl-es,shader,artifacts,opengl-es-3.0,Android,Opengl Es,Shader,Artifacts,Opengl Es 3.0,我正在尝试实现各向异性照明。 顶点着色器: #version 300 es uniform mat4 u_mvMatrix; uniform mat4 u_vMatrix; in vec4 a_position; in vec3 a_normal; ... out lowp float v_DiffuseIntensity; out lowp float v_SpecularIntensity; const vec3 lightPosition = vec3(-1.0, 0.0, 5.

我正在尝试实现各向异性照明。 顶点着色器:

#version 300 es
uniform mat4 u_mvMatrix; 
uniform mat4 u_vMatrix;

in vec4 a_position; 
in vec3 a_normal; 
...
out lowp float v_DiffuseIntensity;
out lowp float v_SpecularIntensity;

const vec3 lightPosition = vec3(-1.0, 0.0, 5.0);
const lowp vec3 grainDirection = vec3(15.0, 2.8, -1.0);
const vec3 eye_positiion = vec3(0.0, 0.0, 0.0);

void main() {
    // transform normal orientation into eye space
    vec3 modelViewNormal = mat3(u_mvMatrix) * a_normal;
    vec3 modelViewVertex = vec3(u_mvMatrix * a_position);
    vec3 lightVector = normalize(lightPosition - modelViewVertex);
    lightVector = mat3(u_vMatrix) * lightVector;

    vec3 normalGrain = cross(modelViewNormal, grainDirection);
    vec3 tangent = normalize(cross(normalGrain, modelViewNormal));
    float LdotT = dot(tangent, normalize(lightVector));
    float VdotT = dot(tangent, normalize(mat3(u_mvMatrix) * eye_position));
    float NdotL = sqrt(1.0 - pow(LdotT, 2.0));
    float VdotR = NdotL * sqrt(1.0 - pow(VdotT, 2.0)) - VdotT * LdotT;
    v_DiffuseIntensity = max(NdotL * 0.4 + 0.6, 0.0);
    v_SpecularIntensity = max(pow(VdotR, 2.0) * 0.9, 0.0);
    ...
}
片段着色器:

...
in lowp float v_DiffuseIntensity;
in lowp float v_SpecularIntensity;

const lowp vec3 default_color = vec3(0.1, 0.7, 0.9);

void main() {
    ...
    lowp vec3 resultColor = (default_color * v_DiffuseIntensity) 
        + v_SpecularIntensity;
    outColor = vec4(resultColor, 1.0);
}
总的来说,照明在不同的设备上工作良好。但三星平板电脑上出现了一个工件,如图所示:


似乎最黑暗的地方正在变成一片漆黑。谁能告诉我为什么会这样?谢谢你的回答/评论

您有两个表达式存在未定义行为的风险:

sqrt(1.0 - pow(LdotT, 2.0))
sqrt(1.0 - pow(VdotT, 2.0))
如果x为负值,则未定义
pow
函数。我怀疑你没有受到影响,因为y是2.0,所以它们可能被优化为x*x

如果x为负值,则
sqrt
函数未定义。从数学上讲,它永远不应该是,因为两个标准化向量的点积的大小永远不应该大于1,但计算总是有误差的。我认为这是导致渲染瑕疵的原因

我将这两个表达式更改为:

sqrt(max(0.0, 1.0 - pow(max(0.0, LdotT), 2.0)))
sqrt(max(0.0, 1.0 - pow(max(0.0, VdotT), 2.0)))
代码看起来更难看,但更安全,
max(0.0,x)
是一个非常便宜的操作


编辑:刚刚注意到
pow(VdotR,2.0)
,我也要更改它。

更改sqrt表达式解决了这个问题。文物完全消失了。非常感谢你!