thebookofshaders icon indicating copy to clipboard operation
thebookofshaders copied to clipboard

Inconsistency between operating systems

Open michaeljblum opened this issue 4 years ago • 5 comments

Thanks so much for this awesome resource!

Wondering about inconsistency of some shaders between browsers, though - for example, the final code example on /13/ appears much differently - far more jagged and aliased - on Mac than it does on Windows, where the seamless, lush blur effect fully comes through.

I've been trying to understand why this is so - thought at first maybe it had to do with high DPI on Mac-run hardware, but I think I ruled that out. This little issue seems to be browser agnostic as well.

Anyone know why this is so, and how it can be resolved?

michaeljblum avatar Jun 23 '20 18:06 michaeljblum

I faced the same problem.

I'll share screenshots and environment informations.

macOS 10.15


Google Chrome 83.0.4103.116(Official Build) macOS 10.15.2 Mac mini (2018) LCD-MF245XD(1920*1080)


Safari 13.0.4 macOS 10.15.2 Mac mini (2018) LCD-MF245XD(1920*1080)


Firefox 78.0.2 macOS 10.15.2 Mac mini (2018) LCD-MF245XD(1920*1080)


macOS 10.14


Chrome 79 macOS 10.14 virtual machine( https://www.lambdatest.com/ )


Windows 10


Microsoft Edge 81.0.416.86 Windows 10 1909 build 18363.900


Google Chrome 83.0.4103.116 Windows 10 1909 build 18363.900

My environment is FullHD + standard dpi. The problem and the result are the same.

I hope this information is helpful to you.

MasatoMakino avatar Jul 11 '20 04:07 MasatoMakino

In my experience the inconsistencies are more related to GPU hardware and drivers that the browser. Those inconsistencies becomes more obvious when using random or noise functions, they introduce different precision issues. One way around it is to force the driver to use maximum precision by changing

#ifdef GL_ES
precision mediump float;
#endif

for

#ifdef GL_ES
precision highp float;
#endif

at the top of the shader

patriciogonzalezvivo avatar Jul 12 '20 13:07 patriciogonzalezvivo

Perhaps I have found a solution.

Solution

Replace the random function.

float random (in vec2 _st) {
    return fract(sin(dot(_st.xy,
                         vec2(0.129898,0.78233)))*
        437.585453123);
}

Procedure

To narrow down the issues, I checked the chapter on noise.

https://thebookofshaders.com/11/

I found a strange behavior. The 2D Noise results are different on macOS 10.15 and on Windows 10. Since the random function is a pseudo-random number, it should return the same result for the same input.

I changed 43758.5453123 to 1.0 as a test. The result is the same. When I adjust the variable, the result seems to change after 20,000. From this result, I suspect that the values passed to the fract function are too large and that the decimal point is being lost.

Using the same approach, I was able to resolve the error by setting constants in random function to 1/100.

With this solution, I am getting visually correct results. But I'm not sure if this is the correct method. If anyone has any information on this, please provide it.

Thanks.

MasatoMakino avatar Jul 14 '20 08:07 MasatoMakino

In Chrome on iPad Pro, most of the rendered noise images are severely reduced in detail. I have to declare highp to fix.

joebowbeer avatar Aug 06 '20 04:08 joebowbeer

I found a different solution.

Solution

Replace the random function with the hash function, which can be found here.

//	<https://www.shadertoy.com/view/4dS3Wd>
//	By Morgan McGuire @morgan3d, http://graphicscodex.com
//
float hash(float n) { return fract(sin(n) * 1e4); }
float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }

This hash function takes vec2 as input and outputs a random value. it is an alternative to the random function.

The original code is BSD licensed. Please check before using.

Thanks.

MasatoMakino avatar Apr 10 '21 05:04 MasatoMakino