Skip to content

Commit

Permalink
merge Inuniku master (#81)
Browse files Browse the repository at this point in the history
* added parameter for flip book blending: blendTiles

* switched to particle type material

* particle material dispose

* upgraded three to v155

* build fixes

* added soft particles (#1)

* added soft particles

---------

Co-authored-by: Stefan Schmutz <[email protected]>

---------

Co-authored-by: Stefan Schmutz <[email protected]>
Co-authored-by: Inuniku <[email protected]>
  • Loading branch information
3 people authored May 13, 2024
1 parent 1f26ab7 commit 78d86a7
Show file tree
Hide file tree
Showing 34 changed files with 759 additions and 120 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Change Log
## version 0.12.0
- Support soft particles
- Support uv blend tiles.

## version 0.11.2
- Fix Major bug: particles are emitted at incorrect positions at first time
Expand Down
2 changes: 0 additions & 2 deletions examples/billboardDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ export class BillboardDemo extends Demo {
this.scene.add(billboard1.emitter);
this.scene.add(billboard2.emitter);
this.scene.add(billboard3.emitter);
this.scene.add(this.batchRenderer);

return this.scene;
}
}
7 changes: 7 additions & 0 deletions examples/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ export class Demo {
refreshIndex = 0;
refreshTime = 2;
texture;
camera;
renderer;

name = 'Unname';

constructor(camera, renderer) {
this.camera = camera;
this.renderer = renderer;
}

render(delta) {
this.groups.forEach((group) =>
group.traverse((object) => {
Expand Down
25 changes: 17 additions & 8 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import {AlphaTestDemo} from "./alphaTestDemo.js";
import {BillboardDemo} from "./billboardDemo.js";
import {NodeBasedVFXDemo} from "./nodeBasedVFXDemo.js";
import {SoftParticleDemo} from "./softParticleDemo.js";

const WEBGL = {
isWebGLAvailable: function () {
Expand Down Expand Up @@ -154,7 +155,7 @@
let scene;
let demo;

let demos = [MuzzleFlashDemo, ExplosionDemo, EmitterShapeDemo, TrailDemo, SequencerDemo, MeshMaterialDemo, SubEmitterDemo, TurbulenceDemo, AlphaTestDemo, CustomPluginDemo, BillboardDemo, NodeBasedVFXDemo];
let demos = [MuzzleFlashDemo, ExplosionDemo, EmitterShapeDemo, TrailDemo, SequencerDemo, MeshMaterialDemo, SubEmitterDemo, TurbulenceDemo, AlphaTestDemo, CustomPluginDemo, BillboardDemo, SoftParticleDemo, NodeBasedVFXDemo];
let demoIndex = 0;

function init() {
Expand Down Expand Up @@ -194,20 +195,22 @@
stats.dom.style.right = "0";
container.appendChild(stats.dom);

window.addEventListener('resize', onReize, false);
window.addEventListener('resize', onResize, false);

demoIndex = 0;
demo = new demos[demoIndex]();
demo = new demos[demoIndex](camera, renderer);
document.querySelector("#demo-name").innerText = demo.name;
scene = demo.initScene();

document.getElementById("nextBtn").addEventListener("click", nextDemo, false);
document.getElementById("previousBtn").addEventListener("click", previousDemo, false);

onReize();
onResize();
}

function onReize() {
function onResize() {
if (demo.onWindowResize)
demo.onWindowResize();

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
Expand All @@ -217,7 +220,7 @@
function animate() {
requestAnimationFrame(animate);

onReize(null);
onResize(null);
render();
stats.update();
}
Expand All @@ -235,7 +238,10 @@
if (demoIndex >= demos.length) {
demoIndex = 0;
}
demo = new demos[demoIndex]();
if (demo && demo.deinitScene) {
demo.deinitScene();
}
demo = new demos[demoIndex](camera, renderer);
document.querySelector("#demo-name").innerText = demo.name;
scene = demo.initScene();
}
Expand All @@ -245,7 +251,10 @@
if (demoIndex < 0) {
demoIndex = demos.length - 1;
}
demo = new demos[demoIndex]();
if (demo && demo.deinitScene) {
demo.deinitScene();
}
demo = new demos[demoIndex](camera, renderer);
document.querySelector("#demo-name").innerText = demo.name;
scene = demo.initScene();
}
Expand Down
1 change: 0 additions & 1 deletion examples/muzzleFlashDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
RotationOverLife,
SizeOverLife,
ParticleSystem,
ParticleEmitter,
BatchedParticleRenderer,
} from 'three.quarks';
import {Demo} from './demo.js';
Expand Down
1 change: 1 addition & 0 deletions examples/ps.json
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@
"arc": 6.283185307179586,
"thickness": 0
},
"blendTiles": true,
"startLife": {
"type": "IntervalValue",
"a": 0.8,
Expand Down
116 changes: 116 additions & 0 deletions examples/softParticleDemo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import {Demo} from "./demo.js";
import {BatchedParticleRenderer,
Bezier,
ConstantColor,
ParticleSystem,
ConstantValue,
FrameOverLife,
ForceOverLife,
RenderMode,
PiecewiseBezier, PointEmitter} from "three.quarks";
import {
DepthTexture,
FloatType,
Mesh, MeshBasicMaterial,
NearestFilter,
TorusKnotGeometry,
WebGLRenderTarget,
RGBAFormat, MeshStandardMaterial, Vector4, DoubleSide, TextureLoader, NormalBlending
} from "three";

export class SoftParticleDemo extends Demo {
name = 'Soft Particle & Blend Tiles Demo';
refreshTime = 2;

constructor(camera, renderer) {
super(camera, renderer);
}

initScene() {
super.initScene();

this.batchRenderer = new BatchedParticleRenderer();
this.scene.add(this.batchRenderer);

// Create a multi render target with Float buffers
this.target = new WebGLRenderTarget(window.innerWidth, window.innerHeight);
this.target.texture.format = RGBAFormat;
this.target.texture.minFilter = NearestFilter;
this.target.texture.magFilter = NearestFilter;
this.target.texture.generateMipmaps = false;
this.target.stencilBuffer = false;
this.target.depthBuffer = true;
this.target.depthTexture = new DepthTexture();
this.target.depthTexture.type = FloatType;

this.batchRenderer.setDepthTexture(this.target.depthTexture);

// Our scene
this.setupScene();

// Setup post-processing step
this.texture = new TextureLoader().load('textures/cfxr smoke cloud x4.png', (texture) => {
this.setupPost();
});

this.onWindowResize();
return this.scene;
}

deinitScene() {
this.target.dispose();
}

setupPost() {
const smoke = new ParticleSystem({
duration: 2,
looping: true,
startLife: new ConstantValue(2.0),
startSpeed: new ConstantValue(10),
startSize: new ConstantValue(2),
startColor: new ConstantColor(new Vector4(1, 1, 1, 1)),
worldSpace: true,
maxParticle: 1000,
emissionOverTime: new ConstantValue(60),
emissionBursts: [],
blendTiles: true,
softParticles: true,
softFarFade: 1,
softNearFade: 0,
shape: new PointEmitter(),
material: new MeshBasicMaterial({
map: this.texture,
blending: NormalBlending,
transparent: true,
side: DoubleSide,
}),
startTileIndex: new ConstantValue(0),
uTileCount: 2,
vTileCount: 2,
renderOrder: 0,
renderMode: RenderMode.BillBoard,
});
smoke.addBehavior(new FrameOverLife(new PiecewiseBezier([[new Bezier(0, 1.33333, 2.66667, 4), 0]])));
smoke.addBehavior(new ForceOverLife(new ConstantValue(0), new ConstantValue(-10), new ConstantValue(0)));
smoke.emitter.name = 'beam';
this.batchRenderer.addSystem(smoke);
//this.groups.push(smoke.emitter);
this.scene.add(smoke.emitter);

}

onWindowResize = () => {
const dpr = this.renderer.getPixelRatio();
this.target.setSize( window.innerWidth * dpr, window.innerHeight * dpr );
}

render(delta) {
super.render(delta);

// render scene into target
this.renderer.setRenderTarget( this.target );
this.renderer.render( this.scene, this.camera);
this.renderer.setRenderTarget( null );
}
}

1 change: 0 additions & 1 deletion examples/turbulenceDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export class TurbulenceDemo extends Demo {
worldSpace: true,

emissionOverTime: new ConstantValue(500),

shape: new ConeEmitter({radius: 0.5, angle: 0.5}),
material: new MeshBasicMaterial({
map: this.texture,
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "three.quarks",
"version": "0.11.2",
"version": "0.12.0",
"description": "A General-Purpose Particle System for three.js",
"type": "module",
"types": "./dist/types/index.d.ts",
Expand All @@ -14,6 +14,8 @@
}
},
"files": [
"dist",
"src",
"dist",
"README.md",
"LICENSE"
Expand Down
20 changes: 20 additions & 0 deletions src/BatchedRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export interface VFXBatchSettings {
material: Material;
uTileCount: number;
vTileCount: number;
blendTiles: boolean;
softParticles: boolean;
softNearFade: number;
softFarFade: number;
renderMode: RenderMode;
renderOrder: number;
layers: Layers;
Expand Down Expand Up @@ -83,6 +87,8 @@ export class BatchedRenderer extends Object3D {
systemToBatchIndex: Map<IParticleSystem, number> = new Map<IParticleSystem, number>();
type = 'BatchedRenderer';

depthTexture: THREE.Texture | null = null;

constructor() {
super();
}
Expand All @@ -96,6 +102,10 @@ export class BatchedRenderer extends Object3D {
a.material.alphaTest === b.material.alphaTest &&
(a.material as any).map === (b.material as any).map &&
a.renderMode === b.renderMode &&
a.blendTiles === b.blendTiles &&
a.softParticles === b.softParticles &&
a.softFarFade === b.softFarFade &&
a.softNearFade === b.softNearFade &&
a.uTileCount === b.uTileCount &&
a.vTileCount === b.vTileCount &&
a.instancingGeometry === b.instancingGeometry &&
Expand Down Expand Up @@ -127,6 +137,9 @@ export class BatchedRenderer extends Object3D {
batch = new SpriteBatch(settings);
break;
}
if (this.depthTexture) {
batch.applyDepthTexture(this.depthTexture);
}
batch.addSystem(system);
this.batches.push(batch);
this.systemToBatchIndex.set(system, this.batches.length - 1);
Expand All @@ -148,6 +161,13 @@ export class BatchedRenderer extends Object3D {
}*/
}

setDepthTexture(depthTexture: THREE.Texture | null) {
this.depthTexture = depthTexture;
for (const batch of this.batches) {
batch.applyDepthTexture(depthTexture);
}
}

updateSystem(system: IParticleSystem) {
this.deleteSystem(system);
this.addSystem(system);
Expand Down
Loading

0 comments on commit 78d86a7

Please sign in to comment.