Skip to content

Commit

Permalink
Instanced geometry emitters
Browse files Browse the repository at this point in the history
All MDX geometry particles now use instancing.
This means that significantly less memory is required (~50%).
In addition, most of the emitted objects logic was moved into the new shader, making them a lot lighter on the CPU.
  • Loading branch information
flowtsohg committed Oct 2, 2019
1 parent d08e565 commit d8bbfa3
Show file tree
Hide file tree
Showing 45 changed files with 898 additions and 791 deletions.
Binary file modified clients/tests/compare/base-attachments.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-event-object-spl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-event-object-spn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-event-object-ubr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-base.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-line-emitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-repeat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-squirt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-tail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-particle-2-emitter-xy-quad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-ribbon-emitter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-sequence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-team-color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-texture-overriding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-vertex-and-team-colors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified clients/tests/compare/mdx-vertex-color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion clients/tests/mdx.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ let mdxTests = {

scene.addInstance(instance);

for (let i = 0; i < 205; i++) {
for (let i = 0; i < 170; i++) {
viewer.update();
}
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mdx-m3-viewer",
"version": "4.7.7",
"version": "4.8.0",
"description": "A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.",
"main": "src/index.js",
"directories": {
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import viewer from './viewer';
import utils from './utils';

export default {
version: '4.7.7',
version: '4.8.0',
common,
parsers,
viewer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/**
* A shared emitter.
* An emitter.
* The base class of all MDX emitters.
*/
export default class SharedEmitter {
export default class Emitter {
/**
* @param {ModelViewData} modelViewData
* @param {ParticleEmitter|ParticleEmitter2|RibbonEmitter|EventObject} modelObject
*/
constructor(modelObject) {
constructor(modelViewData, modelObject) {
/** @member {ModelViewData} */
this.modelViewData = modelViewData;
/** @member {ParticleEmitter|ParticleEmitter2|RibbonEmitter|EventObject} */
this.modelObject = modelObject;
/** @member {Array<Particle|Particle2|Ribbon|EventObjectSpn|EventObjectSpl|EventObjectUbr>} */
Expand All @@ -16,13 +19,13 @@ export default class SharedEmitter {
}

/**
* Note: flag is used for ParticleEmitter2's head/tail selection.
* Note: tail is used for ParticleEmitter2's head/tail selection.
*
* @param {ParticleEmitterView|ParticleEmitter2View|RibbonEmitterView|EventObjectEmitterView} emitterView
* @param {boolean} flag
* @param {number} tail
* @return {Particle|Particle2|Ribbon|EventObjectSpn|EventObjectSpl|EventObjectUbr}
*/
emitObject(emitterView, flag) {
emitObject(emitterView, tail) {
let objects = this.objects;

// If there are no unused objects, create a new one.
Expand All @@ -35,7 +38,7 @@ export default class SharedEmitter {

this.alive += 1;

object.reset(emitterView, flag);
object.bind(emitterView, tail);

return object;
}
Expand All @@ -44,27 +47,29 @@ export default class SharedEmitter {
*
*/
update() {
let dt = this.modelObject.model.viewer.frameTime * 0.001;
let objects = this.objects;
let offset = 0;

for (let i = 0; i < this.alive; i++) {
let object = objects[i];

object.update();
object.render(offset, dt);

if (object.health <= 0) {
if (object.health > 0) {
offset += 1;
} else {
this.alive -= 1;

// Swap between this object and the first unused object.
// Decrement the iterator so the moved object is indexed.
// Swap between this object and the last living object.
// Decrement the iterator so the swapped object is updated this frame.
if (i !== this.alive) {
objects[i] = objects[this.alive];
objects[this.alive] = object;
i -= 1;
}
}
}

this.updateData();
}

/**
Expand All @@ -80,13 +85,6 @@ export default class SharedEmitter {
}
}

/**
*
*/
updateData() {

}

/**
* @param {ModelView} modelView
* @param {ShaderProgram} shader
Expand Down
36 changes: 29 additions & 7 deletions src/viewer/handlers/mdx/emittergroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@
export default class EmitterGroup {
/**
* @param {ModelView} modelView
* @param {boolean} isRibbons
*/
constructor(modelView, isRibbons) {
constructor(modelView) {
/** @member {ModelView} */
this.modelView = modelView;
/** @member {Array<ParticleEmitter2|RibbonEmitter>} */
this.objects = [];
/** @member {boolean} */
this.isRibbons = isRibbons;
}

/**
Expand All @@ -21,8 +18,11 @@ export default class EmitterGroup {
render(modelViewData) {
let viewer = this.modelView.model.viewer;
let gl = viewer.gl;
let instancedArrays = gl.extensions.instancedArrays;
let modelView = modelViewData.modelView;
let shader = viewer.shaderMap.get('MdxParticleShader');
let uniforms = shader.uniforms;
let attribs = shader.attribs;

gl.depthMask(0);
gl.enable(gl.BLEND);
Expand All @@ -31,12 +31,34 @@ export default class EmitterGroup {

viewer.webgl.useShaderProgram(shader);

gl.uniformMatrix4fv(shader.uniforms.u_mvp, false, modelViewData.scene.camera.worldProjectionMatrix);
gl.uniform1i(shader.uniforms.u_texture, 0);
gl.uniform1f(shader.uniforms.u_isRibbonEmitter, this.isRibbons);
gl.uniformMatrix4fv(uniforms.u_mvp, false, modelViewData.scene.camera.worldProjectionMatrix);
gl.uniform1i(uniforms.u_texture, 0);

instancedArrays.vertexAttribDivisorANGLE(attribs.a_position, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, viewer.rectBuffer);
gl.vertexAttribPointer(attribs.a_position, 1, gl.UNSIGNED_BYTE, false, 0, 0);

instancedArrays.vertexAttribDivisorANGLE(attribs.a_p0, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p1, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p2, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p3, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_health, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_color, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_tail, 1);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_leftRightTop, 1);

for (let emitter of this.objects) {
emitter.render(modelView, shader);
}

instancedArrays.vertexAttribDivisorANGLE(attribs.a_leftRightTop, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_tail, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_color, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_health, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p3, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p2, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p1, 0);
instancedArrays.vertexAttribDivisorANGLE(attribs.a_p0, 0);
}
}
43 changes: 27 additions & 16 deletions src/viewer/handlers/mdx/eventobjectsndemitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,27 @@ export default class EventObjectSndEmitter {
*/
constructor(modelObject) {
this.modelObject = modelObject;
this.type = 'SND';

/**
* Does nothing.
* Defined to stay compatible with Emitter.
*
* @member {number}
*/
this.alive = 0;
}

/**
* @param {*} emitterView
*/
fill(emitterView) {
let emission = emitterView.currentEmission;

if (emission >= 1) {
for (let i = 0; i < emission; i += 1, emitterView.currentEmission--) {
this.emit(emitterView);
}
}
}

/**
Expand Down Expand Up @@ -43,26 +63,17 @@ export default class EventObjectSndEmitter {
}

/**
*
* Does nothing.
* Defined to stay compatible with Emitter.
*/
update() {

}

/**
* @param {*} emitterView
*/
fill(emitterView) {
let emission = emitterView.currentEmission;

if (emission >= 1) {
for (let i = 0; i < emission; i += 1, emitterView.currentEmission--) {
this.emit(emitterView);
}
}
}

/**
* Does nothing.
* Defined to stay compatible with Emitter.
*
* @param {ModelView} modelView
* @param {ShaderProgram} shader
*/
Expand All @@ -72,7 +83,7 @@ export default class EventObjectSndEmitter {

/**
* Does nothing.
* Defined to stay compatible with SharedEmitter.
* Defined to stay compatible with Emitter.
*
* @param {ModelInstance} owner
*/
Expand Down
106 changes: 0 additions & 106 deletions src/viewer/handlers/mdx/eventobjectspl.js

This file was deleted.

Loading

0 comments on commit d8bbfa3

Please sign in to comment.