Andrew Geissler | 72956ed | 2021-01-08 16:11:14 -0600 | [diff] [blame] | 1 | From 90e837ffd1ff5c9add1074d69de23e58a3a4810e Mon Sep 17 00:00:00 2001 |
| 2 | From: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 3 | Date: Wed, 11 Nov 2020 09:26:03 -0500 |
| 4 | Subject: [PATCH 1/3] terrain: Fix precision bug in light rendering |
| 5 | |
| 6 | Resulting in overly bright rendering when mediump is implemented as |
| 7 | fp16. |
| 8 | |
| 9 | Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 10 | --- |
| 11 | data/shaders/terrain.frag | 5 +++++ |
| 12 | 1 file changed, 5 insertions(+) |
| 13 | |
| 14 | diff --git a/data/shaders/terrain.frag b/data/shaders/terrain.frag |
| 15 | index 84d085c..58f17ea 100644 |
| 16 | --- a/data/shaders/terrain.frag |
| 17 | +++ b/data/shaders/terrain.frag |
| 18 | @@ -67,7 +67,12 @@ void main() { |
| 19 | vec3 pointSpecular = vec3( 0.0 ); |
| 20 | for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { |
| 21 | vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); |
| 22 | +#ifdef GL_FRAGMENT_PRECISION_HIGH |
| 23 | + // should be highp for correct behaviour if mediump is implemented as fp16 |
| 24 | + highp vec3 lVector = lPosition.xyz + vViewPosition.xyz; |
| 25 | +#else |
| 26 | vec3 lVector = lPosition.xyz + vViewPosition.xyz; |
| 27 | +#endif |
| 28 | float lDistance = 1.0; |
| 29 | if ( pointLightDistance[ i ] > 0.0 ) |
| 30 | lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 ); |
| 31 | |
| 32 | From 1edd76fda77edabd49d713912aee49b8360c86c3 Mon Sep 17 00:00:00 2001 |
| 33 | From: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 34 | Date: Wed, 11 Nov 2020 09:49:52 -0500 |
| 35 | Subject: [PATCH 2/3] terrain: Fix precision handling in noise shader |
| 36 | |
| 37 | Another overflow resulting in infinity in mediump. Note this bug is |
| 38 | masked if the driver clamps infinity to MAX_FLOAT, but it's still our |
| 39 | bug. |
| 40 | |
| 41 | Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 42 | --- |
| 43 | data/shaders/terrain-noise.frag | 6 ++++++ |
| 44 | 1 file changed, 6 insertions(+) |
| 45 | |
| 46 | diff --git a/data/shaders/terrain-noise.frag b/data/shaders/terrain-noise.frag |
| 47 | index 7fea5c0..9535e58 100644 |
| 48 | --- a/data/shaders/terrain-noise.frag |
| 49 | +++ b/data/shaders/terrain-noise.frag |
| 50 | @@ -17,7 +17,13 @@ uniform float time; |
| 51 | uniform MEDIUMP vec2 uvScale; |
| 52 | varying vec2 vUv; |
| 53 | |
| 54 | +#ifdef GL_FRAGMENT_PRECISION_HIGH |
| 55 | +// x should be passed as highp since the intermediate multiplications can |
| 56 | +// overflow with mediump |
| 57 | +vec4 permute(highp vec4 x) |
| 58 | +#else |
| 59 | vec4 permute(vec4 x) |
| 60 | +#endif |
| 61 | { |
| 62 | return mod(((x * 34.0) + 1.0) * x, 289.0); |
| 63 | } |
| 64 | |
| 65 | From e866cc633ffc450e5358b2742f32ca360e4f3f12 Mon Sep 17 00:00:00 2001 |
| 66 | From: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 67 | Date: Wed, 11 Nov 2020 09:35:21 -0500 |
| 68 | Subject: [PATCH 3/3] loop,function,conditionals: Fix mediump overflow |
| 69 | |
| 70 | The multiplication can produce infinity. |
| 71 | |
| 72 | Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> |
| 73 | --- |
| 74 | data/shaders/conditionals.frag | 9 ++++++++- |
| 75 | data/shaders/function.frag | 9 ++++++++- |
| 76 | data/shaders/loop.frag | 9 ++++++++- |
| 77 | 3 files changed, 24 insertions(+), 3 deletions(-) |
| 78 | |
| 79 | diff --git a/data/shaders/conditionals.frag b/data/shaders/conditionals.frag |
| 80 | index 3bd2507..e902263 100644 |
| 81 | --- a/data/shaders/conditionals.frag |
| 82 | +++ b/data/shaders/conditionals.frag |
| 83 | @@ -2,7 +2,14 @@ varying vec4 dummy; |
| 84 | |
| 85 | void main(void) |
| 86 | { |
| 87 | - float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001); |
| 88 | +#ifdef GL_FRAGMENT_PRECISION_HIGH |
| 89 | + // should be declared highp since the multiplication can overflow in |
| 90 | + // mediump, particularly if mediump is implemented as fp16 |
| 91 | + highp vec2 FragCoord = gl_FragCoord.xy; |
| 92 | +#else |
| 93 | + vec2 FragCoord = gl_FragCoord.xy; |
| 94 | +#endif |
| 95 | + float d = fract(FragCoord.x * FragCoord.y * 0.0001); |
| 96 | |
| 97 | $MAIN$ |
| 98 | |
| 99 | diff --git a/data/shaders/function.frag b/data/shaders/function.frag |
| 100 | index 3e3c74f..9d0230e 100644 |
| 101 | --- a/data/shaders/function.frag |
| 102 | +++ b/data/shaders/function.frag |
| 103 | @@ -8,7 +8,14 @@ $PROCESS$ |
| 104 | |
| 105 | void main(void) |
| 106 | { |
| 107 | - float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001); |
| 108 | +#ifdef GL_FRAGMENT_PRECISION_HIGH |
| 109 | + // should be declared highp since the multiplication can overflow in |
| 110 | + // mediump, particularly if mediump is implemented as fp16 |
| 111 | + highp vec2 FragCoord = gl_FragCoord.xy; |
| 112 | +#else |
| 113 | + vec2 FragCoord = gl_FragCoord.xy; |
| 114 | +#endif |
| 115 | + float d = fract(FragCoord.x * FragCoord.y * 0.0001); |
| 116 | |
| 117 | $MAIN$ |
| 118 | |
| 119 | diff --git a/data/shaders/loop.frag b/data/shaders/loop.frag |
| 120 | index 31ae23e..9a6afd2 100644 |
| 121 | --- a/data/shaders/loop.frag |
| 122 | +++ b/data/shaders/loop.frag |
| 123 | @@ -3,7 +3,14 @@ uniform int FragmentLoops; |
| 124 | |
| 125 | void main(void) |
| 126 | { |
| 127 | - float d = fract(gl_FragCoord.x * gl_FragCoord.y * 0.0001); |
| 128 | +#ifdef GL_FRAGMENT_PRECISION_HIGH |
| 129 | + // should be declared highp since the multiplication can overflow in |
| 130 | + // mediump, particularly if mediump is implemented as fp16 |
| 131 | + highp vec2 FragCoord = gl_FragCoord.xy; |
| 132 | +#else |
| 133 | + vec2 FragCoord = gl_FragCoord.xy; |
| 134 | +#endif |
| 135 | + float d = fract(FragCoord.x * FragCoord.y * 0.0001); |
| 136 | |
| 137 | $MAIN$ |
| 138 | |