Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Possible to pack a normal vector into a diffuse one?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 vant   Members   -  Reputation: 115

Like
0Likes
Like

Posted 27 August 2012 - 04:27 PM

Say you have two vectors, one for color, and another for normal <dx,dy,dz> <nx,ny,nz>

Is there a way you could pack this into a vector <vx,vy,vz,va> such that you could recreate the two orginial vectors, from the packed one? You can make an assumption that the normal vector is normalized, if that helps.

Some have tried taking dot products, but I don't think that would work in three dimensions.

Thank you!

Sponsor:

#2 Tournicoti   Prime Members   -  Reputation: 683

Like
0Likes
Like

Posted 27 August 2012 - 09:18 PM

irrelevant and wrong. Pardon Posted Image

Edited by Tournicoti, 09 September 2012 - 03:17 PM.


#3 Hodgman   Moderators   -  Reputation: 30958

Like
1Likes
Like

Posted 27 August 2012 - 09:34 PM

If you transform it in view space you can assume that its z component is always negative

Not true -- imagine standing in a room where the roof slopes upwards away from you, and the floor slopes downward away from you. If rendering with perspective, the floor and roof are both visible, but their view-space normal is pointing away from you.
When storing x&y only, you also need an extra 1 bit to store the sign of the z value.

#4 Tournicoti   Prime Members   -  Reputation: 683

Like
0Likes
Like

Posted 27 August 2012 - 09:40 PM

I don't really understand ... Are you talking about the case of showing the back side of a triangle ? Because I always invert normals these faces. I do this in my project and I don't see any problem at all

#5 Hodgman   Moderators   -  Reputation: 30958

Like
1Likes
Like

Posted 27 August 2012 - 09:47 PM

I don't really understand ... Are you talking about the case of showing the back side of a triangle ?

No. I'm talking about triangles where the front is visible, even though it's normal is pointing away from the viewer.
e.g. A smaller corridor connecting to a larger one, via a sloped floor/roof.
Red is the players FOV, green are the surface normals. Blue is the incorrect surface normal that you'll be reconstructing if you don't account for the fact that view-space Z can be negative.
Posted Image

Is there a way you could pack this into a vector such that you could recreate the two orginial vectors, from the packed one? You can make an assumption that the normal vector is normalized, if that helps.

As above, you can discard one of the components of the normal, but keep it's sign (you can encode the sign into the diffuse colour, e.g. make the red channel only 7-bits for colour, and 1 bit for sign(n.z)). This gets you down to 5 components instead of 6.
Alternatively, you can transform colour into 2 chromaticity components and 1 luminance component. You could then scale the vector by the luminance component and throw it away (again getting you down to a total of 5).

Actually, if these are floating point vectors, and your diffuse colour is 8-bit, you might be able to pack them together.
If we assume that your normal components are always less than 1.0, then you can store the normal in the fractional part, and the colour in the integer part of the float.
Something like:
float4 packed = normal + (floor(colour*255)+1);
float4 decodeNormal = frac( packed );
float4 decodeColour = (floor( packed )-1)/255.0;

Edited by Hodgman, 27 August 2012 - 09:58 PM.


#6 Tournicoti   Prime Members   -  Reputation: 683

Like
0Likes
Like

Posted 27 August 2012 - 10:06 PM

Ok thank you for the explanation Posted Image , I didn't noticed my normals were wrong in this case Posted Image . A last question before I really add this extra bit in my gbuffer : couldn'it work in clip space ? I mean is it right to assume this (normal.z<0) in clip space instead of view space ?

#7 vant   Members   -  Reputation: 115

Like
0Likes
Like

Posted 28 August 2012 - 08:29 AM

Actually, if these are floating point vectors, and your diffuse colour is 8-bit, you might be able to pack them together.
If we assume that your normal components are always less than 1.0, then you can store the normal in the fractional part, and the colour in the integer part of the float.


This is clever, and may work. I'm actually packing these not to for the purpose of using to know the direction of the vector (and reversing it for backsides of triangles), but to save several texture samples in the shader. I'm using trilinear sampling, and also using XNA, so texture arrays are out. Now a vertex could sample from 3 different textures at most, combined with trilinear sampling, you have 9 texture samples right there. Now if you add in normals, thats 18 samples just for one pixel.

The issue with this then becomes, you will need to load a processed HalfVector4 texture into the gfx, rather than a dx3 compressed one which will take more time. Not sure if the tradeoff is worth it. It would be best if you could stick to the diffuse being only 32 bit, 8 bits for each rgba. I'm wondering if there is some way to combine them such that fa(<vx,vy,vz,va>) = <dx,dy,dz> and fb(<vx,vy,vz,va>) = <nx,ny,nz>? Some clever math trick or something using the extra alpha channel.

Edited by vant, 28 August 2012 - 09:27 AM.


#8 Hodgman   Moderators   -  Reputation: 30958

Like
0Likes
Like

Posted 28 August 2012 - 11:24 AM

It doesn't sound like it's worth it. Sampling 1 16x4 texture is going to have similar cost to sampling 2 8x4 textures. If those 8-bit textures are DXT compressed, then the 16-bit fetch will probably be much slower than the 2xDXT fetches.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS