glsl|GLSL Shader 中的一些有用的功能函数代码实现

//2D grid,for texture or post:bool grid(vec2 uv) { return fract(uv.x) > 0.5 ^^ fract(uv.y) > 0.5; } //Circle: bool circle(vec2 pos, float rad, vec2 uv) { return dot(uv - pos, uv - pos) < rad * rad; } //Smooth circle: float smooth_circle(float sm, vec2 pos, float rad, vec2 uv) { return 1.0 - smoothstep(rad * rad - sm, rad * rad, dot(uv - pos, uv - pos)); } //Convert boolean to float: float b2f(bool a) { if(a) {return 1.0; } else {return 0.0; } } //Sphere: float sphere(in vec3 pos, in float r, in vec3 ro, in vec3 rd, out vec3 nor) { ro -= pos; float b = dot(ro, rd); float h = b*b - dot(ro, ro) + r*r; if (h<0.0) return -1.0; float t = -b - sqrt(h); nor = (ro + rd * t)/r; return t; } //Horizontal plane: float horizontal_plane(in float height, in vec3 ro, in vec3 rd, out vec3 nor) { nor = vec3(0.0, 1.0, 0.0); return -(ro.y - height)/rd.y; } //Cube: float cube(in vec3 a, in vec3 b, in vec3 ro, in vec3 rd, out vec3 nor) { float min_t = -1.0; float t; t = -(ro.y - b.y)/rd.y; { vec3 pos = ro + rd * t; vec2 ins = step(b.xz, pos.xz) - step(a.xz, pos.xz); if(ins.x * ins.y > 0.0) { nor = vec3(0.0, 1.0, 0.0); min_t = t; } } t = -(ro.y - a.y)/rd.y; if(min_t == -1.0 || t < min_t) { vec3 pos = ro + rd * t; vec2 ins = step(b.xz, pos.xz) - step(a.xz, pos.xz); if(ins.x * ins.y > 0.0) { nor = vec3(0.0, -1.0, 0.0); min_t = t; } } t = -(ro.x - b.x)/rd.x; if(min_t == -1.0 || t < min_t) { vec3 pos = ro + rd * t; vec2 ins = step(b.yz, pos.yz) - step(a.yz, pos.yz); if(ins.x * ins.y > 0.0) { nor = vec3(1.0, 0.0, 0.0); min_t = t; } } t = -(ro.x - a.x)/rd.x; if(min_t == -1.0 || t < min_t) { vec3 pos = ro + rd * t; vec2 ins = step(b.yz, pos.yz) - step(a.yz, pos.yz); if(ins.x * ins.y > 0.0) { nor = vec3(-1.0, 0.0, 0.0); min_t = t; } } t = -(ro.z - b.z)/rd.z; if(min_t == -1.0 || t < min_t) { vec3 pos = ro + rd * t; vec2 ins = step(b.xy, pos.xy) - step(a.xy, pos.xy); if(ins.x * ins.y > 0.0) { nor = vec3(0.0, 0.0, -1.0); min_t = t; } } t = -(ro.z - a.z)/rd.z; if(min_t == -1.0 || t < min_t) { vec3 pos = ro + rd * t; vec2 ins = step(b.xy, pos.xy) - step(a.xy, pos.xy); if(ins.x * ins.y > 0.0) { nor = vec3(0.0, 0.0, 1.0); min_t = t; } }return min_t; } //Order intersection results: void order(in int oid, in float ot, in vec3 onor, in int ignore_id, inout int id, inout float t, inout vec3 nor) { if(ignore_id != oid && ot > 0.0 && ot < t) {t = ot; nor = onor; id = oid; } }//Setup rays for ray tracing: vec2 uv = fragCoord.xy / iResolution.xy; uv.y *= iResolution.y / iResolution.x; // Generate a ray with origin ro and direction rd. vec3 ro = vec3( 0.0, 1.0, 4.0 ); vec3 rd = normalize( vec3( -1.0+2.0*uv, -1.0 ) ); //Random number from 2D coordinates: float rand(vec2 co) { return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); } //Random direction from 2D coordinates: vec3 rand_dir(vec2 p) { return normalize(vec3(rand(p)-0.5, rand(p + vec2(1.0))-0.5, rand(p + vec2(2.0))-0.5)); } //Convert from RGB to HSB: vec3 rgb2hsb( in vec3 c ){ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } //Convert from HSB to RGB (official standard): vec3 hsv2rgb( in vec3 c ) { vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); return c.z * mix( vec3(1.0), rgb, c.y); } //Smooth conversion from HSB to RGB (https://www.shadertoy.com/view/MsS3Wc): vec3 hsv2rgb_smooth( in vec3 c ) { vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 ); rgb = rgb*rgb*(3.0-2.0*rgb); // cubic smoothing return c.z * mix( vec3(1.0), rgb, c.y); } //以上code来自于: https://github.com/PistonDevelopers/shaders/wiki/Some-useful-GLSL-functionsfloat near = 0.1; float far= 500.0; float LinearizeDepth(float depth) { float z = depth * 2.0 - 1.0; // back to NDC return (2.0 * near * far) / (far + near - z * (far - near)); }vec4 pixelTo() { float s = uv.y, t = uv.x,w = 64,h = 64; // s = floor(s * h); t = floor(t * w); float pu = (t + 0.5f) / w, pv = (s + 0.5f) / h; // vec4 color; vec4 tc; vec2 puv = vec2(pu,pv); float dt = 0.8f/w; // puv.x = pu + dt; tc = texture( texSampler, puv ).rgba; color += tc; puv.x = pu - dt; if(puv.x < 0.0f) puv.x = 0.0f; tc = texture( texSampler, puv ).rgba; color += tc; puv.x = pu; puv.y = pv + dt; tc = texture( texSampler, puv ).rgba; color += tc; puv.y = pv - dt; if(puv.y < 0.0f) puv.y = 0.0f; tc = texture( texSampler, puv ).rgba; color += tc; return color * 0.25f; } //random of simulation float randomX(float x){ return fract(sin(x)*1e4); } float randomXY(vec2 st){ return fract(sin(dot(st.xy, vec2(12.9898,78.233)))* 43758.5453123); } // const float MATH_PI = 3.1415926; const float MATH_2PI = 2.0 * MATH_PI; const float MATH_1PER2PI = 0.5 * MATH_PI; const float MATH_3PER2PI = 3.0 * MATH_PI * 0.5; // float getRadianByXY(float dx,float dy) { if(abs(dx) < 0.00001) { if(dy >= 0.0) return MATH_1PER2PI; else return MATH_3PER2PI; } float rad = atan(dy/dx); if(dx >= 0.0) { return rad; } rad = MATH_PI + rad; return rad; } // float getMinRadian(float a0, float a1) { a0 = mod(a0,MATH_2PI); a1 = mod(a1,MATH_2PI); if (a0 < a1) { a0 = MATH_2PI - a1 + a0; if (a0 > MATH_PI) return a0 - MATH_2PI; return a0; } else if (a0 > a1) { a1 = MATH_2PI - a0 + a1; if (a1 > MATH_PI) return MATH_2PI - a1; return -a1; } return 0.0; } // smooth min, tnanks:http://www.iquilezles.org/www/articles/smin/smin.htm // exponential smooth min (k = 32); float smin( float a, float b, float k ) { float res = exp2( -k*a ) + exp2( -k*b ); return -log2( res )/k; } // polynomial smooth min (k = 0.1); float smin( float a, float b, float k ) { float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); return mix( b, a, h ) - k*h*(1.0-h); } // power smooth min (k = 8); float smin( float a, float b, float k ) { a = pow( a, k ); b = pow( b, k ); return pow( (a*b)/(a+b), 1.0/k ); } // polynomial smooth min (k = 0.1); float smin( float a, float b, float k ) { float h = max( k-abs(a-b), 0.0 ); return min( a, b ) - h*h*0.25/k; } // polynomial smooth min (k = 0.1); float sminCubic( float a, float b, float k ) { float h = max( k-abs(a-b), 0.0 ); return min( a, b ) - h*h*h/(6.0*k*k); }

【glsl|GLSL Shader 中的一些有用的功能函数代码实现】

    推荐阅读