From 4102b0660fc039b0a15fa5a70315990d518be0bf Mon Sep 17 00:00:00 2001 From: pema99 Date: Fri, 8 Oct 2021 19:33:29 +0200 Subject: [PATCH 1/8] Add function to decode HDR cubemaps. --- .../ShaderLibrary/Common.hlsl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl index 7c0c747371e..94b62a1603a 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl @@ -1315,6 +1315,20 @@ real UnpackHeightmap(real4 height) // Misc utilities // ---------------------------------------------------------------------------- +// Decodes HDR textures. Handles full HDR, dLDR and RGBM formats +float3 DecodeHDR(float4 data, float4 decodeInstructions) +{ + // Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels) + float alpha = decodeInstructions.w * (data.a - 1.0) + 1.0; + + // If Linear mode is not supported we can skip exponent part + #if defined(UNITY_COLORSPACE_GAMMA) + return (decodeInstructions.x * alpha) * data.rgb; + #else + return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb; + #endif +} + // Simple function to test a bitfield bool HasFlag(uint bitfield, uint flag) { From 0623815d4c0be631ff02f28eabdd478e44614183 Mon Sep 17 00:00:00 2001 From: pema99 Date: Fri, 8 Oct 2021 19:34:17 +0200 Subject: [PATCH 2/8] Use new decoding functions in shaders that may sample an encoded cubemap. --- .../Lighting/Reflection/ReflectionProbesPreview.shader | 2 ++ .../Runtime/Core/CoreResources/BlitCubeTextureFace.shader | 5 ++++- .../Runtime/Sky/HDRISky/HDRISky.shader | 5 ++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader index ddb3a183778..e769e7360c0 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader @@ -45,6 +45,7 @@ Shader "Hidden/Debug/ReflectionProbePreview" TEXTURECUBE(_Cubemap); SAMPLER(sampler_Cubemap); + float4 _Cubemap_HDR; float3 _CameraWorldPosition; float _MipLevel; @@ -67,6 +68,7 @@ Shader "Hidden/Debug/ReflectionProbePreview" float3 V = normalize(i.positionWS - GetPrimaryCameraPosition()); float3 R = reflect(V, i.normalWS); float4 color = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, R, _MipLevel).rgba; + color.rgb = DecodeHDR(color, _Cubemap_HDR); color = color * exp2(_Exposure) * GetCurrentExposureMultiplier(); return float4(color); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader b/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader index f98dd74f784..b32f2c32be1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader @@ -22,6 +22,7 @@ Shader "Hidden/SRP/BlitCubeTextureFace" TEXTURECUBE(_InputTex); SAMPLER(sampler_InputTex); + float4 _InputTex_HDR; float _FaceIndex; float _LoD; @@ -59,7 +60,9 @@ Shader "Hidden/SRP/BlitCubeTextureFace" float4 frag (Varyings input) : SV_Target { - return SAMPLE_TEXTURECUBE_LOD(_InputTex, sampler_InputTex, input.texcoord, _LoD); + float4 color = SAMPLE_TEXTURECUBE_LOD(_InputTex, sampler_InputTex, input.texcoord, _LoD); + color.rgb = DecodeHDR(color, _InputTex_HDR); + return color; } ENDHLSL diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader index cde9fdc022e..e9e86bed7a7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader @@ -49,6 +49,7 @@ Shader "Hidden/HDRP/Sky/HDRISky" TEXTURECUBE(_Cubemap); SAMPLER(sampler_Cubemap); + float4 _Cubemap_HDR; TEXTURE2D(_Flowmap); SAMPLER(sampler_Flowmap); @@ -204,7 +205,9 @@ Shader "Hidden/HDRP/Sky/HDRISky" // Sample twice float3 color1 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.x*dd, 0).rgb; + color1.rgb = DecodeHDR(color1, _Cubemap_HDR); float3 color2 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.y*dd, 0).rgb; + color2.rgb = DecodeHDR(color2, _Cubemap_HDR); // Blend color samples return lerp(color1, color2, abs(2.0 * alpha.x)); @@ -212,7 +215,7 @@ Shader "Hidden/HDRP/Sky/HDRISky" else #endif - return SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb; + return DecodeHDR(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0), _Cubemap_HDR); } float4 GetColorWithRotation(float3 dir, float exposure, float2 cos_sin) From 0960b9a35e0838cf8adade40a35f86f0b46825cf Mon Sep 17 00:00:00 2001 From: pema99 Date: Fri, 8 Oct 2021 19:35:21 +0200 Subject: [PATCH 3/8] Always decode encoded HDR cubemaps before use in the probe cache (For non-encoded textures, the overhead will essentially be a no-op). --- .../Reflection/ReflectionProbeCache.cs | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs index 20f9b0e8188..9d7c3f2f0e7 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs @@ -137,32 +137,23 @@ Texture[] ConvolveProbeTexture(CommandBuffer cmd, Texture texture) RenderTexture convolutionSourceTexture = null; if (cubeTexture != null) { - // if the size if different from the cache probe size or if the input texture format is compressed, we need to convert it - // 1) to a format for which we can generate mip maps - // 2) to the proper reflection probe cache size bool sizeMismatch = cubeTexture.width != m_ProbeSize || cubeTexture.height != m_ProbeSize; bool formatMismatch = (GraphicsFormatUtility.GetGraphicsFormat(cubeTexture.format, false) != m_TempRenderTexture.graphicsFormat); - if (formatMismatch || sizeMismatch) + + // We comment the following warning as they have no impact on the result but spam the console, it is just that we waste offline time and a bit of quality for nothing. + if (sizeMismatch) { - // We comment the following warning as they have no impact on the result but spam the console, it is just that we waste offline time and a bit of quality for nothing. - if (sizeMismatch) - { - // Debug.LogWarningFormat("Baked Reflection Probe {0} does not match HDRP Reflection Probe Cache size of {1}. Consider baking it at the same size for better loading performance.", texture.name, m_ProbeSize); - } - else if (cubeTexture.graphicsFormat == GraphicsFormat.RGB_BC6H_UFloat || cubeTexture.graphicsFormat == GraphicsFormat.RGB_BC6H_SFloat) - { - // Debug.LogWarningFormat("Baked Reflection Probe {0} is compressed but the HDRP Reflection Probe Cache is not. Consider removing compression from the input texture for better quality.", texture.name); - } - ConvertTexture(cmd, cubeTexture, m_TempRenderTexture); + // Debug.LogWarningFormat("Baked Reflection Probe {0} does not match HDRP Reflection Probe Cache size of {1}. Consider baking it at the same size for better loading performance.", texture.name, m_ProbeSize); } - else + else if (formatMismatch && (cubeTexture.graphicsFormat == GraphicsFormat.RGB_BC6H_UFloat || cubeTexture.graphicsFormat == GraphicsFormat.RGB_BC6H_SFloat)) { - for (int f = 0; f < 6; f++) - { - cmd.CopyTexture(cubeTexture, f, 0, m_TempRenderTexture, f, 0); - } + // Debug.LogWarningFormat("Baked Reflection Probe {0} is compressed but the HDRP Reflection Probe Cache is not. Consider removing compression from the input texture for better quality.", texture.name); } + // Convert the cubemap to match the size and texture format used for the cache + // This will also take care of decoding manually encoded HDR cubemaps (RGBM, dLDR) + ConvertTexture(cmd, cubeTexture, m_TempRenderTexture); + // Ideally if input is not compressed and has mipmaps, don't do anything here. Problem is, we can't know if mips have been already convolved offline... cmd.GenerateMips(m_TempRenderTexture); convolutionSourceTexture = m_TempRenderTexture; From 953a8613732ff074a2867fc33defe0f1dc3f0f57 Mon Sep 17 00:00:00 2001 From: pema99 Date: Fri, 8 Oct 2021 19:50:58 +0200 Subject: [PATCH 4/8] Add line to changelog. --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index a9c35f07ffe..e566a8a8f4a 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - Added a SG node to get the main directional light direction. +- Added support for encoded HDR cubemaps, configurable via the HDR Cubemap Encoding project setting. ### Changed - MaterialReimporter.ReimportAllMaterials and MaterialReimporter.ReimportAllHDShaderGraphs now batch the asset database changes to improve performance. From 3bc71f3bc4ea99105cb2411a22912d3d4e84e448 Mon Sep 17 00:00:00 2001 From: pema99 Date: Mon, 18 Oct 2021 23:12:12 +0200 Subject: [PATCH 5/8] Revert "Add function to decode HDR cubemaps." This reverts commit 4102b0660fc039b0a15fa5a70315990d518be0bf. --- .../ShaderLibrary/Common.hlsl | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl index 94b62a1603a..7c0c747371e 100644 --- a/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl +++ b/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl @@ -1315,20 +1315,6 @@ real UnpackHeightmap(real4 height) // Misc utilities // ---------------------------------------------------------------------------- -// Decodes HDR textures. Handles full HDR, dLDR and RGBM formats -float3 DecodeHDR(float4 data, float4 decodeInstructions) -{ - // Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels) - float alpha = decodeInstructions.w * (data.a - 1.0) + 1.0; - - // If Linear mode is not supported we can skip exponent part - #if defined(UNITY_COLORSPACE_GAMMA) - return (decodeInstructions.x * alpha) * data.rgb; - #else - return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb; - #endif -} - // Simple function to test a bitfield bool HasFlag(uint bitfield, uint flag) { From 02fe6e3d0d5c5c3235b56c6f8b0788f1388e00ca Mon Sep 17 00:00:00 2001 From: pema99 Date: Mon, 18 Oct 2021 23:14:11 +0200 Subject: [PATCH 6/8] Use already present DecodeHDREnvironment function. --- .../Lighting/Reflection/ReflectionProbesPreview.shader | 3 ++- .../Runtime/Core/CoreResources/BlitCubeTextureFace.shader | 3 ++- .../Runtime/Sky/HDRISky/HDRISky.shader | 7 ++++--- .../Runtime/Sky/HDRISky/IntegrateHDRISky.shader | 4 +++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader index e769e7360c0..957c2d9bfec 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader +++ b/com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesPreview.shader @@ -28,6 +28,7 @@ Shader "Hidden/Debug/ReflectionProbePreview" #pragma fragment frag #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" struct appdata @@ -68,7 +69,7 @@ Shader "Hidden/Debug/ReflectionProbePreview" float3 V = normalize(i.positionWS - GetPrimaryCameraPosition()); float3 R = reflect(V, i.normalWS); float4 color = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, R, _MipLevel).rgba; - color.rgb = DecodeHDR(color, _Cubemap_HDR); + color.rgb = DecodeHDREnvironment(color, _Cubemap_HDR); color = color * exp2(_Exposure) * GetCurrentExposureMultiplier(); return float4(color); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader b/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader index b32f2c32be1..e44b4ed3107 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Core/CoreResources/BlitCubeTextureFace.shader @@ -15,6 +15,7 @@ Shader "Hidden/SRP/BlitCubeTextureFace" #pragma editor_sync_compilation #pragma prefer_hlslcc gles #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #pragma vertex vert #pragma fragment frag @@ -61,7 +62,7 @@ Shader "Hidden/SRP/BlitCubeTextureFace" float4 frag (Varyings input) : SV_Target { float4 color = SAMPLE_TEXTURECUBE_LOD(_InputTex, sampler_InputTex, input.texcoord, _LoD); - color.rgb = DecodeHDR(color, _InputTex_HDR); + color.rgb = DecodeHDREnvironment(color, _InputTex_HDR); return color; } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader index e9e86bed7a7..70ee118d0ca 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader @@ -32,6 +32,7 @@ Shader "Hidden/HDRP/Sky/HDRISky" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUtils.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SDF2D.hlsl" @@ -205,9 +206,9 @@ Shader "Hidden/HDRP/Sky/HDRISky" // Sample twice float3 color1 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.x*dd, 0).rgb; - color1.rgb = DecodeHDR(color1, _Cubemap_HDR); + color1.rgb = DecodeHDREnvironment(color1, _Cubemap_HDR); float3 color2 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.y*dd, 0).rgb; - color2.rgb = DecodeHDR(color2, _Cubemap_HDR); + color2.rgb = DecodeHDREnvironment(color2, _Cubemap_HDR); // Blend color samples return lerp(color1, color2, abs(2.0 * alpha.x)); @@ -215,7 +216,7 @@ Shader "Hidden/HDRP/Sky/HDRISky" else #endif - return DecodeHDR(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0), _Cubemap_HDR); + return DecodeHDREnvironment(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0), _Cubemap_HDR); } float4 GetColorWithRotation(float3 dir, float exposure, float2 cos_sin) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/IntegrateHDRISky.shader b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/IntegrateHDRISky.shader index 6a71fddefab..f9760c745c8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/IntegrateHDRISky.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/IntegrateHDRISky.shader @@ -23,6 +23,7 @@ Shader "Hidden/HDRP/IntegrateHDRI" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl" struct Attributes @@ -37,6 +38,7 @@ Shader "Hidden/HDRP/IntegrateHDRI" }; TextureCube _Cubemap; + float4 _Cubemap_HDR; Varyings Vert(Attributes input) { @@ -65,7 +67,7 @@ Shader "Hidden/HDRP/IntegrateHDRI" { // SphericalToCartesian function is for Z up, lets move to Y up with TransformGLtoDX float3 L = TransformGLtoDX(SphericalToCartesian(phi, cos(theta))); - real3 val = SAMPLE_TEXTURECUBE_LOD(skybox, sampler_skybox, L, 0).rgb; + real3 val = DecodeHDREnvironment(SAMPLE_TEXTURECUBE_LOD(skybox, sampler_skybox, L, 0), _Cubemap_HDR).rgb; sum += (cos(theta)*sin(theta)*coef)*val; } } From f9ee5e21b14d19b544f9d220af57da1ff7062b52 Mon Sep 17 00:00:00 2001 From: pema99 Date: Mon, 18 Oct 2021 23:16:57 +0200 Subject: [PATCH 7/8] Bring back comment about conversion during covolution. --- .../Runtime/Lighting/Reflection/ReflectionProbeCache.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs index 9d7c3f2f0e7..dfd0f67cf7e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeCache.cs @@ -137,6 +137,9 @@ Texture[] ConvolveProbeTexture(CommandBuffer cmd, Texture texture) RenderTexture convolutionSourceTexture = null; if (cubeTexture != null) { + // if the size if different from the cache probe size or if the input texture format is compressed, we need to convert it + // 1) to a format for which we can generate mip maps + // 2) to the proper reflection probe cache size bool sizeMismatch = cubeTexture.width != m_ProbeSize || cubeTexture.height != m_ProbeSize; bool formatMismatch = (GraphicsFormatUtility.GetGraphicsFormat(cubeTexture.format, false) != m_TempRenderTexture.graphicsFormat); From 167df8d2d057b538bc66235ebe324871d5f27a26 Mon Sep 17 00:00:00 2001 From: pema99 Date: Wed, 20 Oct 2021 12:19:22 +0200 Subject: [PATCH 8/8] Fix illegal cast in in HDRISky.shader --- .../Runtime/Sky/HDRISky/HDRISky.shader | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader index 70ee118d0ca..83363eaab31 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/HDRISky/HDRISky.shader @@ -205,10 +205,8 @@ Shader "Hidden/HDRP/Sky/HDRISky" #endif // Sample twice - float3 color1 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.x*dd, 0).rgb; - color1.rgb = DecodeHDREnvironment(color1, _Cubemap_HDR); - float3 color2 = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.y*dd, 0).rgb; - color2.rgb = DecodeHDREnvironment(color2, _Cubemap_HDR); + float3 color1 = DecodeHDREnvironment(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.x * dd, 0), _Cubemap_HDR); + float3 color2 = DecodeHDREnvironment(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir + alpha.y * dd, 0), _Cubemap_HDR); // Blend color samples return lerp(color1, color2, abs(2.0 * alpha.x));