OpenGL ES God Ray 精度错误

OpenGL ES God Ray Precision error

我遇到了以下(我认为)精度错误。

我的灵感来源是: http://fabiensanglard.net/lightScattering/

在 PC 上一切正常,但在 android 上显示那些奇怪的方块。

我在使用程序蒙版精灵时遇到了同样的问题。当圆的半径变得太大时,我遇到了同样的错误,所以我将蒙版从着色器半径统一更改为纹理蒙版统一,所以我猜这是一个精度问题。

这家伙遇到了同样的问题,可惜我看不到答案。

http://community.arm.com/thread/4024

适配OpenGL ES的代码如下:

#version 100

precision mediump float;

uniform sampler2D tex_diff;
uniform vec2 light_on_screen;

varying vec2 texture_coord;

const int NUM_SAMPLES = 128;

void main()
{
    const float exposure = 0.0225;
    const float decay = 0.95;
    const float density = 0.95;
    const float weight = 3.75;

    // Inner used valuesa
    vec2 deltaTextCoord = vec2(texture_coord.st - light_on_screen.xy);
    vec2 textCoo = texture_coord.st;
    deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density;
    float illuminationDecay = 1.0;

    vec4 c = vec4(0, 0, 0, 0);

    for(int i=0; i < NUM_SAMPLES ; i++)
    {
        textCoo -= deltaTextCoord;

        textCoo.s = clamp(textCoo.s, 0.0, 1.0);
        textCoo.t = clamp(textCoo.t, 0.0, 1.0);

        vec4 sample = texture2D(tex_diff, textCoo);

        sample *= illuminationDecay * weight;

        c += sample;

        illuminationDecay *= decay;
    }

    c *= exposure;

    c.r = clamp(c.r, 0.0, 1.0);
    c.g = clamp(c.g, 0.0, 1.0);
    c.b = clamp(c.b, 0.0, 1.0);
    c.a = clamp(c.a, 0.0, 1.0);

    gl_FragColor = c;
}

显示整个引擎没有用,因为它太大了。所有着色器输入都是正确的,坐标也是正确的,唯一的问题是内部着色器计算。

有人遇到过这个问题或有任何解决方法的想法吗?

搜索了整个网络以寻找解决方案,但我似乎找不到。任何人都可以指出我正确的方向吗?或者也许有人在不同的上下文或不同的着色器中遇到了这种类型的错误?也许我也可以在这里应用相同的解决方法。

一个常见的区别是在移动设备(通常是 fp16)和桌面设备(通常不实现 fp16,只是升级到 fp32)上使用 mediump。

如果你使用 highp 看起来会更好吗?

更新了一个小修复:

是的,问题是:

'textCoo -= deltaTextCoord';

由于 fp 精度,累积的误差增长到大约 2.7%。在每个循环中计算它而不是减去增量可以解决大部分问题。

至于优化,我使用了一些技巧,得到了合理的 40fps。

看到这个post,我在这里问了同样的问题: http://community.arm.com/message/29658?et=watches.email.thread#29658

有关使用的优化,请参阅此 post: http://www.gamedev.net/topic/670346-opengl-es-god-ray-precision-error/