0 ~ 1 사이의 값을 갖는 간단한 노이즈 함수
float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123); } // Based on Morgan McGuire @morgan3d // https://www.shadertoy.com/view/4dS3Wd float noise (in vec2 st) { vec2 i = floor(st); vec2 f = fract(st); // Four corners in 2D of a tile float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; }
-1 ~ 1 사이의 값을 갖는 Simplex 노이즈 함수
// Some useful functions vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); } // // Description : GLSL 2D simplex noise function // Author : Ian McEwan, Ashima Arts // Maintainer : ijm // Lastmod : 20110822 (ijm) // License : // Copyright (C) 2011 Ashima Arts. All rights reserved. // Distributed under the MIT License. See LICENSE file. // https://github.com/ashima/webgl-noise // float snoise(vec2 v) { // Precompute values for skewed triangular grid const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner (x0) vec2 i = floor(v + dot(v, C.yy)); vec2 x0 = v - i + dot(i, C.xx); // Other two corners (x1, x2) vec2 i1 = vec2(0.0); i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0); vec2 x1 = x0.xy + C.xx - i1; vec2 x2 = x0.xy + C.zz; // Do some permutations to avoid // truncation effects in permutation i = mod289(i); vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3( dot(x0,x0), dot(x1,x1), dot(x2,x2) ), 0.0); m = m*m ; m = m*m ; // Gradients: // 41 pts uniformly over a line, mapped onto a diamond // The ring size 17*17 = 289 is close to a multiple // of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt(a0*a0 + h*h); m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h); // Compute final noise value at P vec3 g = vec3(0.0); g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y); return 130.0 * dot(m, g); }
좀더 고른 분포의 랜던 hash
uvec2 murmurHash21(uint src) { const uint M = 0x5bd1e995u; uvec2 h = uvec2(1190494759u, 2147483647u); src *= M; src ^= src>>24u; src *= M; h *= M; h ^= src; h ^= h>>13u; h *= M; h ^= h>>15u; return h; } // 2 outputs, 1 input vec2 hash21(float src) { uvec2 h = murmurHash21(floatBitsToUint(src)); return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0; }
smoothstep의 보간식
아래의 a와 b는 동일한 값이다.
float f = uv.x; float a = smoothstep(0., 1., f); float b = f * f * (3. - 2. * f);
위의 보간식을 cubic Hermite curve(큐빅 헤르미트 곡선)라고 한다. 0~1 사이의 영역에서 시작과 끝을 좀더 편평하게 만들어주는 quintic interpolation cuver(퀸틱 보간 곡선)에 대한 코드는 다음과 같다.
float f = uv.x; float b = f * f * f * (6. * f * f - 15. * f + 10.);
modelMatrix로 변환된 normal 얻기
varying vec3 vNormal; ... vNormal = mat3(transpose(inverse(modelMatrix))) * normal;
프레그먼트 쉐이더에서는 받은 vNormal을 반드시 정규화(normalize)해야 한다.
3초 주기로 0 ~ 1 사이의 연속된 값 얻기
uniform float u_time; // 0, 1, 2, ...의 값이며 각각 0초, 1초, 2초, ...를 나타냄 ... float period = 3.; // 3초 주기 float t = mod(u_time, period) / period; // 0 ~ 1 사이의 연속된 값 // sin 함수에 3.1415를 곱하는 이유는 sin 함수의 한 주기가 360도이기 때문임 vec3 color = mix(vec3(0), vec3(1), abs(sin(3.1415 * t))); // or vec3 color = mix(vec3(0), vec3(1), sin(3.1415 * t) * .5 + .5);
원하는 각도를 이루는 선
아래의 이미지는 45도를 이루는 선인데, 이처럼 원하는 각도를 이루는 선을 만들기 위한 코드이다.
uniform vec3 uResolution; uniform float uTime; uniform vec4 uMouse; #define PI (3.141592) void main() { vec2 st = gl_FragCoord.xy / uResolution.xy; st = (gl_FragCoord.xy - .5 * uResolution.xy) / uResolution.y; float w = fwidth(st.y); float a = (45.) * PI / 180.0; float d = dot(st, vec2(cos(a), sin(a))); d = smoothstep(-w, w, abs(d)); gl_FragColor = vec4(vec3(1. - d), 1.); }
다각형 그리기
uniform vec3 uResolution; uniform float uTime; uniform vec4 uMouse; #define PI 3.14159265359 #define TWO_PI 6.28318530718 void main(){ vec2 st = gl_FragCoord.xy/uResolution.xy * 2. - 1.; //-1-1 st.x *= uResolution.x/uResolution.y; vec3 color = vec3(0.0); float d = 0.0; // Number of sides of your shape int N = 6; // int N = int(floor(mod(uTime * 10., 20.))) + 3; // Angle and radius from the current pixel float a = atan(st.x,st.y)+PI; float r = TWO_PI/float(N); // Shaping function that modulate the distance d = cos(floor(.5+a/r)*r-a)*length(st); // color = vec3(d); // Distance Field color = vec3(1.0-step(.5, d)); // Fill // color = vec3(step(.5,d) * step(d,.51)); // Only outline gl_FragColor = vec4(color,1.0); }