module
CrShader::Std
Defined in:
crshader/std/registry.crConstant Summary
-
ATMOSPHERE_LIB =
" def hg_phase(cos_theta : Float32, g : Float32) : Float32\n g2 = g * g\n num = 1.0 - g2\n denom = 4.0 * 3.14159265 * (1.0 + g2 - 2.0 * g * cos_theta) ** 1.5\n num / max(denom, 0.0001)\n end\n\n def ray_sphere_intersect(ro : Vec3, rd : Vec3, radius : Float32) : Vec2\n b = dot(ro, rd)\n c = dot(ro, ro) - radius * radius\n d = b * b - c\n if d < 0.0\n vec2(-1.0, -1.0)\n else\n sqrt_d = sqrt(d)\n vec2(-b - sqrt_d, -b + sqrt_d)\n end\n end" -
COLOR_LIB =
" def hsv2rgb(c : Vec3) : Vec3\n rgb = clamp(abs(fract(vec3(c.x, c.x, c.x) + vec3(0.0, 4.0, 2.0) / 6.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0)\n c.z * mix(vec3(1.0, 1.0, 1.0), rgb, c.y)\n end\n\n def rgb2hsv(c : Vec3) : Vec3\n k = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0)\n p = mix(vec4(c.b, c.g, k.w, k.z), vec4(c.g, c.b, k.x, k.y), step(c.b, c.g))\n q = mix(vec4(p.x, p.y, p.w, c.r), vec4(c.r, p.y, p.z, p.x), step(p.x, c.r))\n d = q.x - min(q.w, q.y)\n e = 1.0e-10\n vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x)\n end\n\n def grayscale(c : Vec3) : Float32\n dot(c, vec3(0.299, 0.587, 0.114))\n end\n\n def adjust_contrast(c : Vec3, contrast : Float32) : Vec3\n (c - 0.5) * contrast + 0.5\n end\n\n def adjust_saturation(c : Vec3, saturation : Float32) : Vec3\n gray = grayscale(c)\n mix(vec3(gray, gray, gray), c, saturation)\n end" -
COLOR_SPACES_LIB =
" def linear_srgb_to_oklab(c : Vec3) : Vec3\n l = 0.4122214708 * c.r + 0.5363325363 * c.g + 0.0514459929 * c.b\n m = 0.2119034982 * c.r + 0.6806995451 * c.g + 0.1073969566 * c.b\n s = 0.0883024619 * c.r + 0.2817188376 * c.g + 0.6299787005 * c.b\n l_ = cbrt(l)\n m_ = cbrt(m)\n s_ = cbrt(s)\n l_out = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_\n a_out = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_\n b_out = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_\n vec3(l_out, a_out, b_out)\n end\n\n def oklab_to_linear_srgb(c : Vec3) : Vec3\n l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z\n m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z\n s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z\n l = l_ * l_ * l_\n m = m_ * m_ * m_\n s = s_ * s_ * s_\n r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s\n g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s\n b = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s\n vec3(r, g, b)\n end\n\n def delta_e_oklab(c1 : Vec3, c2 : Vec3) : Float32\n lab1 = linear_srgb_to_oklab(c1)\n lab2 = linear_srgb_to_oklab(c2)\n length(lab1 - lab2)\n end" -
COMPOSITOR_LIB =
" def linear_depth(depth : Float32, z_near : Float32, z_far : Float32) : Float32\n z_near * z_far / (z_far + depth * (z_near - z_far))\n end\n\n def depth_sobel(d_up : Float32, d_down : Float32, d_left : Float32, d_right : Float32) : Float32\n abs(d_up - d_down) + abs(d_left - d_right)\n end" -
CURL_NOISE_LIB =
" def simplex_noise_2d(p : Vec2) : Float32\n c = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439)\n i = floor(p + dot(p, c.yy))\n x0 = p - i + dot(i, c.xx)\n i1 = x0.x > x0.y ? vec2(1.0, 0.0) : vec2(0.0, 1.0)\n x12 = x0.xyxy + c.xxzz\n x12.xy = x12.xy - i1\n p3 = fract(vec3(i.x, i.y, i.x) * 0.1031)\n p3 += dot(p3, p3.yzx + 33.33)\n m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3(0.0, 0.0, 0.0))\n m = m * m\n m = m * m\n dot(m, vec3(p3.x, p3.y, p3.z) - 0.5) * 70.0\n end\n\n def curl_noise_2d(p : Vec2, eps : Float32) : Vec2\n n1 = simplex_noise_2d(p + vec2(0.0, eps))\n n2 = simplex_noise_2d(p - vec2(0.0, eps))\n n3 = simplex_noise_2d(p + vec2(eps, 0.0))\n n4 = simplex_noise_2d(p - vec2(eps, 0.0))\n x = (n1 - n2) / (2.0 * eps)\n y = -(n3 - n4) / (2.0 * eps)\n vec2(x, y)\n end\n\n def curl_noise_3d(p : Vec3, eps : Float32) : Vec3\n dx = vec3(eps, 0.0, 0.0)\n dy = vec3(0.0, eps, 0.0)\n dz = vec3(0.0, 0.0, eps)\n p_x0 = simplex_noise_2d(p.yz - dx.yz)\n p_x1 = simplex_noise_2d(p.yz + dx.yz)\n p_y0 = simplex_noise_2d(p.zx - dy.zx)\n p_y1 = simplex_noise_2d(p.zx + dy.zx)\n p_z0 = simplex_noise_2d(p.xy - dz.xy)\n p_z1 = simplex_noise_2d(p.xy + dz.xy)\n x = (p_y1 - p_y0) - (p_z1 - p_z0)\n y = (p_z1 - p_z0) - (p_x1 - p_x0)\n z = (p_x1 - p_x0) - (p_y1 - p_y0)\n normalize(vec3(x, y, z))\n end" -
DITHER_LIB =
" def bayer2x2(p : IVec2) : Float32\n m = (p.x % 2) * 2 + (p.y % 2)\n (m == 0 ? 0.0 : (m == 1 ? 2.0 : (m == 2 ? 3.0 : 1.0))) / 4.0\n end\n\n def bayer4x4(p : IVec2) : Float32\n x = p.x % 4\n y = p.y % 4\n val = 0.0\n if y == 0\n val = x == 0 ? 0.0 : (x == 1 ? 8.0 : (x == 2 ? 2.0 : 10.0))\n elsif y == 1\n val = x == 0 ? 12.0 : (x == 1 ? 4.0 : (x == 2 ? 14.0 : 6.0))\n elsif y == 2\n val = x == 0 ? 3.0 : (x == 1 ? 11.0 : (x == 2 ? 1.0 : 9.0))\n else\n val = x == 0 ? 15.0 : (x == 1 ? 7.0 : (x == 2 ? 13.0 : 5.0))\n end\n val / 16.0\n end\n\n def ign(pos : Vec2) : Float32\n fract(52.9829189 * fract(dot(pos, vec2(0.06711056, 0.00583715))))\n end\n\n def dither_quantize(color : Float32, steps : Float32, dither_val : Float32) : Float32\n floor(color * steps + dither_val) / steps\n end" -
GLITCH_LIB =
" def scanline_jitter(uv : Vec2, time : Float32, intensity : Float32) : Vec2\n j = fract(sin(dot(vec2(floor(uv.y * 240.0), time), vec2(12.9898, 78.233))) * 43758.5453)\n offset = (j - 0.5) * intensity * step(0.92, j)\n vec2(uv.x + offset, uv.y)\n end\n\n def rgb_split(uv : Vec2, amount : Float32) : Vec4\n vec4(uv.x - amount, uv.y, uv.x + amount, uv.y)\n end" -
LIGHTING_LIB =
" def cel_shade(n_dot_l : Float32, steps : Float32) : Float32\n floor(clamp(n_dot_l, 0.0, 1.0) * steps) / steps\n end\n\n def blinn_phong(normal : Vec3, light_dir : Vec3, view_dir : Vec3, shininess : Float32) : Float32\n half_dir = normalize(light_dir + view_dir)\n clamp(dot(normal, half_dir), 0.0, 1.0) ** shininess\n end" -
MATH_LIB =
" def saturate(x : Float32) : Float32\n clamp(x, 0.0, 1.0)\n end\n\n def lerp(a : Float32, b : Float32, t : Float32) : Float32\n mix(a, b, t)\n end\n\n def remap(val : Float32, in_min : Float32, in_max : Float32, out_min : Float32, out_max : Float32) : Float32\n out_min + (val - in_min) * (out_max - out_min) / (in_max - in_min)\n end\n\n def rotate_2d(p : Vec2, angle : Float32) : Vec2\n s = sin(angle)\n c = cos(angle)\n vec2(p.x * c - p.y * s, p.x * s + p.y * c)\n end\n\n def fresnel(power : Float32, normal : Vec3, view : Vec3) : Float32\n clamp(1.0 - dot(normal, view), 0.0, 1.0) ** power\n end\n\n def rand(uv : Vec2) : Float32\n fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453123)\n end\n\n def rand() : Float32\n fract(sin(dot(vec2(0.123, 0.456), vec2(12.9898, 78.233))) * 43758.5453123)\n end" -
NOISE_LIB =
" def hash11(p : Float32) : Float32\n p3 = fract(vec3(p, p, p) * 0.1031)\n p3 += dot(p3, p3.yzx + 33.33)\n fract((p3.x + p3.y) * p3.z)\n end\n\n def hash22(p : Vec2) : Vec2\n p3 = fract(vec3(p.x, p.y, p.x) * vec3(0.1031, 0.1030, 0.0973))\n p3 += dot(p3, p3.yzx + 33.33)\n fract((p3.xx + p3.yz) * p3.zy)\n end\n\n def value_noise(p : Vec2) : Float32\n i = floor(p)\n f = fract(p)\n u = f * f * (3.0 - 2.0 * f)\n\n a = hash11(i.x + i.y * 57.0)\n b = hash11(i.x + 1.0 + i.y * 57.0)\n c = hash11(i.x + (i.y + 1.0) * 57.0)\n d = hash11(i.x + 1.0 + (i.y + 1.0) * 57.0)\n\n mix(mix(a, b, u.x), mix(c, d, u.x), u.y)\n end\n\n def voronoi(p : Vec2) : Float32\n n = floor(p)\n f = fract(p)\n min_dist = 8.0\n\n diff_0 = hash22(n) - f\n min_dist = min(min_dist, length(diff_0))\n\n diff_1 = hash22(n + vec2(1.0, 0.0)) + vec2(1.0, 0.0) - f\n min_dist = min(min_dist, length(diff_1))\n\n diff_2 = hash22(n + vec2(0.0, 1.0)) + vec2(0.0, 1.0) - f\n min_dist = min(min_dist, length(diff_2))\n\n diff_3 = hash22(n + vec2(1.0, 1.0)) + vec2(1.0, 1.0) - f\n min_dist = min(min_dist, length(diff_3))\n\n min_dist\n end" -
PARTICLES_LIB =
" def integrate_euler(pos : Vec3, vel : Vec3, dt : Float32) : Vec3\n pos + vel * dt\n end\n\n def integrate_verlet(pos : Vec3, vel : Vec3, accel : Vec3, dt : Float32) : Vec3\n pos + vel * dt + accel * (0.5 * dt * dt)\n end\n\n def apply_linear_drag(vel : Vec3, drag : Float32, dt : Float32) : Vec3\n vel * max(0.0, 1.0 - drag * dt)\n end\n\n def attract_point(pos : Vec3, target : Vec3, strength : Float32, radius : Float32) : Vec3\n diff = target - pos\n dist = max(length(diff), 0.0001)\n atten = clamp(1.0 - dist / max(radius, 0.0001), 0.0, 1.0)\n (diff / dist) * (strength * atten * atten)\n end\n\n def vortex_force_3d(pos : Vec3, center : Vec3, strength : Float32, radius : Float32) : Vec3\n diff = center - pos\n dist = max(length(diff), 0.0001)\n atten = clamp(1.0 - dist / max(radius, 0.0001), 0.0, 1.0)\n dir = diff / dist\n tangent = vec3(-dir.z, 0.0, dir.x)\n (tangent + dir * 0.25) * (strength * atten)\n end\n\n def bounce_plane(pos : Vec3, vel : Vec3, plane_normal : Vec3, plane_d : Float32, restitution : Float32) : Vec3\n dist = dot(pos, plane_normal) - plane_d\n if dist < 0.0\n reflect(vel, plane_normal) * restitution\n else\n vel\n end\n end\n\n def wrap_box_3d(pos : Vec3, box_min : Vec3, box_max : Vec3) : Vec3\n span = max(box_max - box_min, vec3(0.0001, 0.0001, 0.0001))\n box_min + mod(pos - box_min + span, span)\n end" -
POST_PROCESSING_LIB =
" def linear_depth(depth_sample : Float32, inv_proj : Mat4) : Float32\n view_pos = inv_proj * vec4(0.0, 0.0, depth_sample, 1.0)\n -view_pos.z / view_pos.w\n end\n\n def luminance(c : Vec3) : Float32\n dot(c, vec3(0.2126, 0.7152, 0.0722))\n end\n\n def barrel_distortion(uv : Vec2, distortion : Float32) : Vec2\n d = uv - vec2(0.5, 0.5)\n uv + d * dot(d, d) * distortion\n end\n\n def vignette(uv : Vec2, radius : Float32, softness : Float32) : Float32\n d = length(uv - vec2(0.5, 0.5))\n smoothstep(radius, radius - softness, d)\n end" -
REGISTRY =
{"math" => MATH_LIB, "noise" => NOISE_LIB, "color" => COLOR_LIB, "lighting" => LIGHTING_LIB, "sdf" => SDF_LIB, "tonemap" => TONEMAP_LIB, "triplanar" => TRIPLANAR_LIB, "post_processing" => POST_PROCESSING_LIB, "compositor" => COMPOSITOR_LIB, "dither" => DITHER_LIB, "curl_noise" => CURL_NOISE_LIB, "color_spaces" => COLOR_SPACES_LIB, "atmosphere" => ATMOSPHERE_LIB, "glitch" => GLITCH_LIB, "particles" => PARTICLES_LIB} -
SDF_LIB =
" def sdf_sphere(p : Vec3, radius : Float32) : Float32\n length(p) - radius\n end\n\n def sdf_box(p : Vec3, b : Vec3) : Float32\n q = abs(p) - b\n length(max(q, vec3(0.0, 0.0, 0.0))) + min(max(q.x, max(q.y, q.z)), 0.0)\n end\n\n def smin(a : Float32, b : Float32, k : Float32) : Float32\n h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0)\n mix(b, a, h) - k * h * (1.0 - h)\n end\n\n def smax(a : Float32, b : Float32, k : Float32) : Float32\n h = clamp(0.5 - 0.5 * (b - a) / k, 0.0, 1.0)\n mix(b, a, h) + k * h * (1.0 - h)\n end" -
TONEMAP_LIB =
" def aces_tonemap(x : Vec3) : Vec3\n a = 2.51\n b = 0.03\n c = 2.43\n d = 0.59\n e = 0.14\n clamp((x * (a * x + b)) / (x * (c * x + d) + e), 0.0, 1.0)\n end\n\n def reinhard_tonemap(x : Vec3) : Vec3\n x / (x + vec3(1.0, 1.0, 1.0))\n end" -
TRIPLANAR_LIB =
" def triplanar_weights(normal : Vec3) : Vec3\n w = abs(normal)\n w = w / (w.x + w.y + w.z)\n w\n end"