three实现三维天空海面正方体粒子透明反射效果代码

代码语言:html

所属分类:三维

代码描述:three实现三维天空海面正方体粒子透明反射效果代码

代码标签: three 三维 天空 海面 正方体 粒子 透明 反射

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

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

<head>

  <meta charset="UTF-8">
  

  
<style>
@import url("https://fonts.googleapis.com/css?family=Homenaje");
.p-canvas-webgl {
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
}

.p-summary {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 2;
  color: #fff;
  font-family: "Homenaje", sans-serif;
}
.p-summary h1 {
  margin: 0 0 0.2em;
  font-size: 42px;
  font-weight: 400;
  letter-spacing: 0.05em;
}
.p-summary p {
  margin: 0;
  font-size: 1.1rem;
  letter-spacing: 0.1em;
}
.p-summary a {
  color: #fff;
}
</style>



</head>

<body  >
  <div class="p-summary">
  <h1>three.js Instancing & SkyBox</h1>

</div>
<canvas class="p-canvas-webgl" id="canvas-webgl"></canvas>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.84.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gl-matrix-min.js"></script>
      <script  >
const debounce = (callback, duration) => {
  var timer;
  return function (event) {
    clearTimeout(timer);
    timer = setTimeout(function () {
      callback(event);
    }, duration);
  };
};

const MathEx = {
  degrees: function (radian) {
    return radian / Math.PI * 180;
  },
  radians: function (degree) {
    return degree * Math.PI / 180;
  },
  clamp: function (value, min, max) {
    return Math.min(Math.max(value, min), max);
  },
  mix: function (x1, x2, a) {
    return x1 * (1 - a) + x2 * a;
  },
  polar: function (radian1, radian2, radius) {
    return [
    Math.cos(radian1) * Math.cos(radian2) * radius,
    Math.sin(radian1) * radius,
    Math.cos(radian1) * Math.sin(radian2) * radius];

  } };


const force3 = {
  updateVelocity: (velocity, acceleration, mass) => {
    vec3.scale(acceleration, acceleration, 1 / mass);
    vec3.add(velocity, velocity, acceleration);
  },
  applyFriction: (acceleration, mu, n) => {
    const friction = [0, 0, 0];
    vec3.scale(friction, acceleration, -1);
    const normal = n ? n : 1;
    vec3.normalize(friction, friction);
    vec3.scale(friction, friction, mu);
    vec3.add(acceleration, acceleration, friction);
  },
  applyDrag: (acceleration, value) => {
    const drag = [0, 0, 0];
    vec3.scale(drag, acceleration, -1);
    vec3.normalize(drag, drag);
    vec3.scale(drag, drag, vec3.length(acceleration) * value);
    vec3.add(acceleration, acceleration, drag);
  },
  applyHook: (velocity, acceleration, anchor, rest_length, k) => {
    const hook = [0, 0, 0];
    vec3.sub(hook, velocity, anchor);
    const distance = vec3.length(hook) - rest_length;
    vec3.normalize(hook, hook);
    vec3.scale(hook, hook, -1 * k * distance);
    vec3.add(acceleration, acceleration, hook);
  } };


const normalizeVector2 = vector => {
  vector.x = vector.x / window.innerWidth * 2 - 1;
  vector.y = -(vector.y / window.innerHeight) * 2 + 1;
};

class ForcePerspectiveCamera extends THREE.PerspectiveCamera {
  constructor(fov, aspect, near, far) {
    super(fov, aspect, near, far);
    this.k = 0.02;
    this.d = 0.2;
    this.velocity = [0, 0, 0];
    this.acceleration = [0, 0, 0];
    this.anchor = [0, 0, 0];
    this.lookK = 0.02;
    this.lookD = 0.2;
    this.lookVelocity = [0, 0, 0];
    this.lookAcceleration = [0, 0, 0];
    this.lookAnchor = [0, 0, 0];
  }
  updatePosition() {
    force3.applyHook(this.velocity, this.acceleration, this.anchor, 0, this.k);
    force3.applyDrag(this.acceleration, this.d);
    force3.updateVelocity(this.velocity, this.acceleration, 1);
  }
  updateLook() {
    force3.applyHook(this.lookVelocity, this.lookAcceleration, this.lookAnchor, 0, this.lookK);
    force3.applyDrag(this.lookAcceleration, this.lookD);
    force3.updateVelocity(this.lookVelocity, this.lookAcceleration, 1);
  }
  render() {
    this.updatePosition();
    this.updateLook();
    this.position.set(
    this.velocity[0],
    this.velocity[1],
    this.velocity[2]);

    this.lookAt({
      x: this.lookVelocity[0],
      y: this.lookVelocity[1],
      z: this.lookVelocity[2] });

  }}


