This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl
Clément Foucault 80859a6cb2 GPU: Make nodetree GLSL Codegen render engine agnostic
This commit removes all EEVEE specific code from the `gpu_shader_material*.glsl`
files. It defines a clear interface to evaluate the closure nodes leaving
more flexibility to the render engine.

Some of the long standing workaround are fixed:
- bump mapping support is no longer duplicating a lot of node and is instead
  compiled into a function call.
- bump rewiring to Normal socket is no longer needed as we now use a global
  `g_data.N` for that.


Closure sampling with upstread weight eval is now supported if the engine needs
it.

This also makes all the material GLSL sources use `GPUSource` for better
debugging experience. The `GPUFunction` parsing now happens in `GPUSource`
creation.

The whole `GPUCodegen` now uses the `ShaderCreateInfo` and is object type
agnostic. Is has also been rewritten in C++.

This patch changes a view behavior for EEVEE:
- Mix shader node factor imput is now clamped.
- Tangent Vector displacement behavior is now matching cycles.
- The chosen BSDF used for SSR might change.
- Hair shading may have very small changes on very large hairs when using hair
  polygon stripes.
- ShaderToRGB node will remove any SSR and SSS form a shader.
- SSS radius input now is no longer a scaling factor but defines an average
  radius. The SSS kernel "shape" (radii) are still defined by the socket default
  values.

Appart from the listed changes no other regressions are expected.
2022-04-14 18:47:58 +02:00

301 lines
7.3 KiB
GLSL

#pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl)
/* clang-format off */
#define FLOORFRAC(x, x_int, x_fract) { float x_floor = floor(x); x_int = int(x_floor); x_fract = x - x_floor; }
/* clang-format on */
/* Bilinear Interpolation:
*
* v2 v3
* @ + + + + @ y
* + + ^
* + + |
* + + |
* @ + + + + @ @------> x
* v0 v1
*
*/
float bi_mix(float v0, float v1, float v2, float v3, float x, float y)
{
float x1 = 1.0 - x;
return (1.0 - y) * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x);
}
/* Trilinear Interpolation:
*
* v6 v7
* @ + + + + + + @
* +\ +\
* + \ + \
* + \ + \
* + \ v4 + \ v5
* + @ + + + +++ + @ z
* + + + + y ^
* v2 @ + +++ + + + @ v3 + \ |
* \ + \ + \ |
* \ + \ + \|
* \ + \ + +---------> x
* \+ \+
* @ + + + + + + @
* v0 v1
*/
float tri_mix(float v0,
float v1,
float v2,
float v3,
float v4,
float v5,
float v6,
float v7,
float x,
float y,
float z)
{
float x1 = 1.0 - x;
float y1 = 1.0 - y;
float z1 = 1.0 - z;
return z1 * (y1 * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x)) +
z * (y1 * (v4 * x1 + v5 * x) + y * (v6 * x1 + v7 * x));
}
float quad_mix(float v0,
float v1,
float v2,
float v3,
float v4,
float v5,
float v6,
float v7,
float v8,
float v9,
float v10,
float v11,
float v12,
float v13,
float v14,
float v15,
float x,
float y,
float z,
float w)
{
return mix(tri_mix(v0, v1, v2, v3, v4, v5, v6, v7, x, y, z),
tri_mix(v8, v9, v10, v11, v12, v13, v14, v15, x, y, z),
w);
}
float fade(float t)
{
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
}
float negate_if(float value, uint condition)
{
return (condition != 0u) ? -value : value;
}
float noise_grad(uint hash, float x)
{
uint h = hash & 15u;
float g = 1u + (h & 7u);
return negate_if(g, h & 8u) * x;
}
float noise_grad(uint hash, float x, float y)
{
uint h = hash & 7u;
float u = h < 4u ? x : y;
float v = 2.0 * (h < 4u ? y : x);
return negate_if(u, h & 1u) + negate_if(v, h & 2u);
}
float noise_grad(uint hash, float x, float y, float z)
{
uint h = hash & 15u;
float u = h < 8u ? x : y;
float vt = ((h == 12u) || (h == 14u)) ? x : z;
float v = h < 4u ? y : vt;
return negate_if(u, h & 1u) + negate_if(v, h & 2u);
}
float noise_grad(uint hash, float x, float y, float z, float w)
{
uint h = hash & 31u;
float u = h < 24u ? x : y;
float v = h < 16u ? y : z;
float s = h < 8u ? z : w;
return negate_if(u, h & 1u) + negate_if(v, h & 2u) + negate_if(s, h & 4u);
}
float noise_perlin(float x)
{
int X;
float fx;
FLOORFRAC(x, X, fx);
float u = fade(fx);
float r = mix(noise_grad(hash_int(X), fx), noise_grad(hash_int(X + 1), fx - 1.0), u);
return r;
}
float noise_perlin(vec2 vec)
{
int X, Y;
float fx, fy;
FLOORFRAC(vec.x, X, fx);
FLOORFRAC(vec.y, Y, fy);
float u = fade(fx);
float v = fade(fy);
float r = bi_mix(noise_grad(hash_int2(X, Y), fx, fy),
noise_grad(hash_int2(X + 1, Y), fx - 1.0, fy),
noise_grad(hash_int2(X, Y + 1), fx, fy - 1.0),
noise_grad(hash_int2(X + 1, Y + 1), fx - 1.0, fy - 1.0),
u,
v);
return r;
}
float noise_perlin(vec3 vec)
{
int X, Y, Z;
float fx, fy, fz;
FLOORFRAC(vec.x, X, fx);
FLOORFRAC(vec.y, Y, fy);
FLOORFRAC(vec.z, Z, fz);
float u = fade(fx);
float v = fade(fy);
float w = fade(fz);
float r = tri_mix(noise_grad(hash_int3(X, Y, Z), fx, fy, fz),
noise_grad(hash_int3(X + 1, Y, Z), fx - 1, fy, fz),
noise_grad(hash_int3(X, Y + 1, Z), fx, fy - 1, fz),
noise_grad(hash_int3(X + 1, Y + 1, Z), fx - 1, fy - 1, fz),
noise_grad(hash_int3(X, Y, Z + 1), fx, fy, fz - 1),
noise_grad(hash_int3(X + 1, Y, Z + 1), fx - 1, fy, fz - 1),
noise_grad(hash_int3(X, Y + 1, Z + 1), fx, fy - 1, fz - 1),
noise_grad(hash_int3(X + 1, Y + 1, Z + 1), fx - 1, fy - 1, fz - 1),
u,
v,
w);
return r;
}
float noise_perlin(vec4 vec)
{
int X, Y, Z, W;
float fx, fy, fz, fw;
FLOORFRAC(vec.x, X, fx);
FLOORFRAC(vec.y, Y, fy);
FLOORFRAC(vec.z, Z, fz);
FLOORFRAC(vec.w, W, fw);
float u = fade(fx);
float v = fade(fy);
float t = fade(fz);
float s = fade(fw);
float r = quad_mix(
noise_grad(hash_int4(X, Y, Z, W), fx, fy, fz, fw),
noise_grad(hash_int4(X + 1, Y, Z, W), fx - 1.0, fy, fz, fw),
noise_grad(hash_int4(X, Y + 1, Z, W), fx, fy - 1.0, fz, fw),
noise_grad(hash_int4(X + 1, Y + 1, Z, W), fx - 1.0, fy - 1.0, fz, fw),
noise_grad(hash_int4(X, Y, Z + 1, W), fx, fy, fz - 1.0, fw),
noise_grad(hash_int4(X + 1, Y, Z + 1, W), fx - 1.0, fy, fz - 1.0, fw),
noise_grad(hash_int4(X, Y + 1, Z + 1, W), fx, fy - 1.0, fz - 1.0, fw),
noise_grad(hash_int4(X + 1, Y + 1, Z + 1, W), fx - 1.0, fy - 1.0, fz - 1.0, fw),
noise_grad(hash_int4(X, Y, Z, W + 1), fx, fy, fz, fw - 1.0),
noise_grad(hash_int4(X + 1, Y, Z, W + 1), fx - 1.0, fy, fz, fw - 1.0),
noise_grad(hash_int4(X, Y + 1, Z, W + 1), fx, fy - 1.0, fz, fw - 1.0),
noise_grad(hash_int4(X + 1, Y + 1, Z, W + 1), fx - 1.0, fy - 1.0, fz, fw - 1.0),
noise_grad(hash_int4(X, Y, Z + 1, W + 1), fx, fy, fz - 1.0, fw - 1.0),
noise_grad(hash_int4(X + 1, Y, Z + 1, W + 1), fx - 1.0, fy, fz - 1.0, fw - 1.0),
noise_grad(hash_int4(X, Y + 1, Z + 1, W + 1), fx, fy - 1.0, fz - 1.0, fw - 1.0),
noise_grad(hash_int4(X + 1, Y + 1, Z + 1, W + 1), fx - 1.0, fy - 1.0, fz - 1.0, fw - 1.0),
u,
v,
t,
s);
return r;
}
/* Remap the output of noise to a predictable range [-1, 1].
* The scale values were computed experimentally by the OSL developers.
*/
float noise_scale1(float result)
{
return 0.2500 * result;
}
float noise_scale2(float result)
{
return 0.6616 * result;
}
float noise_scale3(float result)
{
return 0.9820 * result;
}
float noise_scale4(float result)
{
return 0.8344 * result;
}
/* Safe Signed And Unsigned Noise */
float snoise(float p)
{
float r = noise_perlin(p);
return (isinf(r)) ? 0.0 : noise_scale1(r);
}
float noise(float p)
{
return 0.5 * snoise(p) + 0.5;
}
float snoise(vec2 p)
{
float r = noise_perlin(p);
return (isinf(r)) ? 0.0 : noise_scale2(r);
}
float noise(vec2 p)
{
return 0.5 * snoise(p) + 0.5;
}
float snoise(vec3 p)
{
float r = noise_perlin(p);
return (isinf(r)) ? 0.0 : noise_scale3(r);
}
float noise(vec3 p)
{
return 0.5 * snoise(p) + 0.5;
}
float snoise(vec4 p)
{
float r = noise_perlin(p);
return (isinf(r)) ? 0.0 : noise_scale4(r);
}
float noise(vec4 p)
{
return 0.5 * snoise(p) + 0.5;
}