Monday, July 18, 2011

Encoding normals for Gbuffer

Deferred shading has nowadays become nearly ubiquitous in real-time rendering due to the separation of geometry and lighting passes. The general idea of this technique is to render all important properties (color, normal, reflectivity and so on) of all visible surfaces to a set of screen-sized textures. Later rendering passes (lighting) get surface parameters from those textures and thus complex geometries do not have to be rendered multiple times.

One design problem of Gbuffer implementation is the efficient encoding of surface normals. Normals in three-dimensional space have three components:

N = Nx,Ny,Nz

The most intuitive way would be to store those in three texture channels. But this would be wasteful, because we know, that:

Nx2 + Ny2 + Nz2 = 1

Gbuffer requires many texture channels for other data, thus we want to cut off as many unnecessary channels as possible to conserve memory and fillrate.

Another simple alternative would be to store only two components (Nx and Ny) and reconstruct third (Nz) in pixel shader. Unfortunately we will lose the sign of Nz in that process. While in ideal scene there should be no normals with negative Z (facing away from camera), they happen in real scenes because of realistic polygon counts.

There exist several techniques for encoding normals while (at least partially) preserving Z component. Unfortunately no one of those is ideal. Either they are not able to encode full range of Z (various projections) or waste precision and calculation (polar coordinates).

While implementing foliage shader for Khayyam I needed a way to encode full range of possible normals into two-component vector (that will later be stored in 4-component 8-bit RGBA texture of Gbuffer). The following is the brief introduction of the technique used. It solves all the problems I am aware of - with the price of slightly more shader instructions than simple projection encoders.

Efficient projection of normal space

We forget for awhile the need of storing the sign of Z component and look, how we can store X and Y components most efficently.
The trivial way is to simply forget Z and store X and Y. In geometric terms it means projecting the hemisphere of normal space to an unit circle on XY plane along Z vector as in following figure:

The trivial projection of normal space to XY plane

The problem with this projection is, that the uniform angular difference between normals near equator gives much smaller difference in X and Y coordinates than near poles. If the precision of normal texture is limited to 16 bits (4x8 bit or 2x16 bit integer buffers) or even less (FP16 buffers) , the loss of precision may become visible. For example, for 16 bit buffers, the minimum representable angle near equator is:

acos (1 - 2e-15) = 1.44°

Near poles it is much better:

asin (2e-15) = 0.002°

Clearly we are wasting precision near poles and introduce errors near equator.

To get better distribution of precision, we can switch projection from parallel to radial, with the projection center at the point (0,0,-1) as on the following figure:

The radial projection of normal space

The distribution of angles is still not uniform but is clearly much better (it differs only by the factor of 2 at poles and equator).
Actually, having the center of projection at (0,0,-sqrt(2)) would result in even better distribution, but I wanted to keep it at (0,0,-1) to simplify calculations a bit.

The hemisphere is still projected at unit circle at XY plane, although now we cannot project the normals on negative hemisphere directly but have to take the absolute value of Z coordinate before projecting.

This solves the problem of effecient use of normal texture precision. Now we can go on to encoding the sign of Z into the same buffer.

Encoding the sign of normal Z coordinate

Our positive hemisphere of normal space got projected to unit circle on XY plane as in following figure:

The normal space projection to XY plane and compaction schema

As we can see, we are actually wasting the numerical space of normal texture. The texture is able to encode values in unit square, but only unit circle is used - the possible values on dashed areas can never happen in our projected normals. We could store normals with negative Z in those areas, but unfortunately there is no easy algorithm to do that.

Now we do another conversion and pack all the values from unit circle into diamond-shaped area, given by the following formula:

|X| + |Y| <= 1

This can be done with the following algorithm (let the normal be Nx', Ny' and the projection be Nx'', Ny''):

r = sqrt (Nx' * Nx' + Ny' * Ny')
D = |Nx'| + |Ny'|
Nx" = Nx' * r / D
Ny" = Ny' * r / D

