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