• 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
xytor

Tangents and Binormals?

11 posts in this topic

Hi, I have a normal map which I use to replace the normals of each pixel in the HLSL pixel shader. The result looks good. What's the point of tangents and bitangents? I don't use them but the result looks pretty good!
0

Share this post


Link to post
Share on other sites
Tangent/Bitangent/Normal form an orthonormal basis (usually given in object-space of a model for every vertex), which is used to transform all vectors (that you use in your computations) to tangent-space of a texture (normal map). This way all vectors and also vectors you sample from the texture reside in the same space so the computations can be correct. This is needed for normal maps that have vectors in tangent-space (such normal maps have blueish colors).
Other possibility is to store the normals in a normal map in object-space (or any other you wish). In this case you do not need tangents and bitangents since, for example, transforming the normals form the sampled normal map would only require to use world transform to get them in world-space.
If you want some solid reference, Eric Lengyel's "Mathematics for 3D Game Programming and Computer Graphics" gives a very nice dicussion on this topic.
1

Share this post


Link to post
Share on other sites
A similar reference to the one mentioned above can be found here as well: [url="http://www.terathon.com/code/tangent.html"]http://www.terathon.com/code/tangent.html[/url]
1

Share this post


Link to post
Share on other sites
What do object space normal maps look like?
Wouldn't it be easier to convert a normal map into object space rather than converting each vertex into tangent space?
0

Share this post


Link to post
Share on other sites
Of course that workings with object-space normal maps is much easier ;). But... imagine you have a wall texture that appears notorously on many walls. For every "orientation" of a wall using that texture you would need one separate normal map. Having normal maps in tangent space and doind computations in that space is thus much more universal and much less memory consuming. You can imagine this using for example for characters. A character's texture will probably be used only on that particular character so having normal map in object-space in this case makes sense. Moreover, you avoid many problems associated with tangent-space computations, like sheared texture coordinates, non-orthogonal tangent basis and so on. So a good idea seems to be to have unique objects with object-space normal maps and "general" textures (like walls, decals, floors) in tangent-space. Note however that this requires from you to keep two slightly distinc shader paths for rendering one type of meshes and the other.
Object-space normal map: http://www.3dkingdoms.com/tut2.jpg
0

Share this post


Link to post
Share on other sites
[quote name='maxest' timestamp='1296863304' post='4769800']
Of course that workings with object-space normal maps is much easier ;). But... imagine you have a wall texture that appears notorously on many walls. For every "orientation" of a wall using that texture you would need one separate normal map. Having normal maps in tangent space and doind computations in that space is thus much more universal and much less memory consuming. You can imagine this using for example for characters. A character's texture will probably be used only on that particular character so having normal map in object-space in this case makes sense. Moreover, you avoid many problems associated with tangent-space computations, like sheared texture coordinates, non-orthogonal tangent basis and so on. So a good idea seems to be to have unique objects with object-space normal maps and "general" textures (like walls, decals, floors) in tangent-space. Note however that this requires from you to keep two slightly distinc shader paths for rendering one type of meshes and the other.
Object-space normal map: [url="http://www.3dkingdoms.com/tut2.jpg"]http://www.3dkingdoms.com/tut2.jpg[/url]
[/quote]

I am generating a normal map per-pixel from a different height map texture for every object anyway. Unfortunately the way I'm generating it places it in tangent space. I was trying to avoid sending more data with my vertices. Is there anything I can do on a per-pixel or per-vertex basis (in the hlsl shader)?
0

Share this post


Link to post
Share on other sites
I my engine I send a normal and a tangent, leaving a bitangent to be computed with the cross product of the normal and the tangent. Certainly, we have two perpendicular vectors to normal and tangent and we must choose the proper one. The idea I use is to send a normal, a tangent, and a determinant of a matrix formed with (tangent, bitangent, normal). The determinant gives the handedness of the basis. So in my vertex shader I do something like:
[code]
bitangent = determinant * cross(normal, tangent)
[/code]
Passing a normal, a tangent and a determinant takes 7 floats, whereas passing the whole basis takes 9 floats. 2 floats my is not much, but is a good step to start :). Maybe someone has some better idea on how to save sending to much data to a vertex shader?
0

Share this post


