gxquickly / angleproject

Automatically exported from code.google.com/p/angleproject
Other
0 stars 0 forks source link

ANGLE computes the wrong value for this GLSL expression #851

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.  Go to http://threejs.org/examples/#webgl_shaders_sky

What is the expected output? 

It's blue/green on the top half, rust tones on the buttom

What do you see instead?

It's blue/grey everywhere

See this SO thread

http://stackoverflow.com/questions/27348125/colors-output-from-webgl-fragment-sh
ader-differ-significantly-across-platforms/

The 2nd answer pasted here

I tried displaying results at various places in the fragment shader. After a 
few bisects I found that this line produced different results on Windows vs OSX

     vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;

totalRayleigh looks like this

    vec3 totalRayleigh(vec3 lambda) {
        return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / 
                (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));
    }

Which looking at the code is entirely a constant compile time expression. as 
lambda is a constant.

So, I pasted it into JavaScript, added Math. in front of the pows and then 
computed each of the x, y, and z values for the result.

Changing it to just use that result like this

vec3 totalRayleigh(vec3 lambda) {
    return vec3(0.000005804542996261093, 
                0.000013562911419845635, 
                0.00003026590629238531);
}

Fixed the problem. 

Original issue reported on code.google.com by g...@chromium.org on 14 Dec 2014 at 11:11

GoogleCodeExporter commented 9 years ago
So I'm not sure it's ANGLE or if it's DirectX. I haven't go through the entire 
shaders but...

using the WEBGL_debug_shaders extension shows the shader passed to the driver. 
The function in question looks the same on both GLSL and HLSL

--GLSL--

vec3 webgl_411896f5d9a657de(in vec3 webgl_f4a871322329f1f){
return ((((8.0 * pow(3.1415927, 3.0)) * pow((pow(1.0003, 2.0) - 1.0), 2.0)) * 
6.105) / ((76349999198241540557242368.0 * pow(webgl_f4a871322329f1f, vec3(4.0, 
4.0, 4.0))) * 5.7550001));
}
--HLSL--

float3 _webgl_411896f5d9a657de(in float3 _webgl_f4a871322329f1f)
{
{
return ((((8.0 * pow(3.1415927, 3.0)) * pow((pow(1.0003, 2.0) - 1.0), 2.0)) * 
6.105) / ((76349999198241541000000000.0 * pow(_webgl_f4a871322329f1f, 
float3(4.0, 4.0, 4.0))) * 5.7550001));
;
}
}
;
The calling points too

--GLSL--

vec3 webgl_6ecdfd37473d07b4 = (webgl_411896f5d9a657de(vec3(6.8000003e-07, 
5.4999998e-07, 4.4999999e-07)) * webgl_6a82dfb3c4d3d759);

--HLSL--

float3 _webgl_6ecdfd37473d07b4 = 
(_webgl_411896f5d9a657de(float3(6.8000003e-007, 5.4999998e-007, 
4.4999999e-007)) * _webgl_6a82dfb3c4d3d759);

I though maybe HLSL's compiler doesn't have enough resolution for the tiny 
values? As in maybe it's using floats to compute compile time constants instead 
of doubles? So, I tried converting that function to C++

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

const float pi = 3.141592653589793238462643383279502884197169f;

const float n = 1.0003f; // refractive index of air",
const float N = 2.545E25f; // number of molecules per unit volume for air at",
                            // 288.15K and 1013mb (sea level -45 celsius)",
const float pn = 0.035f;    // depolatization factor for standard air",

float totalRayleigh(float lambda) {
    return (8.0f * powf(pi, 3.0f) * powf(powf(n, 2.0f) - 1.0f, 2.0f) * (6.0f + 3.0f * pn)) /
            (3.0f * N * powf(lambda, 4.0f) * (6.0f - 7.0f * pn));
}

int main() {
  //const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);
  printf("%g, %g, %g", totalRayleigh(680E-9), totalRayleigh(550E-9), totalRayleigh(450E-9));
  return EXIT_SUCCESS;
}
which prints

5.80703e-06, 1.35687e-05, 3.02789e-05
Plugging those into totalRayleigh still produces the correct result so that 
wasn't the issue.

OTOH changing totalRayleigh to just return vec3(0,0,0) produces the incorrect 
blue result. Not sure if that's helpful or not

Original comment by g...@chromium.org on 14 Dec 2014 at 11:45

GoogleCodeExporter commented 9 years ago

Original comment by g...@chromium.org on 14 Dec 2014 at 11:46

GoogleCodeExporter commented 9 years ago
Olli just found a bunch of bugs in the handling of const expressions and added 
WebGL conformance tests for them. I wonder whether they could be affecting the 
results here.

Original comment by kbr@chromium.org on 15 Dec 2014 at 7:36

GoogleCodeExporter commented 9 years ago
I don't think that there's a direct connection to the other constant related 
bugs I found - though I suppose better constant folding in ANGLE could help to 
reduce both the number of exposed D3D issues like this and other bugs within 
ANGLE itself.

I made a minimal test case based on this report and submitted it to the WebGL 
repo:

https://github.com/KhronosGroup/WebGL/pull/812

The conditions for reproducing this issue are bizarre: A constant value less 
than 1.0e-5 needs to be passed to pow in an user-defined function. If the 
expression is outside an user-defined function, the bug doesn't repro, or if an 
uniform is passed instead of a constant, the bug doesn't repro either.

Original comment by oetu...@nvidia.com on 16 Dec 2014 at 1:32

GoogleCodeExporter commented 9 years ago
+1 to angle doing constant folding. It would probably smooth out various issues 

Original comment by g...@chromium.org on 16 Dec 2014 at 6:18

GoogleCodeExporter commented 9 years ago
Project: angle/angle
Branch : master
Author : Jamie Madill <jmadill@chromium.org>
Commit : 4052dfc8be95115764b18ff37f39113b18d7c726

Code-Review  0 : Jamie Madill
Code-Review  +1: Olli Etuaho
Code-Review  +2: Geoff Lang
Verified     0 : Geoff Lang, Olli Etuaho
Verified     +1: Jamie Madill
Commit Queue   : Chumped
Change-Id      : I41a4ad9354e32bb2d48894d75676a9dfe226e9d8
Reviewed-at    : https://chromium-review.googlesource.com/269747

Add test for HLSL "pow" constant folding bug.

This covers 'pow-of-small-constant-in-user-defined-function' from
the WebGL CTS. Leave disabled until we have a proper fix.

BUG=angleproject:851

src/tests/end2end_tests/GLSLTest.cpp

Original comment by bugdroid1@chromium.org on 7 May 2015 at 5:17

GoogleCodeExporter commented 9 years ago

Original comment by jmad...@chromium.org on 7 May 2015 at 6:33