We lose some precision at  the normals close to 45° angles, but the maximum loss is by the factor of sqrt(2).

The resulting projection of normal space is shown in following figure:

Compacted normal space and Z flipping directions

Now the whole projection of the positive hemisphere of normal space takes exactly the half of the size of unit square. The extra space can be used to encode normals with negative Z.

We do this by mirroring the final normal projections by the closest one of diagonal lines (|x| + |y| = 1).

Thus we have encoded the full normal space to unit square with minimal loss of precision.

Decoding normals

To decode normals we have first to find the sign of Z coordinate. This is done with the following formula:

Zsign =  1 if (|x| + |y|) <= 1
Zsign = -1 if (|x| + |y|) >  1

Now, if Z is negative, we have to mirror our encoded normal by the closest  diagonal line (|x| + |y| = 1) so the resulting normal is inside the diamond shaped area.

We unpack normals to unit circle with reverse packing algorithm:

d = sqrt (Nx" * Nx" + Ny" * Ny")
r = |Nx"| + |Ny"|
Nx' = Nx" * d / r
Ny' = Ny" * d / r

From normal projection on unit sphere (N') unit sphere we unproject to normal on positive hemisphere (N).

Finally we set the sign of the Z component of N from previously found Zsign.

And that is it.

Encoding quality

I ran simulated tests of this algorithm on CPU with 100 000 000 randomly generated normals, including normals with any 1 or 2 components zero. Encoded vector was written and then read back from 4-component unsigned char buffer to simulate storing of 2-component normal in RGBA8 texture.

The maximum angular error between original and retrieved normal was 0.028°.

GLSL shader code

For those interested, here is current GLSL shader code of libsehle implementation. It is a bit heavy, but if your lighting is fill-rate bound, as is mine, you can spare some GPU cycles.


vec2 encodeNormal (vec3 normal)
    // Project normal positive hemisphere to unit circle
    // We project from point (0,0,-1) to the plane [0,(0,0,-1)]
    // den = dot (l.d, p.n)
    // t = -(dot (p.n, l.p) + p.d) / den
    vec2 p = normal.xy / (abs (normal.z) + 1.0);

    // Convert unit circle to square
    // We add epsilon to avoid division by zero
    float d = abs (p.x) + abs (p.y) + EPSILON;
    float r = length (p);
    vec2 q = p * r / d;

    // Mirror triangles to outer edge if z is negative
    float z_is_negative = max (-sign (normal.z), 0.0);
    vec2 q_sign = sign (q);
    q_sign = sign (q_sign + vec2 (0.5, 0.5));
    // Reflection
    // qr = q - 2 * n * (dot (q, n) - d) / dot (n, n)
    q -= z_is_negative * (dot (q, q_sign) - 1.0) * q_sign;

    return q;


vec3 decodeNormal (vec2 encodedNormal)
    vec2 p = encodedNormal;
    // Find z sign
    float zsign = sign (1.0 - abs (p.x) - abs (p.y));
    // Map outer triangles to center if encoded z is negative
    float z_is_negative = max (-zsign, 0.0);
    vec2 p_sign = sign (p);
    p_sign = sign (p_sign + vec2 (0.5, 0.5));
    // Reflection
    // qr = q - 2 * n * (dot (q, n) - d) / dot (n, n)
    p -= z_is_negative * (dot (p, p_sign) - 1.0) * p_sign;

    // Convert square to unit circle
    // We add epsilon to avoid division by zero
    float r = abs (p.x) + abs (p.y);
    float d = length (p) + EPSILON;
    vec2 q = p * r / d;

    // Deproject unit circle to sphere
    float den = 2.0 / (dot (q, q) + 1.0);
    vec3 v = vec3(den * q, zsign * (den - 1.0));

    return v;


  1. Thanks for that awesome and insightful article!
    What I'm still wondering however is how you're dealing with negative XY-Values when storing in the usual RGBA8 UNSIGNED_BYTE-texture. Assuming you are packing x to 16bit RG components and y to 16bit BA,
    as far as I know, the usual way to go about this would be to scale all values by ( + 1 ) / 2 and unscale by * 2 + 1 during unpacking. Thus all above considerations would be essentially broken down to the first quadrant. And if I'm not mistaken, that would also speed up the z-sign reflection as xy' = 1 - xy.

    Or would you use e.g. the R-channel for -x, the G-channel for +x and thus restricting to only 8 bit precision?

    Or do you yo use Floating-point textures? ;)

  2. To be honest I have not tried to optimize it much yet. At moment I am doing the usual (V + 1) / 2 transformation and I am not sure, whether moving everything to 0,0 - 1,1 quadrant during packing would make things faster.
    I tried FP16 buffers, but my card did not like mixing U8 and FP16 color buffers on the same render target. Thus I went back to RGBA8 and just pack normals into RG and BA parts.

  3. اليك خدمات منزلية متقدمة تساعدنا علي الارتقاء بشركة ركن البيت في مدينة الدمام من خلال اعمالها المتميزة التي تقدمها في مجال النظافة والقضاء علي الحشرات فخدماتنا متنوعة مثل شركة تنظيف بالدمام التي تكون متخصصة في اعمال النظافة العامة التي تتمثل في المنشأت الكبيرة والصغيرة بجميع انواع واليك خدمة متميزة ايضا وهي شركة تنظيف فلل بالدمام التي تكون لديها كل الامكانيات المثالية التي تساعدنا في تنفيذ خدمات نظافة الفلل المستعملة والمفروشة بواسطة فريق فني لديه كل الامكانيات التي تساعده في تقديم ذلك ولديك خدمة ايضا نظافة الشقق بواسطة شركة تنظيف شقق بالدمام وعمل التنظيف اللازم لها بواسطة فريق لديه اعمال التميز والتنفيذ في تقديم الخدمات المخصصة في اعمال النظافة واليك خدمة مثالية نقدمها في القضاء علي الحشرات الصغيرة بواسطة مبيدات طبيعة تساعدنا في ذلك فتعاملك مع شركة مكافحة حشرات بالدمام لديها امكانيات متميزة تساعدك علي ان تخلصك من الحشرات لان تجد كل ذلك الا من خلال ركن البيت التي لديها كل الامكانيات في البحث عن شركة رش مبيدات بالدمام التي تقوم بالرش بواسطة فني مختص معه الادوات اللازمة للقيام بذلك وعطائك الضمانات اللازمة علي ذلك واليك خدمة نقل اثاث منزلية تساعدك في الوصول الي مكانك الجديد بواسطة شركة نقل اثاث بالدمام التي لديها كل الامكانيات والسيارات التي تساعدك علي تحقيق ذلك

  4. شركة نقل عفش بالدمام
    عالميه الدمام- 0542613483 - افضل شركات نقل العفش بالمنطقه الشرقيه شركة نقل اثاث بالدمام
    ارخص شركة نقل اثاث بالدمام
    شركة نقل اثاث بالجبيل
    أن الشركة تتمتع بالالتزام التام بمواعيدها، فلا تعمل على مخالفتها تحت أي ظرف من الظروف وهذا بداية من عملية الاتصال وحتى إنهاء الخدمة تمامًا، كما أن فريق العمل ذو حجم كبير نسبيًا نقل عفش بالخبر
    شركة نقل عفش بالجبيل

  5. شركتنا شركة نقل اثاث بالجبيل الأفضل كونها تنظم من عملها، وتنظم من عمالتها، فكل عامل له عمل مخصص يقوم به. نقل عفش بالدمام
    نقل اثاث بالدمام
    نقل عفش بالاحساء
    لن تجد أجدر من شركه نقل عفش بالدمام قادرة على إتمام تلك المهمة حيث ثقة عملائها الكرام على المحك ولن تقبل تحت أي حال من الأحوال أن يخيب ظن العملاء نقل اثاث بالاحساء

  6. يمكن تعريف الشحن المحدود الذي تقدمه شركه نقل اثاث بالدمام بكونه ما يقتصر على نقل ما قد يحتاجه العميل من أثاث كالأجهزة الكهربائية أو الأثاث الخشبية حتى وإن كان لقطع غيرة ومدودة منه. شركة نقل عفش بالخبر
    نقل عفش بالخبر
    شركة نقل عفش فى بالخبر
    وجدير بالذكر أنه بعد الرفع يقوم العمال بتركيب الأثاث كما كان شركات نقل العفش بالخبر

  7. انوار طيبة أفضل شركة نظافة بالدمام متخصصة في مجال التنظيف بالدمام والمناطق المجاورة فنحن شركة تنظيف مكيفات بالدمام نقوم أيضاً بتنظيف (فلل– شقق- منازل- بيوت- المجالس- العمائر- الشركات – المطاعم – الفنادق- المحال التجارية) وجميع الأماكن التي تحتاج للتنظيف، وتقوم الشركة بتنظيف منزلك بأحدث الماكينات شركة تنظيف مكيفات بالدمام
    شركة تنظيف مكيفات بالخبر
    شركة تنظيف بالخبر تقدم أسعار مميزة لعملائها فهي أرخص شركة تنظيف مكيفات حيث تقوم بتنظيف المنازل والشقق والفلل والكنب والسجاد والمسابح والمدارس والمساجد والخزانات بالدمام و بالخبر و بالجبيل و بالقطيف تستخدم أجود أنواع المنظفات فهي افضل شركة نظافة بالخبر شركة غسيل مكيفات بالدمام
    شركة تنظيف مكيفات بالقطيف
    مؤسسة انوار طيبة-ارخص شركة تنظيف مكيفات بالقطيف والدمام والجبيل – افضل شركة تنظيف مكيفات السبلت بالدمام والقطيف، وتنظيف وصيانة وغسيل المكيفات سبليت ومركزية ومخفي وكاست ودولابي وشباك وتركيب جميع المكيفات شركتنا افضل شركة غسيل مكيفات بالدمام والجبيل تتعامل معكم شركة تنظيف مكيفات برأس تنورة

  8. ان حشرة البق تشكل خطورة كبيرة علي المنازل وحصوصا الاطفال لذلك يمكنك ايجاد الحل الامثل من خلال شركة مكافحة البق بالدمام حيث تضم الشركة افضل الخبراء فهي افضل شركة مكافحة البق بالدمام شركة مكافحة البق بالدمام
    شركة مكافحة البق بالخبر
    شركة مكافحة النمل الابيض بالدمام
    افضل شركة مكافحة النمل الابيض بالقطيف شركة  انوار طيبة ونصلك اينما كنت نستخدم افضل المبيدات للقضاء علي الحشرات النمل والصراصير وبق الفراش والوزع والنمل الابيض وجميع الحشرات الزاحفة ,مكافحة جميع انواع الحشرات باستخدام افضل المبيدات المستوردة والمحلية لضمان القضاء علي الحشرات مع الضمان وخصومات هائلة شركة مكافحة النمل الابيض بالقطيف
    شركات مكافحة حشرات ورش مبيدات بالدمام هل تبحث عن شركة مكافحة حشرات بالسعودية هل لديك نمل في المطبخ او حشرة البق في الخشب؟ هل عندك صراصير او نمل او فئران وتفسد عليك حياتك في منزلك او شركتك؟ لا تقلق فهناك العديد من شركات مكافحة الحشرات في السعودية وأيضا يوجد العديد من شركة رش مبيدات ومكافحة الحشرات بالدمام شركة رش مبيدات بالدمام

  9. قبطان الخليج -0504353061-يُعد الأثاث من أكثر الأشياء التي تحتاج إلى حرص ودقة بالغة عند القيام بنقلها شركة نقل عفش بالظهران
    تحرص على تقديم الضمان اللازم عن العمل الذي تقوم به لعملائها الكرام، فالضمان بدوره يطمئن العميل وفي النفس الوقت يضمن مصداقية الشركة شركة نقل اثاث بالظهران

  10. ان حشرة البق تشكل خطورة كبيرة علي المنازل وحصوصا الاطفال لذلك يمكنك ايجاد الحل الامثل من خلال شركة مكافحة البق بالدمام حيث تضم الشركة افضل الخبراء فهي افضل شركة مكافحة البق بالدمام شركة رش حشرات بالدمام
    شركة مكافحة حشرات بالدمام
    شركة مكافحة حشرات بالخبر تقدم لكم العديد من الخدمات المميزة، حيث أن الشركة تستطيع مكافحة النمل الابيض بالقطيف بالإضافة إلى كافة أنواع الحشرات الأخرى بكل سهولة وبأحدث الإمكانيات مثل مكافحة البق بالقطيف ومكافحة الصراصير بالقطيف ومكافحة الصراصير بالقطيف ولها فروع مثل شركة مكافحة حشرات بالدمام شركة مكافحة حشرات بالخبر
    شركة مكافحة البق بالدمام

  11. We find lots of learning after reading this very useful article . cara menggugurkan hamil

  12. شركة الغدير تعد من اهم شركات تنظيف المكيفات على مستوى مدن المملكة العربية السعودية فالشركة تمتلك من الكوادر التى جعلتها أفضل شركة تنظيف مكيفات بالدمام والتى تقدم العديد من الخدمات المتعلقة بالمكيفات ومن ابرز ما تم تقديمة فى التكييف ( صيانة المكيفات ، غسيل المكيفات ، تركيب المكيفات ، تعبئة الفريون ) والشركة تفعل خدماتها لمختلف انواع المكيفات مثل السبلت والمركزى والدكت والمخفى والصحرواى والشركة لديها أفضل فنى مكيفات فلبينى فى الصيانة وكل مدينة فى الشرقية يوجد فرع مخصص فى صيانة وتنظيف المكيفات مثل ( الدمام والخبر والظهران والقطيف وعنك وسيهات وصفوى وام الساهك والجبيل والهفوف وبقيق والرياض .
    شركة تنظيف مكيفات بالرياض هى الشركة الام فى غسيل المكيفات وتنظيف المكيفات
    من اهم شروع شركات تنظيف المكيفات
    1- شركة تنظيف مكيفات بالخبر تعد افضل شركة غسيل المكيفات بالخبر وتغطى كافة انحاء احياء الخبر ( العزيزية والعقربية الدانة والحزام الزهبى ) وخدماتها غسيل المكيفات وصيانة التكييف
    2- شركة تنظيف مكيفات بالقطيف تعد افضل شركة صيانة المكيفات فى القطيف وتوفر خدمات عروض تنظيف المكيفات وافضل سعر نظافة المكيفات
    3- شركة تنظيف مكيفات بالاحساء تعد هى افضل شركة غسيل المكيفات فى الهفوف وتخدم منطقة سلوى وبقيق وكم سعر تنظيف مكيف سبليت تعد شركة تنظيف مكيفات بالجبيل ارخص شركة نظافة مكيفات
    4 - شركة تنظيف مكيفات بالجبيل تعد منطقة الجبيل هى عامود شركات تنظيف التكييف ويوجد محل صيانة المكيفات بالجبيل
    5- شركة تنظيف مكيفات بالظهران وتتيع شركة صيانة المكيفات بالخبر
    6- شركة تنظيف مكيفات بالرياض تعد عامود شركات نظافة المكيفات وتعمل فى مختلف انواع المكيفات السبلت والمركزى والداكت
    7- شركة تنظيف مكيفات بالدمام عامود شركات صيانة وتنظيف المكيفات ونظافة التكييف
    هناك طلب كبير على صيانة المكيفات وتنظيف التكييف فى فصل الصيف وهو ما قدمته شركات المكيفات من امثلة شركة تنظيف مكيفات بجدة التى تخدم المنطقة الغربية
    درجات الحرارة
    درجة الحراة هى المؤشر الذى يعتاد به فى تنظيف المكيفات والتى تعد من ثمار شركات تنظيف التكييف وعلى نحوكبير من الخدمات
    اهم الادوات التى تستخدمها الشركة فى غسيل المكيفات
    1- كيس تنظيف المكيفات
    - مضخة تنظيف المكيفات
    مادة تنظيف المكيفات ولمتابعة المزيد عبر موقع الشركة
    واصبحت عمليات تنظيف المكيفات من الامور السلسة التى تتبعها شركة تنظيف مكيفات بالخبر
    اهم شركات التنظيف المعمول بها فى المملكة شركة صيانة المكيفات المركزية والدكت والمخفى وغيرها من رواد الشركات العالمية فى التنظيف والصيانة

  13. Air conditioning cleaning company in Al-Ahsa makes you receive the summer and air-conditioner with high efficiency and excellent, as it is known that air-conditioners in the summer and in the Kingdom of Saudi Arabia in particular cannot be dispensed with due to the high temperatures, so our company provides the best level of air-conditioning cleaning service so that it works with good efficiency, The company also provides maintenance services and provision of damaged spare parts with original and branded ones. The company also provides all its services through a team of technicians and specialists who have long experience in this field, in addition to the company's competitive and distinguished prices, with u Katana will find all of the services that belong to the highest quality Macaivk and the required level and the lowest prices on the market, ask our services now
    شركة تنظيف مكيفات بالاحساء تجعلك تستقبل شهر الصيف ومكيفك بكفاءة عالية وممتازة، فكما هو معروف أن المكيفات في فصل الصيف وفي المملكة العربية السعودي بصفة خاصة لا يمكن الاستغناء عنها بسبب ارتفاع درجات الحرارة، لذلك تقدم شركتنا أفضل مستوى من خدمة تنظيف المكيفات حتى تعمل بكفاءة جيدة، كما تقوم الشركة أيضًا بتقديم خدمات الصيانة وتوفير قطع الغيار التالفة بأخرى أصلية ومن ذات العلامة التجارية، كما تقوم الشركة بتقديم كل خدماتها عن طريق فريق من الفنيين والمتخصصين الذين لديهم خبرة طويلة في هذا المجال، هذا فضلاً عن أسعار الشركة المتميزة والتنافسية، فمع شركتنا سوف تجد كل الخدمات التي تخُص مكيفك بأعلى جودة وبالمستوى المطلوب وأقل الأسعار الموجودة في السوق، اطلب خدماتنا الآن ولا تتردد فشركتنا هي ساعدك الأيمن للحصول على مكيف نظيفًا وبكفاءة ممتازة.
    شركة تنظيف مكيفات بالاحساء
    شركة غسيل مكيفات بالاحساء
    تنظيف مكيفات بالاحساء
    شركة تنظيف بالاحساء
    شركة تنظيف بالرياض

  14. I’m impressed, I have to admit. Rarely do I come across a blog that’s both educative and interesting, and let me tell you, you have hit the nail on the head. The issue is an issue that not enough folks are speaking intelligently about. I'm very happy I found this in my search for something relating to this.
    Jio Lottery Winner 2020
    KBC Lottery Winner 2020
    KBC Winner List 2020
    KBC Head Office Contact Number

  15. KBC Winner List 2021 is going to update soon after the completion of current season.

  16. Packers and Movers Bangalore - Reliable and Verified Household Shifting Service Providers Give Reasonable ###Packers and Movers Charges. Cheap and Best Office Relocation Compare Quotation for Assurance for Local and Domestic House Shifting and Get estimates today to save upto 20%, ***Read Customer Reviews - @ Packers And Movers Bangalore