class CameraController {
  constructor(camera) {
    this.camera = camera;
    this.radian1 = 0;
    this.radian1Base = 0;
    this.radian2 = 0;
    this.radian2Base = 0;
    this.radius = 2500;
    this.isZoom = false;
  }
  rotate(x, y) {
    if (this.isZoom === true) this.isZoom = false;
    this.radian1 = MathEx.clamp(this.radian1Base + y, MathEx.radians(-75), MathEx.radians(75));
    this.radian2 = this.radian2Base - x * 2;
  }
  zoom(delta) {
    if (!delta) return;
    if (this.isZoom === false) this.isZoom = true;
    const prevRadius = this.radius;
    this.radius -= delta / Math.abs(delta) * 200;
    this.radius = MathEx.clamp(this.radius, 700, 8000);
    const diff = prevRadius - this.radius;
  }
  touchEnd() {
    this.radian1Base = this.radian1;
    this.radian2Base = this.radian2;
  }
  render() {
    this.camera.anchor = MathEx.polar(this.radian1, this.radian2, this.radius);
    this.camera.render();
  }
  computeZoomLength() {
    if (this.isZoom) {
      return vec3.length(this.camera.acceleration) * 0.05;
    } else {
      return 0;
    }
  }
  computeAcceleration() {
    return vec3.length(this.camera.acceleration) * 0.05;
  }}
;

