Last active
December 1, 2024 09:30
-
-
Save andanteyk/ce0a5eb497074e0bcbf5600ef8bc20a3 to your computer and use it in GitHub Desktop.
Perlin and Simplex noise implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This work is marked with CC0 1.0. To view a copy of this license, visit https://creativecommons.org/publicdomain/zero/1.0/ | |
Shader "Unlit/PerlinTest" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
Tags { "RenderType"="Transparent" } | |
Pass | |
{ | |
CGPROGRAM | |
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices | |
#pragma exclude_renderers gles | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
#include "UnityCustomRenderTexture.cginc" | |
//#pragma vertex CustomRenderTextureVertexShader | |
//#pragma fragment frag_crt | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
UNITY_FOG_COORDS(1) | |
float4 vertex : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
return o; | |
} | |
static int permutation[512] = { | |
151,160,137,91,90,15, | |
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, | |
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, | |
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, | |
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, | |
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, | |
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, | |
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, | |
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, | |
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, | |
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, | |
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, | |
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, | |
151,160,137,91,90,15, | |
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, | |
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, | |
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, | |
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, | |
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, | |
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, | |
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, | |
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, | |
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, | |
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, | |
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, | |
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 | |
}; | |
static float3 grad3vecs[] = { | |
float3(1, 1, 0), | |
float3(-1, 1, 0), | |
float3(1, -1, 0), | |
float3(-1, -1, 0), | |
float3(1, 0, 1), | |
float3(-1, 0, 1), | |
float3(1, 0, -1), | |
float3(-1, 0, -1), | |
float3(0, 1, 1), | |
float3(0, -1, 1), | |
float3(0, 1, -1), | |
float3(0, -1, -1), | |
}; | |
static float4 grad4vecs[] = { | |
float4(0, -1, -1, -1), | |
float4(0, -1, -1, +1), | |
float4(0, -1, +1, -1), | |
float4(0, -1, +1, +1), | |
float4(0, +1, -1, -1), | |
float4(0, +1, -1, +1), | |
float4(0, +1, +1, -1), | |
float4(0, +1, +1, +1), | |
float4(-1, 0, -1, -1), | |
float4(-1, 0, -1, +1), | |
float4(-1, 0, +1, -1), | |
float4(-1, 0, +1, +1), | |
float4(+1, 0, -1, -1), | |
float4(+1, 0, -1, +1), | |
float4(+1, 0, +1, -1), | |
float4(+1, 0, +1, +1), | |
float4(-1, -1, 0, -1), | |
float4(-1, -1, 0, +1), | |
float4(-1, +1, 0, -1), | |
float4(-1, +1, 0, +1), | |
float4(+1, -1, 0, -1), | |
float4(+1, -1, 0, +1), | |
float4(+1, +1, 0, -1), | |
float4(+1, +1, 0, +1), | |
float4(-1, -1, -1, 0), | |
float4(-1, -1, +1, 0), | |
float4(-1, +1, -1, 0), | |
float4(-1, +1, +1, 0), | |
float4(+1, -1, -1, 0), | |
float4(+1, -1, +1, 0), | |
float4(+1, +1, -1, 0), | |
float4(+1, +1, +1, 0), | |
}; | |
float rand2(float2 pos) | |
{ | |
return permutation[((int)pos.x & 255) + permutation[((int)pos.y & 255)]] / 256.0; | |
} | |
float2 grad2(float2 pos) | |
{ | |
int p = permutation[((int)pos.x & 255) + permutation[((int)pos.y & 255)]]; | |
return grad3vecs[(uint)p % 12].xy; | |
//return float2(cos(p / 256.0 * 6.283185), sin(p / 256.0 * 6.283185)); | |
} | |
float rand3(float3 pos) | |
{ | |
return permutation[((int)pos.x & 255) + permutation[((int)pos.y & 255) + permutation[(int)pos.z & 255]]] / 256.0; | |
} | |
float3 grad3(float3 pos) | |
{ | |
int p = permutation[((int)pos.x & 255) + permutation[((int)pos.y & 255) + permutation[(int)pos.z & 255]]]; | |
return grad3vecs[(uint)p % 12]; | |
//return float3(cos((p / 16) * 0.392699) * cos((p & 15) * 0.392699), cos((p / 16) * 0.392699) * sin((p & 15) * 0.392699), sin((p / 16) * 0.392699)); | |
} | |
float4 grad4(float4 pos) | |
{ | |
int p = permutation[((int)pos.x & 255) + permutation[((int)pos.y & 255) + permutation[((int)pos.z & 255) + permutation[(int)pos.w & 255]]]]; | |
return grad4vecs[(uint)p & 0x1f]; | |
} | |
float interpolate3(float x, float y, float t) | |
{ | |
return x + (y - x) * (3 - t * 2) * t * t; | |
} | |
float interpolate5(float x, float y, float t) | |
{ | |
return x + (y - x) * t * t * t * (t * (t * 6 - 15) + 10); | |
} | |
float interpolate3derivative(float x, float y, float t) | |
{ | |
return x + (y - x) * t * (6 - t * 6); | |
} | |
float interpolate5derivative(float x, float y, float t) | |
{ | |
return x + (y - x) * t * t * (t * (t * 30 - 60) + 30); | |
} | |
float approx(float x, float y) | |
{ | |
return abs(x - y) < 0.001; | |
} | |
// 2D value noise | |
float3 value2(float2 pos) | |
{ | |
float2 intpos0 = floor(pos); | |
float2 intpos1 = intpos0 + 1; | |
float2 fracpos = pos - intpos0; | |
float2 p00 = float2(intpos0.x, intpos0.y); | |
float2 p01 = float2(intpos0.x, intpos1.y); | |
float2 p10 = float2(intpos1.x, intpos0.y); | |
float2 p11 = float2(intpos1.x, intpos1.y); | |
float value00 = rand2(p00); | |
float value01 = rand2(p01); | |
float value10 = rand2(p10); | |
float value11 = rand2(p11); | |
float intp0 = interpolate3(value00, value01, fracpos.y); | |
float intp1 = interpolate3(value10, value11, fracpos.y); | |
float intp = interpolate3(intp0, intp1, fracpos.x); | |
return intp.xxx; | |
} | |
// 3D value noise | |
float3 value3(float3 pos) | |
{ | |
float3 intpos0 = floor(pos); | |
float3 intpos1 = intpos0 + 1; | |
float3 fracpos = pos - intpos0; | |
float3 p000 = float3(intpos0.x, intpos0.y, intpos0.z); | |
float3 p001 = float3(intpos0.x, intpos0.y, intpos1.z); | |
float3 p010 = float3(intpos0.x, intpos1.y, intpos0.z); | |
float3 p011 = float3(intpos0.x, intpos1.y, intpos1.z); | |
float3 p100 = float3(intpos1.x, intpos0.y, intpos0.z); | |
float3 p101 = float3(intpos1.x, intpos0.y, intpos1.z); | |
float3 p110 = float3(intpos1.x, intpos1.y, intpos0.z); | |
float3 p111 = float3(intpos1.x, intpos1.y, intpos1.z); | |
float value000 = rand3(p000).x; | |
float value001 = rand3(p001).x; | |
float value010 = rand3(p010).x; | |
float value011 = rand3(p011).x; | |
float value100 = rand3(p100).x; | |
float value101 = rand3(p101).x; | |
float value110 = rand3(p110).x; | |
float value111 = rand3(p111).x; | |
float intp00 = interpolate3(value000, value001, fracpos.z); | |
float intp01 = interpolate3(value010, value011, fracpos.z); | |
float intp10 = interpolate3(value100, value101, fracpos.z); | |
float intp11 = interpolate3(value110, value111, fracpos.z); | |
float intp0 = interpolate3(intp00, intp01, fracpos.y); | |
float intp1 = interpolate3(intp10, intp11, fracpos.y); | |
float intp = interpolate3(intp0, intp1, fracpos.x); | |
return intp.xxx; | |
} | |
// 2D perlin noise (∂f/∂x, ∂f/∂y, f) | |
float3 perlin2(float2 pos) | |
{ | |
float2 intpos0 = floor(pos); | |
float2 intpos1 = intpos0 + 1; | |
float2 fracpos = pos - intpos0; | |
float2 p00 = float2(intpos0.x, intpos0.y); | |
float2 p01 = float2(intpos0.x, intpos1.y); | |
float2 p10 = float2(intpos1.x, intpos0.y); | |
float2 p11 = float2(intpos1.x, intpos1.y); | |
float2 grad00 = grad2(p00); | |
float2 grad01 = grad2(p01); | |
float2 grad10 = grad2(p10); | |
float2 grad11 = grad2(p11); | |
float value00 = dot(grad00, pos - p00); | |
float value01 = dot(grad01, pos - p01); | |
float value10 = dot(grad10, pos - p10); | |
float value11 = dot(grad11, pos - p11); | |
float intp0 = interpolate5(value00, value01, fracpos.y); | |
float intp1 = interpolate5(value10, value11, fracpos.y); | |
float intp = interpolate5(intp0, intp1, fracpos.x); | |
float tx = interpolate5(0, 1, fracpos.x); | |
float ty = interpolate5(0, 1, fracpos.y); | |
float2 tp = float2(interpolate5derivative(0, 1, fracpos.x), interpolate5derivative(0, 1, fracpos.y)); | |
float2 alphap = grad00 + (grad01 - grad00) * ty + (value01 - value00) * float2(0, tp.y); | |
float2 betap = grad10 + (grad11 - grad10) * ty + (value11 - value10) * float2(0, tp.y); | |
float2 p = alphap + (betap - alphap) * tx + (intp1 - intp0) * float2(tp.x, 0); | |
return float3(p, intp); | |
} | |
// 3D perlin noise (∂f/∂x, ∂f/∂y, ∂f/∂z, f) | |
float4 perlin3(float3 pos) | |
{ | |
float3 intpos0 = floor(pos); | |
float3 intpos1 = intpos0 + 1; | |
float3 fracpos = pos - intpos0; | |
float3 p000 = float3(intpos0.x, intpos0.y, intpos0.z); | |
float3 p001 = float3(intpos0.x, intpos0.y, intpos1.z); | |
float3 p010 = float3(intpos0.x, intpos1.y, intpos0.z); | |
float3 p011 = float3(intpos0.x, intpos1.y, intpos1.z); | |
float3 p100 = float3(intpos1.x, intpos0.y, intpos0.z); | |
float3 p101 = float3(intpos1.x, intpos0.y, intpos1.z); | |
float3 p110 = float3(intpos1.x, intpos1.y, intpos0.z); | |
float3 p111 = float3(intpos1.x, intpos1.y, intpos1.z); | |
float3 grad000 = grad3(p000); | |
float3 grad001 = grad3(p001); | |
float3 grad010 = grad3(p010); | |
float3 grad011 = grad3(p011); | |
float3 grad100 = grad3(p100); | |
float3 grad101 = grad3(p101); | |
float3 grad110 = grad3(p110); | |
float3 grad111 = grad3(p111); | |
float value000 = dot(grad000, pos - p000); | |
float value001 = dot(grad001, pos - p001); | |
float value010 = dot(grad010, pos - p010); | |
float value011 = dot(grad011, pos - p011); | |
float value100 = dot(grad100, pos - p100); | |
float value101 = dot(grad101, pos - p101); | |
float value110 = dot(grad110, pos - p110); | |
float value111 = dot(grad111, pos - p111); | |
float intp00 = interpolate5(value000, value001, fracpos.z); | |
float intp01 = interpolate5(value010, value011, fracpos.z); | |
float intp10 = interpolate5(value100, value101, fracpos.z); | |
float intp11 = interpolate5(value110, value111, fracpos.z); | |
float intp0 = interpolate5(intp00, intp01, fracpos.y); | |
float intp1 = interpolate5(intp10, intp11, fracpos.y); | |
float intp = interpolate5(intp0, intp1, fracpos.x); | |
float3 t = float3(interpolate5(0, 1, fracpos.x), interpolate5(0, 1, fracpos.y), interpolate5(0, 1, fracpos.z)); | |
float3 tp = float3(interpolate5derivative(0, 1, fracpos.x), interpolate5derivative(0, 1, fracpos.y), interpolate5derivative(0, 1, fracpos.z)); | |
float3 d00p = grad000 + (grad001 - grad000) * t.z + (value001 - value000) * float3(0, 0, tp.z); | |
float3 d01p = grad010 + (grad011 - grad010) * t.z + (value011 - value010) * float3(0, 0, tp.z); | |
float3 d10p = grad100 + (grad101 - grad100) * t.z + (value101 - value100) * float3(0, 0, tp.z); | |
float3 d11p = grad110 + (grad111 - grad110) * t.z + (value111 - value110) * float3(0, 0, tp.z); | |
float3 d0p = d00p + (d01p - d00p) * t.y + (intp01 - intp00) * float3(0, tp.y, 0); | |
float3 d1p = d10p + (d11p - d10p) * t.y + (intp11 - intp10) * float3(0, tp.y, 0); | |
float3 dp = d0p + (d1p - d0p) * t.x + (intp1 - intp0) * float3(tp.x, 0, 0); | |
return float4(dp, intp); | |
} | |
// 4D perlin noise | |
float perlin4(float4 pos) | |
{ | |
float4 intpos0 = floor(pos); | |
float4 intpos1 = intpos0 + 1; | |
float4 fracpos = pos - intpos0; | |
float4 p0000 = float4(intpos0.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p0001 = float4(intpos0.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p0010 = float4(intpos0.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p0011 = float4(intpos0.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p0100 = float4(intpos0.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p0101 = float4(intpos0.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p0110 = float4(intpos0.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p0111 = float4(intpos0.x, intpos1.y, intpos1.z, intpos1.w); | |
float4 p1000 = float4(intpos1.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p1001 = float4(intpos1.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p1010 = float4(intpos1.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p1011 = float4(intpos1.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p1100 = float4(intpos1.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p1101 = float4(intpos1.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p1110 = float4(intpos1.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p1111 = float4(intpos1.x, intpos1.y, intpos1.z, intpos1.w); | |
float grad0000 = dot(grad4(p0000), pos - p0000); | |
float grad0001 = dot(grad4(p0001), pos - p0001); | |
float grad0010 = dot(grad4(p0010), pos - p0010); | |
float grad0011 = dot(grad4(p0011), pos - p0011); | |
float grad0100 = dot(grad4(p0100), pos - p0100); | |
float grad0101 = dot(grad4(p0101), pos - p0101); | |
float grad0110 = dot(grad4(p0110), pos - p0110); | |
float grad0111 = dot(grad4(p0111), pos - p0111); | |
float grad1000 = dot(grad4(p1000), pos - p1000); | |
float grad1001 = dot(grad4(p1001), pos - p1001); | |
float grad1010 = dot(grad4(p1010), pos - p1010); | |
float grad1011 = dot(grad4(p1011), pos - p1011); | |
float grad1100 = dot(grad4(p1100), pos - p1100); | |
float grad1101 = dot(grad4(p1101), pos - p1101); | |
float grad1110 = dot(grad4(p1110), pos - p1110); | |
float grad1111 = dot(grad4(p1111), pos - p1111); | |
float intp000 = interpolate5(grad0000, grad0001, fracpos.w); | |
float intp001 = interpolate5(grad0010, grad0011, fracpos.w); | |
float intp010 = interpolate5(grad0100, grad0101, fracpos.w); | |
float intp011 = interpolate5(grad0110, grad0111, fracpos.w); | |
float intp100 = interpolate5(grad1000, grad1001, fracpos.w); | |
float intp101 = interpolate5(grad1010, grad1011, fracpos.w); | |
float intp110 = interpolate5(grad1100, grad1101, fracpos.w); | |
float intp111 = interpolate5(grad1110, grad1111, fracpos.w); | |
float intp00 = interpolate5(intp000, intp001, fracpos.z); | |
float intp01 = interpolate5(intp010, intp011, fracpos.z); | |
float intp10 = interpolate5(intp100, intp101, fracpos.z); | |
float intp11 = interpolate5(intp110, intp111, fracpos.z); | |
float intp0 = interpolate5(intp00, intp01, fracpos.y); | |
float intp1 = interpolate5(intp10, intp11, fracpos.y); | |
float intp = interpolate5(intp0, intp1, fracpos.x); | |
return intp; | |
} | |
// 4D perlin noise's derivative (∂f/∂x, ∂f/∂y, ∂f/∂z, ∂f/∂w) | |
float4 perlin4derivative(float4 pos) | |
{ | |
float4 intpos0 = floor(pos); | |
float4 intpos1 = intpos0 + 1; | |
float4 fracpos = pos - intpos0; | |
float4 p0000 = float4(intpos0.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p0001 = float4(intpos0.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p0010 = float4(intpos0.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p0011 = float4(intpos0.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p0100 = float4(intpos0.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p0101 = float4(intpos0.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p0110 = float4(intpos0.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p0111 = float4(intpos0.x, intpos1.y, intpos1.z, intpos1.w); | |
float4 p1000 = float4(intpos1.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p1001 = float4(intpos1.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p1010 = float4(intpos1.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p1011 = float4(intpos1.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p1100 = float4(intpos1.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p1101 = float4(intpos1.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p1110 = float4(intpos1.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p1111 = float4(intpos1.x, intpos1.y, intpos1.z, intpos1.w); | |
float4 grad0000 = grad4(p0000); | |
float4 grad0001 = grad4(p0001); | |
float4 grad0010 = grad4(p0010); | |
float4 grad0011 = grad4(p0011); | |
float4 grad0100 = grad4(p0100); | |
float4 grad0101 = grad4(p0101); | |
float4 grad0110 = grad4(p0110); | |
float4 grad0111 = grad4(p0111); | |
float4 grad1000 = grad4(p1000); | |
float4 grad1001 = grad4(p1001); | |
float4 grad1010 = grad4(p1010); | |
float4 grad1011 = grad4(p1011); | |
float4 grad1100 = grad4(p1100); | |
float4 grad1101 = grad4(p1101); | |
float4 grad1110 = grad4(p1110); | |
float4 grad1111 = grad4(p1111); | |
float value0000 = dot(grad0000, pos - p0000); | |
float value0001 = dot(grad0001, pos - p0001); | |
float value0010 = dot(grad0010, pos - p0010); | |
float value0011 = dot(grad0011, pos - p0011); | |
float value0100 = dot(grad0100, pos - p0100); | |
float value0101 = dot(grad0101, pos - p0101); | |
float value0110 = dot(grad0110, pos - p0110); | |
float value0111 = dot(grad0111, pos - p0111); | |
float value1000 = dot(grad1000, pos - p1000); | |
float value1001 = dot(grad1001, pos - p1001); | |
float value1010 = dot(grad1010, pos - p1010); | |
float value1011 = dot(grad1011, pos - p1011); | |
float value1100 = dot(grad1100, pos - p1100); | |
float value1101 = dot(grad1101, pos - p1101); | |
float value1110 = dot(grad1110, pos - p1110); | |
float value1111 = dot(grad1111, pos - p1111); | |
float intp000 = interpolate5(value0000, value0001, fracpos.w); | |
float intp001 = interpolate5(value0010, value0011, fracpos.w); | |
float intp010 = interpolate5(value0100, value0101, fracpos.w); | |
float intp011 = interpolate5(value0110, value0111, fracpos.w); | |
float intp100 = interpolate5(value1000, value1001, fracpos.w); | |
float intp101 = interpolate5(value1010, value1011, fracpos.w); | |
float intp110 = interpolate5(value1100, value1101, fracpos.w); | |
float intp111 = interpolate5(value1110, value1111, fracpos.w); | |
float intp00 = interpolate5(intp000, intp001, fracpos.z); | |
float intp01 = interpolate5(intp010, intp011, fracpos.z); | |
float intp10 = interpolate5(intp100, intp101, fracpos.z); | |
float intp11 = interpolate5(intp110, intp111, fracpos.z); | |
float intp0 = interpolate5(intp00, intp01, fracpos.y); | |
float intp1 = interpolate5(intp10, intp11, fracpos.y); | |
float intp = interpolate5(intp0, intp1, fracpos.x); | |
float4 t = float4( | |
interpolate5(0, 1, fracpos.x), | |
interpolate5(0, 1, fracpos.y), | |
interpolate5(0, 1, fracpos.z), | |
interpolate5(0, 1, fracpos.w)); | |
float4 tp = float4( | |
interpolate5derivative(0, 1, fracpos.x), | |
interpolate5derivative(0, 1, fracpos.y), | |
interpolate5derivative(0, 1, fracpos.z), | |
interpolate5derivative(0, 1, fracpos.w)); | |
float4 d000p = grad0000 + (grad0001 - grad0000) * t.w + (value0001 - value0000) * float4(0, 0, 0, tp.w); | |
float4 d001p = grad0010 + (grad0011 - grad0010) * t.w + (value0011 - value0010) * float4(0, 0, 0, tp.w); | |
float4 d010p = grad0100 + (grad0101 - grad0100) * t.w + (value0101 - value0100) * float4(0, 0, 0, tp.w); | |
float4 d011p = grad0110 + (grad0111 - grad0110) * t.w + (value0111 - value0110) * float4(0, 0, 0, tp.w); | |
float4 d100p = grad1000 + (grad1001 - grad1000) * t.w + (value1001 - value1000) * float4(0, 0, 0, tp.w); | |
float4 d101p = grad1010 + (grad1011 - grad1010) * t.w + (value1011 - value1010) * float4(0, 0, 0, tp.w); | |
float4 d110p = grad1100 + (grad1101 - grad1100) * t.w + (value1101 - value1100) * float4(0, 0, 0, tp.w); | |
float4 d111p = grad1110 + (grad1111 - grad1110) * t.w + (value1111 - value1110) * float4(0, 0, 0, tp.w); | |
float4 d00p = d000p + (d001p - d000p) * t.z + (intp001 - intp000) * float4(0, 0, tp.z, 0); | |
float4 d01p = d010p + (d011p - d010p) * t.z + (intp011 - intp010) * float4(0, 0, tp.z, 0); | |
float4 d10p = d100p + (d101p - d100p) * t.z + (intp101 - intp100) * float4(0, 0, tp.z, 0); | |
float4 d11p = d110p + (d111p - d110p) * t.z + (intp111 - intp110) * float4(0, 0, tp.z, 0); | |
float4 d0p = d00p + (d01p - d00p) * t.y + (intp01 - intp00) * float4(0, tp.y, 0, 0); | |
float4 d1p = d10p + (d11p - d10p) * t.y + (intp11 - intp10) * float4(0, tp.y, 0, 0); | |
float4 dp = d0p + (d1p - d0p) * t.x + (intp1 - intp0) * float4(tp.x, 0, 0, 0); | |
return dp; | |
} | |
// 4D perlin noise (∂f/∂x, ∂f/∂y, ∂f/∂z, ∂f/∂w, f, f, f, f) | |
float2x4 perlin4dual(float4 pos) | |
{ | |
float4 intpos0 = floor(pos); | |
float4 intpos1 = intpos0 + 1; | |
float4 fracpos = pos - intpos0; | |
float4 p0000 = float4(intpos0.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p0001 = float4(intpos0.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p0010 = float4(intpos0.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p0011 = float4(intpos0.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p0100 = float4(intpos0.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p0101 = float4(intpos0.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p0110 = float4(intpos0.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p0111 = float4(intpos0.x, intpos1.y, intpos1.z, intpos1.w); | |
float4 p1000 = float4(intpos1.x, intpos0.y, intpos0.z, intpos0.w); | |
float4 p1001 = float4(intpos1.x, intpos0.y, intpos0.z, intpos1.w); | |
float4 p1010 = float4(intpos1.x, intpos0.y, intpos1.z, intpos0.w); | |
float4 p1011 = float4(intpos1.x, intpos0.y, intpos1.z, intpos1.w); | |
float4 p1100 = float4(intpos1.x, intpos1.y, intpos0.z, intpos0.w); | |
float4 p1101 = float4(intpos1.x, intpos1.y, intpos0.z, intpos1.w); | |
float4 p1110 = float4(intpos1.x, intpos1.y, intpos1.z, intpos0.w); | |
float4 p1111 = float4(intpos1.x, intpos1.y, intpos1.z, intpos1.w); | |
float4 grad0000 = grad4(p0000); | |
float4 grad0001 = grad4(p0001); | |
float4 grad0010 = grad4(p0010); | |
float4 grad0011 = grad4(p0011); | |
float4 grad0100 = grad4(p0100); | |
float4 grad0101 = grad4(p0101); | |
float4 grad0110 = grad4(p0110); | |
float4 grad0111 = grad4(p0111); | |
float4 grad1000 = grad4(p1000); | |
float4 grad1001 = grad4(p1001); | |
float4 grad1010 = grad4(p1010); | |
float4 grad1011 = grad4(p1011); | |
float4 grad1100 = grad4(p1100); | |
float4 grad1101 = grad4(p1101); | |
float4 grad1110 = grad4(p1110); | |
float4 grad1111 = grad4(p1111); | |
float value0000 = dot(grad0000, pos - p0000); | |
float value0001 = dot(grad0001, pos - p0001); | |
float value0010 = dot(grad0010, pos - p0010); | |
float value0011 = dot(grad0011, pos - p0011); | |
float value0100 = dot(grad0100, pos - p0100); | |
float value0101 = dot(grad0101, pos - p0101); | |
float value0110 = dot(grad0110, pos - p0110); | |
float value0111 = dot(grad0111, pos - p0111); | |
float value1000 = dot(grad1000, pos - p1000); | |
float value1001 = dot(grad1001, pos - p1001); | |
float value1010 = dot(grad1010, pos - p1010); | |
float value1011 = dot(grad1011, pos - p1011); | |
float value1100 = dot(grad1100, pos - p1100); | |
float value1101 = dot(grad1101, pos - p1101); | |
float value1110 = dot(grad1110, pos - p1110); | |
float value1111 = dot(grad1111, pos - p1111); | |
float intp000 = interpolate5(value0000, value0001, fracpos.w); | |
float intp001 = interpolate5(value0010, value0011, fracpos.w); | |
float intp010 = interpolate5(value0100, value0101, fracpos.w); | |
float intp011 = interpolate5(value0110, value0111, fracpos.w); | |
float intp100 = interpolate5(value1000, value1001, fracpos.w); | |
float intp101 = interpolate5(value1010, value1011, fracpos.w); | |
float intp110 = interpolate5(value1100, value1101, fracpos.w); | |
float intp111 = interpolate5(value1110, value1111, fracpos.w); | |
float intp00 = interpolate5(intp000, intp001, fracpos.z); | |
float intp01 = interpolate5(intp010, intp011, fracpos.z); | |
float intp10 = interpolate5(intp100, intp101, fracpos.z); | |
float intp11 = interpolate5(intp110, intp111, fracpos.z); | |
float intp0 = interpolate5(intp00, intp01, fracpos.y); | |
float intp1 = interpolate5(intp10, intp11, fracpos.y); | |
float intp = interpolate5(intp0, intp1, fracpos.x); | |
float4 t = float4( | |
interpolate5(0, 1, fracpos.x), | |
interpolate5(0, 1, fracpos.y), | |
interpolate5(0, 1, fracpos.z), | |
interpolate5(0, 1, fracpos.w)); | |
float4 tp = float4( | |
interpolate5derivative(0, 1, fracpos.x), | |
interpolate5derivative(0, 1, fracpos.y), | |
interpolate5derivative(0, 1, fracpos.z), | |
interpolate5derivative(0, 1, fracpos.w)); | |
float4 d000p = grad0000 + (grad0001 - grad0000) * t.w + (value0001 - value0000) * float4(0, 0, 0, tp.w); | |
float4 d001p = grad0010 + (grad0011 - grad0010) * t.w + (value0011 - value0010) * float4(0, 0, 0, tp.w); | |
float4 d010p = grad0100 + (grad0101 - grad0100) * t.w + (value0101 - value0100) * float4(0, 0, 0, tp.w); | |
float4 d011p = grad0110 + (grad0111 - grad0110) * t.w + (value0111 - value0110) * float4(0, 0, 0, tp.w); | |
float4 d100p = grad1000 + (grad1001 - grad1000) * t.w + (value1001 - value1000) * float4(0, 0, 0, tp.w); | |
float4 d101p = grad1010 + (grad1011 - grad1010) * t.w + (value1011 - value1010) * float4(0, 0, 0, tp.w); | |
float4 d110p = grad1100 + (grad1101 - grad1100) * t.w + (value1101 - value1100) * float4(0, 0, 0, tp.w); | |
float4 d111p = grad1110 + (grad1111 - grad1110) * t.w + (value1111 - value1110) * float4(0, 0, 0, tp.w); | |
float4 d00p = d000p + (d001p - d000p) * t.z + (intp001 - intp000) * float4(0, 0, tp.z, 0); | |
float4 d01p = d010p + (d011p - d010p) * t.z + (intp011 - intp010) * float4(0, 0, tp.z, 0); | |
float4 d10p = d100p + (d101p - d100p) * t.z + (intp101 - intp100) * float4(0, 0, tp.z, 0); | |
float4 d11p = d110p + (d111p - d110p) * t.z + (intp111 - intp110) * float4(0, 0, tp.z, 0); | |
float4 d0p = d00p + (d01p - d00p) * t.y + (intp01 - intp00) * float4(0, tp.y, 0, 0); | |
float4 d1p = d10p + (d11p - d10p) * t.y + (intp11 - intp10) * float4(0, tp.y, 0, 0); | |
float4 dp = d0p + (d1p - d0p) * t.x + (intp1 - intp0) * float4(tp.x, 0, 0, 0); | |
return float2x4(dp, intp.xxxx); | |
} | |
// 2D simplex noise (∂f/∂x, ∂f/∂y, f) | |
float3 simplex2(float2 pos) | |
{ | |
float skewConstant = 0.5 * (sqrt(3.0) - 1.0); | |
float unskewConstant = (sqrt(3.0) - 3.0) / 6.0; | |
float2 skewedIntpos0 = floor(pos + (pos.x + pos.y) * skewConstant); | |
float2 intpos0 = skewedIntpos0 + (skewedIntpos0.x + skewedIntpos0.y) * unskewConstant; | |
float2 offset0 = pos - intpos0; | |
float2 intOffset1 = offset0.x > offset0.y ? float2(1, 0) : float2(0, 1); | |
float2 skewedIntpos1 = skewedIntpos0 + intOffset1; | |
float2 intpos1 = skewedIntpos1 + (skewedIntpos1.x + skewedIntpos1.y) * unskewConstant; | |
float2 offset1 = pos - intpos1; | |
float2 skewedIntpos2 = skewedIntpos0 + 1; | |
float2 intpos2 = skewedIntpos2 + (skewedIntpos2.x + skewedIntpos2.y) * unskewConstant; | |
float2 offset2 = pos - intpos2; | |
float2 gradient0 = grad2(skewedIntpos0); | |
float2 gradient1 = grad2(skewedIntpos1); | |
float2 gradient2 = grad2(skewedIntpos2); | |
float t0 = 0.5 - (offset0.x * offset0.x + offset0.y * offset0.y); | |
t0 = t0 < 0 ? 0 : t0 * t0 * t0 * t0; | |
float n0 = t0 * dot(gradient0, offset0); | |
float t1 = 0.5 - (offset1.x * offset1.x + offset1.y * offset1.y); | |
t1 = t1 < 0 ? 0 : t1 * t1 * t1 * t1; | |
float n1 = t1 * dot(gradient1, offset1); | |
float t2 = 0.5 - (offset2.x * offset2.x + offset2.y * offset2.y); | |
t2 = t2 < 0 ? 0 : t2 * t2 * t2 * t2; | |
float n2 = t2 * dot(gradient2, offset2); | |
float2 dt0 = t0 * gradient0 - 8 * pow(t0, 3.0 / 4.0) * dot(gradient0, offset0) * offset0; | |
float2 dt1 = t1 * gradient1 - 8 * pow(t1, 3.0 / 4.0) * dot(gradient1, offset1) * offset1; | |
float2 dt2 = t2 * gradient2 - 8 * pow(t2, 3.0 / 4.0) * dot(gradient2, offset2) * offset2; | |
return (70.0 * float3(dt0 + dt1 + dt2, n0 + n1 + n2)); | |
} | |
// 3D simplex noise (∂f/∂x, ∂f/∂y, ∂f/∂z, f) | |
float4 simplex3(float3 pos) | |
{ | |
float skewConstant = 1 / 3.0; | |
float unskewConstant = -1 / 6.0; | |
float3 skewedIntpos0 = floor(pos + (pos.x + pos.y + pos.z) * skewConstant); | |
float3 intpos0 = skewedIntpos0 + (skewedIntpos0.x + skewedIntpos0.y + skewedIntpos0.z) * unskewConstant; | |
float3 offset0 = pos - intpos0; | |
float3 intOffset1 = | |
offset0.x > offset0.y ? | |
offset0.y > offset0.z ? float3(1, 0, 0) : // xyz | |
offset0.z > offset0.x ? float3(0, 0, 1) : // zxy | |
float3(1, 0, 0) : // xzy | |
offset0.z > offset0.y ? float3(0, 0, 1) : // zyx | |
offset0.x > offset0.z ? float3(0, 1, 0) : // yxz | |
float3(0, 1, 0); // yzx | |
float3 intOffset2 = | |
offset0.x > offset0.y ? | |
offset0.y > offset0.z ? float3(1, 1, 0) : // xyz | |
offset0.z > offset0.x ? float3(1, 0, 1) : // zxy | |
float3(1, 0, 1) : // xzy | |
offset0.z > offset0.y ? float3(0, 1, 1) : // zyx | |
offset0.x > offset0.z ? float3(1, 1, 0) : // yxz | |
float3(0, 1, 1); // yzx | |
float3 skewedIntpos1 = skewedIntpos0 + intOffset1; | |
float3 intpos1 = skewedIntpos1 + (skewedIntpos1.x + skewedIntpos1.y + skewedIntpos1.z) * unskewConstant; | |
float3 offset1 = pos - intpos1; | |
float3 skewedIntpos2 = skewedIntpos0 + intOffset2; | |
float3 intpos2 = skewedIntpos2 + (skewedIntpos2.x + skewedIntpos2.y + skewedIntpos2.z) * unskewConstant; | |
float3 offset2 = pos - intpos2; | |
float3 skewedIntpos3 = skewedIntpos0 + 1; | |
float3 intpos3 = skewedIntpos3 + (skewedIntpos3.x + skewedIntpos3.y + skewedIntpos3.z) * unskewConstant; | |
float3 offset3 = pos - intpos3; | |
float3 gradient0 = grad3(skewedIntpos0); | |
float3 gradient1 = grad3(skewedIntpos1); | |
float3 gradient2 = grad3(skewedIntpos2); | |
float3 gradient3 = grad3(skewedIntpos3); | |
float t0 = 0.5 - dot(offset0, offset0); | |
t0 = t0 < 0 ? 0 : t0 * t0 * t0; | |
float n0 = t0 * dot(gradient0, offset0); | |
float t1 = 0.5 - dot(offset1, offset1); | |
t1 = t1 < 0 ? 0 : t1 * t1 * t1; | |
float n1 = t1 * dot(gradient1, offset1); | |
float t2 = 0.5 - dot(offset2, offset2); | |
t2 = t2 < 0 ? 0 : t2 * t2 * t2; | |
float n2 = t2 * dot(gradient2, offset2); | |
float t3 = 0.5 - dot(offset3, offset3); | |
t3 = t3 < 0 ? 0 : t3 * t3 * t3; | |
float n3 = t3 * dot(gradient3, offset3); | |
float3 dt0 = t0 * gradient0 - 6 * pow(t0, 2.0 / 3.0) * dot(gradient0, offset0) * offset0; | |
float3 dt1 = t1 * gradient1 - 6 * pow(t1, 2.0 / 3.0) * dot(gradient1, offset1) * offset1; | |
float3 dt2 = t2 * gradient2 - 6 * pow(t2, 2.0 / 3.0) * dot(gradient2, offset2) * offset2; | |
float3 dt3 = t3 * gradient3 - 6 * pow(t3, 2.0 / 3.0) * dot(gradient3, offset3) * offset3; | |
return (32.0 * float4(dt0 + dt1 + dt2 + dt3, n0 + n1 + n2 + n3)); | |
} | |
// 4D simplex noise | |
float simplex4(float4 pos) | |
{ | |
float skewConstant = (sqrt(5.0) - 1.0) / 4.0; | |
float unskewConstant = (sqrt(5.0) - 5.0) / 20.0; | |
float4 skewedIntpos0 = floor(pos + dot(pos, 1) * skewConstant); | |
float4 intpos0 = skewedIntpos0 + dot(skewedIntpos0, 1) * unskewConstant; | |
float4 offset0 = pos - intpos0; | |
float2x4 order = { 0, 1, 2, 3, offset0 }; | |
// sort order by order[1] (offset0) | |
order = order[1].x > order[1].y ? float2x4(order[0].yxzw, order[1].yxzw) : order; | |
order = order[1].z > order[1].w ? float2x4(order[0].xywz, order[1].xywz) : order; | |
order = order[1].x > order[1].z ? float2x4(order[0].zyxw, order[1].zyxw) : order; | |
order = order[1].y > order[1].w ? float2x4(order[0].xwzy, order[1].xwzy) : order; | |
order = order[1].y > order[1].z ? float2x4(order[0].xzyw, order[1].xzyw) : order; | |
float4x4 unit4x4 = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; | |
float4 intOffset1 = unit4x4[order[0][3]]; | |
float4 intOffset2 = intOffset1 + unit4x4[order[0][2]]; | |
float4 intOffset3 = intOffset2 + unit4x4[order[0][1]]; | |
float4 skewedIntpos1 = skewedIntpos0 + intOffset1; | |
float4 intpos1 = skewedIntpos1 + dot(skewedIntpos1, 1) * unskewConstant; | |
float4 offset1 = pos - intpos1; | |
float4 skewedIntpos2 = skewedIntpos0 + intOffset2; | |
float4 intpos2 = skewedIntpos2 + dot(skewedIntpos2, 1) * unskewConstant; | |
float4 offset2 = pos - intpos2; | |
float4 skewedIntpos3 = skewedIntpos0 + intOffset3; | |
float4 intpos3 = skewedIntpos3 + dot(skewedIntpos3, 1) * unskewConstant; | |
float4 offset3 = pos - intpos3; | |
float4 skewedIntpos4 = skewedIntpos0 + 1; | |
float4 intpos4 = skewedIntpos4 + dot(skewedIntpos4, 1) * unskewConstant; | |
float4 offset4 = pos - intpos4; | |
float4 gradient0 = grad4(skewedIntpos0); | |
float4 gradient1 = grad4(skewedIntpos1); | |
float4 gradient2 = grad4(skewedIntpos2); | |
float4 gradient3 = grad4(skewedIntpos3); | |
float4 gradient4 = grad4(skewedIntpos4); | |
float t0 = 0.5 - dot(offset0, offset0); | |
t0 = t0 < 0 ? 0 : t0 * t0 * t0; | |
float n0 = t0 * dot(gradient0, offset0); | |
float t1 = 0.5 - dot(offset1, offset1); | |
t1 = t1 < 0 ? 0 : t1 * t1 * t1; | |
float n1 = t1 * dot(gradient1, offset1); | |
float t2 = 0.5 - dot(offset2, offset2); | |
t2 = t2 < 0 ? 0 : t2 * t2 * t2; | |
float n2 = t2 * dot(gradient2, offset2); | |
float t3 = 0.5 - dot(offset3, offset3); | |
t3 = t3 < 0 ? 0 : t3 * t3 * t3; | |
float n3 = t3 * dot(gradient3, offset3); | |
float t4 = 0.5 - dot(offset4, offset4); | |
t4 = t4 < 0 ? 0 : t4 * t4 * t4; | |
float n4 = t4 * dot(gradient4, offset4); | |
/* | |
float3 dt0 = t0 * gradient0 - 8 * pow(t0, 3.0 / 4.0) * dot(gradient0, offset0) * offset0; | |
float3 dt1 = t1 * gradient1 - 8 * pow(t1, 3.0 / 4.0) * dot(gradient1, offset1) * offset1; | |
float3 dt2 = t2 * gradient2 - 8 * pow(t2, 3.0 / 4.0) * dot(gradient2, offset2) * offset2; | |
float3 dt3 = t3 * gradient3 - 8 * pow(t3, 3.0 / 4.0) * dot(gradient3, offset3) * offset3; | |
float3 dt4 = t4 * gradient4 - 8 * pow(t4, 3.0 / 4.0) * dot(gradient4, offset4) * offset4; | |
*/ | |
return 27.0 * (n0 + n1 + n2 + n3 + n4); | |
} | |
// 4D simplex noise (∂f/∂x, ∂f/∂y, ∂f/∂z, ∂f/∂w, f, f, f, f) | |
float2x4 simplex4dual(float4 pos) | |
{ | |
float skewConstant = (sqrt(5.0) - 1.0) / 4.0; | |
float unskewConstant = (sqrt(5.0) - 5.0) / 20.0; | |
float4 skewedIntpos0 = floor(pos + dot(pos, 1) * skewConstant); | |
float4 intpos0 = skewedIntpos0 + dot(skewedIntpos0, 1) * unskewConstant; | |
float4 offset0 = pos - intpos0; | |
float2x4 order = { 0, 1, 2, 3, offset0 }; | |
// sort order by order[1] (offset0) | |
order = order[1].x > order[1].y ? float2x4(order[0].yxzw, order[1].yxzw) : order; | |
order = order[1].z > order[1].w ? float2x4(order[0].xywz, order[1].xywz) : order; | |
order = order[1].x > order[1].z ? float2x4(order[0].zyxw, order[1].zyxw) : order; | |
order = order[1].y > order[1].w ? float2x4(order[0].xwzy, order[1].xwzy) : order; | |
order = order[1].y > order[1].z ? float2x4(order[0].xzyw, order[1].xzyw) : order; | |
float4x4 unit4x4 = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; | |
float4 intOffset1 = unit4x4[order[0][3]]; | |
float4 intOffset2 = intOffset1 + unit4x4[order[0][2]]; | |
float4 intOffset3 = intOffset2 + unit4x4[order[0][1]]; | |
float4 skewedIntpos1 = skewedIntpos0 + intOffset1; | |
float4 intpos1 = skewedIntpos1 + dot(skewedIntpos1, 1) * unskewConstant; | |
float4 offset1 = pos - intpos1; | |
float4 skewedIntpos2 = skewedIntpos0 + intOffset2; | |
float4 intpos2 = skewedIntpos2 + dot(skewedIntpos2, 1) * unskewConstant; | |
float4 offset2 = pos - intpos2; | |
float4 skewedIntpos3 = skewedIntpos0 + intOffset3; | |
float4 intpos3 = skewedIntpos3 + dot(skewedIntpos3, 1) * unskewConstant; | |
float4 offset3 = pos - intpos3; | |
float4 skewedIntpos4 = skewedIntpos0 + 1; | |
float4 intpos4 = skewedIntpos4 + dot(skewedIntpos4, 1) * unskewConstant; | |
float4 offset4 = pos - intpos4; | |
float4 gradient0 = grad4(skewedIntpos0); | |
float4 gradient1 = grad4(skewedIntpos1); | |
float4 gradient2 = grad4(skewedIntpos2); | |
float4 gradient3 = grad4(skewedIntpos3); | |
float4 gradient4 = grad4(skewedIntpos4); | |
float t0 = 0.5 - dot(offset0, offset0); | |
t0 = t0 < 0 ? 0 : t0 * t0 * t0; | |
float n0 = t0 * dot(gradient0, offset0); | |
float t1 = 0.5 - dot(offset1, offset1); | |
t1 = t1 < 0 ? 0 : t1 * t1 * t1; | |
float n1 = t1 * dot(gradient1, offset1); | |
float t2 = 0.5 - dot(offset2, offset2); | |
t2 = t2 < 0 ? 0 : t2 * t2 * t2; | |
float n2 = t2 * dot(gradient2, offset2); | |
float t3 = 0.5 - dot(offset3, offset3); | |
t3 = t3 < 0 ? 0 : t3 * t3 * t3; | |
float n3 = t3 * dot(gradient3, offset3); | |
float t4 = 0.5 - dot(offset4, offset4); | |
t4 = t4 < 0 ? 0 : t4 * t4 * t4; | |
float n4 = t4 * dot(gradient4, offset4); | |
float4 dt0 = t0 * gradient0 - 8 * pow(t0, 3.0 / 4.0) * dot(gradient0, offset0) * offset0; | |
float4 dt1 = t1 * gradient1 - 8 * pow(t1, 3.0 / 4.0) * dot(gradient1, offset1) * offset1; | |
float4 dt2 = t2 * gradient2 - 8 * pow(t2, 3.0 / 4.0) * dot(gradient2, offset2) * offset2; | |
float4 dt3 = t3 * gradient3 - 8 * pow(t3, 3.0 / 4.0) * dot(gradient3, offset3) * offset3; | |
float4 dt4 = t4 * gradient4 - 8 * pow(t4, 3.0 / 4.0) * dot(gradient4, offset4) * offset4; | |
return float2x4(27.0 * (dt0 + dt1 + dt2 + dt3 + dt4), 27.0 * (n0 + n1 + n2 + n3 + n4).xxxx); | |
} | |
// 3D curl noise (by 3D simplex noise) | |
float3 curl(float3 pos) | |
{ | |
float delta = 0.001; | |
float3x3 v = float3x3(pos, pos + float3(123.456, 789.012, 345.678), pos + float3(901.234, 567.890, 123.456)); | |
float pxpx = (simplex3(v[0] + float3(+delta, 0, 0)).w - simplex3(v[0] + float3(-delta, 0, 0)).w) / (2 * delta); | |
float pxpy = (simplex3(v[0] + float3(0, +delta, 0)).w - simplex3(v[0] + float3(0, -delta, 0)).w) / (2 * delta); | |
float pxpz = (simplex3(v[0] + float3(0, 0, +delta)).w - simplex3(v[0] + float3(0, 0, -delta)).w) / (2 * delta); | |
float pypx = (simplex3(v[1] + float3(+delta, 0, 0)).w - simplex3(v[1] + float3(-delta, 0, 0)).w) / (2 * delta); | |
float pypy = (simplex3(v[1] + float3(0, +delta, 0)).w - simplex3(v[1] + float3(0, -delta, 0)).w) / (2 * delta); | |
float pypz = (simplex3(v[1] + float3(0, 0, +delta)).w - simplex3(v[1] + float3(0, 0, -delta)).w) / (2 * delta); | |
float pzpx = (simplex3(v[2] + float3(+delta, 0, 0)).w - simplex3(v[2] + float3(-delta, 0, 0)).w) / (2 * delta); | |
float pzpy = (simplex3(v[2] + float3(0, +delta, 0)).w - simplex3(v[2] + float3(0, -delta, 0)).w) / (2 * delta); | |
float pzpz = (simplex3(v[2] + float3(0, 0, +delta)).w - simplex3(v[2] + float3(0, 0, -delta)).w) / (2 * delta); | |
return float3(pzpy - pypz, pxpz - pzpx, pypx - pxpy); | |
} | |
// 3D curl noise - alternative implementation (by 3D simplex noise) | |
float3 curl2(float3 pos) | |
{ | |
float4 a = simplex3(pos); | |
float4 b = simplex3(pos + float3(123.456, 789.012, 345.678)); | |
return cross(a.xyz, b.xyz); | |
} | |
// domain rotation in 3D | |
// usage: someNoise(domainRotation(pos)) | |
float3 domainRotation(float3 pos) | |
{ | |
return float3( | |
pos.x + (pos.x + pos.z) * -0.211324865405187 + pos.y * 0.577350269189626, | |
(pos.x + pos.z) * -0.577350269189626 + pos.y * 0.577350269189626, | |
pos.z + (pos.x + pos.z) * -0.211324865405187 + pos.y * 0.577350269189626); | |
} | |
float3 curltest(float3 pos) | |
{ | |
float3 curlval = curl(pos); | |
fixed4 col = tex2D(_SelfTexture2D, (pos - curlval * 0.1 * unity_DeltaTime.x).xy); | |
return col; | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
float4 pos = float4(i.uv * 4, _Time.x * 2, _Time.x); | |
float4 val = simplex3(pos).xyzw; | |
return fixed4((val.www + 1) * 0.5, 1); | |
} | |
// note: if you use it, comment out #pragma vert/frag | |
half4 frag_crt(v2f_customrendertexture i) : SV_Target | |
{ | |
float4 pos = float4(i.globalTexcoord.xy, _Time.x * 2, _Time.x); | |
return fixed4(curltest(pos), 1); | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment