Compiler Behavior Notes
From shaderLABS
Windows
NVIDIA
- Includes before the
#version
argument are not supported.- The GLSL spec says that
#version
must be the first non-whitespace line in your code.
- The GLSL spec says that
- Equal conditions using floats may not work as intended.
- e.g.
if (a == 1.0)
- Comparing floats this way is considered bad practice since there's multiple ways to represent a lot of numbers, meaning that they might have different values. A more reliable way is to either convert them to
int
s first or do something likeif(abs(a - 1.0) < 0.0001)
- e.g.
- Constant arguments of functions get compiled as actual constants and can be used in constant expressions.
- e.g.
void blah(const int a, const float b)
- e.g.
mix()
is not supported in constant expressions on GeForce 500 and older.- Can be manually implemented like this:
#define cmix(x, y, a) (y * a + x * (1.0 - a))
- Can be manually implemented like this:
- GL Extensions have to be explicitly enabled (e.g.
GL_ARB_shader_texture_lod
). - GL Extension
#extension GL_EXT_gpu_shader4 : enable
is required for specific operations, even on GL300 and newer when using function calls with the2D
or3D
suffix (e.g.texelFetch2D()
). - NaNs may occur when not clamping the framebuffer used for the main scene color, especially on blacks.
- Doing a clamp with a minimum of
1.0 / k
on said buffer fixes the issue, with k being the maximum amount of discreet values supported by the current buffer precision (e.g.255.0
on 8 bit and65535.0
on 16 bit).
- Doing a clamp with a minimum of
- Normalizing a zero vector results in NaNs.
- Implicit casts from
int
/uint
to float may fail to compile. - Variables marked as
const
that aren't constant expressions are allowed treated as immutable, even prior to GLSL 4.2 where this is illegal according to the spec.
AMD
- Constants using some of the built-in functions are not supported.
- e.g.
const float f = const_func();
- They can be manually implemented as macro, just like non-built-in functions:
- e.g.
#define add(x, y) (x + y)
instead offloat add(float x, float y) { return x + y; }
- e.g.
- The same might apply to constants made of other constants.
- e.g.
- Sampling textures outside of
void main()
causes sampling of a wrong texture.- Sampling inside a function works fine, as long as it doesn't get used outside of
void main()
or other functions.
- Sampling inside a function works fine, as long as it doesn't get used outside of
- Reserved words:
buffer
,input
andhalf
input
is reserved for future use as part of specification.half
is reserved as part of specification.
- Using
gl_MultiTexcoord
on GLSL 1.3+ without the compatibility profile is allowed.gl_MultiTexCoord
was deprecated in GLSL 1.3 and removed from the core profile in 1.4, so it shouldn't be possible to use in a core profile of 1.4 or later.
- Some GL Extensions will be enabled automatically when used without explicitly being enabled (e.g.
GL_ARB_shader_texture_lod
). - The usage of geometry shaders on terrain requires external triangulation for quad-geometry.
- Using shadow mipmaps with a shadow map resolution that is not a power of two can cause a crash on loading.
- Function type casting from float to a vector type is apparently supported.
- Variables marked as
const
that aren't constant expressions are not allowed, even in GLSL 4.2+ where this is legal according to the spec (the variables should be treated as immutable).
Intel
- Reserved word:
half
half
is reserved as part of specification.
- Only up to seven framebuffer attachments are supported.
- The specification only guarantees seven but allows more.
- GLSL 3.0+ guarantees eight framebuffer attachments.
- Recursive macros are not allowed (e.g.
#define smoothstep(x, low, high) smoothstep(low, high, x)
). - Extensions have to be declared directly after the
#version
directive. - Constants using built-in functions may fail to compile.
- e.g.
const float f = const_func();
- They can be manually implemented as macro.
- e.g.
#define add(x, y) (x+y)
instead offloat add(float x, float y) {return x + y;}
- e.g.
- e.g.
- Constants using
struct
inputs are not supported.
macOS
- Empty external declarations (just a single
;
at the global level) are not allowed. This includes semicolons after function definitions likevoid main() { ... };
where the semicolon is technically separate from the function definition and constitutes its own (empty) external declaration.
M1
- Calling a function in the global scope (outside of other functions) crashes the whole application.
- Instead, move the initialization to the top of the
main
function and only keep the declaration in its original location.
- Instead, move the initialization to the top of the
Linux
Mesa (AMD, open source)
- Only GLSL 1.1, 1.2, 1.3, 1.0 ES, 3.0 ES, 3.1 ES and 3.2 ES are supported (possibly only affects APUs).
- On Polaris/Vega based cards, GLSL 4.3 compatibility is available.
EXT_gpu_shader_4
is not supported.- Certain features can be achieved with different extensions.
- If an image has LODs enabled but gets overwritten in the next pass, the LODs from the previous pass are still bound.
- This can lead to wrong information being read unless the LOD to be read from is explicitly declared (
textureLod()
).
- This can lead to wrong information being read unless the LOD to be read from is explicitly declared (
Nouveau (NVIDIA, open source)
- Not compatible.
NVIDIA (proprietary)
- Same as on Windows.
AMD (proprietary)
- Same as on Windows.