class Debris {
  constructor() {
    this.uniforms = {
      time: {
        type: 'f',
        value: 0 },

      cubeTex: {
        type: 't',
        value: null } };


    this.instances = 1000;
    this.obj = null;
  }
  init(texture) {
    this.uniforms.cubeTex.value = texture;
    this.obj = this.createObj();
  }
  createObj() {
    const geometry = new THREE.InstancedBufferGeometry();
    const baseGeometry = new THREE.BoxBufferGeometry(10, 10, 10);
    geometry.addAttribute('position', baseGeometry.attributes.position);
    geometry.addAttribute('normal', baseGeometry.attributes.normal);
    geometry.setIndex(baseGeometry.index);
    const translate = new THREE.InstancedBufferAttribute(new Float32Array(this.instances * 3), 3, 1);
    const offsets = new THREE.InstancedBufferAttribute(new Float32Array(this.instances), 1, 1);
    const rotates = new THREE.InstancedBufferAttribute(new Float32Array(this.instances * 3), 3, 1);
    for (var i = 0, ul = offsets.count; i < ul; i++) {
      const polar = MathEx.polar(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 3000 + 100);
      translate.setXYZ(i, polar[0], polar[1], polar[2]);
      offsets.setXYZ(i, Math.random() * 100);
      rotates.setXYZ(i, Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
    }
    geometry.addAttribute('translate', translate);
    geometry.addAttribute('offset', offsets);
    geometry.addAttribute('rotate', rotates);
    return new THREE.Mesh(
    geometry,
    new THREE.RawShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: `attribute vec3 position;
        attribute vec3 normal;
        attribute vec3 translate;
        attribute float offset;
        attribute vec3 rotate;

        uniform mat4 projectionMatrix;
        uniform mat4 modelViewMatrix;
        uniform mat4 modelMatrix;
        uniform float time;

        varying vec3 vPosition;
        varying vec3 vNormal;

        mat4 computeTranslateMat(vec3 v) {
          return mat4(
            1.0, 0.0, 0.0, 0.0,
            0.0, 1.0, 0.0, 0.0,
            0.0, 0.0, 1.0, 0.0,
            v.x, v.y, v.z, 1.0
          );
        }
        mat4 computeRotateMatX(float radian) {
          return mat4(
            1.0, 0.0, 0.0, 0.0,
            0.0, cos(radian), -sin(radian), 0.0,
            0.0, sin(radian), cos(radian), 0.0,
            0.0, 0.0, 0.0, 1.0
          );
        }
        mat4 computeRotateMatY(float radian) {
          return mat4(
            cos(radian), 0.0, sin(radian), 0.0,
            0.0, 1.0, 0.0, 0.0,
            -sin(radian), 0.0, cos(radian), 0.0,
            0.0, 0.0, 0.0, 1.0
          );
        }
        mat4 computeRotateMatZ(float radian) {
          return mat4(
            cos(radian), -sin(radian), 0.0, 0.0,
            sin(radian), cos(radian), 0.0, 0.0,
            0.0, 0.0, 1.0, 0.0,
            0.0, 0.0, 0.0, 1.0
          );
        }
        mat4 computeRotateMat(float radX, float radY, float radZ) {
          return computeRotateMatX(radX) * computeRotateMatY(radY) * computeRotateMatZ(radZ);
        }

        void main(void) {
          float radian = radians(time);
          mat4 rotateWorld = computeRotateMat(radian * 5.0 + rotate.x, radian * 20.0 + rotate.y, radian + rotate.z);
          mat4 rotateSelf = computeRotateMat(radian * rotate.x * 100.0, radian * rotate.y * 100.0, radian * rotate.z * 100.0);
          vec4 updatePosition =
            rotateWorld
            * computeTranslateMat(translate)
            * rotateSelf
            * vec4(position + normalize(position) * offset, 1.0);
          vPosition = (modelMatrix * updatePosition).xyz;
          vNormal = (modelMatrix * rotateWorld * rotateSelf * vec4(normal, 1.0)).xyz;
          gl_Position = projectionMatrix * modelViewMatrix * updatePosition;
        }`,
      fragmentShader: `precision highp float;

        uniform vec3 cameraPosition;
        uniform float time;
        uniform samplerCube cubeTex;

        varying vec3 vPosition;
        varying vec3 vNormal;

        void main() {
          vec3 ref = reflect(vPosition - cameraPosition, vNormal);
          vec4 envColor = textureCube(cubeTex, ref);
          gl_FragColor = envColor * vec4(0.8, 1.0, 0.95, 0.7);
        }`,
      transparent: true,
      side: THREE.DoubleSide }));


  }
  render(time) {
    this.uniforms.time.value += time;
  }}
;

class SkyBox {
  constructor() {
    this.uniforms = {
      time: {
        type: 'f',
        value: 0 },

      cubeTex: {
        type: 't',
        value: null } };


    this.obj = null;
  }
  init(texture) {
    this.uniforms.cubeTex.value = texture;
    this.obj = this.createObj();
  }
  createObj() {
    return new THREE.Mesh(
    new THREE.BoxBufferGeometry(30000, 30000, 30000, 1, 1, 1),
    new THREE.RawShaderMaterial({
      uniforms: this.uniforms,
      vertexShader: `attribute vec3 position;
        attribute vec3 normal;
        attribute vec2 uv;

        uniform mat4 projectionMatrix;
        uniform mat4 modelViewMatrix;
        uniform float time;

        varying vec3 vPosition;

        void main(void) {
          vPosition = position;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }`,
      fragmentShader: `precision highp float;

        uniform samplerCube cubeTex;

        varying vec3 vPosition;

        void main() {
          vec3 normal = normalize(vPosition);
          vec4 color = textureCube(cubeTex, normal);
          gl_FragColor = color;
        }`,
      side: THREE.BackSide }));


  }
  render(time) {
    this.uniforms.time.value += time;
  }}


class PostEffect {
  constructor(texture) {
    this.uniforms = {
      time: {
        type: 'f',
        value: 0 },

      resolution: {
        type: 'v2',
        value: new THREE.Vector2(window.innerWidth, window.innerHeight) },

      texture: {
        type: 't',
        value: texture },

      strengthZoom: {
        type: 'f',
        value: 0 },

      strengthGlitch: {
        type: 'f',
        value: 0 } };


    this.obj = this.createObj();
  }
  createObj() {
    return new THREE.Mesh(
    new THREE.PlaneBuf.........完整代码请登录后点击上方下载按钮下载查看

网友评论0