Let's talk about the Pack/unpack normal problem.

Source: Internet
Author: User

Currently, many delayed illumination algorithms store the normal pass. To save resources, many algorithms pack the normal three components into two components. Take the left-hand coordinates of d3d as an example, normal is in the camera space.
The first steps are as follows:
Pack: xy = norm. XY;
Unpack: norm. XY = xy;
Norm. z =-SQRT (1-x ^ 2-y ^ 2 );
This method is widely used at the beginning, but it is wrong, because due to the relationship between perspective projection, some faces are not in the eye direction, but can still be rendered into the buffer, therefore, the Z symbol cannot be determined.
Stalker makes a very direct improvement on it:
Pack: xy = norm. XY * 0.5 + 0.5;
X * = norm. z> 0? 1:-1;
Unpack: norm. XY = ABS (xy) * 2.0-1.0;
Norm. z = (x> 0? 1:-1) * SQRT (1-x ^ 2-y ^ 2 );
In short, it is to save the Z symbol to X after pack, because X must be a positive number after pack, which is correct in algorithm, but in actual use, it is usually used to save the normal texture. Each component does not exceed 16 bits. When X and Y are close to 1, there will be a large error. At this time, z is close to 0, if it is a large plane, the symbol of X will shake between 1 and-1, which is mainly indicated by gray stripes on the image.
The cryengine3 present also has a pack method:
Pack: xy = normalize (norm. XY) * SQRT (norm. z * 0.5 + 0.5 );
Unpack: norm. z = length (xy) ^ 2*2-1;
Norm. XY = normalize (xy) * SQRT (1-norm. z * norm. z );
This means that the value of Z is used as the length of the XY vector. When unpack is used, the length is first Z. Then, due to the consistent XY ratio, the norm is solved. XY/SQRT (1-norm.z * norm. z) = norm. XY/SQRT (norm. x * norm. X + norm. y * norm. y) = xy/SQRT (x * x + y * Y) to obtain XY, which is correct in the algorithm, but it is actually a problem to use, one problem is the division of 0. Because of the normalize operation, when Z is close to 1 or-1, unpack XY will get a result with a large error, and the illumination effect will jump, but it is not obvious. The other is that this algorithm requires a large amount of computing, resulting in a large accumulation of errors. In the same plane, the camera may have different brightness at different angles, which is obvious in some cases.

In fact, in the absence of a relatively large plane, the problem is sometimes not obvious, and the problem will be improved after the number of BITs is increased, but since the number of BITs is increased, it is better to simply store three components without the need for the pack/unpack command. So far, I still have not found a satisfactory algorithm, and it is most satisfactory to store three components directly.

 

Well, after sending the message, I checked the normalmap Method for Xiao Q's blessing, but it also applies here:

Pack: Px = x/(1 + Z)
Py = y/(1 + Z)

Unpack: denom = 2/(1 + px * px + py * Py)
X = px * denom
Y = py * denom
Z = denom-1

At present, it seems that this is a good method. Although it is a little slow, there is no problem with the boundary value and numerical accuracy. Relatively stable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.