canvas+webgl三维晶莹剔透玻璃方块透镜效果代码
代码语言:html
所属分类:三维
代码描述:canvas+webgl三维晶莹剔透玻璃方块透镜效果代码
代码标签: canvas webgl 三维 晶莹 剔透 玻璃 方块 透镜
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> * { box-sizing: border-box; } html, body { margin: 0; min-height: 100vh; overflow: hidden; background: repeating-radial-gradient( circle at center, #444 0 10%, #111 10% 20% ); touch-action: none; } canvas { width: 100%; height: auto; object-fit: contain; } </style> </head> <body > <canvas id="canvas"></canvas> <script > /********* * made by Matthias Hurrle (@atzedent) */ /** @type {HTMLCanvasElement} */ const canvas = window.canvas; const gl = canvas.getContext("webgl2"); const dpr = Math.max(1, window.devicePixelRatio); /** @type {Map<string,PointerEvent>} */ const touches = new Map(); const vertexSource = `#version 300 es #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif in vec2 position; void main(void) { gl_Position = vec4(position, 0., 1.); } `; const fragmentSource = `#version 300 es /********* * made by Matthias Hurrle (@atzedent) */ #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif out vec4 fragColor; uniform vec2 resolution; uniform int pointerCount; uniform vec2 touch; uniform float time; const float PI = radians(180.); const float TAU = 2.*PI; const float IOR = 1.45; const float DENSE = .8; #define MAX_STEPS 100 #define MAX_DIST 20. #define SURF_DIST 1e-3 #define T 3.+time vec2 MatMin(vec2 lhs, vec2 rhs) { if (lhs.x < rhs.x) return lhs; return rhs; } mat2 Rot(float a) { float s = sin(a), c = cos(a); return mat2(c, -s, s, c); } vec3 Pattern(vec2 uv) { uv *= .5; float t = 8.9; float fa = 1., fb = 1., fc = 1., fd = .0; for (int i = 0; i < 10; i++) { vec2 p = vec2( cos(uv.y * fa - fd + t / fb), sin(uv.x * fa - fd + t / fb) ) / fc; p += vec2(-p.y, p.x) * .3; uv.xy += p; fa *= 2.; fb *= 1.5; fc *= 1.75; fd += .05 + .1 * t * fb; } float r = sin(uv.x - t) * .5 + .5, g = sin(uv.y + t) * .5 + .5, b = sin((uv.x + uv.y + sin(t * .5)) * .5) * .5 + .5; return vec3(r, g, b); } float Box(vec3 p, vec3 b, float r) { vec3 q = abs(p) - b; return length( max(q, .0)) + min(max(q.x, max(q.y, q.z)), .0) - r; } vec2 GetDist(vec3 p) { vec2 md = MatMin( vec2( Box(vec3(p.x, p.y+.45, p.z), vec3(1., .5, 1.), .125), 1. ), vec2( dot( p, normalize(vec3(.0, 1., .0)) ) + 1.08, 2. ) ); return md; } float SoftShadow(in vec3 ro, in vec3 rd, float mint, float maxt, float k) { float res = 1.; for (float t=mint; t<maxt;) { float h = GetDist(ro + rd*t).x; if(h < 1e-3) return .0; res = min(res, k*h/t); t += h; } return res; } vec2 RayMarch(vec3 ro, vec3 rd, float side) { float d = .0; vec2 mat; for (int i = 0; i < MAX_STEPS; i++) { vec3 p = ro + rd*d; mat = GetDist(p) * side; d += mat.x; if (d > MAX_DIST || abs(mat.x) < SURF_DIST) break; } return vec2(d, mat.y); } vec3 GetNormal(vec3 p) { float d = GetDist(p).x; vec2 e = vec2(1e-3, 0); vec3 n = d - vec3( GetDist(p-e.xyy).x, GetDist(p-e.yxy).x, GetDist(p-e.yyx).x); return normalize(n); } vec3 GetRayDir(vec2 uv, vec3 p, vec3 l, float z) { vec3 f = normalize(l-p), r = normalize(cross(vec3(0, 1, 0), f)), u = cross(f, r), c = f*z, i = c + uv.x*r + uv.y*u, d = normalize(i); return d; } vec3 Refract(vec3 p, vec3 n, inout vec3 ro, inout vec3 rd, inout float od) { vec3 rdIn = refract(rd, n, 1./IOR); vec3 pEnter = p-n*SURF_DIST*3.; vec2 dIn = RayMarch(pEnter, rdIn, -1.); vec3 pExit = pEnter + rdIn * dIn.x; vec3 nExit = -GetNormal(pExit); vec3 rdOut = refract(rdIn, nExit, IOR); if (dot(rdOut, rdOut) == .0) { rdOut = reflect(rdIn, nExit); } rd = rdOut; ro = pEnter; od = exp(-dIn.x * DENSE); return pExit; } vec3 Render(inout vec3 ro, inout vec3 rd, inout float ref) { vec2 d = RayMarch(ro, rd, 1.); vec3 col = vec3(0); if (d.x > MAX_DIST) return col; vec3 p = ro + rd * d.x; vec3 lightPos = ro; vec3 l = normalize(lightPos - p); vec3 n = GetNormal(p); vec3 r = reflect(rd, n); // light float fres = clamp(1.+dot(r, n), .0, 1.); float diffuse = smoothstep(.05, .95, dot(l, n) * .5 + .5); float shadow = SoftShadow(p+n*3e-3,l,1e-3,10.,4.); diffuse *= shadow; float spot = clamp(dot(normalize(ro), re.........完整代码请登录后点击上方下载按钮下载查看
网友评论0