From 9242339a59ed72048dcc7bde37d143c62d2677a6 Mon Sep 17 00:00:00 2001 From: Adrien de Tocqueville Date: Fri, 10 Jul 2020 12:49:37 +0200 Subject: [PATCH 1/3] Change cloud layer API --- .../Documentation~/Override-Cloud-Layer.md | 4 +- .../Shader/DefaultCloudLayerShader.shader | 98 ++++++++++--------- .../Texture/DefaultCloudLayer.asset | 2 +- .../Runtime/Sky/CloudLayer/CloudLayer.cs | 36 +------ .../Runtime/Sky/CloudLayer/CloudLayer.hlsl | 56 ++++++----- .../Runtime/Sky/SkyManager.cs | 2 +- .../Runtime/Sky/SkyRenderer.cs | 2 +- 7 files changed, 92 insertions(+), 108 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Cloud-Layer.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Cloud-Layer.md index da9ca42aa1a..a49e92dfa5b 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Cloud-Layer.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Cloud-Layer.md @@ -26,8 +26,8 @@ This example Cloud Map is a read-only **CustomRenderTexture**. This means that, ## Customizing the Cloud Map -The Cloud Map is a 2D texture in LatLong layout (sometimes called Cylindrical or Equirectangular) that contains cloud color in the RGB channel and cloud coverage in the alpha channel. -If **Upper Hemisphere Only** is checked, the map is interpreted as being the upper half of a LatLong texture. +The Cloud Map is a 2D texture in LatLong layout (sometimes called Cylindrical or Equirectangular) that contains cloud opacity in the red channel. +If **Upper Hemisphere Only** is checked, the map is interpreted as being the upper half of a LatLong texture. It means that it will only conver the sky above the horizon. diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader index e6ebbeaa8c8..4e5287a1aac 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader @@ -1,48 +1,50 @@ -Shader "Hidden/DefaultCloudLayer" -{ - Properties - { - [NoScaleOffset] - _Tex("Cloud Texture", 2D) = "white" {} - - Opacity_R("Cumulus Opacity", Range(0,1)) = 1 - Opacity_G("Stratus Opacity", Range(0,1)) = 0.25 - Opacity_B("Cirrus Opacity", Range(0,1)) = 1 - Opacity_A("Wispy Opacity", Range(0,1)) = 0.1 - } - - SubShader - { - Lighting Off - Blend One Zero - - Pass - { - CGPROGRAM - - #include "UnityCustomRenderTexture.cginc" - #pragma vertex CustomRenderTextureVertexShader - #pragma fragment frag - #pragma target 3.0 - - sampler2D _Tex; - float Opacity_R; - float Opacity_G; - float Opacity_B; - float Opacity_A; - - float4 frag(v2f_customrendertexture IN) : COLOR - { - float2 UV = float2 (IN.localTexcoord.x, IN.localTexcoord.y); - float4 opacity = float4(Opacity_R, Opacity_G, Opacity_B, Opacity_A); - float4 clouds = tex2D(_Tex, UV) * opacity; - - return max(max(clouds.r, clouds.g), max(clouds.b, clouds.a)); - } - - ENDCG - } - } - Fallback Off - CustomEditor "Rendering.HighDefinition.DefaultCloudLayerGUI" -} +Shader "Hidden/DefaultCloudLayer" +{ + Properties + { + [NoScaleOffset] + _Tex("Cloud Texture", 2D) = "white" {} + + Opacity_R("Cumulus Opacity", Range(0,1)) = 1 + Opacity_G("Stratus Opacity", Range(0,1)) = 0.25 + Opacity_B("Cirrus Opacity", Range(0,1)) = 1 + Opacity_A("Wispy Opacity", Range(0,1)) = 0.1 + } + + SubShader + { + Lighting Off + Blend One Zero + + Pass + { + Name "Cloud Map" + + CGPROGRAM + + #include "UnityCustomRenderTexture.cginc" + #pragma vertex CustomRenderTextureVertexShader + #pragma fragment frag + #pragma target 3.0 + + sampler2D _Tex; + float Opacity_R; + float Opacity_G; + float Opacity_B; + float Opacity_A; + + float4 frag(v2f_customrendertexture IN) : COLOR + { + float2 UV = float2 (IN.localTexcoord.x, IN.localTexcoord.y); + float4 opacity = float4(Opacity_R, Opacity_G, Opacity_B, Opacity_A); + float4 clouds = tex2D(_Tex, UV) * opacity; + + return max(max(clouds.r, clouds.g), max(clouds.b, clouds.a)); + } + + ENDCG + } + } + Fallback Off + CustomEditor "Rendering.HighDefinition.DefaultCloudLayerGUI" +} diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Texture/DefaultCloudLayer.asset b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Texture/DefaultCloudLayer.asset index 86fa47e3ea5..90c07aa77cd 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Texture/DefaultCloudLayer.asset +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Texture/DefaultCloudLayer.asset @@ -19,7 +19,7 @@ CustomRenderTexture: m_AntiAliasing: 1 m_MipCount: -1 m_DepthFormat: 0 - m_ColorFormat: 8 + m_ColorFormat: 9 m_MipMap: 0 m_GenerateMips: 1 m_SRGB: 0 diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs index 10815785e6d..a900149f6f4 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs @@ -60,9 +60,6 @@ public class CloudLayer : VolumeComponent /// The shader parameters of the cloud layer. public Vector4 GetParameters() { - scrollFactor += scrollSpeed.value * (Time.time - lastTime) * 0.01f; - lastTime = Time.time; - float rot = -Mathf.Deg2Rad*scrollDirection.value; float upper = upperHemisphereOnly.value ? 1.0f : -1.0f; return new Vector4(upper * (rotation.value / 360.0f + 1), scrollFactor, Mathf.Cos(rot), Mathf.Sin(rot)); @@ -75,6 +72,9 @@ public static void Apply(CloudLayer layer, Material skyMaterial) { if (layer != null && layer.enabled.value == true) { + layer.scrollFactor += layer.scrollSpeed.value * (Time.time - layer.lastTime) * 0.01f; + layer.lastTime = Time.time; + Vector4 cloudParam = layer.GetParameters(); Vector4 cloudParam2 = layer.tint.value; cloudParam2.w = layer.intensityMultiplier.value; @@ -112,33 +112,8 @@ public override int GetHashCode() unchecked { -#if UNITY_2019_3 // In 2019.3, when we call GetHashCode on a VolumeParameter it generate garbage (due to the boxing of the generic parameter) - hash = cloudMap.value != null ? hash * 23 + cloudMap.value.GetHashCode() : hash; - hash = flowmap.value != null ? hash * 23 + flowmap.value.GetHashCode() : hash; - hash = hash * 23 + enabled.value.GetHashCode(); - hash = hash * 23 + upperHemisphereOnly.value.GetHashCode(); - hash = hash * 23 + tint.value.GetHashCode(); - hash = hash * 23 + intensityMultiplier.value.GetHashCode(); - hash = hash * 23 + rotation.value.GetHashCode(); - hash = hash * 23 + enableDistortion.value.GetHashCode(); - hash = hash * 23 + procedural.value.GetHashCode(); - hash = hash * 23 + scrollDirection.value.GetHashCode(); - hash = hash * 23 + scrollSpeed.value.GetHashCode(); - - hash = cloudMap.value != null ? hash * 23 + cloudMap.overrideState.GetHashCode() : hash; - hash = flowmap.value != null ? hash * 23 + flowmap.overrideState.GetHashCode() : hash; - hash = hash * 23 + enabled.overrideState.GetHashCode(); - hash = hash * 23 + upperHemisphereOnly.overrideState.GetHashCode(); - hash = hash * 23 + tint.overrideState.GetHashCode(); - hash = hash * 23 + intensityMultiplier.overrideState.GetHashCode(); - hash = hash * 23 + rotation.overrideState.GetHashCode(); - hash = hash * 23 + enableDistortion.overrideState.GetHashCode(); - hash = hash * 23 + procedural.overrideState.GetHashCode(); - hash = hash * 23 + scrollDirection.overrideState.GetHashCode(); - hash = hash * 23 + scrollSpeed.overrideState.GetHashCode(); -#else - hash = cloudMap.value != null ? hash * 23 + cloudMap.GetHashCode() : hash; - hash = flowmap.value != null ? hash * 23 + flowmap.GetHashCode() : hash; + hash = hash * 23 + cloudMap.GetHashCode(); + hash = hash * 23 + flowmap.GetHashCode(); hash = hash * 23 + enabled.GetHashCode(); hash = hash * 23 + upperHemisphereOnly.GetHashCode(); hash = hash * 23 + tint.GetHashCode(); @@ -148,7 +123,6 @@ public override int GetHashCode() hash = hash * 23 + procedural.GetHashCode(); hash = hash * 23 + scrollDirection.GetHashCode(); hash = hash * 23 + scrollSpeed.GetHashCode(); -#endif } return hash; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl index e5614ad87d9..691f0e8f50e 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl @@ -19,12 +19,13 @@ float4 _CloudParam2; // xyz tint, w intensity #define USE_CLOUD_LAYER defined(USE_CLOUD_MAP) || (!defined(USE_CLOUD_MAP) && defined(USE_CLOUD_MOTION)) -float3 sampleCloud(float3 dir, float3 sky) +float4 sampleCloud(float3 dir) { float2 coords = GetLatLongCoords(dir, _CloudUpperHemisphere); coords.x = frac(coords.x + _CloudRotation); - float4 cloudLayerColor = SAMPLE_TEXTURE2D_LOD(_CloudMap, sampler_CloudMap, coords, 0); - return lerp(sky, sky + cloudLayerColor.rgb * _CloudTint * _CloudIntensity, cloudLayerColor.a); + float4 cloudLayerColor = SAMPLE_TEXTURE2D_LOD(_CloudMap, sampler_CloudMap, coords, 0).r; + cloudLayerColor.rgb *= _CloudTint * _CloudIntensity * cloudLayerColor.a; + return cloudLayerColor; } float3 CloudRotationUp(float3 p, float2 cos_sin) @@ -35,46 +36,53 @@ float3 CloudRotationUp(float3 p, float2 cos_sin) return float3(dot(rotDirX, p), p.y, dot(rotDirY, p)); } -float3 GetDistordedCloudColor(float3 dir, float3 sky) +float4 GetDistordedCloudColor(float3 dir) { #if USE_CLOUD_MOTION - if (dir.y >= 0 || !_CloudUpperHemisphere) - { - float2 alpha = frac(float2(_CloudScrollFactor, _CloudScrollFactor + 0.5)) - 0.5; + float2 alpha = frac(float2(_CloudScrollFactor, _CloudScrollFactor + 0.5)) - 0.5; #ifdef USE_CLOUD_MAP - float3 tangent = normalize(cross(dir, float3(0.0, 1.0, 0.0))); - float3 bitangent = cross(tangent, dir); + float3 tangent = normalize(cross(dir, float3(0.0, 1.0, 0.0))); + float3 bitangent = cross(tangent, dir); - float3 windDir = CloudRotationUp(dir, _CloudScrollDirection); - float2 flow = SAMPLE_TEXTURE2D_LOD(_CloudFlowmap, sampler_CloudFlowmap, GetLatLongCoords(windDir, _CloudUpperHemisphere), 0).rg * 2.0 - 1.0; + float3 windDir = CloudRotationUp(dir, _CloudScrollDirection); + float2 flow = SAMPLE_TEXTURE2D_LOD(_CloudFlowmap, sampler_CloudFlowmap, GetLatLongCoords(windDir, _CloudUpperHemisphere), 0).rg * 2.0 - 1.0; - float3 dd = flow.x * tangent + flow.y * bitangent; + float3 dd = flow.x * tangent + flow.y * bitangent; #else - float3 windDir = CloudRotationUp(float3(0, 0, 1), _CloudScrollDirection); - windDir.x *= -1.0; - float3 dd = windDir*sin(dir.y*PI*0.5); + float3 windDir = CloudRotationUp(float3(0, 0, 1), _CloudScrollDirection); + windDir.x *= -1.0; + float3 dd = windDir*sin(dir.y*PI*0.5); #endif - // Sample twice - float3 color1 = sampleCloud(normalize(dir - alpha.x * dd), sky); - float3 color2 = sampleCloud(normalize(dir - alpha.y * dd), sky); + // Sample twice + float4 color1 = sampleCloud(normalize(dir - alpha.x * dd)); + float4 color2 = sampleCloud(normalize(dir - alpha.y * dd)); - // Blend color samples - sky = lerp(color1, color2, abs(2.0 * alpha.x)); - } - return sky; + // Blend color samples + return lerp(color1, color2, abs(2.0 * alpha.x)); #else - return sampleCloud(dir, sky); + return sampleCloud(dir); #endif } +float GetCloudOpacity(float3 dir) +{ +#if USE_CLOUD_LAYER + if (dir.y >= 0 || !_CloudUpperHemisphere) + return GetDistordedCloudColor(dir).a; + else +#endif + + return 0; +} + float3 ApplyCloudLayer(float3 dir, float3 sky) { #if USE_CLOUD_LAYER if (dir.y >= 0 || !_CloudUpperHemisphere) - sky = GetDistordedCloudColor(dir, sky); + sky += GetDistordedCloudColor(dir).rgb; #endif return sky; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index a68ed110d27..95fc6e846b2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -670,7 +670,7 @@ int ComputeSkyHash(HDCamera camera, SkyUpdateContext skyContext, Light sunLight, sunHash = GetSunLightHashCode(sunLight); int cloudHash = 0; - if (skyContext.cloudLayer != null && skyContext.skyRenderer.SupportCloudLayer) + if (skyContext.cloudLayer != null && skyContext.skyRenderer.SupportDynamicCloudLayer) cloudHash = skyContext.cloudLayer.GetHashCode(); // For planar reflections we want to use the parent position for hash. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderer.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderer.cs index 64d226a480b..2449c1b37ed 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyRenderer.cs @@ -10,7 +10,7 @@ public abstract class SkyRenderer /// Determines if the sky should be rendered when the sun light changes. public bool SupportDynamicSunLight = true; /// Determines if the sky should be rendered when the cloud layer changes. - public bool SupportCloudLayer = true; + public bool SupportDynamicCloudLayer = true; /// /// Called on startup. Create resources used by the renderer (shaders, materials, etc). From 370b4979422cd53f3b10db7b869c45a23e3790ab Mon Sep 17 00:00:00 2001 From: Adrien de Tocqueville Date: Fri, 10 Jul 2020 12:52:25 +0200 Subject: [PATCH 2/3] fix line endings --- .../Shader/DefaultCloudLayerShader.shader | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader index 4e5287a1aac..9d27c22d649 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipelineResources/Shader/DefaultCloudLayerShader.shader @@ -1,50 +1,50 @@ -Shader "Hidden/DefaultCloudLayer" -{ - Properties - { - [NoScaleOffset] - _Tex("Cloud Texture", 2D) = "white" {} - - Opacity_R("Cumulus Opacity", Range(0,1)) = 1 - Opacity_G("Stratus Opacity", Range(0,1)) = 0.25 - Opacity_B("Cirrus Opacity", Range(0,1)) = 1 - Opacity_A("Wispy Opacity", Range(0,1)) = 0.1 - } - - SubShader - { - Lighting Off - Blend One Zero - - Pass - { - Name "Cloud Map" - - CGPROGRAM - - #include "UnityCustomRenderTexture.cginc" - #pragma vertex CustomRenderTextureVertexShader - #pragma fragment frag - #pragma target 3.0 - - sampler2D _Tex; - float Opacity_R; - float Opacity_G; - float Opacity_B; - float Opacity_A; - - float4 frag(v2f_customrendertexture IN) : COLOR - { - float2 UV = float2 (IN.localTexcoord.x, IN.localTexcoord.y); - float4 opacity = float4(Opacity_R, Opacity_G, Opacity_B, Opacity_A); - float4 clouds = tex2D(_Tex, UV) * opacity; - - return max(max(clouds.r, clouds.g), max(clouds.b, clouds.a)); - } - - ENDCG - } - } - Fallback Off - CustomEditor "Rendering.HighDefinition.DefaultCloudLayerGUI" -} +Shader "Hidden/DefaultCloudLayer" +{ + Properties + { + [NoScaleOffset] + _Tex("Cloud Texture", 2D) = "white" {} + + Opacity_R("Cumulus Opacity", Range(0,1)) = 1 + Opacity_G("Stratus Opacity", Range(0,1)) = 0.25 + Opacity_B("Cirrus Opacity", Range(0,1)) = 1 + Opacity_A("Wispy Opacity", Range(0,1)) = 0.1 + } + + SubShader + { + Lighting Off + Blend One Zero + + Pass + { + Name "Cloud Map" + + CGPROGRAM + + #include "UnityCustomRenderTexture.cginc" + #pragma vertex CustomRenderTextureVertexShader + #pragma fragment frag + #pragma target 3.0 + + sampler2D _Tex; + float Opacity_R; + float Opacity_G; + float Opacity_B; + float Opacity_A; + + float4 frag(v2f_customrendertexture IN) : COLOR + { + float2 UV = float2 (IN.localTexcoord.x, IN.localTexcoord.y); + float4 opacity = float4(Opacity_R, Opacity_G, Opacity_B, Opacity_A); + float4 clouds = tex2D(_Tex, UV) * opacity; + + return max(max(clouds.r, clouds.g), max(clouds.b, clouds.a)); + } + + ENDCG + } + } + Fallback Off + CustomEditor "Rendering.HighDefinition.DefaultCloudLayerGUI" +} From 1dcea42977ab2f06996a03dbc9d46483c8bbf5bd Mon Sep 17 00:00:00 2001 From: Adrien de Tocqueville Date: Fri, 10 Jul 2020 13:52:19 +0200 Subject: [PATCH 3/3] Change default value --- .../Runtime/Sky/CloudLayer/CloudLayer.cs | 2 +- .../Runtime/Sky/CloudLayer/CloudLayer.hlsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs index a900149f6f4..31f980f39e1 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.cs @@ -43,7 +43,7 @@ public class CloudLayer : VolumeComponent public ClampedFloatParameter scrollDirection = new ClampedFloatParameter(0.0f, 0.0f, 360.0f); /// Speed of the distortion. [Tooltip("Sets the cloud scrolling speed. The higher the value, the faster the clouds will move.")] - public MinFloatParameter scrollSpeed = new MinFloatParameter(2.0f, 0.0f); + public MinFloatParameter scrollSpeed = new MinFloatParameter(1.0f, 0.0f); private float scrollFactor = 0.0f, lastTime = 0.0f; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl index 691f0e8f50e..67cff3b0161 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Sky/CloudLayer/CloudLayer.hlsl @@ -82,7 +82,7 @@ float3 ApplyCloudLayer(float3 dir, float3 sky) { #if USE_CLOUD_LAYER if (dir.y >= 0 || !_CloudUpperHemisphere) - sky += GetDistordedCloudColor(dir).rgb; + sky += GetDistordedCloudColor(dir).rgb; #endif return sky;