webgl+canvas实现三维可旋转空间圆环效果代码
代码语言:html
所属分类:三维
代码描述:webgl+canvas实现三维可旋转空间圆环效果代码
代码标签: webgl canvas 三维 旋转 空间 圆环
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> * { box-sizing: border-box; } html, body { position: relative; 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; } button { padding: 0.5rem; font-size: 1rem; background: #444; border: 2px solid; border-radius: 0.5rem; justify-self: end; } kbd { background-color: #eee; border-radius: 3px; border: 1px solid #b4b4b4; color: #333; display: inline-block; font-size: 0.85em; font-weight: 700; line-height: 1; padding: 2px 4px; white-space: nowrap; box-shadow: 0 1px 1px #0001, 0 2px 0 0 #fffb inset; } #dialog { user-select: none; position: fixed; inset: 0; padding: 1em 2em 3em 2em; border-radius: 4px; font-family: system-ui; line-height: 1.6; } .x { filter: grayscale(1); border: none; background: none; position: absolute; top: 0; right: 0.4rem; cursor: pointer; } .x:hover, .x:focus-visible { outline: none; box-shadow: 0 1px 1px 1px #1111; } </style> </head> <body > <canvas id="canvas"></canvas> <script > /********* * made by Matthias Hurrle (@atzedent) */ /** @type {HTMLCanvasElement} */ const canvas = window.canvas; const gl = canvas.getContext('webgl'); const dpr = window.devicePixelRatio; const vertexSource = ` #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif attribute vec2 position; void main(void) { gl_Position = vec4(position, 0., 1.); } `; const fragmentSource = ` /********* * made by Matthias Hurrle (@atzedent) */ #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec2 resolution; uniform float time; uniform vec2 pointers[10]; #define MAX_STEPS 100 #define MAX_DIST 100. #define SURF_DIST .001 #define T time * .25 #define mouse pointers[0] mat2 Rot(float a) { float s = sin(a), c = cos(a); return mat2(c, -s, s, c); } float sdBoxFrame(vec3 p, vec3 b, float e, float r) { p = abs(p ) - b; vec3 q = abs(p+e) - e; return min(min( length( max(vec3(p.x, q.y, q.z), .0)) + min(max(p.x, max(q.y, q.z)), .0) - r, length( max(vec3(q.x, p.y, q.z), .0)) + min(max(q.x, max(p.y, q.z)), .0) - r), length( max(vec3(q.x, q.y, p.z), .0)) + min(max(q.x, max(q.y, p.z)), .0) - r); } float sdRoundBox(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; } float sdOctahedron( vec3 p, float s) { p = abs(p); return (p.x + p.y + p.z - s) * .57735027; } float sdTorus(vec3 p, vec2 t) { vec2 q = vec2(length(p.xz) - t.x, p.y); return length(q) - t.y; } float sdSphere(vec3 p, float s) { return length(p) - s; } float opSmoothUnion(float d1, float d2, float k) { float h = clamp(.5 + .5 * (d2 - d1) / k, .0, 1.); return mix(d2, d1, h) - k * h * (1. - h); } float opSmoothSubtraction(float d1, float d2, float k) { float h = clamp(.5 - .5 * (d2 + d1) / k, .0, 1.); return mix(d2, -d1, h) + k * h * (1. - h); } float opSmoothIntersection(float d1, float d2, float k) { float h = clamp(.5 - .5 * (d2 - d1) / k, .0, 1.); return mix(d2, d1, h) + k * h * (1. -h ); } float opRep(in vec3 p, in vec3 c) { vec3 q = mod(p + .5 * c, c) - .5 * c; // Just try a different SDF or boolen operation. return //sdSphere(q, 1.); //sdTorus(q, vec2(1., .5)); //sdOctahedron(q, 1.); //sdRoundBox(q, vec3(.5), .05); //sdBoxFrame(q, vec3(1.), .25, .05); //opSmoothIntersection(sdBoxFrame(q, vec3(1.), .25, .125), sdSphere(q, 1.5), .05); //opSmoothUnion(sdSphere(q, .75), sdOctahedron(q, 1.), .05); //opSmoothSubtraction(sdRoundBox(q, vec3(.5), .05), sdOctahedron(q, 1.25), .05); opSmoothIntersection(sdTorus(q, vec2(1., .75)), sdSphere(q, 1.), .05); } float GetDist(vec3 p) { // Adjust the grid with a distance factor for each axis. // Higher values result in a less dense grid. vec3 spread = vec3(12. + 6. * (.5 + .5 * -cos(T))); float d = opRep(p, spread); return d; } float RayMarch(vec3 ro, vec3 rd) { float dO = .0; for(int i = 0; i < MAX_STEPS; i++) { vec3 p = ro + rd*dO; float dS = GetDist(p); dO += dS; if(dO > MAX_DIST || abs(dS) < SURF_DIST) break; } return dO; } vec3 GetNormal(vec3 p) { float d = GetDist(p); vec2 e = vec2(SURF_DIST, 0.); vec3 n = d - vec3( GetDist(p-e.xyy), GetDist(p-e.yxy), GetDist(p-e.yyx)); 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 Render(inout.........完整代码请登录后点击上方下载按钮下载查看
网友评论0