Projecting a Quad from light source and Normal Vector

Started by
17 comments, last by AhmedCoeia 9 years, 12 months ago

I had a problem that I investigated, that the normal of the bike, is changing while driving in the terrain, and that affects that shadow, and we didn't account for in the above equations.

Advertisement
The "normal" of the motorcycle is used when calculating the positions of the points A and B. I put the word normal in quotes because the motorcycle has a transform and a mesh, and each of these have several vectors that you could consider as normals. What I refer to as the normal of the motorcycle is the forward vector of the transform of the object.
It is expected to change with time as the motorcycle steers around, so the points A and B need to account for that.

You need the bottom-centre position of the motorcycle model (the point that is centred in the model, but placed on the ground).
With this centre position, you can calculate the points A and B based on the forward vector of the transform of the motorcycle, provided that the model actually faces the +Z direction.
This depends on how you have your model set. If it doesn't face the +Z direction then the mesh won't be pointing to the forward vector of its transform, and the points A and B will be placed incorrectly.

Once you make sure that the motorcycle model is facing the forward vector of its transform (the blue axis), you can calculate points A and B as follows:

bottomCentre	= [...] // Obtain the bottom-centre position of the motorcycle model in world coordinates.

modelDir	= motorcycle.transform.forward // Direction of the model.

/* Calculating points A and B based on the position "bottomCentre," the
direction "modelDir" and the distance "offset." */

offset = 2.57 // An arbitrary value that is HALF THE SPAN of the motorcycle model in 3D units.

A = bottomCentre - ( modelDir * offset ) // Position point A on the back extremity of the model.
B = bottomCentre + ( modelDir * offset ) // Position point B on the front extremity of the model.
After reading the Unity documentation, the shorthand vectors of a transform (up, right, left, back, front and forward) are always normalized, so there's no need to write ".normalized" after "transform.forward."
Additionally, a way to easily get the bottom-centre position of the motorcycle is to attach a child game object (an empty one, without a mesh) to the motorcycle object, and position the child at that bottom-centre position. The child will move along with the motorcycle, and any time you need that bottom-centre position you just need to retrieve the position of the child with "bottomCentre.transform.position."

Kyrzon, that's what I already did, but I missed the center point of the model. I used the touching point of the normal to the surface each frame, and it seems there is a problem when the biker jumps, because I lose the touching point. Your idea of putting a game object, is really NICE!

I thought about it in other way, that I could do ray to plan intersection as shown in the figure. but I still can't figure out how would I get the points parallel to the wheels.

If I have a touching point and a normal of the bike that I use for the terrain, I would get a plane.. correct?

What considerations should I have to achieve the ray to plane intersection?

Thanks so much

Is the motorcycle navigating through an irregular environment (with ramps etc.), or is it planar?

If the terrain is planar, performing a ray-cast from that "bottomCentre" object downwards should obtain the point on the ground, in the middle of the motorcycle, where the shadow should be placed.
Instead of calculating the A and B points with the position of "bottomCentre," you would calculate them with the point of contact of the ray-cast.

Since these points are extruded with the motorcycle forward vector, they will naturally be aligned to the wheels as the wheels are also aligned to the forward vector.

The terrain is not planar, it has ramps. so ray cast wouldn't car for the "bottomCentre" for ramps that are higher than the normal distance between the bike and the floor :/.

and that's my current problem right now.

Hello.
The simplest way to account for this is to align the shadow mesh to the normal of the point of contact of the raycast below the motorcycle.
However, this is an approximation and there will be instances where the shadow mesh will go off a ramp and into the air. The user will notice when the shadow mesh "realigns" itself, as this happens on a single frame.

motorcycle_Shadow.png

There's no way to account for that if not for generating the shadow mesh dynamically: adding more segments to the mesh so that it wraps the different surface directions (I believe that this is called a "towel mesh").
Blizzard does this with the "Warcraft 3" and the "World of Warcraft" games for the spell-targetting marker, but even then it's not perfect:

wowscrnshot082310181654.jpg

It would be much more convenient to just use the native hard-edged shadow maps that Unity offers.

I reiterate that you would be better served on the Unity official forums, as the developers there have lots of experience with these implementation difficulties and know the shortcuts that you can take with the engine.
It's free to create an account there, and here are some thread examples:
- http://answers.unity3d.com/questions/559078/aligning-an-object-with.html
- http://forum.unity3d.com/threads/33987-Character-align-to-surface-normal
- http://forum.unity3d.com/threads/63619-Aligning-object-to-surface-normal-with-Quaternion-LookRotation
- http://forum.unity3d.com/threads/65006-Raycast-Normal-Rotation-Alignment
- http://answers.unity3d.com/questions/8867/how-to-get-quaternionfromtorotation-and-hitnormal.html

Hi Kryzon,

I'm trying to translate the quad based on my how much my charterer has leaned towards the light direction. So I had the dot product between light direction and up vector, then I tried to use that value to scale up two vertices of a quad, but it doesn't work at all. When I stop lighting in the scene, I still get cosine angles from the dot product.


float leaningAngle = Mathf.Abs(Vector3.Dot(lightDir.normalized, mUp.GetVector3().normalized));
Global.Log("leaningAngle" + leaningAngle);

// leaning left
if (mLean > 0 && lerp < 0)
{
vertexLeftOffset = mLean; // squeeze left side
vertexRightOffset = leaningAngle; // extend the other side


}

// right leaning
if (mLean < 0 && lerp < 0)
{

vertexRightOffset = mLean; // squeeze right side quad
vertexLeftOffset = leaningAngle; // scale the shadow based on light's direction, left side

}



Vector3 vxPos1Top = pos + rot * (new Vector3(-offsetX + vertexLeftOffset, 0, offsetY) * scale); // 1,2 vertices or on its left
Vector3 vxPos2Top = pos + rot * (new Vector3(-offsetX + vertexLeftOffset, 0, -offsetY) * scale);
Vector3 vxPos3Top = pos + (mForward.GetVector3().normalized * mMiddleVerticesScale; // two middle vertices
Vector3 vxPos4Top = pos - (mForward.GetVector3().normalized * mMiddleVerticesScale;
Vector3 vxPos5Top = pos + rot * (new Vector3(offsetX + vertexRightOffset, 0, offsetY) * scale); // 5,6 vertices are on the right of the bikeer
Vector3 vxPos6Top = pos + rot * (new Vector3(offsetX + vertexRightOffset, 0, -offsetY) * scale);
 
Game Programming is the process of converting dead pictures to live ones .

Hi Kyron,

Today I just wanted to project the light onto the quad and use its value for translating the vertices.

I'm currently having 6 vertices, two quads,

The points are

A X C

B Y D

Point X, Y are coming from two ray casting downwards.

C = X + RightVector

D = Y + RightVector

A = X- RightVector

B = Y - RightVector

Now I want to translate the vertices based on lightDirectionVector, how would I do that ?

This topic is closed to new replies.

Advertisement