Jump to content
  • Advertisement
Sign in to follow this  

OpenGL OpenGL ES God Ray Precision error

This topic is 1237 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have encountered the following (i think) precision error.






My source of inspiration was:
On the PC everything works fine, but on android it shows those weird squares.
 I had the same problem with a procedurally masked sprite. When the radius of the circle was getting too big i had the same error so i changed the mask from a shader radius uniform to a texture mask uniform, so i guess there is a precision problem.
This guy here had the same problem but unfortunately i can't see the answer.
The code adapted to OpenGL ES is the following:
#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 values
    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;
Showing the whole engine is useless since it's huge. All the shader input is correct, the coordinates are correct, the only problem is the inner shader computation. 
Anybody encountered this or has any ideas for any workarounds?
Scanned the whole net for a solution for this, and i couldn't seem to find one. Any can point me in the right direction? Or maybe someone encountered this type of error in a different context or in a different shader? Maybe i can apply the same workaround here too.
I thought that if there's a right place to get answers to this kind of questions it's here on Gamedev smile.png .

Share this post

Link to post
Share on other sites

The best way to start would be to force everything to use highp and see if the problem goes away. If it does, then you can start the process of figuring out what needs to be highp and what can be mediump or lowp.


IMO, using a precision declaration at the top (the line: "precision mediump float;") is bad practice, on mobile fragment shaders you ought to think about the required precision of every operation. But in this case it makes life easier because all you need to do to confirm whether it's a precision problem is change that line to be "precision highp float;". You should also go into your vertex shader and make sure the texture_coord varying is being output as a highp too.


If that fixes it, then that's great, but you do need to bear in mind that not all Android GPUs support high precision floats in their fragment shader. However, you might be able to get it all working at mediump. Most likely the place where precision is being lost is the iterative adjustment of textCoo, you might see an improvement by calculating textCoo on each iteration rather than applying a delta. (change the line "textCoo -= deltaTextCoord;" to something like "textCoo = texture_coord.st - (deltaTextCoord * (i + 1));" or if tweak stuff correctly before you enter your loop you could use the far more optimal "textCoo = texture_coord.st + (deltaTextCoord * i);")


As an aside, attempting 128 samples might be too many unless you're targeting only the extreme high end devices.

Edited by C0lumbo

Share this post

Link to post
Share on other sites

Trying it now. And yes, the max number of samples is at around 15-20 but i used that high number to better illustrate the problem.


Update after changing '(texCoo - delta)':






The precision is a lot better now. Unfortunately i can't use 'highp' at the moment, but in a few hours i am borrowing a device that can handle 'high'. In the upper image there's a slight distortion but i will see if 'highp' tricks it.


As for the optimization ill optimize for 10(low) - 50(ultra high) samples, and before adding the final effect i'll vertically and horizontally blur the rays to get over the remaining little defects and make it mobile ready. Also rendering to a lower 1/2, 1/3, 1/4 renderbuffer will improve performance.


Thanks for all the help!




'highp' did not fixed the later problem it entirely will still have to blur a little.

Edited by AssemblyJohn

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!