cancel
Showing results for 
Search instead for 
Did you mean: 

HMD Roll and Particles

RaveTZ
Protege
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?

18 REPLIES 18

raidho36
Explorer
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.

owenwp
Expert Protege
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.

RaveTZ
Protege
"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!

boone188
Honored Guest
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?

owenwp
Expert Protege
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.

zwickarr
Honored Guest
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

RaveTZ
Protege
the mesh technique ended up not being viable due to the lack of particle rotation control in shurikan. Orientation was not optimal.

digital
Explorer
@RaveTZ Did you have any solution to this?

Regards:


John

bgolus
Explorer
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.