patriciogonzalezvivo / thebookofshaders

Step-by-step guide through the abstract and complex universe of Fragment Shaders.

Home Page:http://TheBookOfShaders.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inconsistency between operating systems

michaeljblum opened this issue · 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?

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.

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

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.

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

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.