[SOLVED] Particle system is not working with curved world shader

I have used the following curved world shader in the game.
https://playcanvas.com/editor/scene/1353984

Could anyone please help?

Has anyone figured this out? I’m having the same issue.

@Albertos Please help us figure out this issue. Or tag someone who could help?

Hi @yash_mehrotra!

Unfortunately, I’m not the creator of the shader and I have no knowledge of it.

It may be helpful if you share the project where you use the particle system.

@Albertos Here is a demo project link. You could see that the Trail particle system is not following the world curve shader that is attached to the root entity.

https://playcanvas.com/editor/scene/1923511

I think this is because the shader manipulates the visual position of all materials in the project, but not the actual position of the entities. Since the particle system is not a material, it is not included in this visual manipulation.

I’m afraid you should come up with an alternative to the particle system. Maybe you can create some animated entities with a material (using a tween or something), but I’m not sure if you might run into the same problem with this.

maybe you can just change the position of the entity that contains the particle system to match the curvature of the world?

1 Like

Yes, if you are be able to get the correct position from the shader you can update the positions of the entities as well. That will be the best solution.

Looking at the shader, this is the custom bit that handles the curving. You just need the same code (in javascript) to work on positions of entities

    // --- START custom curve code
    '    float amountX = curveCameraDirection.x * pow(posW.x - curveCenterPos.x, 2.0);\n' +
    '    float amountY = curveCameraDirection.y * pow(posW.y - curveCenterPos.y, 2.0);\n' +
    '    float amountZ = curveCameraDirection.z * pow(posW.z - curveCenterPos.z, 2.0);\n' +
    '    float amountSum = (amountX * curveCameraDirection.x + amountY * curveCameraDirection.y + amountZ * curveCameraDirection.z) * curvePower;\n' +
    '    posW.y += -amountSum;\n' +
    // --- END custom curve code

@mvaligursky I have tried and implement the code as you suggested. Some issue with position I guess. Please have a look at it. Meanwhile I am also debugging. Project link is as follows.
https://playcanvas.com/editor/scene/1923511

CurvedWorld.prototype.update = function () {
    if (!this.materials) return;

    this.materials.forEach(material => this.updateShaderUniforms(material));

    for(let i=0; i<this.particles.length; i++)
    {
      // Update entity position based on curvature
      const entity = this.particles[i];
      const currentPos = entity.getLocalPosition();
      const amountX = this.curveCameraDirectionDemo.x * Math.pow(currentPos.x - this.curveCenterPosDemo.x, 2.0);
      const amountY = this.curveCameraDirectionDemo.y * Math.pow(currentPos.y - this.curveCenterPosDemo.y, 2.0);
      const amountZ = this.curveCameraDirectionDemo.z * Math.pow(currentPos.z - this.curveCenterPosDemo.z, 2.0);
      const amountSum = (amountX * this.curveCameraDirectionDemo.x + amountY * this.curveCameraDirectionDemo.y + amountZ * this.curveCameraDirectionDemo.z) * this.curvePowerDemo;
      const newPos = new pc.Vec3(currentPos.x, currentPos.y - amountSum, currentPos.z);

      // Set the new position to the entity
      entity.setLocalPosition(newPos);
      console.log(newPos);
    } 
};

CurvedWorld.prototype.updateShaderUniforms = function (material) {

  if(material == undefined) return;

  this.curvePowerDemo = this.curvePower * 0.001;
  material.setParameter('curvePower', this.curvePower * 0.001);

  const cameraPos = this.activeCamera.getPosition();
  this.curveCenterPosDemo = new pc.Vec3(cameraPos.x, cameraPos.y, cameraPos.z);
  material.setParameter('curveCenterPos', [cameraPos.x, cameraPos.y, cameraPos.z]);

  const cameraDir = this.activeCamera.forward;
  this.curveCameraDirectionDemo = new pc.Vec3(cameraDir.x, cameraDir.y, cameraDir.z);
  material.setParameter('curveCameraDirection', [cameraDir.x, cameraDir.y, cameraDir.z]);
};

In your code this.curveCameraDirectionDemo is undefined.

It looks like the code where it is defined is disabled for some reason?

That I have corrected now, but the position of the particle system is still not sorted. Please check the logs.

You get some NaN results with your logic.

No idea how to solve this.

Fixed version: https://playcanvas.com/project/1176017/overview/f-curved-world

The difference is that the shader never changed the entity position, only where it’s rendered based on its position

However your implementation for the particles was also setting the entity position

This project works around that by using another entity (the particle parent) that we don’t change the position of in the curve calculation

3 Likes