webgl实现三维立方体镜面反射折射动画效果代码

代码语言:html

所属分类:三维

代码描述:webgl实现三维立方体镜面反射折射动画效果代码

代码标签: webgl 三维 立方体 镜面 反射 折射 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  

  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  
  
<style>
body {
  margin: 0;
  touch-action: none;
  overflow: hidden;
}

canvas {
  width: 100%;
  height: auto;
  object-fit: contain;
  user-select: none;
}
</style>

  
</head>

<body translate="no">
  <canvas id="canvas"></canvas>
  <script type="x-shader/x-fragment" id="rusty">#version 300 es
    /*********
    * made by Matthias Hurrle (@atzedent)
    */
    #ifdef GL_FRAGMENT_PRECISION_HIGH
    precision highp float;
    #else
    precision mediump float;
    #endif
    out vec4 O;
    uniform vec2 resolution;
    uniform float time;
    #define FC gl_FragCoord.xy
    #define R resolution
    #define T mod(time*.25,60.)
    #define S smoothstep
    
    vec3 palette(float t) {
      vec3
      a=vec3(.5),
      b=vec3(.5),
      c=vec3(1),
      d=vec3(.2,.3,.4);
    
      return a+b*cos(6.3*(c*d+t));
    }
    
    float rnd(vec2 p) {
      return fract(sin(dot(p,vec2(12.9898,78.233))+floor(T))*345678.);
    }
    
    float noise(vec2 p) {
      vec2 i=floor(p), f=fract(p), u=S(.0,1.,f);
    
      float
      a=rnd(i),
      b=rnd(i+vec2(1,0)),
      c=rnd(i+vec2(0,1)),
      d=rnd(i+1.);
    
      return mix(mix(a,b,u.x),mix(c,d,u.x),u.y);
    }
    
    float fbm(vec2 p) {
      float t=.0, a=1.;
    
      for (int i=0; i<5; i++) {
        t += a*noise(p);
        p *= 2.;
        a *= .5;
      }
    
      return t;
    }
    
    vec3 pattern1(vec2 uv) {
      vec3 col = vec3(0);
      vec2 p=uv;
      float d=1.;
    
      for (float i=.0; i<3.; i++) {
        p = vec2(cos(.125*sin(uv.x)),sin(uv.y)*.25);
        float
        a = fbm(-T*.25+120.*uv*length(p)*d),
        b = fbm(-T*.25+vec2(0,1.25)+8.*uv*length(p)*d);
        d = mix(a,b,pow(fract(T),.25));
        uv *= .25;
        col += palette(d)*.5;
      }
    
      col = mix(col, vec3(.5),.5);
      col = mix(col, col*col*col*col, col);
      col = S(.0, 1., col);
      col = pow(col, vec3(.4545));
    
      return col;
    }
    
    vec3 pattern2(vec2 uv) {
    	vec3 col = vec3(0);
    	vec2 p=uv;
    	float d=1.;
    
    	for (float i=.0; i<3.; i++) {
    		p = vec2(cos(.25*sin(uv.x)),cos(uv.y)*.25);
    		float a=fbm(2.*uv*length(p)*d);
    		d = a;
    		uv *= .25;
    		col += palette(d)*.5;
    	}
    
    	col = mix(col, vec3(.5),.5);
      col = mix(col, col*col*col*col, col);
      col = S(.0, 1., col);
      col = pow(col, vec3(.4545));
    
    	return col;
    }
    
    void main(void) {
      vec2 uv = (FC-.5*R)/min(R.x,R.y);
      vec3 p1 = pattern1(uv), p2 = pattern2(uv),
      col = mix(p1, p2, .65);
      O = vec4(col,1);
    }
  </script>
  <script type="x-shader/x-fragment" id="fragmentSource">#version 300 es
    /*********
    * made by Matthias Hurrle (@atzedent)
    */
    #ifdef GL_FRAGMENT_PRECISION_HIGH
    precision highp float;
    #else
    precision mediump float;
    #endif
    out vec4 O;
    uniform float time;
    uniform vec2 resolution;
    uniform vec2 touch;
    uniform int pointerCount;
    uniform sampler2D rusty;
    uniform sampler2D textTexture;
    #define mouse (touch/resolution)
    #define P pointerCount
    #define FC gl_FragCoord.xy
    #define R resolution
    #define S smoothstep
    #define T mod(time*.25, 180.)
    #define rot(a) mat2(cos(a-vec4(0,11,33,0)))
    
    float mapto(float x, float a, float b, float c, float d) {
        return c+(d-c)*(x-a)/(b-a);
    }
    
    float rnd(vec2 p) {
        return fract(sin(dot(p, vec2(12.9898,78.233)))*345678.);
    }
    
    float noise(vec2 p) {
        vec2 i = floor(p), f = fract(p), u = S(.0, 1., f);
        
        float
        a = rnd(i),
        b = rnd(i+vec2(1,0)),
        c = rnd(i+vec2(0,1)),
        d = rnd(i+1.);
        
        return mix(mix(a,b,u.x),mix(c,d,u.x),u.y);
    }
    
    float fbm(vec2 p) {
        float t = .0, a = 1.;
        
        for (int i=0; i<5; i++) {
            t += a*noise(p);
            p *= 2.;
            a *= .5;
        }
        
        return t;
    }
    
    vec3 palette(float t) {
        vec3
        a = vec3(.5),
        b = vec3(.5),
        c = vec3(1),
        d = vec3(.2,.3,.4);
        
        return a+b*cos(6.3*(c*d+t));
    }
    
    vec3 pattern(vec2 uv) {
        uv.x = mapto(uv.x, .0, 1., .0, .035);
        uv.y = mapto(uv.y, .0, 1., .0, .035);
        vec3 tex = texture(rusty, uv+.5).rgb;

        return S(.0, 1., tex);
    }
    
    float box(vec3 p, vec3 s, float r) {
        p = abs(p) - (s-r);
        
        return length(max(p, .0))+
            min(.0, max(max(p.x,p.y),p.z))-r;
    }
    
    float smin(float a, float b, float k) {
        float h = clamp(
            .5+.5*(b-a)/k,
            .0,
            1.
        );
        
        return mix(b,a,h)-k*h*(1.-h);
    }
    
    float bod(vec3 p, float r) {
        return smin(
          smin(
            length(p.xy)-r,
            length(p.yz)-r,
            -.01
          ),
          length(p.xz)-r,
          -.01
        );
    }
    
    vec2 map(vec3 p) {
        vec3 q = p;
        if (P > 0) {
            p.yz *= rot(-mouse.y*3.14+1.57);
            p.xz *= rot(3.14-mouse.x*6.3);
        } else {
            float t = T*.2;
            p.yz *= rot(-t*.5);
            p.xz *= rot(t);
        }

        vec2
        a = vec2(bod(p, 1.7), 1),
        b = vec2(-box(q, vec3(14, 14, 4), .05), 0);
        a = a.x < b.x ? a: b;
    
        return a;
    }
    
    vec3 norm(vec3 p) {
        float h = 1e-3;
        vec2 k = vec2(-1,1);
        return normalize(
            k.xyy*map(p+k.xyy*h).x+
            k.yxy*map(p+k.yxy*h).x+
            k.yyx*map(p+k.yyx*h).x+
            k.xxx*map(p+k.xxx*h).x
        );
    }
    
    void main(void) {
        vec2 uv = (FC-.5*R)/min(R.x,R.y);
        vec3 col = vec3(0),
        p = vec3(0,0,-3),
        rd = normalize(vec3(uv, 1));
        
        const float steps = 300.;
        float dd = .0, bnz = .0;
        
        for (float i=.0; i<steps; i++) {
            vec2 d = map(p);
            
            if (d.x < 1e-3) {
                vec3 n = norm(p);
                
                if (d.y == .0) {
                    col += pattern(p.xy)*abs(n.z);
                    col += pattern(p.xz)*abs(n.y);
                    col += pattern(p.yz)*abs(n.x);

                    if (sign(n.z) == -1.) {
                      vec2 st = p.xy;
                      st.y = 1.-st.y;
                      st.y += 2.;
                      st.y *= 4.;
                      st.x -= 7.;
                      st *= .2;
                      vec4 text = texture(textTexture, st);
                      col += S(.0,1.,text.a)*mix(col, vec3(text.a, .75, .5), text.a);
                    }
                    
                    break;
                } else {
                    rd = reflect(rd, n);
                    d.x = .1;
                    float mat = cos(uv.y);
                    col += mat*n.z;
                    col += mat*n.y;
                    col += mat*n.x;
                    col += palette(dot(rd,n));
                    
                    if (bnz++ > 1.) break;
                }
            }
            
            dd += d.x;
            p += rd*d.x;
        }
        
        col = mix(vec3(1), col, exp(-125e-6*dd*dd*dd));
        
        O = vec4(col, 1);
    }
  </script>
  
      <script id="rendered-js" >
const gl = canvas.getContext("webgl2");
const dpr = Math.max(1, .5 * window.devicePixelRatio);
const edge = Math.max(screen.width, screen.height) * window.devicePixelRatio;

function resize() {
  const {
    innerWidth: width,
    innerHeight: height } =
  window;

  canvas.width = width * dpr;
  canvas.height = height * dpr;

  gl.viewport(0, 0, width * dpr, height * dpr);
}

const vertexSource = `#version 300 es
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

in vec4 position;

void main(void) {
    gl_Position = position;
}
`;

function compile(shader, source) {
  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error(gl.getShaderInfoLog(shader));
  }
}

function createProgram(vertexSource, fragmentSource) {
  const vs = gl.createShader(gl.VERTEX_SHADER);
  const fs = gl..........完整代码请登录后点击上方下载按钮下载查看

网友评论0