Link to post
Share on other sites
Well, rather than restructuring my engine to use vertex declarations (instead of FVF), I decided to go a different route:
[url="http://www.gamedev.net/topic/594781-hlsl-height-map-to-normal-algorithm/"]http://www.gamedev.net/topic/594781-hlsl-height-map-to-normal-algorithm/[/url]
0

Share this post


Link to post
Share on other sites
[quote name='maxest' timestamp='1296870489' post='4769845']
I my engine I send a normal and a tangent, leaving a bitangent to be computed with the cross product of the normal and the tangent. Certainly, we have two perpendicular vectors to normal and tangent and we must choose the proper one. The idea I use is to send a normal, a tangent, and a determinant of a matrix formed with (tangent, bitangent, normal). The determinant gives the handedness of the basis. So in my vertex shader I do something like:
[code]
bitangent = determinant * cross(normal, tangent)
[/code]
Passing a normal, a tangent and a determinant takes 7 floats, whereas passing the whole basis takes 9 floats. 2 floats my is not much, but is a good step to start :). Maybe someone has some better idea on how to save sending to much data to a vertex shader?
[/quote]

Personally I send normals, tangents, and bitangents to the vertex shader. I suppose I'd just rater compute all the stuff once per mesh and construct the tangent space matrix in the vertex shader instead of having it computer anything more. Not really sure if thats more efficient or not in the long run.
0

Share this post


Link to post
Share on other sites
[quote name='dsoltyka' timestamp='1296921803' post='4770011']
[quote name='maxest' timestamp='1296870489' post='4769845']
I my engine I send a normal and a tangent, leaving a bitangent to be computed with the cross product of the normal and the tangent. Certainly, we have two perpendicular vectors to normal and tangent and we must choose the proper one. The idea I use is to send a normal, a tangent, and a determinant of a matrix formed with (tangent, bitangent, normal). The determinant gives the handedness of the basis. So in my vertex shader I do something like:
[code]
bitangent = determinant * cross(normal, tangent)
[/code]
Passing a normal, a tangent and a determinant takes 7 floats, whereas passing the whole basis takes 9 floats. 2 floats my is not much, but is a good step to start :). Maybe someone has some better idea on how to save sending to much data to a vertex shader?
[/quote]

Personally I send normals, tangents, and bitangents to the vertex shader. I suppose I'd just rater compute all the stuff once per mesh and construct the tangent space matrix in the vertex shader instead of having it computer anything more. Not really sure if thats more efficient or not in the long run.
[/quote]

I'm currently doing the same, as i'm running into shader complexity issues(PS2.0/running out of instruction space). Efficiency one way or the other will depend on many factors such as scene complexity/geometry complexity, and will probably need to be looked at on a per project basis.
0

Share this post


Link to post
Share on other sites
I also used to send tangent/bitangent/normal but sending tangent/normal/determinant is not only lighter with the memory but also the computations in a vertex shader. For instance, if you have some skeletal animation you probably have a lot of matrix multiplications and you have to transform all tangent/bitangent/normal. With the latter approach you can only transform trangent/normal and once all the computations are done, you simply compute bitangent with the cross product. In general, this will save 1/3 of the matrix transformations (since you avoid dealing with bitangent). Assuming that the cross product has negligible cost.
0

Share this post


Link to post
Share on other sites
For those interested in an thorough explanation of normal mapping and tangent spaces I suggest you take a look
at this -> [url="http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf"]http://image.diku.dk...ikkelsen.08.pdf[/url]
It's a big file, 50 megs, but at least the server is good.

A clear order independent way to define which triangles are to share tangents (averaged) is given at the end of page 47
Order independence is important because otherwise you risk different tools pipelines creating different tangent spaces
for what is essentially the same mesh but with triangles or vertices in a different order. It's also important for getting perfectly
mirrored tangent spaces for mirrored meshes,
Adjacent triangles must share tangent space if and only if the 4 criteria are met.

The first 3 are trivial. The triangles must share
position, normal and texture coordinate at both end-points of the shared edge.
The fourth rule means that the winding (CW/CCW) of the texture coordinates must be the same on both triangles.
The fourth rule is important in the general case but it also allows us to handle mirroring correctly (a split will be created).


The thesis also shows how most commercial products out there have many problems.
Check pages: 44, 45, 52-56

Using the strategy of the thesis gives a perfect result as shown on page 68 (see the tspaces on 67).

Page 7 gives an explanation of the relation between bump mapping and normal mapping.

Hope someone finds this useful.

Cheers,

Morten
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