For fun, I adapted an emitter from an online tutorial to create a smoke plume over my volcano.
The only problem I am having is that the entire smoke plume disappears when the origin of the emitter leaves the field of view - for example, where I rotate my view upwards so that the origin is below the bottom of the screen.
I am guessing that the problem is that the clipping algorithm recognizes only the origin and not the individual particles. I looked at the three.js examples for guidance, but they all appear to involve examples where you are looking directly at the particles, so there is no clipping issue.
Is the proper solution to this problem to create a bounding box? If so, how would that work?
Is it linked to the emitter? Or would I need to reposition the box manually as I move around the map?
Finally, I expect that I would want change the size of the box as the plume changes shape. Would that be a problem?
Maybe this: emitter.frustumCulled=false;
Good idea. But that didn’t fix it.
If it helps, the code for the original version is here.
This original code has a class called ParticleSystemDemo. I pared down this class to eliminate things that are already in place, such as setting up the lights and camera and creating a skybox and renamed it ParticleSystem. Otherwise, I mostly left everything relating to the actual creation and operation of the ParticleSystem alone.
I know SimonDev.
After: this._points = new THREE.Points(this._geometry, this._material);
Add: this._points.frustumCulled=false;
Solution with billboard geometry, not points:
1 Like
That worked perfectly!
And your example is amazing. I am struggling to create one emitter that works and you have quickly provided me with 4 different working examples!
There is one last problem I am having. In most cases, the smoke appears perfectly placed. However, I am still having some problems where the smoke is drawn entirely behind the island (which is an imported gltf object). I tried to fix this problem by changing the shader material definition to include:
opacity: 0.5, // I think this just affects the appearance of the texture.
alphaTest: 0.5, // This helped with the clipping problem
I also tried:
this._particles.renderOrder = 99;
but that did not seem to help with the clipping problem.
It appears that the problem happens when the aircraft is south or west of the map/island center - which is located about where the aircraft starts.
If you want, you can see the problem in action using the flight demo. Or you can use this map demo where you can “slew” to a viewing location (unfortunately, it appears that the slew controls are not working quite as intended).
Try set position Y of emmiter: position.y=1; may be it will sort good
In another exampe particles displays good too
To avoid sorting problems, I always set the Y position of the objects (e.g. the islands) above 0 (the position of the water). In fact, as I climb, I increase the Y heights by a percentage of my altitude. You don’t notice because the objects don’t cast shadows.
FYI - here is how I position load and update the emitter in my program:
// Variables
let NPSPtr = 0; // initialize global variable
// Main Program
initAll();
rendAll();
// Initialize Objects
function initAll() {
[various initializations]
window.addEventListener("DOMContentLoaded", initPrtSys, false);
}
// Update and Render Objects
function rendAll() {
requestAnimationFrame(rendAll);
[various updates]
movePrtSys();
renderer.render(scene, camera);
}
// Initialize Particle System
// called by window event listener above
function initPrtSys() {
NPSPtr = new ParticleSystem({
parent: scene,
camera: camera,
});
}
// Update Particle System
// called by rendAll
// Inputs: MPosXV, MPosYV, MPosZV (my map position)
function movePrtSys() {
let x = 1917-MPosXV; // starts to the right (east) of me
let y = 450-MPosYV*.99; // starts above me
let z = MPosZV-833; // starts in front (north) of me (objects in front have a negative Z value)
NPSPtr.setPosition(x,y,z);
let timeElapsedS = 1/60; // assumes a constant frame rate for now
NPSPtr.Step(timeElapsedS);
}
The rotation of the scenery (XYZ) is handled by attaching the camera to my aircraft - which rotates everything.
[EDIT]
I should have noted that I added the following to the ParticleSytem Class:
setPosition(x,y,z) {
this._points.position.x = x;
this._points.position.y = y;
this._points.position.z = z;
}
That is what I was referencing in the movePrtSys function.
It looks like the clipping problem will not be as easily solved. There is a lot of discussion of this problem and people have tried different solutions - some of which will not work for me. (Or perhaps all I need to do is shift my map origin so that my X and Z coordinates are always positive!)
Thanks for all your help!