• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
AhmedCoeia

Projecting a Quad from light source and Normal Vector

18 posts in this topic

Hi All,

 

I'm having a decal mesh( a quad) which has a shadow texture. and I have a bike, which has its forward direction, I have the normal to the ground, and normal touching point to ground. I have also the direction of light.

 

My quad on the floor has 4 vertices, so I assumed as the figure Points C,D is set to be parallel with the front wheel and the back wheel. 

 

I would like to get the maths and get the points A, B  with respect to the light direction. 

 

My current code is : I would like to determine both vxPosSide2, and VxPosSide3

Quaternion rot = Quaternion.AngleAxis(Source.rotation.eulerAngles.y, normal) * Quaternion.FromToRotation(new Vector3(0, 1, 0), normal);
Vector3 pos = point + new Vector3(0, 0.1f, 0);
Color32 colorSideTexture = mRenderer.sharedMaterial.GetColor("_Color");

Vector3 vxPos1Side = pos + rot * (new Vector3(-1.4f, 0, -0.7f) * scale);
Vector3 vxPos2Side = pos + rot * (new Vector3(0, 0, -0.7f) * scale);
Vector3 vxPos3Side = pos + rot * (new Vector3(0, 0, 0.7f) * scale);
Vector3 vxPos4Side = pos + rot * (new Vector3(-1.4f, 0, 0.7f) * scale);
 
mDecalSide.SetVertex(0, vxPos1Side, colorSideTexture);
mDecalSide.SetVertex(1, vxPos2Side, colorSideTexture);
mDecalSide.SetVertex(2, vxPos3Side, colorSideTexture);
mDecalSide.SetVertex(3, vxPos4Side, colorSideTexture);
0

Share this post


Link to post
Share on other sites

Kryzon, Thanks so much for reply.

 

I actually did that, but I need also to add "shearing" points A and B, not only translation, so that when I steer, the shadow also steers ( point A,B). 

0

Share this post


Link to post
Share on other sites
First, I believe that a change in the naming convention is best.
 
Let A and B be the two points are positioned at either wheel of the bike.
To calculate their positions, you do the following:
 - Obtain the normalized forward vector of the bike. Call it 'normBike.'
 - Point A position is (bikePosition - normBike * scaleBike). Point B position is (bikePosition + normBike * scaleBike).
 
Let C and D be the two points that are offset from the bike based on the direction of the light source.
 - Obtain the normalized forward vector of the light source. Call it 'normLight.'
 - Point C position is (pointA + normLight * scaleShadow). Point D position is (pointB + normLight * scaleShadow).
 
This will account for any light position and bike orientation.
 
EDIT: There may be some confusion as to which values are in world space and which values are in the local space of the shadow mesh. In order to facilitate things, keep the shadow mesh transform placed at the world origin (0,0,0), and without any rotations or scaling. This way the vertex positions will all be in world space as well.

EDIT 2: The scale used for the points C and D ("scaleShadow"), which controls how "tall" the shadow is. is different than the scale used for points A and B ("scaleBike"), which controls how wide the shadow should be. Edited by Kryzon
2

Share this post


Link to post
Share on other sites

Hi Kryzon,

 

I have tried your formula as :

        Vector3 vxPos2Side = pos + rot * (new Vector3(0, 0, -0.7f) * scale);
        Vector3 vxPos3Side = pos + rot * (new Vector3(0, 0, 0.7f) * scale);
        Vector3 vxPos1Side = vxPos2Side + lightDir;
        Vector3 vxPos4Side = vxPos3Side + lightDir;

It's working now,

 

but as you see in the picture, the yellow shadow which is from the hard shadow ( real time ), compared to the billboard shadow(my shadow).

Still I need shearing, or skewing it.

0

Share this post


Link to post
Share on other sites

Would you tell me please, the maths ( magic ) for adding the light vector to the vertices? why would I do that? " adding" two vectors ?

 

I also have a problem with blending that side projected shadow, and the top projected shadow. there are angles that both of them are shown to the viewer.:/

Edited by AhmedCoeia
0

Share this post


Link to post
Share on other sites

Hi Kryzon,

 

Today I tried another idea. I assumed points  C, D comes from ray to plan intersection. So I have the normal point of the plane, and the normal of the bike, light direction, and point A and C.  I tried that, but the shadow gets extended, and it gets very big, unlike your method. 

 

Would you tell me how to get point C,D using pseudo code ? maybe I'm doing some wrong maths.

 

C =  RayToPlane(normal, touchPoint, lightDir.normalized, VxPos1)

D =  RayToPlane(normal, touchPoint, lightDir.normalized, VxPos2)

0

Share this post


Link to post
Share on other sites

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. 

0

Share this post


Link to post
Share on other sites
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." Edited by Kryzon
2

Share this post


Link to post
Share on other sites

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!

0

Share this post


Link to post
Share on other sites

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

0

Share this post


Link to post
Share on other sites
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. Edited by Kryzon
0

Share this post


Link to post
Share on other sites

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.

0

Share this post


Link to post
Share on other sites
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 Edited by Kryzon
1

Share this post


Link to post
Share on other sites

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);
 
0

Share this post


Link to post
Share on other sites

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 ?

0

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  
Followers 0