当前位置:网站首页>Understand encodefloatrgba and decodefloatrgba

Understand encodefloatrgba and decodefloatrgba

2022-07-05 04:47:00 Haro3378

Recently, I'm looking at various methods of rendering shadows , Found generating ShadowMap There is a very common compression method , But you can only find the code on the Internet , I can't see a more detailed explanation , So here is an explanation that I think is relatively easy to understand .

inline float4 EncodeFloatRGBA( float v ) {
  float4 enc = float4(1.0, 255.0, 65025.0, 16581375.0) * v;
  enc = frac(enc);
  enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
  return enc;
}
inline float DecodeFloatRGBA( float4 rgba ) {
  return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0) );
}

First, let's introduce the usage scenarios

ShadowMap Saved when viewing the scene from the light angle , The depth value corresponding to each pixel , The scope is [0,1], This value is later Pass It is used to judge whether it is in the shadow , So we need to save this value , Because calculation ShadowMap Is in a separate Pass in , So you can render it to the map .

We also need to understand the accuracy , float The accuracy of the type is 4btye, Maps have various formats , But in order to 4btye The data is completely saved , We choose R8G8B8A8 Format map as the rendering target .

Now let's calculate step by step

         First of all, will float As four parts 8bit constitute :

        Because we chose RT yes R8G8B8A8, So it happens that each channel stores 8bit data . The four channels are independent , So the natural way is right float Four parts of data are shifted , Then store them separately , These descriptions may still be unclear , You can see the diagram below .

1. First, the data of four parts are “ alignment ”.

about b、c、d, Separate shift 8、16、24, such abcd It appears in a dimension ,

This corresponds to the code

float4 enc = float4(1.0, 255.0, 65025.0, 16581375.0) * v;

The result is like this :

  The first line is multiplicative 1, So it can be regarded as raw data . In the end, we just need to save the data in the Yellow grid .

2. Delete extra data

First of all, remember , Because it's handled ShadowMap Depth in ,float The scope of 0~1, So for beyond 32 Bit data can be regarded as greater than 1 Part of , Delete these data first , This corresponds to the method Frac

The result is shown in Fig. :

Then we need to deal with 0-24 A data , It can be found by observation that , There are two parts of the same data !

So we can continue the displacement , Let the two parts be subtracted . Before will float ride 2^n It's moving left , Then the division operation is shifted to the right , Extract YZW Divide the vector by the corresponding number of digits ( Because the previous data is XYZW, So in order to match , We use YZWW To calculate , But the last one W By 0).

This step corresponds to the code

enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);

  After this step, only the yellow box is left , At this time, the data is directly stored in R8G8B8A8 You won't lose accuracy .Decode and Encode Is a similar idea , It's just the opposite .

 

 

 

原网站

版权声明
本文为[Haro3378]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140629341976.html