summaryrefslogtreecommitdiffstats
path: root/math.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-04-22 16:02:38 -0700
committeryum <yum.food.vr@gmail.com>2024-04-22 16:02:38 -0700
commitdcb15c0d7425f2b3ede070cd97ac8f1bd8386df1 (patch)
treee17e5b620e0784226b6d24acce43c8bbcee22f1f /math.cginc
Initial commit
Code bomb. Put tooner in version control.
Diffstat (limited to 'math.cginc')
-rw-r--r--math.cginc115
1 files changed, 115 insertions, 0 deletions
diff --git a/math.cginc b/math.cginc
new file mode 100644
index 0000000..747c5c2
--- /dev/null
+++ b/math.cginc
@@ -0,0 +1,115 @@
+#ifndef __MATH_INC
+#define __MATH_INC
+
+#include "pema99.cginc"
+
+float4 qmul(float4 q1, float4 q2)
+{
+ return float4(
+ q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz),
+ q1.w * q2.w - dot(q1.xyz, q2.xyz)
+ );
+}
+
+// Vector rotation with a quaternion
+// http://mathworld.wolfram.com/Quaternion.html
+float3 rotate_vector(float3 v, float4 r)
+{
+ float4 r_c = r * float4(-1, -1, -1, 1);
+ return qmul(r, qmul(float4(v, 0), r_c)).xyz;
+}
+
+float4 get_quaternion(float3 axis_normal, float theta) {
+ return float4(
+ axis_normal * sin(theta / 2), cos(theta / 2));
+}
+
+// Differentiable approximation of the standard `max` function.
+float dmax(float a, float b, float k)
+{
+ return log2(exp2(k * a) + exp2(k * b)) / k;
+}
+
+// Differentiable approximation of the standard `min` function.
+float dmin(float a, float b, float k)
+{
+ return -1.0 * dmax(-1.0 * a, -1.0 * b, k);
+}
+
+float dabs(float a, float k)
+{
+ return log2(exp2(k * a) + exp2(-1.0 * k * a));
+}
+
+float rand(uint seed) {
+ seed = seed * 747796405 + 2891336453;
+ uint result = ((seed >> ((seed >> 28) + 4)) ^ seed) * 277803737;
+ result = (result >> 22) ^ result;
+ return result / 4294967295.0;
+}
+
+// Generate a random number on [0, 1].
+float rand2(float2 p)
+{
+ return glsl_mod(sin(dot(p, float2(561.0, 885.0))) * 776.2, 1.0);
+}
+
+// Generate a random number on [0, 1].
+float rand3(float3 p)
+{
+ return glsl_mod(sin(dot(p, float3(897.0, 367.0, 197.0))) * 1073.6, 1.0);
+}
+
+float length2(float2 p)
+{
+ return p.x * p.x + p.y * p.y;
+}
+
+// 3 dimensional value noise. `p` is assumed to be a point inside a unit cube.
+// Theory: https://en.wikipedia.org/wiki/Value_noise
+float vnoise3d(float3 p)
+{
+ float3 pu = floor(p);
+ float3 pv = glsl_mod(frac(p), 1.0);
+
+ // Assign random numbers to the corner of a cube.
+ float n000 = rand3(pu + float3(0,0,0));
+ float n001 = rand3(pu + float3(0,0,1));
+ float n010 = rand3(pu + float3(0,1,0));
+ float n011 = rand3(pu + float3(0,1,1));
+ float n100 = rand3(pu + float3(1,0,0));
+ float n101 = rand3(pu + float3(1,0,1));
+ float n110 = rand3(pu + float3(1,1,0));
+ float n111 = rand3(pu + float3(1,1,1));
+
+ float n00 = lerp(n000, n001, pv.z);
+ float n01 = lerp(n010, n011, pv.z);
+ float n10 = lerp(n100, n101, pv.z);
+ float n11 = lerp(n110, n111, pv.z);
+
+ float n0 = lerp(n00, n01, pv.y);
+ float n1 = lerp(n10, n11, pv.y);
+
+ float n = lerp(n0, n1, pv.x);
+
+ return n;
+}
+
+float fbm(float3 p, const int n_octaves, float w)
+{
+ float g = exp2(-w);
+ float a = 1.0;
+ float p_scale = 1.0;
+
+ float res = 0.0;
+ for (int i = 0; i < n_octaves; i++) {
+ res += a * vnoise3d(p * p_scale);
+
+ p_scale /= w;
+ a *= g;
+ }
+ return res;
+}
+
+#endif // __MATH_INC
+