Skip to main content
Up and Coming
January 18, 2014

HMD Roll and Particles

I'm trying to find a solution to particle effects rolling with the OVR. The issue is that camera facing particles rotate the same direction as the camera so when you tilt your head, the particles rotate to match. This looks terrible. Any elegant solution I'm missing?

    This topic has been closed for replies.

    18 replies

    Up and Coming
    January 19, 2014
    Good quesiton. And honestly I don't recall any game that wouldn't have particles rotated to match your UP-vector.

    I think you can measure the angle of the HMD against some up-vector, and put negative of this value as an orientation parameter in the particle system. Both individual particles and particle system as a whole have rotation property.
    Up and Coming
    January 20, 2014
    The best thing to do would probably by to modify the particle instances directly using Get/SetParticles. You can add any camera roll delta to the rotation each frame.
    RaveTZAuthor
    Up and Coming
    February 8, 2014
    "owenwp" wrote:
    The best thing to do would probably by to modify the particle instances directly using Get/SetParticles. You can add any camera roll delta to the rotation each frame.


    I wasn't able to crack this with Shurikan. Has anyone else figured out this problem? Credit inclusion in Proton Pulse to whoever solves it!
    Up and Coming
    February 11, 2014
    Could you provide steps for reproduction, like the particle system parameters? Maybe you could package the particle system and send it to me for testing?
    Up and Coming
    February 12, 2014
    You will see this with any particle texture that is not radially symmetrical, with any combination of particle system parameters, as long as you use the billboard render mode (which you almost always do).

    Its a natural consequence of the particle billboards aligning with the camera that they do not maintain a consistent up vector. It looks fine in most games because they don't let you roll the camera, but special handling is going to be necessary in VR.
    Up and Coming
    February 16, 2014
    there is a way, but its not cheap...

    you need to emit mesh particles. You can try using quad polys with a shader that uses a transparent Fresnel shader so that when the quad is shown on edge it fades out so you don't see the quad mesh shape. But I found using low res spheres with the same type of Fresnel shader works.

    here is a video showing an example:

    https://vimeo.com/86838964
    RaveTZAuthor
    Up and Coming
    February 28, 2014
    the mesh technique ended up not being viable due to the lack of particle rotation control in shurikan. Orientation was not optimal.
    Up and Coming
    September 30, 2014
    @RaveTZ Did you have any solution to this?

    Regards:


    John
    Participant
    October 3, 2014
    You need to track the previous update's view rotation, find the rotation difference in just the roll, and apply that rotation difference to the particle.

    The "perfect" rotation difference probably isn't as straightforward as grabbing the Z euler rotation of the camera on each frame update, but just the z rotation may result in decently stable results.

    Then it's a matter of getting the particle list, adding this rotation difference to the existing particle rotations, and setting the particles.

    Some proof of concept code:
    using UnityEngine;
    using System.Collections;

    [RequireComponent (typeof (ParticleSystem))]
    public class ParticleViewRollCorrection: MonoBehaviour
    {
    private float lastRotation = 0f;

    private ParticleSystem.Particle[] particles = new ParticleSystem.Particle[1000];

    void LateUpdate()
    {
    if (!Camera.main)
    return;

    float currentRotation = Camera.main.transform.rotation.eulerAngles.z;
    if (lastRotation == currentRotation)
    return;

    float rotationDifference = currentRotation - lastRotation;

    int num = particleSystem.GetParticles(particles);
    for (int i=0; i<num; i++)
    particles[i].rotation += rotationDifference;

    particleSystem.SetParticles(particles, num);
    //particleSystem.startRotation += rotationDifference * Mathf.Deg2Rad;

    lastRotation = currentRotation;
    }
    }


    One issue that remains with this code is Shuriken particle systems do their update from SetParticles() one frame delayed, so the particles will always swim a little bit. This also doesn't correct the initial rotation so particles with a start rotation of 0 will be aligned to your camera when emitted. You can uncomment "particleSystem.startRotation += rotationDifference * Mathf.Deg2Rad;" and it'll try to keep the particles' initial rotation aligned with the world, though if your initial particle rotation is already sufficiently randomized this isn't an issue. If you're using a small initial rotation range or rotation curve that won't work right since it'll scale the rotation values rather than properly counter rotate.
    bzor
    Up and Coming
    September 21, 2015
    super old post but I'm running into this now.. Has anyone found a more elegant solution than what's posted above?

    thanks!