Welcome to the Oculus Developer Forums!

Your participation on the forum is subject to the Oculus Code of Conduct.

In general, please be respectful and kind. If you violate the Oculus Code of Conduct, your access to the developer forums will be revoked at the discretion of Oculus staff.
New to the forums? Click here to read the How To guide. -- Developers click here.

HMD Roll and Particles

RaveTZRaveTZ Posts: 168
Hiro Protagonist
edited March 2016 in Unity Development
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?

PFX_Roll.gif
ProjectBanner.jpg

Comments

  • raidho36raidho36 Posts: 1,312
    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.
  • owenwpowenwp Posts: 668 Oculus Start Member
    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.
    Sanzaru - Programmer
  • RaveTZRaveTZ Posts: 168
    Hiro Protagonist
    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!
    ProjectBanner.jpg
  • boone188boone188 Posts: 231
    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?
  • owenwpowenwp Posts: 668 Oculus Start Member
    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.
    Sanzaru - Programmer
  • zwickarrzwickarr Posts: 45
    Brain Burst
    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
  • RaveTZRaveTZ Posts: 168
    Hiro Protagonist
    the mesh technique ended up not being viable due to the lack of particle rotation control in shurikan. Orientation was not optimal.
    ProjectBanner.jpg
  • digitaldigital Posts: 110
    Hiro Protagonist
    @RaveTZ Did you have any solution to this?

    Regards:


    John
  • bgolusbgolus Posts: 7
    NerveGear
    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.
  • bzorbzor Posts: 19
    NerveGear
    super old post but I'm running into this now.. Has anyone found a more elegant solution than what's posted above?

    thanks!
  • cyberealitycybereality Posts: 26,156 Oculus Staff
    If you use a mesh as the particle, it should look correct from any angle.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i
    Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
  • bgolusbgolus Posts: 7
    NerveGear
    As cybereality said, mesh particles work better for VR, but sometimes they're not quite what you need.

    I've updated this script for the projects I'm working on to have a single manager object that tracks the camera orientation during update and each particle system that needs it has a script that reads that value to apply to the particles in late update. I've been thinking about some way to add some parallelism, but I haven't spent the time to figure out if the expensive part is iterating the particle list or the get/setParticles.
  • RaveTZRaveTZ Posts: 168
    Hiro Protagonist
    Old topic, but still relevant. Anyone have a method for getting around this?
    ProjectBanner.jpg
  • digitaldigital Posts: 110
    Hiro Protagonist
    Apart from not rolling your head no. :(
  • vrdavebvrdaveb Posts: 1,596 Oculus Staff
    This was suggested in https://feedback.unity3d.com/suggestion ... ientationf. Unity is working on it, but I have a feeling it has slipped to 5.4. In the meantime, you would have to use a solution like bgolus's or do something like the following with a non-Shuriken billboard:
    transform.rotation = Quaternion.LookRotation(transform.position - Camera.main.transform.position, Vector3.up);
    
  • vrdavebvrdaveb Posts: 1,596 Oculus Staff
    Actually, it appears to have been fixed in 5.3 and I can see it in 5.3.3p1. See "Billboard Alignment" in the "Renderer" module of the Particle System inspector to control if particles face the camera, the world axes, or locally based on the Transform. You can also use the 3D Rotation settings to set start rotation to any direction, plus animate them to spin in full 3D.
  • bgolusbgolus Posts: 7
    NerveGear
    If you're using camera facing billboard particles you'll still need something like my script to fix the orientation. The billboard alignment settings in 5.3 are nice for the control it gives you, but world and local are explicitly not camera facing, so you'd still need to do something like set the 3d rotation of the particle to orient it towards the camera, and then you'll need to handle all of the rotation yourself since setting the rotation3D also sets the 2d rotation value (it blows it away with the z component of the rotation3D).
  • sh0v0rsh0v0r Posts: 498
    Hiro Protagonist
    I wrote a cloud system for another project that uses quads and a simple lookat script, there was no control over it like a particle system though. I also aligned the vertex normals on the quad to be coplanar to the surface for more even lighting. Made some really nice hand sculpted cloud volumes and a pooled spawner that would randomly spawn them with a direction and control fade in and out. I'm going to reuse some of this for the Mars Dust Storms in Lunar Flight.
Sign In or Register to comment.