webgl实现球体运动效果

代码语言:html

所属分类:动画

代码描述:webgl实现球体运动效果,点击球体可进入球体内部视界

代码标签: 运动 效果

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<style>
body, html {
	position: absolute;
	margin: 0;
	padding: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

canvas {
	position: absolute;
	width: 100%;
	height: 100%;
	background:#000;
	cursor: pointer;
}
</style>

</head>
<body translate="no">

<script >
"use strict";
const webgl = {
  init() {
    this.elem = document.createElement("canvas");
    document.body.appendChild(this.elem);
    let gl = this.elem.getContext("webgl");
    if (!gl) gl = this.elem.getContext("experimental-webgl");
    if (!gl) return false;
    this.gl = gl;
    this.vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(
    this.vertexShader,
    `
				uniform mat4 camProj, camView;
				uniform mat4 model;
				attribute vec3 position;
				uniform vec4 modelColor;
				uniform vec3 light1Pos;
				uniform vec3 light1Color;
				uniform vec3 light2Pos;
				uniform vec3 light2Color;
				varying vec3 vLightWeighting;
				void main(void) {
					vec4 normal = model * vec4(position, 0.0);
					vec4 worldPosition = model * vec4(position, 1.0);
					vec3 lightDirection = normalize(light1Pos - worldPosition.xyz);
					float angle = max(dot(lightDirection, (camView * normal).xyz), 0.0);
					vLightWeighting = light1Color * angle * modelColor.rgb;
					lightDirection = normalize(light2Pos - worldPosition.xyz);
					angle = max(dot(lightDirection, normal.xyz), 0.0);
					vLightWeighting += light2Color * angle * modelColor.rgb;
					gl_Position = camProj * camView * worldPosition;
				}
				`);

    this.fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(
    this.fragmentShader,
    `
				precision highp float;
				uniform vec4 modelColor;
				varying vec3 vLightWeighting;
				void main(void) {
					vec3 col = modelColor.rgb * vLightWeighting;
					gl_FragColor = vec4(col.rgb, modelColor.a);
				}
				`);

    gl.compileShader(this.vertexShader);
    gl.compileShader(this.fragmentShader);
    this.program = gl.createProgram();
    gl.attachShader(this.program, this.vertexShader);
    gl.attachShader(this.program, this.fragmentShader);
    gl.linkProgram(this.program);
    gl.useProgram(this.program);
    this.camera = {
      pos: this.vec3(),
      mov: this.vec3(),
      proj: this.mat4().uniform("camProj"),
      view: this.mat4().uniform("camView") };

    this.resize();
    window.addEventListener("resize", () => this.resize(), false);
    return gl;
  },
  Attribute: class {
    constructor(name) {
      this.gl = webgl.gl;
      this.index = gl.getAttribLocation(webgl.program, name);
      gl.enableVertexAttribArray(this.index);
      this.buffer = gl.createBuffer();
      this.numElements = 0;
    }
    load(data, size, stride, offset) {
      this.itemSize = size;
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
      this.gl.bufferData(
      this.gl.ARRAY_BUFFER,
      data instanceof Array ? new Float32Array(data) : data,
      this.gl.STATIC_DRAW);

      this.numElements = data.length / size;
      this.gl.vertexAttribPointer(
      this.index,
      size,
      gl.FLOAT,
      false,
      stride,
      offset);

      return this.buffer;
    }
    loadIndices(indices) {
      if (!this.indices) this.indices = this.gl.createBuffer();
      this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indices);
      this.gl.bufferData(
      this.gl.ELEMENT_ARRAY_BUFFER,
      indices instanceof Array ? new Uint16Array(indices) : indices,
      this.gl.STATIC_DRAW);

      this.numElements = indices.length;
      return this.indices;
    }},

  resize() {
    this.width = this.elem.width = this.elem.offsetWidth;
    this.height = this.elem.height = this.elem.offsetHeight;
    this.aspect = this.width / this.height;
    this.camera.proj.perspective(60).load();
    this.gl.viewport(
    0,
    0,
    this.gl.drawingBufferWidth,
    this.gl.drawingBufferHeight);

  },
  mat4() {
    return new this.Mat4();
  },
  vec3(x, y, z) {
    return new this.Vec3(x, y, z);
  },
  vec4(x, y, z, w) {
    return new this.Vec4(x, y, z, w);
  },
  Mat4: class {
    constructor() {
      this.matrix = new Float32Array([
      1, 0, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, 1]);

      this.gl = webgl.gl;
      this.u = null;
    }
    identity() {
      const d = this.matrix;
      d[0] = 1;
      d[1] = 0;
      d[2] = 0;
      d[3] = 0;
      d[4] = 0;
      d[5] = 1;
      d[6] = 0;
      d[7] = 0;
      d[8] = 0;
      d[9] = 0;
      d[10] = 1;
      d[11] = 0;
      d[12] = 0;
      d[13] = 0;
      d[14] = 0;
      d[15] = 1;
      return this;
    }
    translate(x, y, z) {
      const d = this.matrix;
      d[12] = d[0] * x + d[4] * y + d[8] * z + d[12];
      d[13] = d[1] * x + d[5] * y + d[9] * z + d[13];
      d[14] = d[2] * x + d[6] * y + d[10] * z + d[14];
      d[15] = d[3] * x + d[7] * y + d[11] * z + d[15];
      return this;
    }
    fromTranslation(x, y, z) {
      const a = this.matrix;
      a[0] = 1;
      a[1] = 0;
      a[2] = 0;
      a[3] = 0;
      a[4] = 0;
      a[5] = 1;
      a[6] = 0;
      a[7] = 0;
      a[8] = 0;
      a[9] = 0;
      a[10] = 1;
      a[11] = 0;
      a[12] = x;
      a[13] = y;
      a[14] = z;
      a[15] = 1;
      return this;
    }
    rotateX(angle) {
      const d = this.matrix;
      const s = Math.sin(angle);
      const c = Math.cos(angle);
      const a10 = d[4];
      const a11 = d[5];
      const a12 = d[6];
      const a13 = d[7];
      const a20 = d[8];
      const a21 = d[9];
      const a22 = d[10];
      const a23 = d[11];
      d[4] = a10 * c + a20 * s;
      d[5] = a11 * c + a21 * s;
      d[6] = a12 * c + a22 * s;
      d[7] = a13 * c + a23 * s;
      d[8] = a10 * -s + a20 * c;
      d[9] = a11 * -s + a21 * c;
      d[10] = a12 * -s + a22 * c;
      d[11] = a13 * -s + a23 * c;
      return this;
    }
    rotateY(angle) {
      const d = this.matrix;
      const s = Math.sin(angle);
      const c = Math.cos(angle);
      const a00 = d[0];
      const a01 = d[1];
      const a02 = d[2];
      const a03 = d[3];
      const a20 = d[8];
      const a21 = d[9];
      const a22 = d[10];
      const a23 = d[11];
      d[0] = a00 * c + a20 * -s;
      d[1] = a01 * c + a21 * -s;
      d[2] = a02 * c + a22 * -s;
      d[3] = a03 * c + a23 * -s;
      d[8] = a00 * s + a20 * c;
      d[9] = a01 * s + a21 * c;
      d[10] = a02 * s + a22 * c;
      d[11] = a03 * s + a23 * c;
      return this;
    }
    rotateZ(angle) {
      const d = this.matrix;
      const s = Math.sin(angle);
      const c = Math.cos(angle);
      const a00 = d[0];
      const a01 = d[1];
      const a02 = d[2];
      const a03 = d[3];
      const a10 = d[4];
      const a11 = d[5];
      const a12 = d[6];
      const a13 = d[7];
      d[0] = a00 * c + a10 * s;
      d[1] = a01 * c + a11 * s;
      d[2] = a02 * c + a12 * s;
      d[3] = a03 * c + a13 * s;
      d[4] = a00 * -s + a10 * c;
      d[5] = a01 * -s + a11 * c;
      d[6] = a02 * -s + a12 * c;
      d[7] = a03 * -s + a13 * c;
      return this;
    }
    scale(x, y, z) {
      const d = this.matrix;
      d[0] *= x;
      d[1] *= x;
      d[2] *= x;
      d[3] *= x;
      d[4] *= y;
      d[5] *= y;
      d[6] *= y;
      d[7] *= y;
      d[8] *= z;
      d[9] *= z;
      d[10] *= z;
      d[11] *= z;
      return this;
    }
    perspective(fov) {
      const d = this.matrix;
      const near = 0.01;
      const far .........完整代码请登录后点击上方下载按钮下载查看

网友评论0