Divergent/mods/Shaders Look Better/gamedata/shaders/r3/slb_common.h

249 lines
7.2 KiB
C
Raw Normal View History

#ifndef SLB_COMMON_H
#define SLB_COMMON_H
#include "slb_aliases.h"
#define SLB_PI 3.14159265358979323846
#define SLB_TAU 6.28318530717958647693
#define SLB_GoldenAngle 2.39996322972865332223
#define SLB_GoldenRatio 0.61803398874989484820
/// Taken from https://gist.github.com/yiwenl/3f804e80d0930e34a0b33359259b556c
float2x2 SLB_Rotate2Matrix(float a) {
float s = sin(a);
float c = cos(a);
return float2x2(float2(c, s), float2(-s, c));
}
float2 SLB_Rotate2(float2 v, float a) {
float2x2 m = SLB_Rotate2Matrix(a);
return mul(v, m);
}
float SLB_ToFloat1(uint v) {
return float(v) * (1.0/float(0xffffffffu));
}
float2 SLB_ToFloat2(uint2 v) {
return float2(v) * (1.0/float(0xffffffffu));
}
float3 SLB_ToFloat3(uint3 v) {
return float3(v) * (1.0/float(0xffffffffu));
}
float4 SLB_ToFloat4(uint4 v) {
return float4(v) * (1.0/float(0xffffffffu));
}
float SLB_Min3(float3 v) {
return min(v.x, min(v.y, v.z));
}
float SLB_Max3(float3 v) {
return max(v.x, max(v.y, v.z));
}
/// Taken from https://web.archive.org/web/20200306054846/http://lolengine.net:80/blog/2013/07/27/rgb-to-hsv-in-glsl
float3 SLB_RGB_To_HSV(float3 c) {
float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
float4 p = c.g < c.b ? float4(c.bg, K.wz) : float4(c.gb, K.xy);
float4 q = c.r < p.x ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
float d = q.x - min(q.w, q.y);
const float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
/// It took me long time to found this somewhere in vanilla shaders codebase;
float2 SLB_Pos2DToCoord(float2 pos2d) {
// return float2((pos2d.x * screen_res.z * 2.0 - 1.0), (pos2d.y * screen_res.w * 2.0 - 1.0))/2.0 * screen_res.xy;
return (pos2d.xy * screen_res.zw - 0.5) * screen_res.xy;
}
/// Taken from https://iquilezles.org/articles/smoothsteps
float SLB_Cubic1D(float x) {
return x*x*(3.0 - 2.0*x);
}
/// Taken from https://iquilezles.org/articles/smoothsteps
float SLB_Quartic1D(float x) {
return x*x*(2.0 - x*x);
}
/// Taken from https://iquilezles.org/articles/smoothsteps
float SLB_Quintic1D(float x) {
return x*x*x*(x*(6.0*x - 15.0) + 10.0);
}
/// Taken from https://iquilezles.org/articles/smoothsteps
float SLB_CubicRational1D(float x) {
return x*x*x/(3.0*x*x - 3.0*x + 1.0);
}
/// Taken from https://iquilezles.org/articles/smoothsteps
float SLB_QuarticRational1D(float x) {
return x*x*x*x/(2.0*x*x*x*x - 4.0*x*x*x + 6.0*x*x - 4.0*x + 1.0);
}
/// Taken from somewhere
float SLB_Gaussian1D(float x, float sigma) {
return exp(-(x * x) / (2.0 * sigma * sigma));
}
/// Taken from http://www.java-gaming.org/index.php?topic=35123.0
/// Idk how to name it
float4 SLB_Cubic_For_Bicubic(float v) {
float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
float4 s = n * n * n;
float x = s.x;
float y = s.y - 4.0 * s.x;
float z = s.z - 4.0 * s.y + 6.0 * s.x;
float w = 6.0 - x - y - z;
return float4(x, y, z, w) * (1.0/6.0);
}
float2 SLB_VogelDisk_Sample(const int sample_index, const int samples_count) {
const float r = sqrt(float(sample_index) + 0.5) / sqrt(float(samples_count));
const float theta = float(sample_index) * SLB_GoldenAngle;
const float sine = sin(theta), cosine = cos(theta);
return float2(r * cosine, r * sine);
}
/// Taken from https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences
float SLB_R1(float n) {
const float g = 1.6180339887498948482;
const float a1 = 1.0 - 1.0/g;
float _n = floor(n);
return frac(0.5 + a1*_n);
}
/// Taken from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes
uint SLB_Part1By1(uint x) {
x &= 0x0000ffffu;
x = (x ^ (x << 8u)) & 0x00ff00ffu;
x = (x ^ (x << 4u)) & 0x0f0f0f0fu;
x = (x ^ (x << 2u)) & 0x33333333u;
x = (x ^ (x << 1u)) & 0x55555555u;
return x;
}
/// Taken from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes
uint SLB_EncodeMorton2(uint x, uint y) {
return (SLB_Part1By1(y) << 1u) + SLB_Part1By1(x);
}
/// From https://psychopath.io post
uint SLB_OwenHash4(uint n, uint seed) {
n ^= n * 0x3d20adeau;
n ^= (n >> 1u) & (n << 1u) & 0x55555555u;
n += seed;
n *= (seed >> 16u) | 1u;
n ^= (n >> 1u) & (n << 1u) & 0x55555555u;
n ^= n * 0x05526c56u;
n ^= n * 0x53a22864u;
return n;
}
/// Inspired by https://www.shadertoy.com/view/ssBBW1 shader and https://psychopath.io posts
uint SLB_Morton_OwenHash4_Bluenoise(uint2 coord) {
uint m;
m = SLB_EncodeMorton2(coord.x, coord.y);
m = SLB_OwenHash4(reversebits(m), 0xe7843fbfu); // owen-scramble morton index
m = SLB_OwenHash4(reversebits(m), 0x8d8fb1e0u); // map morton index to sobol sequence and owen-scramble
return reversebits(m); // convert to float
}
float SLB_Morton_OwenHash4_Bluenoise_float(uint2 coord) {
return SLB_ToFloat1(SLB_Morton_OwenHash4_Bluenoise(coord));
}
/// Taken from https://www.shadertoy.com/view/wltSDn
uint SLB_PhiNoise(uint2 uv) {
// flip every other tile to reduce anisotropy
if(((uv.x ^ uv.y) & 4u) == 0u) uv = uv.yx;
// constants of 2d Roberts sequence rounded to nearest primes
const uint r0 = 3242174893u;// prime[(2^32-1) / phi_2 ]
const uint r1 = 2447445397u;// prime[(2^32-1) / phi_2^2]
// h = high-freq dither noise
uint h = (uv.x * r0) + (uv.y * r1);
// l = low-freq white noise
uv = uv >> 2u;// 3u works equally well (I think)
uint l = ((uv.x * r0) ^ (uv.y * r1)) * r1;
// combine low and high
return l + h;
}
float SLB_PhiNoise_float(uint2 uv) {
return SLB_ToFloat1(SLB_PhiNoise(uv));
}
/// Taken from https://www.shadertoy.com/view/wltSDn
uint SLB_PhiNoise2(uint2 uv) {
uint2 uv0 = uv;
// flip every other tile to reduce anisotropy
if(((uv.x ^ uv.y) & 4u) == 0u) uv = uv.yx;
if(((uv.x ) & 4u) == 0u) uv.x = -uv.x;// more iso but also more low-freq content
// constants of 2d Roberts sequence rounded to nearest primes
const uint r0 = 3242174893u;// prime[(2^32-1) / phi_2 ]
const uint r1 = 2447445397u;// prime[(2^32-1) / phi_2^2]
// h = high-freq dither noise
uint h = (uv.x * r0) + (uv.y * r1);
uint l;
{
uv = uv0 >> 2u;
if(((uv.x ^ uv.y) & 4u) == 0u) uv = uv.yx;
if(((uv.x ) & 4u) == 0u) uv.x = -uv.x;
uint h = (uv.x * r0) + (uv.y * r1);
h = h ^ 0xE2E17FDCu;
l = h;
{
uv = uv0 >> 4u;
if(((uv.x ^ uv.y) & 4u) == 0u) uv = uv.yx;
if(((uv.x ) & 4u) == 0u) uv.x = -uv.x;
uint h = (uv.x * r0) + (uv.y * r1);
h = h ^ 0x1B98264Du;
l += h;
}
}
// combine low and high
return l + h;
}
float SLB_PhiNoise2_float(uint2 uv) {
return SLB_ToFloat1(SLB_PhiNoise2(uv));
}
/// Taken from paper named "Hash Functions for GPU Rendering"
uint4 SLB_PCG4D(uint4 v) {
v = v * 1664525u + 1013904223u;
v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z;
v ^= v >> 16u;
v.x += v.y*v.w; v.y += v.z*v.x; v.z += v.x*v.y; v.w += v.y*v.z;
return v;
}
/// Taken from https://www.pcg-random.org
uint SLB_PCG(uint v) {
uint state = v * 747796405u + 2891336453u;
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
return (word >> 22u) ^ word;
}
#endif // SLB_COMMON_H