mirror of
https://github.com/photonstorm/phaser
synced 2025-02-17 06:28:30 +00:00
Merge branch 'master' of https://github.com/svipal/phaser into master
This commit is contained in:
commit
7ca2f9f10b
17 changed files with 727 additions and 397 deletions
|
@ -11,7 +11,9 @@ var GameObjectEvents = require('../events');
|
||||||
var GetCalcMatrix = require('../GetCalcMatrix');
|
var GetCalcMatrix = require('../GetCalcMatrix');
|
||||||
var MeshRender = require('./MeshRender');
|
var MeshRender = require('./MeshRender');
|
||||||
var MeshCamera = require('./MeshCamera');
|
var MeshCamera = require('./MeshCamera');
|
||||||
|
var MeshLight = require('./MeshLight');
|
||||||
var Model = require('../../geom/mesh/Model');
|
var Model = require('../../geom/mesh/Model');
|
||||||
|
var Vector3 = require('../../math/Vector3');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
|
@ -84,6 +86,8 @@ var Mesh = new Class({
|
||||||
*/
|
*/
|
||||||
this.camera = new MeshCamera(45, 0, 0, -10, 0.01, 1000);
|
this.camera = new MeshCamera(45, 0, 0, -10, 0.01, 1000);
|
||||||
|
|
||||||
|
this.light = new MeshLight();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of Model instances that have been created in this Mesh.
|
* An array of Model instances that have been created in this Mesh.
|
||||||
*
|
*
|
||||||
|
@ -152,7 +156,8 @@ var Mesh = new Class({
|
||||||
|
|
||||||
this.setSize(renderer.width, renderer.height);
|
this.setSize(renderer.width, renderer.height);
|
||||||
|
|
||||||
this.initPipeline();
|
// TODO - Change to const
|
||||||
|
this.initPipeline('MeshPipeline');
|
||||||
|
|
||||||
if (vertices)
|
if (vertices)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +329,7 @@ var Mesh = new Class({
|
||||||
|
|
||||||
var vertices = modelData.vertices;
|
var vertices = modelData.vertices;
|
||||||
var textureCoords = modelData.textureCoords;
|
var textureCoords = modelData.textureCoords;
|
||||||
|
var normals = modelData.vertexNormals;
|
||||||
var faces = modelData.faces;
|
var faces = modelData.faces;
|
||||||
|
|
||||||
var defaultUV1 = { u: 0, v: 1 };
|
var defaultUV1 = { u: 0, v: 1 };
|
||||||
|
@ -334,14 +340,20 @@ var Mesh = new Class({
|
||||||
{
|
{
|
||||||
var face = faces[i];
|
var face = faces[i];
|
||||||
|
|
||||||
|
// {textureCoordsIndex: 0, vertexIndex: 16, vertexNormalIndex: 16}
|
||||||
var v1 = face.vertices[0];
|
var v1 = face.vertices[0];
|
||||||
var v2 = face.vertices[1];
|
var v2 = face.vertices[1];
|
||||||
var v3 = face.vertices[2];
|
var v3 = face.vertices[2];
|
||||||
|
|
||||||
|
// {x: 0.19509, y: 0.980785, z: 0}
|
||||||
var m1 = vertices[v1.vertexIndex];
|
var m1 = vertices[v1.vertexIndex];
|
||||||
var m2 = vertices[v2.vertexIndex];
|
var m2 = vertices[v2.vertexIndex];
|
||||||
var m3 = vertices[v3.vertexIndex];
|
var m3 = vertices[v3.vertexIndex];
|
||||||
|
|
||||||
|
var n1 = normals[v1.vertexNormalIndex];
|
||||||
|
var n2 = normals[v2.vertexNormalIndex];
|
||||||
|
var n3 = normals[v3.vertexNormalIndex];
|
||||||
|
|
||||||
var t1 = v1.textureCoordsIndex;
|
var t1 = v1.textureCoordsIndex;
|
||||||
var t2 = v2.textureCoordsIndex;
|
var t2 = v2.textureCoordsIndex;
|
||||||
var t3 = v3.textureCoordsIndex;
|
var t3 = v3.textureCoordsIndex;
|
||||||
|
@ -350,9 +362,9 @@ var Mesh = new Class({
|
||||||
var uv2 = (t2 === -1) ? defaultUV2 : textureCoords[t2];
|
var uv2 = (t2 === -1) ? defaultUV2 : textureCoords[t2];
|
||||||
var uv3 = (t3 === -1) ? defaultUV3 : textureCoords[t3];
|
var uv3 = (t3 === -1) ? defaultUV3 : textureCoords[t3];
|
||||||
|
|
||||||
var vert1 = model.addVertex(originX + m1.x * scale, originY + m1.y * scale, originZ + m1.z * scale, uv1.u, uv1.v);
|
var vert1 = model.addVertex(originX + m1.x * scale, originY + m1.y * scale, originZ + m1.z * scale, uv1.u, uv1.v, n1.x, n1.y, n1.z);
|
||||||
var vert2 = model.addVertex(originX + m2.x * scale, originY + m2.y * scale, originZ + m2.z * scale, uv2.u, uv2.v);
|
var vert2 = model.addVertex(originX + m2.x * scale, originY + m2.y * scale, originZ + m2.z * scale, uv2.u, uv2.v, n2.x, n2.y, n2.z);
|
||||||
var vert3 = model.addVertex(originX + m3.x * scale, originY + m3.y * scale, originZ + m3.z * scale, uv3.u, uv3.v);
|
var vert3 = model.addVertex(originX + m3.x * scale, originY + m3.y * scale, originZ + m3.z * scale, uv3.u, uv3.v, n3.x, n3.y, n3.z);
|
||||||
|
|
||||||
model.addFace(vert1, vert2, vert3);
|
model.addFace(vert1, vert2, vert3);
|
||||||
}
|
}
|
||||||
|
@ -533,6 +545,7 @@ var Mesh = new Class({
|
||||||
|
|
||||||
var camera = this.camera;
|
var camera = this.camera;
|
||||||
|
|
||||||
|
/*
|
||||||
if (camera.dirty || width !== this._prevWidth || height !== this._prevHeight)
|
if (camera.dirty || width !== this._prevWidth || height !== this._prevHeight)
|
||||||
{
|
{
|
||||||
// Mesh has resized, flow that down to the Camera
|
// Mesh has resized, flow that down to the Camera
|
||||||
|
@ -541,6 +554,9 @@ var Mesh = new Class({
|
||||||
this._prevWidth = width;
|
this._prevWidth = width;
|
||||||
this._prevHeight = height;
|
this._prevHeight = height;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
camera.update(width, height);
|
||||||
|
|
||||||
var models = this.models;
|
var models = this.models;
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,10 @@ var MeshCamera = new Class({
|
||||||
this.up = new Vector4(); // What the up direction is, invert to get bottom
|
this.up = new Vector4(); // What the up direction is, invert to get bottom
|
||||||
this.right = new Vector4(); // What the right direction is, invert to get left
|
this.right = new Vector4(); // What the right direction is, invert to get left
|
||||||
|
|
||||||
this.matView = new Matrix4();
|
this.matrix = new Matrix4(); // the transform matrix
|
||||||
this.viewMatrix = new Matrix4();
|
this.viewMatrix = new Matrix4(); // the inverse of the transform matrix
|
||||||
this.projectionMatrix = new Matrix4();
|
this.projectionMatrix = new Matrix4(); // perspective projection matrix
|
||||||
|
this.viewProjectionMatrix = new Matrix4(); // perspective projection matrix multiplied by the view matrix
|
||||||
|
|
||||||
this.mode = MeshCamera.MODE_ORBIT;
|
this.mode = MeshCamera.MODE_ORBIT;
|
||||||
},
|
},
|
||||||
|
@ -88,30 +89,20 @@ var MeshCamera = new Class({
|
||||||
// To have different modes of movements, this function handles the view matrix update for the transform object.
|
// To have different modes of movements, this function handles the view matrix update for the transform object.
|
||||||
updateViewMatrix: function ()
|
updateViewMatrix: function ()
|
||||||
{
|
{
|
||||||
var d = Math.PI / 180;
|
var matView = this.matrix;
|
||||||
var matView = this.matView;
|
|
||||||
var rotation = this.rotation;
|
|
||||||
|
|
||||||
matView.identity();
|
|
||||||
|
|
||||||
// Optimize camera transform update, no need for scale nor rotateZ
|
|
||||||
if (this.mode === MeshCamera.MODE_FREE)
|
if (this.mode === MeshCamera.MODE_FREE)
|
||||||
{
|
{
|
||||||
matView.translate(this.position);
|
matView.fromRotationXYTranslation(this.rotation, this.position, true);
|
||||||
matView.rotateX(rotation.x * d);
|
|
||||||
matView.rotateY(rotation.y * d);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matView.rotateX(rotation.x * d);
|
matView.fromRotationXYTranslation(this.rotation, this.position, false);
|
||||||
matView.rotateY(rotation.y * d);
|
|
||||||
matView.translate(this.position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDirection();
|
this.updateDirection();
|
||||||
|
|
||||||
this.viewMatrix.copy(matView);
|
this.viewMatrix.copy(matView).invert();
|
||||||
this.viewMatrix.invert();
|
|
||||||
|
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
},
|
},
|
||||||
|
@ -120,28 +111,21 @@ var MeshCamera = new Class({
|
||||||
{
|
{
|
||||||
this.aspectRatio = width / height;
|
this.aspectRatio = width / height;
|
||||||
|
|
||||||
this.updateViewMatrix();
|
// TODO - Only needs changing when the fov/etc does
|
||||||
|
|
||||||
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
|
this.projectionMatrix.perspective(DegToRad(this._fov), this.aspectRatio, this._near, this._far);
|
||||||
|
|
||||||
|
// TODO - Only needs calculating when this camera is dirty
|
||||||
|
this.projectionMatrix.multiplyToMat4(this.viewMatrix, this.viewProjectionMatrix);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateDirection: function ()
|
updateDirection: function ()
|
||||||
{
|
{
|
||||||
var matView = this.matView;
|
var matView = this.matrix;
|
||||||
|
|
||||||
this.forward.set(0, 0, 1, 0).transformMat4(matView);
|
this.forward.set(0, 0, 1, 0).transformMat4(matView);
|
||||||
this.up.set(0, 1, 0, 0).transformMat4(matView);
|
this.up.set(0, 1, 0, 0).transformMat4(matView);
|
||||||
this.right.set(1, 0, 0, 0).transformMat4(matView);
|
this.right.set(1, 0, 0, 0).transformMat4(matView);
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function ()
|
|
||||||
{
|
|
||||||
this.position.set();
|
|
||||||
this.rotation.set();
|
|
||||||
|
|
||||||
this.updateViewMatrix();
|
|
||||||
},
|
|
||||||
|
|
||||||
fov: {
|
fov: {
|
||||||
|
|
||||||
get: function ()
|
get: function ()
|
||||||
|
|
103
src/gameobjects/mesh/MeshLight.js
Normal file
103
src/gameobjects/mesh/MeshLight.js
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* @author Richard Davey <rich@photonstorm.com>
|
||||||
|
* @copyright 2020 Photon Storm Ltd.
|
||||||
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Class = require('../../utils/Class');
|
||||||
|
var Vector3 = require('../../math/Vector3');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc
|
||||||
|
* The Mesh Light.
|
||||||
|
*
|
||||||
|
* @class MeshLight
|
||||||
|
* @memberof Phaser.GameObjects
|
||||||
|
* @constructor
|
||||||
|
* @since 3.50.0
|
||||||
|
*/
|
||||||
|
var MeshLight = new Class({
|
||||||
|
|
||||||
|
initialize:
|
||||||
|
|
||||||
|
function MeshLight (x, y, z)
|
||||||
|
{
|
||||||
|
this.position = new Vector3(x, y, z);
|
||||||
|
this.ambient = new Vector3(1, 1, 1);
|
||||||
|
this.diffuse = new Vector3(1, 1, 1);
|
||||||
|
this.specular = new Vector3(1, 1, 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
setPosition: function (x, y, z)
|
||||||
|
{
|
||||||
|
this.position.set(x, y, z);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setAmbient: function (r, g, b)
|
||||||
|
{
|
||||||
|
this.ambient.set(r, g, b);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setDiffuse: function (r, g, b)
|
||||||
|
{
|
||||||
|
this.diffuse.set(r, g, b);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
setSpecular: function (r, g, b)
|
||||||
|
{
|
||||||
|
this.specular.set(r, g, b);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
x: {
|
||||||
|
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this.position.x;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.position.x = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
y: {
|
||||||
|
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this.position.y;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.position.y = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
z: {
|
||||||
|
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this.position.z;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.position.z = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = MeshLight;
|
|
@ -4,8 +4,6 @@
|
||||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var GetCalcMatrix = require('../GetCalcMatrix');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
||||||
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
||||||
|
@ -20,7 +18,7 @@ var GetCalcMatrix = require('../GetCalcMatrix');
|
||||||
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
||||||
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
||||||
*/
|
*/
|
||||||
var MeshWebGLRenderer = function (renderer, src, camera, parentMatrix)
|
var MeshWebGLRenderer = function (renderer, src)
|
||||||
{
|
{
|
||||||
var models = src.models;
|
var models = src.models;
|
||||||
var totalModels = models.length;
|
var totalModels = models.length;
|
||||||
|
@ -30,88 +28,18 @@ var MeshWebGLRenderer = function (renderer, src, camera, parentMatrix)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderer.pipelines.clear();
|
||||||
|
|
||||||
var pipeline = renderer.pipelines.set(src.pipeline, src);
|
var pipeline = renderer.pipelines.set(src.pipeline, src);
|
||||||
|
|
||||||
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
|
|
||||||
|
|
||||||
var vertexOffset = (pipeline.vertexCount * pipeline.vertexComponentCount) - 1;
|
|
||||||
|
|
||||||
var debugVerts;
|
|
||||||
var debugCallback = src.debugCallback;
|
|
||||||
|
|
||||||
var a = calcMatrix.a;
|
|
||||||
var b = calcMatrix.b;
|
|
||||||
var c = calcMatrix.c;
|
|
||||||
var d = calcMatrix.d;
|
|
||||||
var e = calcMatrix.e;
|
|
||||||
var f = calcMatrix.f;
|
|
||||||
|
|
||||||
var F32 = pipeline.vertexViewF32;
|
|
||||||
var U32 = pipeline.vertexViewU32;
|
|
||||||
|
|
||||||
var globalAlpha = camera.alpha * src.alpha;
|
|
||||||
|
|
||||||
for (var m = 0; m < totalModels; m++)
|
for (var m = 0; m < totalModels; m++)
|
||||||
{
|
{
|
||||||
var model = models[m];
|
var model = models[m];
|
||||||
|
|
||||||
var faces = model.faces;
|
pipeline.drawModel(src, model);
|
||||||
var totalFaces = faces.length;
|
|
||||||
var alpha = globalAlpha * model.alpha;
|
|
||||||
|
|
||||||
if (totalFaces === 0 || !model.visible || alpha <= 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debugCallback)
|
|
||||||
{
|
|
||||||
debugVerts = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var tintEffect = model.tintFill;
|
|
||||||
var textureUnit = pipeline.setGameObject(model);
|
|
||||||
|
|
||||||
for (var i = 0; i < totalFaces; i++)
|
|
||||||
{
|
|
||||||
var face = faces[i];
|
|
||||||
|
|
||||||
if (model.hideCCW && !face.isCounterClockwise())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipeline.shouldFlush(3))
|
|
||||||
{
|
|
||||||
pipeline.flush();
|
|
||||||
|
|
||||||
vertexOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexOffset = face.vertex1.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
|
||||||
vertexOffset = face.vertex2.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
|
||||||
vertexOffset = face.vertex3.load(F32, U32, vertexOffset, textureUnit, tintEffect, alpha, a, b, c, d, e, f);
|
|
||||||
|
|
||||||
pipeline.vertexCount += 3;
|
|
||||||
|
|
||||||
if (debugCallback && model.drawDebug)
|
|
||||||
{
|
|
||||||
debugVerts.push(
|
|
||||||
F32[vertexOffset - 20],
|
|
||||||
F32[vertexOffset - 19],
|
|
||||||
F32[vertexOffset - 13],
|
|
||||||
F32[vertexOffset - 12],
|
|
||||||
F32[vertexOffset - 6],
|
|
||||||
F32[vertexOffset - 5]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debugCallback && model.drawDebug)
|
|
||||||
{
|
|
||||||
debugCallback.call(src, src, debugVerts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderer.pipelines.rebind();
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = MeshWebGLRenderer;
|
module.exports = MeshWebGLRenderer;
|
||||||
|
|
|
@ -8,9 +8,8 @@ var AnimationState = require('../../animations/AnimationState');
|
||||||
var Class = require('../../utils/Class');
|
var Class = require('../../utils/Class');
|
||||||
var Components = require('../../gameobjects/components');
|
var Components = require('../../gameobjects/components');
|
||||||
var Face = require('./Face');
|
var Face = require('./Face');
|
||||||
var GetCalcMatrix = require('../../gameobjects/GetCalcMatrix');
|
|
||||||
var Matrix4 = require('../../math/Matrix4');
|
var Matrix4 = require('../../math/Matrix4');
|
||||||
var StableSort = require('../../utils/array/StableSort');
|
var Quaternion = require('../../math/Quaternion');
|
||||||
var Vector3 = require('../../math/Vector3');
|
var Vector3 = require('../../math/Vector3');
|
||||||
var Vertex = require('./Vertex');
|
var Vertex = require('./Vertex');
|
||||||
var WrapAngle = require('../../math/angle/Wrap');
|
var WrapAngle = require('../../math/angle/Wrap');
|
||||||
|
@ -59,7 +58,7 @@ var Model = new Class({
|
||||||
*
|
*
|
||||||
* A Face consists of 3 Vertex objects.
|
* A Face consists of 3 Vertex objects.
|
||||||
*
|
*
|
||||||
* This array is populated during the `setVertices` method.
|
* This array is populated during the `addVertices` method.
|
||||||
*
|
*
|
||||||
* @name Phaser.Geom.Mesh.Model#faces
|
* @name Phaser.Geom.Mesh.Model#faces
|
||||||
* @type {Phaser.Geom.Mesh.Face[]}
|
* @type {Phaser.Geom.Mesh.Face[]}
|
||||||
|
@ -78,39 +77,18 @@ var Model = new Class({
|
||||||
*/
|
*/
|
||||||
this.vertices = [];
|
this.vertices = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* The tint fill mode.
|
|
||||||
*
|
|
||||||
* `false` = An additive tint (the default), where vertices colors are blended with the texture.
|
|
||||||
* `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.
|
|
||||||
*
|
|
||||||
* @name Phaser.Geom.Mesh.Model#tintFill
|
|
||||||
* @type {boolean}
|
|
||||||
* @default false
|
|
||||||
* @since 3.50.0
|
|
||||||
*/
|
|
||||||
this.tintFill = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When rendering, skip any Face that isn't counter clockwise?
|
|
||||||
*
|
|
||||||
* Enable this to hide backward-facing Faces during rendering.
|
|
||||||
* Disable it to render all Faces.
|
|
||||||
*
|
|
||||||
* @name Phaser.Geom.Mesh.Model#hideCCW
|
|
||||||
* @type {boolean}
|
|
||||||
* @since 3.50.0
|
|
||||||
*/
|
|
||||||
this.hideCCW = true;
|
|
||||||
|
|
||||||
this.drawDebug = true;
|
|
||||||
|
|
||||||
this.position = new Vector3(x, y, z);
|
this.position = new Vector3(x, y, z);
|
||||||
this.rotation = new Vector3();
|
|
||||||
this.scale = new Vector3(1, 1, 1);
|
this.scale = new Vector3(1, 1, 1);
|
||||||
|
this.rotation = new Quaternion();
|
||||||
|
|
||||||
this.dirtyCache = [ x, y, z, 0, 0, 0, 1, 1, 1, 0 ];
|
this.dirtyCache = [ x, y, z, 0, 0, 0, 0, 1, 1, 1, 0 ];
|
||||||
|
|
||||||
|
this.ambient = new Vector3(1, 1, 1);
|
||||||
|
this.diffuse = new Vector3(1, 1, 1);
|
||||||
|
this.specular = new Vector3(1, 1, 1);
|
||||||
|
this.shine = 0.25;
|
||||||
|
|
||||||
|
this.normalMatrix = new Matrix4();
|
||||||
this.transformMatrix = new Matrix4();
|
this.transformMatrix = new Matrix4();
|
||||||
|
|
||||||
if (!texture)
|
if (!texture)
|
||||||
|
@ -165,6 +143,7 @@ var Model = new Class({
|
||||||
var rx = rotation.x;
|
var rx = rotation.x;
|
||||||
var ry = rotation.y;
|
var ry = rotation.y;
|
||||||
var rz = rotation.z;
|
var rz = rotation.z;
|
||||||
|
var rw = rotation.w;
|
||||||
|
|
||||||
var sx = scale.x;
|
var sx = scale.x;
|
||||||
var sy = scale.y;
|
var sy = scale.y;
|
||||||
|
@ -179,12 +158,13 @@ var Model = new Class({
|
||||||
var rxCached = dirtyCache[3];
|
var rxCached = dirtyCache[3];
|
||||||
var ryCached = dirtyCache[4];
|
var ryCached = dirtyCache[4];
|
||||||
var rzCached = dirtyCache[5];
|
var rzCached = dirtyCache[5];
|
||||||
|
var rwCached = dirtyCache[6];
|
||||||
|
|
||||||
var sxCached = dirtyCache[6];
|
var sxCached = dirtyCache[7];
|
||||||
var syCached = dirtyCache[7];
|
var syCached = dirtyCache[8];
|
||||||
var szCached = dirtyCache[8];
|
var szCached = dirtyCache[9];
|
||||||
|
|
||||||
var fCached = dirtyCache[9];
|
var fCached = dirtyCache[10];
|
||||||
|
|
||||||
dirtyCache[0] = px;
|
dirtyCache[0] = px;
|
||||||
dirtyCache[1] = py;
|
dirtyCache[1] = py;
|
||||||
|
@ -193,43 +173,40 @@ var Model = new Class({
|
||||||
dirtyCache[3] = rx;
|
dirtyCache[3] = rx;
|
||||||
dirtyCache[4] = ry;
|
dirtyCache[4] = ry;
|
||||||
dirtyCache[5] = rz;
|
dirtyCache[5] = rz;
|
||||||
|
dirtyCache[6] = rw;
|
||||||
|
|
||||||
dirtyCache[6] = sx;
|
dirtyCache[7] = sx;
|
||||||
dirtyCache[7] = sy;
|
dirtyCache[8] = sy;
|
||||||
dirtyCache[8] = sz;
|
dirtyCache[9] = sz;
|
||||||
|
|
||||||
dirtyCache[9] = faces;
|
dirtyCache[10] = faces;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
pxCached !== px || pyCached !== py || pzCached !== pz ||
|
pxCached !== px || pyCached !== py || pzCached !== pz ||
|
||||||
rxCached !== rx || ryCached !== ry || rzCached !== rz ||
|
rxCached !== rx || ryCached !== ry || rzCached !== rz || rwCached !== rw ||
|
||||||
sxCached !== sx || syCached !== sy || szCached !== sz ||
|
sxCached !== sx || syCached !== sy || szCached !== sz ||
|
||||||
fCached !== faces
|
fCached !== faces
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
preUpdate: function (time, delta, camera, width, height)
|
preUpdate: function (time, delta)
|
||||||
{
|
{
|
||||||
this.anims.update(time, delta);
|
this.anims.update(time, delta);
|
||||||
|
|
||||||
if (!camera.dirty && !this.isDirty())
|
// If the model isn't dirty we can bail out and save lots of math
|
||||||
|
if (this.isDirty())
|
||||||
{
|
{
|
||||||
// If neither the camera or the model is dirty, we can bail out and save lots of math
|
var normalMatrix = this.normalMatrix;
|
||||||
return;
|
var transformMatrix = this.transformMatrix;
|
||||||
|
|
||||||
|
// TODO - No scale
|
||||||
|
transformMatrix.fromRotationTranslation(this.rotation, this.position);
|
||||||
|
transformMatrix.scale(this.scale);
|
||||||
|
|
||||||
|
normalMatrix.copy(transformMatrix);
|
||||||
|
normalMatrix.invert();
|
||||||
|
normalMatrix.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
var transformMatrix = this.transformMatrix;
|
|
||||||
|
|
||||||
transformMatrix.setWorldMatrix(this.rotation, this.position, this.scale, camera.viewMatrix, camera.projectionMatrix);
|
|
||||||
|
|
||||||
var vertices = this.vertices;
|
|
||||||
|
|
||||||
for (var i = 0; i < vertices.length; i++)
|
|
||||||
{
|
|
||||||
vertices[i].transformCoordinatesLocal(transformMatrix, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.depthSort();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,79 +250,6 @@ var Model = new Class({
|
||||||
return this.faces[index];
|
return this.faces[index];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an array of Face objects from this Mesh that intersect with the given coordinates.
|
|
||||||
*
|
|
||||||
* The given position is translated through the matrix of this Mesh and the given Camera,
|
|
||||||
* before being compared against the vertices.
|
|
||||||
*
|
|
||||||
* If more than one Face intersects, they will all be returned in the array, but the array will
|
|
||||||
* be depth sorted first, so the first element will always be that closest to the camera.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#getFaceAt
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {number} x - The x position to check against.
|
|
||||||
* @param {number} y - The y position to check against.
|
|
||||||
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not given, the default Scene Camera is used.
|
|
||||||
*
|
|
||||||
* @return {Phaser.Geom.Mesh.Face[]} An array of Face objects that intersect with the given point, ordered by depth.
|
|
||||||
*/
|
|
||||||
getFaceAt: function (x, y, camera, calcMatrix)
|
|
||||||
{
|
|
||||||
if (camera === undefined) { camera = this.scene.sys.cameras.main; }
|
|
||||||
if (calcMatrix === undefined) { calcMatrix = GetCalcMatrix(this.mesh, camera).calc; }
|
|
||||||
|
|
||||||
var faces = this.faces;
|
|
||||||
var results = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < faces.length; i++)
|
|
||||||
{
|
|
||||||
var face = faces[i];
|
|
||||||
|
|
||||||
if (face.contains(x, y, calcMatrix))
|
|
||||||
{
|
|
||||||
results.push(face);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return StableSort(results, this.sortByDepth);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a depth sort across all Faces in this Mesh, comparing their averaged depth.
|
|
||||||
*
|
|
||||||
* This is called automatically if you use any of the `rotate` methods, but you can
|
|
||||||
* also invoke it to sort the Faces should you manually position them.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#depthSort
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @return {this} This Mesh Game Object.
|
|
||||||
*/
|
|
||||||
depthSort: function ()
|
|
||||||
{
|
|
||||||
StableSort(this.faces, this.sortByDepth);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare the depth of two Faces.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#sortByDepth
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {Phaser.Geom.Mesh.Face} faceA - The first Face.
|
|
||||||
* @param {Phaser.Geom.Mesh.Face} faceB - The second Face.
|
|
||||||
*
|
|
||||||
* @return {integer} The difference between the depths of each Face.
|
|
||||||
*/
|
|
||||||
sortByDepth: function (faceA, faceB)
|
|
||||||
{
|
|
||||||
return faceA.depth - faceB.depth;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new Vertex into the vertices array of this Mesh.
|
* Adds a new Vertex into the vertices array of this Mesh.
|
||||||
*
|
*
|
||||||
|
@ -513,102 +417,6 @@ var Model = new Class({
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates all vertices of this Mesh around the X axis by the amount given.
|
|
||||||
*
|
|
||||||
* It then runs a depth sort on the faces before returning.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesX
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {number} theta - The amount to rotate by in radians.
|
|
||||||
*
|
|
||||||
* @return {this} This Mesh Game Object.
|
|
||||||
*/
|
|
||||||
rotateVerticesX: function (theta)
|
|
||||||
{
|
|
||||||
var ts = Math.sin(theta);
|
|
||||||
var tc = Math.cos(theta);
|
|
||||||
|
|
||||||
var verts = this.vertices;
|
|
||||||
|
|
||||||
for (var n = 0; n < verts.length; n++)
|
|
||||||
{
|
|
||||||
var vert = verts[n];
|
|
||||||
var y = vert.y;
|
|
||||||
var z = vert.z;
|
|
||||||
|
|
||||||
vert.y = y * tc - z * ts;
|
|
||||||
vert.z = z * tc + y * ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.depthSort();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates all vertices of this Mesh around the Y axis by the amount given.
|
|
||||||
*
|
|
||||||
* It then runs a depth sort on the faces before returning.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesY
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {number} theta - The amount to rotate by in radians.
|
|
||||||
*
|
|
||||||
* @return {this} This Mesh Game Object.
|
|
||||||
*/
|
|
||||||
rotateVerticesY: function (theta)
|
|
||||||
{
|
|
||||||
var ts = Math.sin(theta);
|
|
||||||
var tc = Math.cos(theta);
|
|
||||||
|
|
||||||
var verts = this.vertices;
|
|
||||||
|
|
||||||
for (var n = 0; n < verts.length; n++)
|
|
||||||
{
|
|
||||||
var vert = verts[n];
|
|
||||||
var x = vert.x;
|
|
||||||
var z = vert.z;
|
|
||||||
|
|
||||||
vert.x = x * tc - z * ts;
|
|
||||||
vert.z = z * tc + x * ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.depthSort();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates all vertices of this Mesh around the Z axis by the amount given.
|
|
||||||
*
|
|
||||||
* It then runs a depth sort on the faces before returning.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#rotateVerticesZ
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {number} theta - The amount to rotate by in radians.
|
|
||||||
*
|
|
||||||
* @return {this} This Mesh Game Object.
|
|
||||||
*/
|
|
||||||
rotateVerticesZ: function (theta)
|
|
||||||
{
|
|
||||||
var ts = Math.sin(theta);
|
|
||||||
var tc = Math.cos(theta);
|
|
||||||
|
|
||||||
var verts = this.vertices;
|
|
||||||
|
|
||||||
for (var n = 0; n < verts.length; n++)
|
|
||||||
{
|
|
||||||
var vert = verts[n];
|
|
||||||
var x = vert.x;
|
|
||||||
var y = vert.y;
|
|
||||||
|
|
||||||
vert.x = x * tc - y * ts;
|
|
||||||
vert.y = y * tc + x * ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.depthSort();
|
|
||||||
},
|
|
||||||
|
|
||||||
x: {
|
x: {
|
||||||
|
|
||||||
get: function ()
|
get: function ()
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Class = require('../../utils/Class');
|
var Class = require('../../utils/Class');
|
||||||
var Vector3 = require('../../math/Vector3');
|
|
||||||
var Utils = require('../../renderer/webgl/Utils');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
|
@ -17,7 +15,6 @@ var Utils = require('../../renderer/webgl/Utils');
|
||||||
*
|
*
|
||||||
* @class Vertex
|
* @class Vertex
|
||||||
* @memberof Phaser.Geom.Mesh
|
* @memberof Phaser.Geom.Mesh
|
||||||
* @extends Phaser.Math.Vector3
|
|
||||||
* @constructor
|
* @constructor
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*
|
*
|
||||||
|
@ -31,43 +28,69 @@ var Utils = require('../../renderer/webgl/Utils');
|
||||||
*/
|
*/
|
||||||
var Vertex = new Class({
|
var Vertex = new Class({
|
||||||
|
|
||||||
Extends: Vector3,
|
|
||||||
|
|
||||||
initialize:
|
initialize:
|
||||||
|
|
||||||
function Vertex (x, y, z, u, v, color, alpha)
|
function Vertex (x, y, z, u, v, normalX, normalY, normalZ, color, alpha)
|
||||||
{
|
{
|
||||||
|
if (normalX === undefined) { normalX = 0; }
|
||||||
|
if (normalY === undefined) { normalY = 0; }
|
||||||
|
if (normalZ === undefined) { normalZ = 0; }
|
||||||
if (color === undefined) { color = 0xffffff; }
|
if (color === undefined) { color = 0xffffff; }
|
||||||
if (alpha === undefined) { alpha = 1; }
|
if (alpha === undefined) { alpha = 1; }
|
||||||
|
|
||||||
Vector3.call(this, x, y, z);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The projected x coordinate of this vertex.
|
* The x coordinate of this vertex.
|
||||||
*
|
*
|
||||||
* @name Phaser.Geom.Mesh.Vertex#vx
|
* @name Phaser.Geom.Mesh.Vertex#vx
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*/
|
*/
|
||||||
this.vx = 0;
|
this.x = x;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The projected y coordinate of this vertex.
|
* The y coordinate of this vertex.
|
||||||
*
|
*
|
||||||
* @name Phaser.Geom.Mesh.Vertex#vy
|
* @name Phaser.Geom.Mesh.Vertex#vy
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*/
|
*/
|
||||||
this.vy = 0;
|
this.y = y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The projected z coordinate of this vertex.
|
* The z coordinate of this vertex.
|
||||||
*
|
*
|
||||||
* @name Phaser.Geom.Mesh.Vertex#vz
|
* @name Phaser.Geom.Mesh.Vertex#vz
|
||||||
* @type {number}
|
* @type {number}
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*/
|
*/
|
||||||
this.vz = 0;
|
this.z = z;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The x normal of this vertex.
|
||||||
|
*
|
||||||
|
* @name Phaser.Geom.Mesh.Vertex#nx
|
||||||
|
* @type {number}
|
||||||
|
* @since 3.50.0
|
||||||
|
*/
|
||||||
|
this.nx = normalX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The y normal of this vertex.
|
||||||
|
*
|
||||||
|
* @name Phaser.Geom.Mesh.Vertex#ny
|
||||||
|
* @type {number}
|
||||||
|
* @since 3.50.0
|
||||||
|
*/
|
||||||
|
this.ny = normalY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The z normal of this vertex.
|
||||||
|
*
|
||||||
|
* @name Phaser.Geom.Mesh.Vertex#nz
|
||||||
|
* @type {number}
|
||||||
|
* @since 3.50.0
|
||||||
|
*/
|
||||||
|
this.nz = normalZ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UV u coordinate of this vertex.
|
* UV u coordinate of this vertex.
|
||||||
|
@ -115,7 +138,6 @@ var Vertex = new Class({
|
||||||
* @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex.
|
* @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex.
|
||||||
* @param {number} width - The width of the parent Mesh.
|
* @param {number} width - The width of the parent Mesh.
|
||||||
* @param {number} height - The height of the parent Mesh.
|
* @param {number} height - The height of the parent Mesh.
|
||||||
*/
|
|
||||||
transformCoordinatesLocal: function (transformMatrix, width, height)
|
transformCoordinatesLocal: function (transformMatrix, width, height)
|
||||||
{
|
{
|
||||||
var x = this.x;
|
var x = this.x;
|
||||||
|
@ -133,39 +155,7 @@ var Vertex = new Class({
|
||||||
this.vy = -(ty / tw) * height;
|
this.vy = -(ty / tw) * height;
|
||||||
this.vz = (tz / tw);
|
this.vz = (tz / tw);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads this vertex into the given Typed Arrays.
|
|
||||||
*
|
|
||||||
* @method Phaser.Geom.Mesh.Model#load
|
|
||||||
* @since 3.50.0
|
|
||||||
*
|
|
||||||
* @param {Float32Array} F32 - The Float32 Array to put the position data in.
|
|
||||||
* @param {Uint32Array} U32 - The Uint32 Array to put the color data in.
|
|
||||||
* @param {number} offset - The vertex offset to place the data at.
|
|
||||||
* @param {number} textureUnit - The currently bound texture unit.
|
|
||||||
* @param {number} alpha - The alpha value.
|
|
||||||
* @param {number} a - The transform matrix a value.
|
|
||||||
* @param {number} b - The transform matrix b value.
|
|
||||||
* @param {number} c - The transform matrix c value.
|
|
||||||
* @param {number} d - The transform matrix d value.
|
|
||||||
* @param {number} e - The transform matrix e value.
|
|
||||||
* @param {number} f - The transform matrix f value.
|
|
||||||
*
|
|
||||||
* @return {number} The new vertex offset.
|
|
||||||
*/
|
*/
|
||||||
load: function (F32, U32, offset, textureUnit, tintEffect, alpha, a, b, c, d, e, f)
|
|
||||||
{
|
|
||||||
F32[++offset] = this.vx * a + this.vy * c + e;
|
|
||||||
F32[++offset] = this.vx * b + this.vy * d + f;
|
|
||||||
F32[++offset] = this.u;
|
|
||||||
F32[++offset] = this.v;
|
|
||||||
F32[++offset] = textureUnit;
|
|
||||||
F32[++offset] = tintEffect;
|
|
||||||
U32[++offset] = Utils.getTintAppendFloatAlpha(this.color, alpha * this.alpha);
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,90 @@ var Matrix4 = new Class({
|
||||||
return this.copy(src);
|
return this.copy(src);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO - Docs
|
||||||
|
fromRotationXYTranslation: function (rotation, position, translateFirst)
|
||||||
|
{
|
||||||
|
var x = position.x;
|
||||||
|
var y = position.y;
|
||||||
|
var z = position.z;
|
||||||
|
|
||||||
|
var sx = Math.sin(rotation.x);
|
||||||
|
var cx = Math.cos(rotation.x);
|
||||||
|
|
||||||
|
var sy = Math.sin(rotation.y);
|
||||||
|
var cy = Math.cos(rotation.y);
|
||||||
|
|
||||||
|
var a30 = x;
|
||||||
|
var a31 = y;
|
||||||
|
var a32 = z;
|
||||||
|
|
||||||
|
// Rotate X
|
||||||
|
|
||||||
|
var b21 = -sx;
|
||||||
|
|
||||||
|
// Rotate Y
|
||||||
|
|
||||||
|
var c01 = 0 - b21 * sy;
|
||||||
|
|
||||||
|
var c02 = 0 - cx * sy;
|
||||||
|
|
||||||
|
var c21 = b21 * cy;
|
||||||
|
|
||||||
|
var c22 = cx * cy;
|
||||||
|
|
||||||
|
// Translate
|
||||||
|
if (!translateFirst)
|
||||||
|
{
|
||||||
|
// a30 = cy * x + 0 * y + sy * z;
|
||||||
|
a30 = cy * x + sy * z;
|
||||||
|
a31 = c01 * x + cx * y + c21 * z;
|
||||||
|
a32 = c02 * x + sx * y + c22 * z;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.setValues(
|
||||||
|
cy,
|
||||||
|
c01,
|
||||||
|
c02,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cx,
|
||||||
|
sx,
|
||||||
|
0,
|
||||||
|
sy,
|
||||||
|
c21,
|
||||||
|
c22,
|
||||||
|
0,
|
||||||
|
a30,
|
||||||
|
a31,
|
||||||
|
a32,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
setValues: function (m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33)
|
||||||
|
{
|
||||||
|
var out = this.val;
|
||||||
|
|
||||||
|
out[0] = m00;
|
||||||
|
out[1] = m01;
|
||||||
|
out[2] = m02;
|
||||||
|
out[3] = m03;
|
||||||
|
out[4] = m10;
|
||||||
|
out[5] = m11;
|
||||||
|
out[6] = m12;
|
||||||
|
out[7] = m13;
|
||||||
|
out[8] = m20;
|
||||||
|
out[9] = m21;
|
||||||
|
out[10] = m22;
|
||||||
|
out[11] = m23;
|
||||||
|
out[12] = m30;
|
||||||
|
out[13] = m31;
|
||||||
|
out[14] = m32;
|
||||||
|
out[15] = m33;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the values of a given Matrix into this Matrix.
|
* Copy the values of a given Matrix into this Matrix.
|
||||||
*
|
*
|
||||||
|
@ -478,6 +562,69 @@ var Matrix4 = new Class({
|
||||||
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO - Docs
|
||||||
|
multiplyToMat4: function (src, out)
|
||||||
|
{
|
||||||
|
var a = this.val;
|
||||||
|
var b = src.val;
|
||||||
|
|
||||||
|
var a00 = a[0];
|
||||||
|
var a01 = a[1];
|
||||||
|
var a02 = a[2];
|
||||||
|
var a03 = a[3];
|
||||||
|
var a10 = a[4];
|
||||||
|
var a11 = a[5];
|
||||||
|
var a12 = a[6];
|
||||||
|
var a13 = a[7];
|
||||||
|
var a20 = a[8];
|
||||||
|
var a21 = a[9];
|
||||||
|
var a22 = a[10];
|
||||||
|
var a23 = a[11];
|
||||||
|
var a30 = a[12];
|
||||||
|
var a31 = a[13];
|
||||||
|
var a32 = a[14];
|
||||||
|
var a33 = a[15];
|
||||||
|
|
||||||
|
var b00 = b[0];
|
||||||
|
var b01 = b[1];
|
||||||
|
var b02 = b[2];
|
||||||
|
var b03 = b[3];
|
||||||
|
var b10 = b[4];
|
||||||
|
var b11 = b[5];
|
||||||
|
var b12 = b[6];
|
||||||
|
var b13 = b[7];
|
||||||
|
var b20 = b[8];
|
||||||
|
var b21 = b[9];
|
||||||
|
var b22 = b[10];
|
||||||
|
var b23 = b[11];
|
||||||
|
var b30 = b[12];
|
||||||
|
var b31 = b[13];
|
||||||
|
var b32 = b[14];
|
||||||
|
var b33 = b[15];
|
||||||
|
|
||||||
|
return out.setValues(
|
||||||
|
b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
|
||||||
|
b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
|
||||||
|
b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
|
||||||
|
b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
|
||||||
|
|
||||||
|
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
|
||||||
|
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
|
||||||
|
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
|
||||||
|
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
|
||||||
|
|
||||||
|
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
|
||||||
|
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
|
||||||
|
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
|
||||||
|
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
|
||||||
|
|
||||||
|
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
|
||||||
|
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
|
||||||
|
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
|
||||||
|
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiply this Matrix by the given Matrix.
|
* Multiply this Matrix by the given Matrix.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@ var CONST = require('./pipelines/const');
|
||||||
// Default Phaser 3 Pipelines
|
// Default Phaser 3 Pipelines
|
||||||
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
|
var BitmapMaskPipeline = require('./pipelines/BitmapMaskPipeline');
|
||||||
var LightPipeline = require('./pipelines/LightPipeline');
|
var LightPipeline = require('./pipelines/LightPipeline');
|
||||||
|
var MeshPipeline = require('./pipelines/MeshPipeline');
|
||||||
var MultiPipeline = require('./pipelines/MultiPipeline');
|
var MultiPipeline = require('./pipelines/MultiPipeline');
|
||||||
var RopePipeline = require('./pipelines/RopePipeline');
|
var RopePipeline = require('./pipelines/RopePipeline');
|
||||||
var SinglePipeline = require('./pipelines/SinglePipeline');
|
var SinglePipeline = require('./pipelines/SinglePipeline');
|
||||||
|
@ -131,6 +132,7 @@ var PipelineManager = new Class({
|
||||||
this.add(CONST.SINGLE_PIPELINE, new SinglePipeline({ game: game }));
|
this.add(CONST.SINGLE_PIPELINE, new SinglePipeline({ game: game }));
|
||||||
this.add(CONST.ROPE_PIPELINE, new RopePipeline({ game: game }));
|
this.add(CONST.ROPE_PIPELINE, new RopePipeline({ game: game }));
|
||||||
this.add(CONST.LIGHT_PIPELINE, new LightPipeline({ game: game }));
|
this.add(CONST.LIGHT_PIPELINE, new LightPipeline({ game: game }));
|
||||||
|
this.add(CONST.MESH_PIPELINE, new MeshPipeline({ game: game }));
|
||||||
|
|
||||||
this.set(this.MULTI_PIPELINE);
|
this.set(this.MULTI_PIPELINE);
|
||||||
},
|
},
|
||||||
|
|
|
@ -126,13 +126,19 @@ var WebGLPipeline = new Class({
|
||||||
this.vertexCapacity = GetFastValue(config, 'vertexCapacity', renderer.config.batchSize * 6);
|
this.vertexCapacity = GetFastValue(config, 'vertexCapacity', renderer.config.batchSize * 6);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size in bytes of a vertex.
|
* The size, in bytes, of a single vertex.
|
||||||
*
|
*
|
||||||
* Derived by adding together all of the vertex attributes.
|
* This is derived by adding together all of the vertex attributes.
|
||||||
*
|
*
|
||||||
* For example, the Texture Tint Pipeline has 2 + 2 + 1 + 1 + 4 for the attributes
|
* For example, the Multi Pipeline has the following attributes:
|
||||||
* `inPosition` (size 2), `inTexCoord` (size 2), `inTexId` (size 1), `inTintEffect` (size 1)
|
*
|
||||||
* and `inTint` (size 4), for a total of 28, which is the default for this property.
|
* inPosition - (size 2 x gl.FLOAT) = 8
|
||||||
|
* inTexCoord - (size 2 x gl.FLOAT) = 8
|
||||||
|
* inTexId - (size 1 x gl.FLOAT) = 4
|
||||||
|
* inTintEffect - (size 1 x gl.FLOAT) = 4
|
||||||
|
* inTint - (size 4 x gl.UNSIGNED_BYTE) = 4
|
||||||
|
*
|
||||||
|
* The total is 8 + 8 + 4 + 4 + 4 = 28, which is the default for this property.
|
||||||
*
|
*
|
||||||
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexSize
|
* @name Phaser.Renderer.WebGL.WebGLPipeline#vertexSize
|
||||||
* @type {integer}
|
* @type {integer}
|
||||||
|
@ -459,13 +465,16 @@ var WebGLPipeline = new Class({
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whenever this WebGL Pipeline is bound to a WebGL Renderer.
|
* This method is called every time a Game Object asks the Pipeline Manager to use this pipeline.
|
||||||
*
|
*
|
||||||
* This method is called every time the WebGL Pipeline is attempted to be bound, even if it already is the current pipeline.
|
* Unlike the `bind` method, which is only called once per frame, this is called for every object
|
||||||
|
* that requests it, allowing you to perform per-object GL set-up.
|
||||||
*
|
*
|
||||||
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
|
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*
|
*
|
||||||
|
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
|
||||||
|
*
|
||||||
* @return {this} This WebGLPipeline instance.
|
* @return {this} This WebGLPipeline instance.
|
||||||
*/
|
*/
|
||||||
onBind: function ()
|
onBind: function ()
|
||||||
|
|
190
src/renderer/webgl/pipelines/MeshPipeline.js
Normal file
190
src/renderer/webgl/pipelines/MeshPipeline.js
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/**
|
||||||
|
* @author Richard Davey <rich@photonstorm.com>
|
||||||
|
* @copyright 2020 Photon Storm Ltd.
|
||||||
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Class = require('../../../utils/Class');
|
||||||
|
var GetFastValue = require('../../../utils/object/GetFastValue');
|
||||||
|
var ShaderSourceFS = require('../shaders/Mesh-frag.js');
|
||||||
|
var ShaderSourceVS = require('../shaders/Mesh-vert.js');
|
||||||
|
var WebGLPipeline = require('../WebGLPipeline');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @class MeshPipeline
|
||||||
|
* @extends Phaser.Renderer.WebGL.WebGLPipeline
|
||||||
|
* @memberof Phaser.Renderer.WebGL.Pipelines
|
||||||
|
* @constructor
|
||||||
|
* @since 3.50.0
|
||||||
|
*
|
||||||
|
* @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
|
||||||
|
*/
|
||||||
|
var MeshPipeline = new Class({
|
||||||
|
|
||||||
|
Extends: WebGLPipeline,
|
||||||
|
|
||||||
|
initialize:
|
||||||
|
|
||||||
|
function MeshPipeline (config)
|
||||||
|
{
|
||||||
|
var gl = config.game.renderer.gl;
|
||||||
|
|
||||||
|
config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
|
||||||
|
config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
|
||||||
|
config.vertexCapacity = GetFastValue(config, 'vertexCapacity', 2048 * 8),
|
||||||
|
config.vertexSize = GetFastValue(config, 'vertexSize', 32),
|
||||||
|
config.attributes = GetFastValue(config, 'attributes', [
|
||||||
|
{
|
||||||
|
name: 'aVertexPosition',
|
||||||
|
size: 3,
|
||||||
|
type: gl.FLOAT,
|
||||||
|
normalized: false,
|
||||||
|
offset: 0,
|
||||||
|
enabled: false,
|
||||||
|
location: -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aVertexNormal',
|
||||||
|
size: 3,
|
||||||
|
type: gl.FLOAT,
|
||||||
|
normalized: false,
|
||||||
|
offset: 12,
|
||||||
|
enabled: false,
|
||||||
|
location: -1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aTextureCoord',
|
||||||
|
size: 2,
|
||||||
|
type: gl.FLOAT,
|
||||||
|
normalized: false,
|
||||||
|
offset: 24,
|
||||||
|
enabled: false,
|
||||||
|
location: -1
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
WebGLPipeline.call(this, config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Float32 view of the array buffer containing the pipeline's vertices.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Pipelines.MeshPipeline#vertexViewF32
|
||||||
|
* @type {Float32Array}
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
this.vertexViewF32 = new Float32Array(this.vertexData);
|
||||||
|
|
||||||
|
this.forceZero = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called every time the pipeline is bound by the renderer.
|
||||||
|
* Sets the shader program, vertex buffer and other resources.
|
||||||
|
* Should only be called when changing pipeline.
|
||||||
|
*
|
||||||
|
* @method Phaser.Renderer.WebGL.Pipelines.MeshPipeline#bind
|
||||||
|
* @since 3.50.0
|
||||||
|
*
|
||||||
|
* @param {boolean} [reset=false] - Should the pipeline be fully re-bound after a renderer pipeline clear?
|
||||||
|
*
|
||||||
|
* @return {this} This WebGLPipeline instance.
|
||||||
|
*/
|
||||||
|
bind: function (reset)
|
||||||
|
{
|
||||||
|
if (reset === undefined) { reset = false; }
|
||||||
|
|
||||||
|
WebGLPipeline.prototype.bind.call(this, reset);
|
||||||
|
|
||||||
|
var gl = this.gl;
|
||||||
|
|
||||||
|
gl.enable(gl.DEPTH_TEST);
|
||||||
|
gl.enable(gl.CULL_FACE);
|
||||||
|
gl.cullFace(gl.BACK);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called every time a Game Object asks the Pipeline Manager to use this pipeline.
|
||||||
|
*
|
||||||
|
* Unlike the `bind` method, which is only called once per frame, this is called for every object
|
||||||
|
* that requests it, allowing you to perform per-object GL set-up.
|
||||||
|
*
|
||||||
|
* @method Phaser.Renderer.WebGL.Pipelines.MeshPipeline#onBind
|
||||||
|
* @since 3.50.0
|
||||||
|
*
|
||||||
|
* @param {Phaser.GameObjects.Mesh} mesh - The Mesh that requested this pipeline.
|
||||||
|
*
|
||||||
|
* @return {this} This WebGLPipeline instance.
|
||||||
|
*/
|
||||||
|
onBind: function (mesh)
|
||||||
|
{
|
||||||
|
var program = this.program;
|
||||||
|
var renderer = this.renderer;
|
||||||
|
|
||||||
|
var camera = mesh.camera;
|
||||||
|
var light = mesh.light;
|
||||||
|
|
||||||
|
renderer.setMatrix4(program, 'uViewProjectionMatrix', false, camera.viewProjectionMatrix.val);
|
||||||
|
|
||||||
|
renderer.setFloat3(program, 'uLightPosition', light.x, light.y, light.z);
|
||||||
|
renderer.setFloat3(program, 'uLightAmbient', light.ambient.x, light.ambient.y, light.ambient.z);
|
||||||
|
renderer.setFloat3(program, 'uLightDiffuse', light.diffuse.x, light.diffuse.y, light.diffuse.z);
|
||||||
|
renderer.setFloat3(program, 'uLightSpecular', light.specular.x, light.specular.y, light.specular.z);
|
||||||
|
renderer.setFloat3(program, 'uCameraPosition', camera.x, camera.y, camera.z);
|
||||||
|
},
|
||||||
|
|
||||||
|
drawModel: function (mesh, model)
|
||||||
|
{
|
||||||
|
var program = this.program;
|
||||||
|
var renderer = this.renderer;
|
||||||
|
|
||||||
|
renderer.setMatrix4(program, 'uModelMatrix', false, model.transformMatrix.val);
|
||||||
|
renderer.setMatrix4(program, 'uNormalMatrix', false, model.normalMatrix.val);
|
||||||
|
|
||||||
|
renderer.setFloat3(program, 'uMaterialAmbient', model.ambient.x, model.ambient.y, model.ambient.z);
|
||||||
|
renderer.setFloat3(program, 'uMaterialDiffuse', model.diffuse.x, model.diffuse.y, model.diffuse.z);
|
||||||
|
renderer.setFloat3(program, 'uMaterialSpecular', model.specular.x, model.specular.y, model.specular.z);
|
||||||
|
renderer.setFloat1(program, 'uMaterialShine', model.shine);
|
||||||
|
|
||||||
|
renderer.setTextureZero(model.frame.glTexture);
|
||||||
|
renderer.setInt1(program, 'uTexture', 0);
|
||||||
|
|
||||||
|
// All the uniforms are finally bound, so now lets draw our faces!
|
||||||
|
|
||||||
|
var vertexViewF32 = this.vertexViewF32;
|
||||||
|
|
||||||
|
var vertices = model.vertices;
|
||||||
|
|
||||||
|
for (var i = 0; i < vertices.length; i++)
|
||||||
|
{
|
||||||
|
if (this.shouldFlush(1))
|
||||||
|
{
|
||||||
|
this.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;
|
||||||
|
|
||||||
|
var vert = vertices[i];
|
||||||
|
|
||||||
|
vertexViewF32[++vertexOffset] = vert.x;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.y;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.z;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.nx;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.ny;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.nz;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.u;
|
||||||
|
vertexViewF32[++vertexOffset] = vert.v;
|
||||||
|
|
||||||
|
this.vertexCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = MeshPipeline;
|
|
@ -156,7 +156,7 @@ var SinglePipeline = new Class({
|
||||||
|
|
||||||
var hasFlushed = false;
|
var hasFlushed = false;
|
||||||
|
|
||||||
if (this.vertexCount + 6 > this.vertexCapacity)
|
if (this.shouldFlush(6))
|
||||||
{
|
{
|
||||||
this.flush();
|
this.flush();
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ var SinglePipeline = new Class({
|
||||||
|
|
||||||
var hasFlushed = false;
|
var hasFlushed = false;
|
||||||
|
|
||||||
if (this.vertexCount + 3 > this.vertexCapacity)
|
if (this.shouldFlush(3))
|
||||||
{
|
{
|
||||||
this.flush();
|
this.flush();
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,17 @@ var PIPELINE_CONST = {
|
||||||
* @const
|
* @const
|
||||||
* @since 3.50.0
|
* @since 3.50.0
|
||||||
*/
|
*/
|
||||||
ROPE_PIPELINE: 'RopePipeline'
|
ROPE_PIPELINE: 'RopePipeline',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mesh Pipeline.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Pipelines.MESH_PIPELINE
|
||||||
|
* @type {string}
|
||||||
|
* @const
|
||||||
|
* @since 3.50.0
|
||||||
|
*/
|
||||||
|
MESH_PIPELINE: 'MeshPipeline'
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,11 @@ var Pipelines = {
|
||||||
|
|
||||||
BitmapMaskPipeline: require('./BitmapMaskPipeline'),
|
BitmapMaskPipeline: require('./BitmapMaskPipeline'),
|
||||||
LightPipeline: require('./LightPipeline'),
|
LightPipeline: require('./LightPipeline'),
|
||||||
SinglePipeline: require('./SinglePipeline'),
|
MeshPipeline: require('./MeshPipeline'),
|
||||||
|
ModelViewProjection: require('./components/ModelViewProjection'),
|
||||||
MultiPipeline: require('./MultiPipeline'),
|
MultiPipeline: require('./MultiPipeline'),
|
||||||
RopePipeline: require('./RopePipeline'),
|
RopePipeline: require('./RopePipeline'),
|
||||||
ModelViewProjection: require('./components/ModelViewProjection')
|
SinglePipeline: require('./SinglePipeline')
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
45
src/renderer/webgl/shaders/Mesh-frag.js
Normal file
45
src/renderer/webgl/shaders/Mesh-frag.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
module.exports = [
|
||||||
|
'#define SHADER_NAME PHASER_MESH_FS',
|
||||||
|
'',
|
||||||
|
'precision mediump float;',
|
||||||
|
'',
|
||||||
|
'uniform vec3 uLightPosition;',
|
||||||
|
'uniform vec3 uLightAmbient;',
|
||||||
|
'uniform vec3 uLightDiffuse;',
|
||||||
|
'uniform vec3 uLightSpecular;',
|
||||||
|
'',
|
||||||
|
'uniform vec3 uMaterialAmbient;',
|
||||||
|
'uniform vec3 uMaterialDiffuse;',
|
||||||
|
'uniform vec3 uMaterialSpecular;',
|
||||||
|
'uniform float uMaterialShine;',
|
||||||
|
'',
|
||||||
|
'uniform vec3 uCameraPosition;',
|
||||||
|
'',
|
||||||
|
'uniform sampler2D uTexture;',
|
||||||
|
'',
|
||||||
|
'varying vec2 vTextureCoord;',
|
||||||
|
'varying vec3 vNormal;',
|
||||||
|
'varying vec3 vPosition;',
|
||||||
|
'',
|
||||||
|
'void main (void)',
|
||||||
|
'{',
|
||||||
|
' vec4 color = texture2D(uTexture, vTextureCoord);',
|
||||||
|
'',
|
||||||
|
' vec3 ambient = uLightAmbient * uMaterialAmbient;',
|
||||||
|
'',
|
||||||
|
' vec3 norm = normalize(vNormal);',
|
||||||
|
' vec3 lightDir = normalize(uLightPosition - vPosition);',
|
||||||
|
' float diff = max(dot(norm, lightDir), 0.0);',
|
||||||
|
' vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);',
|
||||||
|
'',
|
||||||
|
' vec3 viewDir = normalize(uCameraPosition - vPosition);',
|
||||||
|
' vec3 reflectDir = reflect(-lightDir, norm);',
|
||||||
|
' float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);',
|
||||||
|
' vec3 specular = uLightSpecular * (spec * uMaterialSpecular);',
|
||||||
|
'',
|
||||||
|
' vec3 result = (ambient + diffuse + specular) * color.rgb;',
|
||||||
|
'',
|
||||||
|
' gl_FragColor = vec4(result, color.a);',
|
||||||
|
'}',
|
||||||
|
''
|
||||||
|
].join('\n');
|
29
src/renderer/webgl/shaders/Mesh-vert.js
Normal file
29
src/renderer/webgl/shaders/Mesh-vert.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = [
|
||||||
|
'#define SHADER_NAME PHASER_MESH_VS',
|
||||||
|
'',
|
||||||
|
'precision mediump float;',
|
||||||
|
'',
|
||||||
|
'attribute vec3 aVertexPosition;',
|
||||||
|
'attribute vec3 aVertexNormal;',
|
||||||
|
'attribute vec2 aTextureCoord;',
|
||||||
|
'',
|
||||||
|
'uniform mat4 uViewProjectionMatrix;',
|
||||||
|
'uniform mat4 uModelMatrix;',
|
||||||
|
'uniform mat4 uNormalMatrix;',
|
||||||
|
'',
|
||||||
|
'varying vec2 vTextureCoord;',
|
||||||
|
'varying vec3 vNormal;',
|
||||||
|
'varying vec3 vPosition;',
|
||||||
|
'',
|
||||||
|
'void main ()',
|
||||||
|
'{',
|
||||||
|
' vTextureCoord = aTextureCoord;',
|
||||||
|
'',
|
||||||
|
' vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));',
|
||||||
|
'',
|
||||||
|
' vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));',
|
||||||
|
'',
|
||||||
|
' gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);',
|
||||||
|
'}',
|
||||||
|
''
|
||||||
|
].join('\n');
|
42
src/renderer/webgl/shaders/src/Mesh.frag
Normal file
42
src/renderer/webgl/shaders/src/Mesh.frag
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#define SHADER_NAME PHASER_MESH_FS
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
uniform vec3 uLightPosition;
|
||||||
|
uniform vec3 uLightAmbient;
|
||||||
|
uniform vec3 uLightDiffuse;
|
||||||
|
uniform vec3 uLightSpecular;
|
||||||
|
|
||||||
|
uniform vec3 uMaterialAmbient;
|
||||||
|
uniform vec3 uMaterialDiffuse;
|
||||||
|
uniform vec3 uMaterialSpecular;
|
||||||
|
uniform float uMaterialShine;
|
||||||
|
|
||||||
|
uniform vec3 uCameraPosition;
|
||||||
|
|
||||||
|
uniform sampler2D uTexture;
|
||||||
|
|
||||||
|
varying vec2 vTextureCoord;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vPosition;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
vec4 color = texture2D(uTexture, vTextureCoord);
|
||||||
|
|
||||||
|
vec3 ambient = uLightAmbient * uMaterialAmbient;
|
||||||
|
|
||||||
|
vec3 norm = normalize(vNormal);
|
||||||
|
vec3 lightDir = normalize(uLightPosition - vPosition);
|
||||||
|
float diff = max(dot(norm, lightDir), 0.0);
|
||||||
|
vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);
|
||||||
|
|
||||||
|
vec3 viewDir = normalize(uCameraPosition - vPosition);
|
||||||
|
vec3 reflectDir = reflect(-lightDir, norm);
|
||||||
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);
|
||||||
|
vec3 specular = uLightSpecular * (spec * uMaterialSpecular);
|
||||||
|
|
||||||
|
vec3 result = (ambient + diffuse + specular) * color.rgb;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(result, color.a);
|
||||||
|
}
|
26
src/renderer/webgl/shaders/src/Mesh.vert
Normal file
26
src/renderer/webgl/shaders/src/Mesh.vert
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#define SHADER_NAME PHASER_MESH_VS
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
attribute vec3 aVertexPosition;
|
||||||
|
attribute vec3 aVertexNormal;
|
||||||
|
attribute vec2 aTextureCoord;
|
||||||
|
|
||||||
|
uniform mat4 uViewProjectionMatrix;
|
||||||
|
uniform mat4 uModelMatrix;
|
||||||
|
uniform mat4 uNormalMatrix;
|
||||||
|
|
||||||
|
varying vec2 vTextureCoord;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vPosition;
|
||||||
|
|
||||||
|
void main ()
|
||||||
|
{
|
||||||
|
vTextureCoord = aTextureCoord;
|
||||||
|
|
||||||
|
vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));
|
||||||
|
|
||||||
|
vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));
|
||||||
|
|
||||||
|
gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue