UNPKG

nidza

Version:

Nidza.js is ultimate canvas2d+3d solution (Easy port any webgl or webgl2 script). In context of 3d graphics it is used for GLSL manipulation. Objective is low CPU usage price.

232 lines (195 loc) 7.36 kB
import {BaseShader} from './base-shader-component.js'; import { Osc } from "./operations.js"; export class ShaderComponent extends BaseShader { constructor( arg ) { super(); this.gl = arg.gl; console.log('Arg -> ', arg); // Just alias this.reloadBuffers = this.initBuffers; // params this.rotationX = new Osc(0, 360, 0.1, 'oscMin'); this.rotationX.setDelay(5) this.rotationY = new Osc(0, 360, 0.1, 'oscMin'); this.rotationY.setDelay(5) this.rotationZ = new Osc(0, 360, 0.1, 'oscMin'); this.rotationZ.setDelay(5) this.rotationX.regimeType = "CONST"; this.rotationZ.regimeType = "CONST"; this.rotationY.regimeType = "CONST"; this.rotator = { x: () => this.rotationX.getValue(), y: () => this.rotationY.getValue(), z: () => this.rotationZ.getValue() }; this.background = [0.5, 0.0, 0.0, 1.0]; this.vertexCount = 4; // cube default this.position = [-0.0, 0.0, -2.0]; this.geometry = [ 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, ]; this.colors = [ 1.0, 1.0, 1.0, 1.0, // white 1.0, 0.0, 0.0, 1.0, // red 0.0, 1.0, 0.0, 1.0, // green 0.0, 0.0, 1.0, 1.0, // blue ]; const shaderProgram = this.initShaderProgram(this.gl, this.initDefaultVSShader(), this.initDefaultFSShader()); this.programInfo = { program: shaderProgram, attribLocations: { vertexPosition: this.gl.getAttribLocation(shaderProgram, 'aVertexPosition'), vertexColor: this.gl.getAttribLocation(shaderProgram, 'aVertexColor'), }, uniformLocations: { projectionMatrix: this.gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), modelViewMatrix: this.gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), }, }; this.buffers = this.initBuffers(this.gl); this.draw(); console.log('ShaderComponent init default shader with single call draw.'); } // move it to common latter degToRad(degrees) { return degrees * Math.PI / 180; } reload() { this.buffers = this.reloadBuffers(this.gl); this.draw(); } initDefaultFSShader() { const fsSource = ` varying lowp vec4 vColor; void main(void) { gl_FragColor = vColor; } `; return fsSource; } initDefaultVSShader() { const vsSource = ` attribute vec4 aVertexPosition; attribute vec4 aVertexColor; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; varying lowp vec4 vColor; void main(void) { gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; vColor = aVertexColor; } `; return vsSource; } initBuffers(gl) { const positionBuffer = gl.createBuffer(); // Select the positionBuffer as the one to apply buffer // operations to from here out. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Now create an array of positions/geometry for the square. // geometry gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.geometry), gl.STATIC_DRAW); // Colors const colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colors), gl.STATIC_DRAW); return { position: positionBuffer, color: colorBuffer, } } draw() { this.gl.clearColor(this.background[0], this.background[1], this.background[2], this.background[3]); // Clear to black, fully opaque this.gl.clearDepth(1.0); // Clear everything this.gl.enable( this.gl.DEPTH_TEST ); // Enable depth testing this.gl.depthFunc( this.gl.LEQUAL ); // Near things obscure far things // Clear the canvas before we start drawing on it. this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); // Create a perspective matrix, a special matrix that is // used to simulate the distortion of perspective in a camera. // Our field of view is 45 degrees, with a width/height // ratio that matches the display size of the canvas // and we only want to see objects between 0.1 units // and 100 units away from the camera. const fieldOfView = 45 * Math.PI / 180; // in radians const aspect = this.gl.canvas.clientWidth / this.gl.canvas.clientHeight; const zNear = 0.1; const zFar = 100.0; const projectionMatrix = mat4.create(); // note: glmatrix.js always has the first argument // as the destination to receive the result. mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar); // Set the drawing position to the "identity" point, which is // the center of the scene. const modelViewMatrix = mat4.create(); // Now move the drawing position a bit to where we want to // start drawing the square. mat4.translate(modelViewMatrix, // destination matrix modelViewMatrix, // matrix to translate this.position ); // amount to translate mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.x()), [1,0,0]); mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.y()), [0,1,0]); mat4.rotate(modelViewMatrix, modelViewMatrix, this.degToRad(this.rotator.z()), [0,0,1]); // Tell WebGL how to pull out the positions/geometry from the position // buffer into the vertexPosition attribute. { const numComponents = 2; const type = this.gl.FLOAT; const normalize = false; const stride = 0; const offset = 0; this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.position); this.gl.vertexAttribPointer( this.programInfo.attribLocations.vertexPosition, numComponents, type, normalize, stride, offset); this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition); } // Tell WebGL how to pull out the colors from the color buffer // into the vertexColor attribute. { const numComponents = 4; const type = this.gl.FLOAT; const normalize = false; const stride = 0; const offset = 0; this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffers.color); this.gl.vertexAttribPointer( this.programInfo.attribLocations.vertexColor, numComponents, type, normalize, stride, offset); this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexColor); } // Tell WebGL to use our program when drawing this.gl.useProgram(this.programInfo.program); // Set the shader uniforms this.gl.uniformMatrix4fv( this.programInfo.uniformLocations.projectionMatrix, false, projectionMatrix ); this.gl.uniformMatrix4fv( this.programInfo.uniformLocations.modelViewMatrix, false, modelViewMatrix ); { const offset = 0; this.gl.drawArrays(this.gl.TRIANGLE_STRIP, offset, this.geometry.length / 2); } } }