Last active
December 4, 2024 23:00
-
-
Save partybusiness/eeefe3686a66b9b50b7b5fc15fc1f8f3 to your computer and use it in GitHub Desktop.
Gem shader in Godot
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
shader_type spatial; | |
render_mode blend_add, cull_disabled; | |
/** amount of influence camera direction has on noise */ | |
uniform float direction_scale = 4.0; | |
/** amount of influence vertex position has on noise */ | |
uniform float vertex_scale = 1.5; | |
/** power applied to each channel | |
Higher values will make edges smoother, low values will make edges sharper | |
*/ | |
uniform vec3 powers = vec3(5.0); | |
/** multiplies for final colours | |
The noise generates separate RGB channels, you can use this to have each channel contribute to the final colours | |
R -> R, G -> R. B -> R | |
R -> G, G -> G. B -> G | |
R -> B, G -> B. B -> B | |
*/ | |
uniform mat3 colour_transform = mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0)); | |
varying vec3 local_vertex; | |
varying vec3 local_camera; | |
varying vec3 local_normal; | |
// SimplexNoise3D functions | |
vec3 mod289_3(vec3 x) { | |
return x - floor(x * (1.0 / 289.0)) * 289.0; | |
} | |
vec4 mod289_4(vec4 x) { | |
return x - floor(x * (1.0 / 289.0)) * 289.0; | |
} | |
vec4 permute(vec4 x) { | |
return mod289_4(((x * 34.0) + 1.0) * x); | |
} | |
vec4 taylorInvSqrt(vec4 r) { | |
return 1.79284291400159 - 0.85373472095314 * r; | |
} | |
float snoise(vec3 v) { | |
const vec2 C = vec2(1.0/6.0, 1.0/3.0); | |
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); | |
// First corner | |
vec3 i = floor(v + dot(v, C.yyy)); | |
vec3 x0 = v - i + dot(i, C.xxx); | |
// Other corners | |
vec3 g = step(x0.yzx, x0.xyz); | |
vec3 l = 1.0 - g; | |
vec3 i1 = min(g.xyz, l.zxy); | |
vec3 i2 = max(g.xyz, l.zxy); | |
vec3 x1 = x0 - i1 + C.xxx; | |
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y | |
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y | |
// Permutations | |
i = mod289_3(i); | |
vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) | |
+ i.y + vec4(0.0, i1.y, i2.y, 1.0)) | |
+ i.x + vec4(0.0, i1.x, i2.x, 1.0)); | |
// Gradients: 7x7 points over a square, mapped onto an octahedron. | |
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) | |
float n_ = 0.142857142857; // 1.0/7.0 | |
vec3 ns = n_ * D.wyz - D.xzx; | |
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) | |
vec4 x_ = floor(j * ns.z); | |
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N) | |
vec4 x = x_ * ns.x + ns.yyyy; | |
vec4 y = y_ * ns.x + ns.yyyy; | |
vec4 h = 1.0 - abs(x) - abs(y); | |
vec4 b0 = vec4(x.xy, y.xy); | |
vec4 b1 = vec4(x.zw, y.zw); | |
vec4 s0 = floor(b0) * 2.0 + 1.0; | |
vec4 s1 = floor(b1) * 2.0 + 1.0; | |
vec4 sh = -step(h, vec4(0.0)); | |
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy; | |
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww; | |
vec3 p0 = vec3(a0.xy,h.x); | |
vec3 p1 = vec3(a0.zw,h.y); | |
vec3 p2 = vec3(a1.xy,h.z); | |
vec3 p3 = vec3(a1.zw,h.w); | |
//Normalise gradients | |
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); | |
p0 *= norm.x; | |
p1 *= norm.y; | |
p2 *= norm.z; | |
p3 *= norm.w; | |
// Mix final noise value | |
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); | |
m = m * m; | |
return 42.0 * dot(m * m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3))); | |
} | |
void vertex() { | |
local_vertex = VERTEX; | |
local_normal = NORMAL; | |
local_camera = -(inverse(MODEL_NORMAL_MATRIX) * CAMERA_POSITION_WORLD); | |
} | |
void fragment() { | |
vec3 camera_view = normalize(local_camera); | |
vec3 surface_normal = normalize(local_normal); | |
vec3 sample_position = local_vertex * vertex_scale + reflect(camera_view, surface_normal) * direction_scale; | |
vec3 noise = vec3(snoise(vec3(sample_position)),snoise(vec3(sample_position.y - 19.1, sample_position.z + 33.4, sample_position.x + 47.2)),snoise(vec3(sample_position.z + 74.2, sample_position.x - 124.5, sample_position.y + 99.4))); | |
vec3 output = pow(max(noise, vec3(0.0)), powers); | |
EMISSION = max(colour_transform * output, vec3(0.0)); | |
ALBEDO = vec3(0.0); | |
ALPHA = 1.0; | |
CLEARCOAT = 1.0; | |
CLEARCOAT_ROUGHNESS = 0.0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment