3 рдбреА рдореЗрдВ рдЖрдВрдЦреЛрдВ рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ, рдпрд╛ рдбрдореА рдХреЗ рд▓рд┐рдП рдПрдЪрдбреАрдЖрд░

рдЬрдм рдЖрдк рдПрдХ рдЙрдЬреНрдЬреНрд╡рд▓ рдХрдорд░реЗ рд╕реЗ рдПрдХ рдЕрдВрдзреЗрд░реЗ рдХрдорд░реЗ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рд░ рдХреЛрдИ рдЕрд╕реНрдерд╛рдпреА рдЕрдВрдзрд╛рдкрди рдХреЗ рдкреНрд░рднрд╛рд╡ рдХреЛ рдЬрд╛рдирддрд╛ рд╣реИред рдПрдХ рдЖрдо рдЧрд▓рдд рдзрд╛рд░рдгрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рджреГрд╖реНрдЯрд┐ рдХреА рд╕рдВрд╡реЗрджрдирд╢реАрд▓рддрд╛ рдкреБрддрд▓реА рдХреЗ рдЖрдХрд╛рд░ рд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рд╣реЛрддреА рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреБрддрд▓реА рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗрд╡рд▓ 25 рдмрд╛рд░ рдЖрдиреЗ рд╡рд╛рд▓реА рд░реЛрд╢рдиреА рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд░реЗрдЯрд┐рдирд╛ рдХреА рдХреЛрд╢рд┐рдХрд╛рдПрдВ рд╕реНрд╡рдпрдВ рдЕрдиреБрдХреВрд▓рди рдореЗрдВ рдореБрдЦреНрдп рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддреА рд╣реИрдВред

рд╢реАрд░реНрд╖рдХ

рдЦреЗрд▓реЛрдВ рдореЗрдВ, рдЗрд╕ рдкреНрд░рднрд╛рд╡ рдХреЛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЛрдирдореИрдкрд┐рдВрдЧ рдирд╛рдордХ рдПрдХ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

tonemapping - рдЖрдВрдЦ / рдХреИрдорд░рд╛ / рдореЙрдирд┐рдЯрд░ ( LDR , рдХрдо рдЧрддрд┐рд╢реАрд▓ рд░реЗрдВрдЬ, рджреЛрдиреЛрдВ рдкрдХреНрд╖реЛрдВ рдкрд░ рд╕реАрдорд┐рдд) рдХреА рдзрд╛рд░рдгрд╛ рдХреЗ рдЕрдВрддрд┐рдо рдЕрдВрддрд░рд╛рд▓ рдкрд░ рдЪрдордХ рдХреА рдкреВрд░реА рдЕрдирдВрдд рд╢реНрд░реЗрдгреА ( HDR , рдЙрдЪреНрдЪ рдЧрддрд┐рд╢реАрд▓ рд░реЗрдВрдЬ, 0 рд╕реЗ рдЕрдирдВрдд рддрдХ) рдХреЛ рдкреЗрд╢ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ред

рдПрдЪрдбреАрдЖрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╕реНрдХреНрд░реАрди рдмрдлрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдп, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реАрдорд╛ [0..1] рдореЗрдВ рд╕рд╣реА рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред



рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рджреГрд╢реНрдп рдХреА рд╕рдордЧреНрд░ рдЪрдордХ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рднреА рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рдЬреНрдпрд╛рдорд┐рддреАрдп рдФрд╕рдд рдЪрдордХ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдорд╛рд░реЗ рд░рд╛рдд рдХреЗ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрдиреБрдЪрд┐рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЫрд╡рд┐ рдХреНрд╖реЗрддреНрд░ рдЕрдВрдзреЗрд░рд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдПрдХ рдЙрдЬреНрдЬреНрд╡рд▓ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рд╣реЛ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдФрд╕рдд рдЪрдордХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реИред рдЗрд╕рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдЪрдордХ рд▓реЗрдВ рдФрд░ рдЗрд╕реЗ рдЖрдзреЗ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВред

рд╣рдо рдЕрдкрдиреА рддрд╕реНрд╡реАрд░ рдХреЛ рджреЛ рдХреА рд╢рдХреНрддрд┐ рдХреЗ рдмрд░рд╛рдмрд░ рдПрдХ рдкрдХреНрд╖ рдХреЗ рд╕рд╛рде рдирд┐рдХрдЯрддрдо рд╡рд░реНрдЧ рдореЗрдВ рдирд┐рдЪреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рддрд┐рд░рд╕реНрдХреГрдд рдХрд░рддреЗ рд╣реИрдВред рддрдм рд╣рдо рдЗрд╕реЗ рд╣рд░ рдмрд╛рд░ рджреЛ рдмрд╛рд░ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЬрдм рддрдХ рдХрд┐ рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рд╢реЗрд╖ рди рд╣реЛ:

downsampling

рддрд╕реНрд╡реАрд░ рдХреЛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЪрд╛рд░ рдкрдбрд╝реЛрд╕реА рдкрд┐рдХреНрд╕реЗрд▓ рд▓реЗрдВрдЧреЗ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдордзреНрдп рдХрд╛ рдЪрдпрди рдХрд░реЗрдВрдЧреЗ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЕрдзрд┐рдХрддрдо рдПрдХ)ред рдЬреНрдпрд╛рдорд┐рддреАрдп рдорд╛рдзреНрдп рдХреА рддреНрд╡рд░рд┐рдд рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ

6c1baa17500174ff1745d50bdabc1399

рдХреНрдпреЛрдВ рдЬреНрдпрд╛рдорд┐рддреАрдп? рдХреНрдпреЛрдВрдХрд┐ рдЬреНрдпреЛрдореЗрдЯреНрд░рд┐рдХ рдХрд╛ рдорддрд▓рдм рдЙрдЪреНрдЪ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП "рдЧреНрд░реЗрд╡рд┐рдЯреЗрдЯреНрд╕" рд╣реИ , рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдмреНрд░рд╛рдЗрдЯ рдкрд┐рдХреНрд╕рд▓ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдЬреЛ рдХрд┐ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЪрд┐рддреНрд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ)ред


RenderTextureFormat rtFormat = RenderTextureFormat.ARGBFloat; if (lumBuffer == null) { lumBuffer = new RenderTexture (LuminanceGridSize, LuminanceGridSize, 0, rtFormat, RenderTextureReadWrite.Default); } RenderTexture currentTex = RenderTexture.GetTemporary (InitialSampling, InitialSampling, 0, rtFormat, RenderTextureReadWrite.Default); Graphics.Blit (source, currentTex, material, PASS_PREPARE); int currentSize = InitialSampling; while (currentSize > LuminanceGridSize) { RenderTexture next = RenderTexture.GetTemporary (currentSize / 2, currentSize / 2, 0, rtFormat, RenderTextureReadWrite.Default); Graphics.Blit (currentTex, next, material, PASS_DOWNSAMPLE); RenderTexture.ReleaseTemporary (currentTex); currentTex = next; currentSize /= 2; } 


 // Downsample pass Pass { CGPROGRAM #pragma vertex vert #pragma fragment fragDownsample float4 fragDownsample(v2f i) : COLOR { float4 v1 = tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,-1)); float4 v2 = tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,1)); float4 v3 = tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,1)); float4 v4 = tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,-1)); float mn = min(min(v1.x,v2.x), min(v3.x,v4.x)); float mx = max(max(v1.y,v2.y), max(v3.y,v4.y)); float avg = (v1.z+v2.z+v3.z+v4.z) / 4; return float4(mn, mx, avg, 1); } ENDCG } // Prepare pass Pass { CGPROGRAM #pragma vertex vert #pragma fragment fragPrepare float4 fragPrepare(v2f i) : COLOR { float v = tex2D(_MainTex, i.uv); float l = log(v + 0.001); return half4(l, l, l, 1); } ENDCG } 


рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЬрдм рдореВрд▓ рдЫрд╡рд┐ рдХреЛ рд▓реЙрдЧрд░рд┐рдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рд▓реЗ (0) рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдмреНрд░рд╣реНрдорд╛рдВрдб рдХреЗ рдкрддрди рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╕реНрдерд┐рд░рд╛рдВрдХ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред

рдкреНрд░рддреНрдпреЗрдХ рдХрдореА рдХрджрдо рдкрд░, рд╣рдорд╛рд░реА рдмрдирд╛рд╡рдЯ рдиреНрдпреВрдирддрдо (R), рдЕрдзрд┐рдХрддрдо (G), рдФрд░ рд▓рдШреБрдЧрдгрдХ (B) рдЪрдордХ рдорд╛рди рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреА рд╣реИред

рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЫреЛрдЯреА рд╕реА рдЯреНрд░рд┐рдХ рдЖрддреА рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдмрдирд╛рд╡рдЯ рдФрд░ "GPU" рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ "рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝" рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛: рд╣рдо рдЖрдХрд╛рд░ рдореЗрдВ 1 рдкрд┐рдХреНрд╕реЗрд▓ рдХреА рдПрдХ рдирд┐рд░рдВрддрд░ рдмрдирд╛рд╡рдЯ рдмрдирд╛рдПрдВрдЧреЗ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдлреНрд░реЗрдо рдкрд░ рд╣рдо рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЕрд▓реНрдлрд╛ (рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛) рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рдЪрдордХ рдорд╛рди (1 рдкрд┐рдХреНрд╕реЗрд▓) рд▓рдЧрд╛рдПрдВрдЧреЗред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рдВрдЧреНрд░рд╣реАрдд рдЪрдордХ рдореВрд▓реНрдп рдзреАрд░реЗ-рдзреАрд░реЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЖ рдЬрд╛рдПрдЧрд╛, рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ред

 if (!lumBuffer.IsCreated ()) { Debug.Log ("Luminance map recreated"); lumBuffer.Create (); //     ,     Graphics.Blit (currentTex, lumBuffer); } else { material.SetFloat ("_Adaptation", AdaptationCoefficient); Graphics.Blit (currentTex, lumBuffer, material, PASS_UPDATE); } 


рдЕрдиреБрдХреВрд▓рди рдХреНрд╖рдорддрд╛ - 0.005 рдХреЗ рдХреНрд░рдо рдХрд╛ рдЧреБрдгрд╛рдВрдХ, рдЬреЛ рдЪрдордХ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди рдХреА рдЧрддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рд╣рдорд╛рд░реЗ рджреЛ рдмрдирд╛рд╡рдЯ (рдореВрд▓ рдЫрд╡рд┐ рдФрд░ рдЪрдордХ) рдФрд░ рдкрд╣рд▓реЗ "рдПрдХреНрд╕рдкреЛрдЬрд░" рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред

 material.SetTexture ("_LumTex", lumBuffer); material.SetFloat ("_Key", Key); material.SetFloat ("_White", White); material.SetFloat ("_Limit", Limit); Graphics.Blit (source, destination, material, PASS_MAIN); 


 // Main pass Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag float4 frag(v2f i) : COLOR { half4 cColor = tex2D(_MainTex, i.uv); float4 cLum = tex2D(_LumTex, i.uv); float lMin = exp(cLum.x); float lMax = exp(cLum.y); float lAvg = exp(cLum.z); lAvg = max(lMax / 2, _Limit); // force override for dark scene float lum = max(0.000001, Luminance(cColor.rgb)); float scaled = _Key / lAvg * lum; scaled *= (1 + scaled / _White / _White) / (1+scaled); return scaled * cColor; } ENDCG } 


рдпрд╣рд╛рдВ рд╣рдо рд▓рдШреБрдЧрдгрдХ рд╕реЗ рдЪрдордХ рдореВрд▓реНрдп рдХреЛ рдмрд╣рд╛рд▓ рдХрд░рддреЗ рд╣реИрдВ, рд╕реНрдХреЗрд▓ рдлреИрдХреНрдЯрд░ (рд╕реНрдХреЗрд▓) рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕рдлреЗрдж рд╕реНрддрд░ (_White) рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрдзрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред

рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреИрд░рд╛рдореАрдЯрд░:

рдкрд░рд┐рдгрд╛рдо:



рдЖрдк рдЪрдордХ рдмрдирд╛рд╡рдЯ рдХреЛ рдХрдо рдХрд░рдХреЗ рди рдХреЗрд╡рд▓ рдПрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдХреБрдЫ рд╣реА рдЪрд░рдгреЛрдВ рдореЗрдВ рд░реЛрдХ рд╕рдХрддреЗ рд╣реИрдВ (LuminanceGridgerize рдмрдврд╝рд╛рдирд╛)ред рдлрд┐рд░ рд╕реНрдХреНрд░реАрди рдХреЗ рдХреБрдЫ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ "рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛"ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рднрд╛рд╡ "рдбрд╛рд░реНрдХ рд╕реНрдкреЙрдЯ" рд╣реЛрдЧрд╛ рдЬрдм рд░реЗрдЯрд┐рдирд╛ рдХреЗ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕реАрдзреЗ рджреАрдкрдХ рдкрд░ рджреЗрдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдорд╕реНрддрд┐рд╖реНрдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рднрдбрд╝рдХрдирд╛ рдкреНрд░рднрд╛рд╡ рдХреЛ рдЫреБрдкрд╛рддрд╛ рд╣реИ, рдФрд░ рдореЙрдирд┐рдЯрд░ рдкрд░ рдпрд╣ рдЕрдкреНрд░рд╛рдХреГрддрд┐рдХ рдФрд░ рдЕрд╕рд╛рдорд╛рдиреНрдп рджрд┐рдЦрддрд╛ рд╣реИред

рд░реЗрдЗрдирд╣рд╛рд░реНрдб рдореЗрдВ рджрд┐рдирдорд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝реЗрдВ
рдХреЛрдб
рд╢реЗрдбрд░

Source: https://habr.com/ru/post/In165669/


All Articles