matrix-engine
Version:
basic_timeline improved, VT func setup vide html element id with name arg.- DISABLE RAYCAST DEBUG TEST [2.3.3] Fix for GUI win desktop [2.3.0] DestrucMesh solution & loading convex objs for physics BASIC, SpriteAnimation CPU/texture solution added, Improv
324 lines (291 loc) • 14.8 kB
JavaScript
/**
* @description
* Optimisation for custom FShaders parts
* GLSL 1.3 for now
Interest links for explore post shader example live:
https://stackoverflow.com/questions/8166384/how-to-get-a-glow-shader-effect-in-opengl-es-2-0
*/
import {raycaster} from "../..";
import {world} from "../matrix-world";
import {E} from "../utility";
export function defineShader() {
return `#version 300 es
// Standard Matrix-engine Shaders attr
precision highp float;
in vec2 vTextureCoord;
in vec3 vLightWeighting;
uniform sampler2D uSampler;
uniform vec2 uSIZE;
uniform float uDelta;
uniform vec2 uMouse;
out vec4 outColor;
`;
};
export function defineShader1() {
return `precision highp float;
// Standard Matrix-engine Shaders attr
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
uniform vec2 uSIZE;
uniform float uDelta;
uniform vec2 uMouse;
`;
};
export var standardMatrixEngineShader = (object) => {
var lighting = true;
var localLooper = 0;
mat4.identity(object.mvMatrix);
world.mvPushMatrix(object.mvMatrix, world.mvMatrixStack);
if(object.isHUD === true) {
mat4.translate(object.mvMatrix, object.mvMatrix, object.position.worldLocation);
if(raycaster.checkingProcedureCalc) raycaster.checkingProcedureCalc(object);
} else {
if(App.camera.FirstPersonController == true) {
camera.setCamera(object)
} else if(App.camera.SceneController == true) {
camera.setSceneCamera(object)
}
mat4.translate(object.mvMatrix, object.mvMatrix, object.position.worldLocation);
if(raycaster.checkingProcedureCalc && typeof ray === 'undefined') raycaster.checkingProcedureCalc(object);
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(object.rotation.rx), object.rotation.getRotDirX());
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(object.rotation.ry), object.rotation.getRotDirY());
mat4.rotate(object.mvMatrix, object.mvMatrix, degToRad(object.rotation.rz), object.rotation.getRotDirZ());
}
// V
if(object.vertexPositionBuffer) {
world.GL.gl.bindBuffer(world.GL.gl.ARRAY_BUFFER, object.vertexPositionBuffer);
if(object.geometry.dynamicBuffer == true) {
world.GL.gl.bufferData(world.GL.gl.ARRAY_BUFFER, object.geometry.vertices, world.GL.gl.STATIC_DRAW);
}
world.GL.gl.vertexAttribPointer(object.shaderProgram.vertexPositionAttribute, object.vertexPositionBuffer.itemSize, world.GL.gl.FLOAT, false, 0, 0);
world.GL.gl.enableVertexAttribArray(object.shaderProgram.vertexPositionAttribute);
localLooper = localLooper + 1;
}
// C
if(object.vertexColorBuffer) {
world.GL.gl.bindBuffer(world.GL.gl.ARRAY_BUFFER, object.vertexColorBuffer);
world.GL.gl.vertexAttribPointer(object.shaderProgram.vertexColorAttribute, object.vertexColorBuffer.itemSize, world.GL.gl.FLOAT, false, 0, 0);
world.GL.gl.enableVertexAttribArray(object.shaderProgram.vertexColorAttribute);
localLooper = localLooper + 1;
}
// L
if(lighting && object.shaderProgram.useLightingUniform) {
world.GL.gl.uniform1i(object.shaderProgram.useLightingUniform, lighting);
/* Set the normals */
if(object.vertexNormalBuffer) {
world.GL.gl.bindBuffer(world.GL.gl.ARRAY_BUFFER, object.vertexNormalBuffer);
world.GL.gl.vertexAttribPointer(object.shaderProgram.vertexNormalAttribute, object.vertexNormalBuffer.itemSize, world.GL.gl.FLOAT, false, 0, 0);
world.GL.gl.enableVertexAttribArray(object.shaderProgram.vertexNormalAttribute);
localLooper = localLooper + 1;
}
/* Set the ambient light */
if(object.shaderProgram.ambientColorUniform) {
if(E('ambLightR')) {
world.GL.gl.uniform3f(
object.shaderProgram.ambientColorUniform,
parseFloat(E('ambLightR').getAttribute('value')),
parseFloat(E('ambLightG').getAttribute('value')),
parseFloat(E('ambLightB').getAttribute('value'))
);
// console.log("LIGHTS UNIFORM AMB B = ", parseFloat(E('ambLightB').value) )
} else {
// object.LightsData.ambientLight
world.GL.gl.uniform3f(object.shaderProgram.ambientColorUniform, object.LightsData.ambientLight.r, object.LightsData.ambientLight.g, object.LightsData.ambientLight.b);
}
}
/* Directional light */
if(object.shaderProgram.directionalColorUniform) {
if(E('dirLightR')) {
world.GL.gl.uniform3f(
object.shaderProgram.directionalColorUniform,
parseFloat(E('dirLightR').getAttribute('value')),
parseFloat(E('dirLightG').getAttribute('value')),
parseFloat(E('dirLightB').getAttribute('value'))
);
} else {
world.GL.gl.uniform3f(object.shaderProgram.directionalColorUniform, object.LightsData.directionLight.R(), object.LightsData.directionLight.G(), object.LightsData.directionLight.B());
}
}
/* Normalize the direction */
var lightingDirection = null;
if(object.shaderProgram.lightingDirectionUniform) {
if(E('dirX') && E('dirY') && E('dirZ')) {
// console.log("LIGHTS UNIFORM AMB B = ", E('dirZ').value )
lightingDirection = [degToRad(parseFloat(E('dirX').getAttribute('value'))), degToRad(parseFloat(E('dirY').getAttribute('value'))), degToRad(parseFloat(E('dirZ').getAttribute('value')))];
} else {
lightingDirection = [object.LightsData.lightingDirection.r, object.LightsData.lightingDirection.g, object.LightsData.lightingDirection.b];
}
var adjustedLD = vec3.create();
vec3.normalize(adjustedLD, lightingDirection);
vec3.scale(adjustedLD, adjustedLD, -1);
world.GL.gl.uniform3fv(object.shaderProgram.lightingDirectionUniform, adjustedLD);
}
} else {
if(object.shaderProgram.useLightingUniform) {
if(object.shaderProgram.ambientColorUniform) {
world.GL.gl.uniform3f(object.shaderProgram.ambientColorUniform, parseFloat(0.2), parseFloat(0.2), parseFloat(0.2));
}
if(object.shaderProgram.directionalColorUniform) {
world.GL.gl.uniform3f(object.shaderProgram.directionalColorUniform, parseFloat(1), parseFloat(0), parseFloat(0));
}
}
}
// T
if(object.vertexTexCoordBuffer) {
world.GL.gl.bindBuffer(world.GL.gl.ARRAY_BUFFER, object.vertexTexCoordBuffer);
if(object.geometry.dynamicBuffer == true) {
world.GL.gl.bufferData(world.GL.gl.ARRAY_BUFFER, object.geometry.texCoords, world.GL.gl.STATIC_DRAW);
}
world.GL.gl.vertexAttribPointer(object.shaderProgram.textureCoordAttribute, object.vertexTexCoordBuffer.itemSize, world.GL.gl.FLOAT, false, 0, 0);
world.GL.gl.enableVertexAttribArray(object.shaderProgram.textureCoordAttribute);
if(object.streamTextures != null) {
if(object.streamTextures.video) {
App.tools.loadVideoTexture('glVideoTexture', object.streamTextures.video);
} else {
App.tools.loadVideoTexture('glVideoTexture', object.streamTextures.videoImage);
}
world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, 0);
} else if(object.FBO) {
// test FBO
world.GL.gl.activeTexture(world.GL.gl.TEXTURE0);
world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.FBO.FB.texture);
world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, 0);
} else {
for(var t = 0;t < object.textures.length;t++) {
if(object.custom.gl_texture == null) {
world.GL.gl.activeTexture(world.GL.gl['TEXTURE' + t]);
world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.textures[t]);
world.GL.gl.pixelStorei(world.GL.gl.UNPACK_FLIP_Y_WEBGL, false);
if(object.texParams.MIPMAP == false) {
world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_S, object.texParams.TEXTURE_WRAP_S | world.GL.gl.REPEAT);
world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_T, object.texParams.TEXTURE_WRAP_T | world.GL.gl.REPEAT);
// -- Allocate storage for the texture
// world.GL.gl.texStorage2D(world.GL.gl.TEXTURE_2D, 1, world.GL.gl.RGB8, 512, 512);
// world.GL.gl.texSubImage2D(world.GL.gl.TEXTURE_2D, 0, 0, 0,512, 512, world.GL.gl.RGB, world.GL.gl.UNSIGNED_BYTE, object.textures[t]);
} else {
world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MAG_FILTER, object.texParams.TEXTURE_MAG_FILTER | world.GL.gl.LINEAR);
world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MIN_FILTER, object.texParams.TEXTURE_MIN_FILTER | world.GL.gl.LINEAR);
world.GL.gl.generateMipmap(world.GL.gl.TEXTURE_2D);
}
if(world.GL.extTFAnisotropic && object.texParams.ANISOTROPIC == true) {
world.GL.gl.texParameterf(world.GL.gl.TEXTURE_2D,
world.GL.extTFAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
world.GL.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
}
//console.log('TEST' , object.texParams)
world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, t);
} else {
object.custom.gl_texture(object, t);
}
}
}
localLooper = localLooper + 1;
} else {
if(object.shaderProgram.samplerUniform) {
world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, 0);
} else if(object.shaderProgram.uCubeMapSampler) {
// CUBE MAP
world.GL.gl.activeTexture(world.GL.gl['TEXTURE0']);
var gl = world.GL.gl;
if(!object.tex) object.tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, object.tex);
if(object.cubeMap.type == 'images') {
object.cubeMap.cubeMap2dCanvasSet.forEach((faceInfo, index) => {
const level = 0;
const internalFormat = gl.RGBA;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(faceInfo.target, level, internalFormat, format, type, object.cubeMap.images[index]);
gl.pixelStorei(world.GL.gl.UNPACK_FLIP_Y_WEBGL, false);
});
} else {
object.cubeMap.cubeMap2dCanvasSet.forEach((faceInfo, index) => {
var args = [];
for(var key in faceInfo) {
if(key !== 'target') {
args.push(faceInfo[key]);
}
}
if(object.cubeMap.drawFunc) {
object.cubeMap.drawFunc(args);
} else {
const {faceColor, textColor, text} = faceInfo;
gen2DTextFace(object.cubeMap.cubeMap2dCtx, faceColor, textColor, text);
}
const level = 0;
const internalFormat = gl.RGBA;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(faceInfo.target, level, internalFormat, format, type, object.cubeMap.cubeMap2dCtx.canvas);
gl.pixelStorei(world.GL.gl.UNPACK_FLIP_Y_WEBGL, false);
});
}
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
world.GL.gl.uniform1i(object.shaderProgram.uCubeMapSampler, 0);
}
}
world.GL.gl.bindBuffer(world.GL.gl.ELEMENT_ARRAY_BUFFER, object.vertexIndexBuffer);
world.setMatrixUniforms(object, world.pMatrix);
// Shadows
if(object.shadows && object.shadows.type == 'spot' ||
object.shadows && object.shadows.type == 'spot-shadow') {
// set the light position
world.GL.gl.uniform3fv(object.shaderProgram.lightWorldPositionLocation, object.shadows.lightPosition);
world.GL.gl.uniform3fv(object.shaderProgram.viewWorldPositionLocation, object.shadows.lightPosition);
world.GL.gl.uniform1f(object.shaderProgram.shininessLocation, object.shadows.shininess);
// Set the spotlight uniforms
{
var target = [0, 0, 0]; // object.position.worldLocation;
var up = [0, 1, 0];
var lmat = m4.lookAt(object.shadows.lightPosition, target, up);
// var lmat = m4.lookAt(object.position.worldLocation, target, up);
lmat = m4.multiply(m4.xRotation(object.shadows.lightRotationX), lmat);
lmat = m4.multiply(m4.yRotation(object.shadows.lightRotationY), lmat);
// get the zAxis from the matrix
// negate it because lookAt looks down the -Z axis
object.shadows.lightDirection = [-lmat[8], -lmat[9], -lmat[10]];
// object.shadows.lightDirection = [-0, -0, -1];
}
world.GL.gl.uniform3fv(object.shaderProgram.lightDirectionLocation, object.shadows.lightDirection);
world.GL.gl.uniform1f(object.shaderProgram.innerLimitLocation, Math.cos(object.shadows.innerLimit));
world.GL.gl.uniform1f(object.shaderProgram.outerLimitLocation, Math.cos(object.shadows.outerLimit));
} else if(object.shadows && object.shadows.type == 'spec') {
world.GL.gl.uniform3fv(object.shaderProgram.specularColor, object.shadows.specularDATA);
world.GL.gl.uniform3fv(object.shaderProgram.uLightPosition, world.uLightPosition);
} else if(object.shadows && object.shadows.type == 'lens') {
world.GL.gl.uniform3fv(object.shaderProgram.uLightPosition, world.uLightPosition);
world.GL.gl.uniform3fv(object.shaderProgram.uControl, object.shadows.uControl);
world.GL.gl.uniform3fv(object.shaderProgram.uResolution, object.shadows.uResolution);
}
if(object.vertexNormalBuffer && object.shaderProgram.nMatrixUniform) {
var normalMatrix = mat3.create();
mat3.normalFromMat4(normalMatrix, object.mvMatrix);
mat3.transpose(normalMatrix, normalMatrix);
world.GL.gl.uniformMatrix3fv(object.shaderProgram.nMatrixUniform, false, normalMatrix);
}
world.disableUnusedAttr(world.GL.gl, localLooper);
if(object.glBlend.blendEnabled == true) {
if(!world.GL.gl.isEnabled(world.GL.gl.BLEND)) {
world.GL.gl.enable(world.GL.gl.BLEND);
}
world.GL.gl.blendFunc(world.GL.gl[object.glBlend.blendParamSrc], world.GL.gl[object.glBlend.blendParamDest]);
} else {
world.GL.gl.disable(world.GL.gl.BLEND);
world.GL.gl.enable(world.GL.gl.DEPTH_TEST);
// world.GL.gl.enable(world.GL.gl.CULL_FACE);
}
//
if(typeof object.addExtraDrawCode != 'undefined') object.addExtraDrawCode(world, object);
//
world.GL.gl.drawElements(world.GL.gl[object.glDrawElements.mode], object.glDrawElements.numberOfIndicesRender, world.GL.gl.UNSIGNED_SHORT, 0);
world.mvPopMatrix(object.mvMatrix, world.mvMatrixStack);
}
// Free shaders
// Personal learning...
export var buildinShaders = {};
buildinShaders.shaderTest = () => {
return `${defineShader()}
`
}