Sign in to follow this  

I want to align my bullet hole decal with the surface hit

Recommended Posts

HI, this is my first post and would appreciate any help.

[url=""]Here's a video of the problem[/url]

I am using the particle system from the "Particles3D" XNA example. Currently the texture is always aligned with the camera. I want it to be aligned with the surface hit.

In the video I have displayed the location and normal of each collision.

The sample particle system has a lot of redundant code that I don't need for the bullet holes. For example I don't need the particles to move, rotate, change size or color.

The vertex shader input contains a float3, Velocity, that I could presumably replace with the normal.

in the ParticleVertexShader the output.Position is calculated in ComputeParticlePosition.

// Custom vertex shader animates particles entirely on the GPU.
VertexShaderOutput ParticleVertexShader(VertexShaderInput input)
VertexShaderOutput output;

// Compute the age of the particle.
float age = CurrentTime - input.Time;

// Apply a random factor to make different particles age at different rates.
age *= 1 + input.Random.x * DurationRandomness;

// Normalize the age into the range zero to one.
float normalizedAge = saturate(age / Duration);
// Compute the particle position, size, color, and rotation.
output.Position = ComputeParticlePosition(input.Position, input.Velocity,
age, normalizedAge);
float size = ComputeParticleSize(input.Random.y, normalizedAge);
float2x2 rotation = ComputeParticleRotation(input.Random.w, age);
output.Position.xy += mul(input.Corner, rotation) * size * ViewportScale;

output.Color = ComputeParticleColor(output.Position, input.Random.z, normalizedAge);
output.TextureCoordinate = (input.Corner + 1) / 2;

return output;

Inside ComputeParticlePosition the position is multiplied by the view and projection matrix.

// Vertex shader helper for computing the position of a particle.
float4 ComputeParticlePosition(float3 position, float3 velocity,
float age, float normalizedAge)
float startVelocity = length(velocity);
// Work out how fast the particle should be moving at the end of its life,
// by applying a constant scaling factor to its starting velocity.
float endVelocity = startVelocity * EndVelocity;

// Our particles have constant acceleration, so given a starting velocity
// S and ending velocity E, at time T their velocity should be S + (E-S)*T.
// The particle position is the sum of this velocity over the range 0 to T.
// To compute the position directly, we must integrate the velocity
// equation. Integrating S + (E-S)*T for T produces S*T + (E-S)*T*T/2.
float velocityIntegral = startVelocity * normalizedAge +
(endVelocity - startVelocity) * normalizedAge *
normalizedAge / 2;

position += normalize(velocity) * velocityIntegral * Duration;

// Apply the gravitational force.
position += Gravity * age * normalizedAge;

// Apply the camera view and projection transforms.
return mul(mul(float4(position, 1), View), Projection);

So in summary, I don't need most of this code, I have only included it so you see what is currently happening. The input velocity is zero.

How do I transform the position so that it aligns with the normal?

Any help or pointers would be great.

Share this post

Link to post
Share on other sites
[url=""]Here's a video of the problem fixed![/url]

I ditched the idea of using a trianglelist based particle system. Instead I use a quad model circular array. I can manipulate the matrix up vector using the normal of the surface hit.

Thanks for looking.

BTW: I think I should have posted this in the XNA section, sorry about that, I didn't realise till after posting.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this