Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm using the particles sample from create.msdn.com/en-US/education/catalog/sample/particle_3d which by default, has all the particles look straight at the camera. I'm trying to modify it so that the particles will still look at the camera but won't rotate up and down. I think these are called billboard particles but I'm not really sure.

Edit:

This is what I have in the shader now. It seems like its working but the particles are really tiny. What did I do wrong?

float4x4 billboardRotation = CreateConstrainedBillboard(output.Position, CameraPosition, float3(0, 1, 0));

output.Position.xy += mul(input.Corner, rotation);
output.Position = mul(output.Position, billboardRotation);
output.Position = mul(mul(output.Position, View), Projection);
output.Position.xy += size * ViewportScale;
share|improve this question
    
Small correction: Rotating up/down (x axis) is called pitch. Rotating left/right (y axis) is called yaw. –  David Gouveia Dec 15 '11 at 13:19
    
Your right, ill fix that –  Telanor Dec 16 '11 at 1:15
add comment

2 Answers

Sprite billboards can be of two types:

  • Spherical: they look always at the camera.
  • Cylindrical/constrained: you define a constraint axis and they always try to face the camera, but rotating along that axis. This is the kind you are aiming for.

So, instead of using Matrix.CreateBillboard when creating the world matrix for your particles, use Matrix.CreateConstrainedBillboard. The only difference is that you need to specify the object's rotation axis instead of the camera up vector, and the optional cameraForwardVector and objectForwardVector to smooth possible deformations when the camera is too close.

share|improve this answer
    
The sample he mentioned is set up a bit differently though, so making those changes won't be that trivial. For instance, the sample does not apply any matrix to billboard the particles. Instead it stores a position and a corner offset for each vertex, and adds the corner offset to the vertex position in clip space (i.e. after view and projection transforms) which is why they're always facing the camera. He'll need to change the sample so that the corner offset is applied in world space followed by a custom billboard matrix, all before applying the view and projection matrices. –  David Gouveia Dec 15 '11 at 15:25
    
+1 But still, your method is the usual way to do it. And the OP may still want to use the Matrix.CreateConstrainedBillboard method and pass that value into the shader to make things easier. –  David Gouveia Dec 15 '11 at 15:28
add comment

I haven't had the time to test this, but after looking through the sample's code I believe you'll need to do a few changes for it to work. Here's what I have in mind, although I'm not sure it will work as it is:

The Sample

For starters, the way the particles are being billboarded at the moment doesn't allow for much variation. Each vertex basically carries the particle position and a 2D corner offset such as (-1,-1) or (1,1).

The GPU does all of the particle animation, applies the view and projection matrices to get it into clip space, and then adds the corner offset multiplied by the particle's size to the clip space XY position. Since this sum is done in clip space, the resulting quad will always be facing you. No billboard matrix anywhere.

The Solution

You'll need to change your shader in order to apply the billboards in a more traditional way using a matrix. Using the method r2d2rigo mentioned (Matrix.CreateConstrainedBillboard) you'll need to calculate a billboard matrix for each particle and pass it to the shader when drawing.

Then you'll need to change the method in the shader that is currently applying the View and Projection matrices and leave that part out, because you still need to do a few other things before converting to clip space.

With the position still in world space, that's when you will need to apply the corner offset, along with the billboard matrix you created before to make it face the camera.

Finally just apply the View and Projection matrices as it was done originally in the sample.

Or...

Start from the billboard sample instead and adapt it to your particle needs. That might turn out to be easier.

share|improve this answer
    
Is there a way to calculate that matrix in the shader? Calculating it individually for each particle would probably kill the performance –  Telanor Dec 16 '11 at 1:28
    
Yep. The way I'd do it would be to get dotPeek or some other .NET decompiler and look into Matrix.CreateConstrainedBillboard's source code. Then just convert that into HLSL. –  David Gouveia Dec 16 '11 at 2:29
    
Ok I got the source, ported it to HLSL, but I'm a little confused on how to use the result. I removed the view/projection multiply in the ComputeParticlePosition function. See my edit for what I've tried –  Telanor Dec 18 '11 at 3:27
    
I'm not sure really, but try placing that multiplication by size/ViewportSize in some other places. E.g. directly on the corner before rotation, or after rotation. Or is there a chance you could isolate this portion of your code and posting it? Would be easier to find out the problem by fiddling with it. –  David Gouveia Dec 18 '11 at 3:36
    
I can post my modifications to the shader file but you'd have to modify the sample a bit to provide a camera location to the shader. pastebin.com/k0gbv29x. Ive tried moving the size part around with various degrees of weirdness being produced. I might have done more than one thing wrong. –  Telanor Dec 18 '11 at 3:53
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.