canvas+webgl实现三维玻璃水晶球旋转动画效果代码

代码语言:html

所属分类:三维

代码描述:canvas+webgl实现三维玻璃水晶球旋转动画效果代码

代码标签: canvas webgl 三维 玻璃 水晶球 旋转 动画

下面为部分代码预览,完整代码请点击下载或在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;
}
</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 64
#define PI radians(180.)
#define TAU (2. * PI)
#define T time * .25
#define mouse pointers[0]

vec2 csqr(vec2 a) {
    return vec2(
        a.x * a.x - a.y * a.y,
        2. * a.x * a.y
    );
}

float Swirls(in vec3 p) {
    float res = .0;
    vec3 c = p;

    for(int i = 0; i < 11; ++ i) {
        p = .7 * abs(p) / dot(p, p) - .7;
        p.yz = csqr(p.yz);
        p = p.zxy;
        res += exp(-19. * abs(dot(p, c)));
        
    }
    return res * .5;
}

mat2 Rot(float a) {
    float s = sin(a), c = cos(a);
    
    return mat2(c, - s, s, c);
}

vec2 Sphere(in vec3 ro, in vec3 rd) {
    vec3 oc = ro;
    float b = dot(oc, rd);
    float c = dot(oc, oc) - 4.;
    float h = b * b - c;

    if (h < .0) {
        return vec2(-1.);
    }
    
    h = sqrt(h);

    return vec2(-b - h, - b + h);
}

vec3 RayMarch(in vec3 ro, vec3 rd, vec2 sdf) {
    float dt = .2 - .18 * cos(T * .75);
    float t = sdf.x;
    float c = .0;
    
    vec3 col = vec3(0.0);

    for(int i = 0; i < MAX_STEPS; i++) {
        t += dt * exp(-2. * c);

        if (t > sdf.y) {
            break;
        }
        
        c = Swirls(ro + rd * t);
        
        col += vec3(c, c * c, c) * .05;
    }
    return col;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    float mn = min(resolution.x, resolution.y);
    float mx = max(resolution.x, resolution.y);
    vec2 uv = (
        2. * fragCoord.xy - resolution.xy
    ) / mix(mn, mx, .5 + .5 * sin(T));
    uv *= .5;
 
    vec2 m = mouse.xy / resolution.xy;
    vec3 ro = vec3(.0, 3., -6.);
    ro.yz *= Rot(mouse.x > 0.0 ? -m.y * PI + 1. : cos(T));
    ro.xz *= Rot(mouse.x > 0.0 ? m.x * TAU : sin(T));    

    vec3 ww = normalize(-ro);
    vec3 uu = normalize(cross(ww, vec3(.0, 1., .0)));
    vec3 vv = normalize(cross(uu, ww));
    vec3 rd = normalize(uv.x * uu + uv.y * vv + ww);
    
    vec2 sdf = Sphere(ro, rd);
    vec3 col = RayMarch(ro, rd, sdf);

    vec3 d = (ro + sdf.x * rd) * .3;
    d = reflect(rd, d);
    vec3 refr = refract(rd, d, .85);
    float fres = pow(.125 + clamp(dot(d, rd), .0, 1.), 3.) * .3;
    fres += pow(.5 + clamp(dot(refr, rd), .0, .0), 3.) * .3;
    col += fres;

    col = .5 * log(1. + col);
    col = clamp(col, .0, 1.);

    fragColor = vec4(col, 1.);
}

void main() {
    vec4 fragment_color;
.........完整代码请登录后点击上方下载按钮下载查看

网友评论0