You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
14 KiB
341 lines
14 KiB
4 years ago
|
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
|
||
|
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||
|
|
||
|
Shader "azure[Sky]/azure[Sky]_ProceduralClouds"
|
||
|
{
|
||
|
Properties
|
||
|
{
|
||
|
[HideInInspector]_WispyCovarage("Covarage", Range(0,5)) = 1
|
||
|
[HideInInspector]_WispyDarkness("Darkness", Color) = (1,1,1,1)
|
||
|
[HideInInspector]_WispyBright("Bright", Color) = (1,1,1,1)
|
||
|
[HideInInspector]_WispyColor("Wispy Color", Color) = (1,1,1,1)
|
||
|
_ProceduralCloudAltitude("Cloud Altitude", Range(10,100)) = 50
|
||
|
}
|
||
|
SubShader
|
||
|
{
|
||
|
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" "IgnoreProjector"="True" }
|
||
|
Cull Back // Render side
|
||
|
Fog{Mode Off} // Don't use fog
|
||
|
ZWrite Off // Don't draw to bepth buffer
|
||
|
Pass
|
||
|
{
|
||
|
CGPROGRAM
|
||
|
#pragma target 3.0
|
||
|
#pragma vertex vert
|
||
|
#pragma fragment frag
|
||
|
#pragma multi_compile HDR_ON HDR_OFF
|
||
|
|
||
|
uniform float3 _Br;
|
||
|
uniform float3 _Br2;
|
||
|
uniform float3 _Bm;
|
||
|
uniform float3 _Brm; //Br + Bm
|
||
|
uniform float3 _mieG;
|
||
|
uniform float _SunIntensity;
|
||
|
uniform float _MoonIntensity;
|
||
|
uniform float _Kr;
|
||
|
uniform float _Km;
|
||
|
uniform float _Altitude;
|
||
|
uniform float _pi316;
|
||
|
uniform float _pi14;
|
||
|
uniform float _pi;
|
||
|
|
||
|
uniform float _Exposure;
|
||
|
uniform float _SkyLuminance;
|
||
|
uniform float _SkyDarkness;
|
||
|
uniform float _SunsetPower;
|
||
|
uniform float _SunDiskSize;
|
||
|
uniform float _SunDiskIntensity;
|
||
|
uniform float _SunDiskPropagation;
|
||
|
uniform float _MoonSize;
|
||
|
uniform float _StarsIntensity;
|
||
|
uniform float _StarsExtinction;
|
||
|
uniform float _MilkyWayIntensity;
|
||
|
uniform float _MilkyWayPower;
|
||
|
|
||
|
// uniform float4 _SunColor;
|
||
|
uniform float4 _SunsetColor;
|
||
|
uniform float4 _MoonColor;
|
||
|
uniform float4 _MoonBrightColor;
|
||
|
uniform float _MoonExtinction;
|
||
|
uniform int _MoonEclipseShadow;
|
||
|
uniform float _Umbra;
|
||
|
uniform float _UmbraSize;
|
||
|
uniform float _Penumbra;
|
||
|
uniform float _PenumbraSize;
|
||
|
|
||
|
uniform sampler2D _MoonSampler;
|
||
|
uniform samplerCUBE _StarField;
|
||
|
uniform samplerCUBE _StarNoise;
|
||
|
uniform samplerCUBE _MilkyWay;
|
||
|
|
||
|
uniform sampler2D _CloudTexture;
|
||
|
uniform float _Longitude;
|
||
|
uniform float _AlphaSaturation;
|
||
|
uniform float _CloudAltitude;
|
||
|
|
||
|
uniform float _ColorCorrection;
|
||
|
|
||
|
uniform float3 _SunDir;
|
||
|
uniform float3 _MoonDir;
|
||
|
uniform float4x4 _SunMatrix;
|
||
|
uniform float4x4 _MoonMatrix;
|
||
|
uniform float4x4 _NoiseMatrix;
|
||
|
uniform float4x4 _MilkyWayMatrix;
|
||
|
|
||
|
uniform float4 _GroundCloseColor;
|
||
|
uniform float4 _GroundFarColor;
|
||
|
uniform float _FarColorDistance;
|
||
|
uniform float _FarColorIntensity;
|
||
|
|
||
|
uniform float4 _PenumbraColor;
|
||
|
uniform float _ProceduralCloudSpeed;
|
||
|
uniform float _WispyCovarage;
|
||
|
|
||
|
struct appdata{
|
||
|
float4 vertex : POSITION;
|
||
|
};
|
||
|
|
||
|
struct v2f
|
||
|
{
|
||
|
float4 Position : SV_POSITION;
|
||
|
float3 WorldPos : TEXCOORD0;
|
||
|
float4 Fade : TEXCOORD1; // sunFade, mix, fadeOtherSideMoon.
|
||
|
float3 moonPos : TEXCOORD2;
|
||
|
float3 sunPos : TEXCOORD3;
|
||
|
float2 nightCompute : TEXCOORD4;
|
||
|
float3 noiseRot : TEXCOORD5;
|
||
|
float3 cloudPos : TEXCOORD6;
|
||
|
};
|
||
|
|
||
|
v2f vert(appdata v)
|
||
|
{
|
||
|
v2f o;
|
||
|
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||
|
|
||
|
o.Position = UnityObjectToClipPos(v.vertex);
|
||
|
o.WorldPos = normalize(mul((float4x4)unity_ObjectToWorld, v.vertex)).xyz;
|
||
|
|
||
|
float3 viewDir = normalize(o.WorldPos+float3(0.0,_Altitude,0.0));
|
||
|
|
||
|
o.Fade.x = saturate( _SunDir.y + 0.25 ); // Fade the sun ("daysky") when cross the horizon.
|
||
|
o.Fade.y = saturate(clamp(1.0 - _SunDir.y, 0.0, 0.5)); // Mix sunset"(fex)" with daysky"(1-fex)".
|
||
|
o.Fade.z = saturate(dot(-_MoonMatrix[2].xyz,o.WorldPos)); // Fade the other side moon generated by the moonMatrix
|
||
|
o.Fade.w = pow(max(0.0,viewDir.y - 0.025),_MoonExtinction); // Fade the moon when cross the horizon.
|
||
|
|
||
|
//////////
|
||
|
//MATRIX//
|
||
|
o.noiseRot = mul((float3x3)_NoiseMatrix,v.vertex.xyz); // Rotate noise texture to apply star scintillation
|
||
|
o.sunPos = mul((float3x3)_SunMatrix,v.vertex.xyz);
|
||
|
o.moonPos = mul((float3x3)_MoonMatrix,v.vertex.xyz);
|
||
|
o.moonPos.x *= -1; //Invert x scale
|
||
|
// For the rotation of the moon
|
||
|
// o.moonPos.x = -dot(_MoonMatrix[0].xyz,v.vertex.xyz); // x scale inverted
|
||
|
// o.moonPos.y = dot(_MoonMatrix[1].xyz,v.vertex.xyz);
|
||
|
// o.moonPos.z = dot(_MoonMatrix[2].xyz,v.vertex.xyz);
|
||
|
|
||
|
// o.nightCompute.x = pow(max(0.0,o.WorldPos.y),_StarsExtinction);
|
||
|
o.nightCompute.x = pow(max(0.0,viewDir.y),_StarsExtinction);// Stars extinction from zenith to the horizon.
|
||
|
o.nightCompute.y = (-_SunDir.y + _Altitude) * ((_MoonDir.y+0.25) + _Altitude);//Fade the moon Bright when is day or cross the horizon
|
||
|
|
||
|
o.cloudPos = o.WorldPos;
|
||
|
o.cloudPos.y *= 1-dot(viewDir.y+25, float3(0,-0.15,0));
|
||
|
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
float4 frag(v2f IN) : SV_Target
|
||
|
{
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//-------------------------------------------Directions--------------------------------------------------
|
||
|
float3 viewDir = normalize(IN.WorldPos);
|
||
|
float sunCosTheta = dot( viewDir, _SunDir );
|
||
|
viewDir = normalize(IN.WorldPos+float3(0.0,_Altitude,0.0)); // Change the horizon altitude. "(0.1=HorAlt)"
|
||
|
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//-------------------------------------------Extinction--------------------------------------------------
|
||
|
float zenith = acos(saturate(viewDir.y));
|
||
|
float z = (cos(zenith) + 0.15 * pow(93.885 - ((zenith * 180.0) / _pi), -1.253));
|
||
|
float SR = _Kr / z;
|
||
|
float SM = _Km / z;
|
||
|
float3 fex = exp(-(_Br*SR + _Bm*SM)); // Original fex calculation.
|
||
|
float3 fex2 = exp(-(_Br2*SR + _Bm*SM)); // Fex calculation with rayleigh coefficient == 3. For the sunset.
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//-------------------------------------------Cloud Mask--------------------------------------------------
|
||
|
float3 cloudViewDir = normalize(IN.cloudPos);
|
||
|
float4 cloud_UV;
|
||
|
float4 cloud_UV2;
|
||
|
float cloudExtinction = pow(cloudViewDir.y-0.25,5);
|
||
|
cloudExtinction = lerp(cloudExtinction, 0.5, _WispyCovarage);
|
||
|
cloud_UV.xy = (cloudViewDir.xz * 0.25) - (0.005 ) + float2(_ProceduralCloudSpeed/20, _ProceduralCloudSpeed);
|
||
|
cloud_UV2.xy = (cloudViewDir.xz * 0.5) - (0.0065 ) + float2(_ProceduralCloudSpeed/20, _ProceduralCloudSpeed);
|
||
|
|
||
|
fixed4 c1 = tex2D(_CloudTexture, cloud_UV.xy );
|
||
|
fixed4 c2 = tex2D(_CloudTexture, cloud_UV2.xy );
|
||
|
float cloudMask = (pow((c1.g+c2.g)/2,0.1) * pow(c2.b * c1.r, 0.25)) * cloudExtinction;
|
||
|
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//-----------------------------------------Sun Scattering------------------------------------------------
|
||
|
//float rayPhase = 1.0 + pow(cosTheta,2.0); // Preetham rayleigh phase function.
|
||
|
float rayPhase = 2.0 + 0.5 * pow(sunCosTheta,2.0); // Rayleigh phase function based on the Nielsen's paper.
|
||
|
float miePhase = _mieG.x / pow(_mieG.y - _mieG.z * sunCosTheta,1.5); // The Henyey-Greenstein phase function.
|
||
|
|
||
|
float3 BrTheta = _pi316 * _Br * rayPhase;
|
||
|
float3 BmTheta = _pi14 * _Bm * miePhase;
|
||
|
float3 BrmTheta = (BrTheta + BmTheta * 2.0) / (_Brm * 0.75); // Brm is "Br+Bm", and the sum is already made in the Control Script.
|
||
|
|
||
|
float3 inScatter = BrmTheta * _SunIntensity * (1.0 - fex);
|
||
|
inScatter *= saturate((lerp( _SunsetPower , pow(2000.0 * BrmTheta * fex2,0.5),IN.Fade.y) * 0.05));
|
||
|
inScatter *= _SkyLuminance * _SunsetColor.rgb;
|
||
|
inScatter *= pow((1-fex),_SkyDarkness);
|
||
|
inScatter *= IN.Fade.x; // Sun fade in the horizon.
|
||
|
|
||
|
////////////////
|
||
|
// Solar Disk //
|
||
|
float3 sunDisk = min(2, pow((1-sunCosTheta) * _SunDiskSize , _SunDiskPropagation )) * fex2 * _SunDiskIntensity;
|
||
|
|
||
|
/////////////////
|
||
|
//Lunar Eclipse//
|
||
|
float Umbra = 1-min(_Umbra, pow((1-(-sunCosTheta)) * _SunDiskSize , -_UmbraSize )) ;
|
||
|
float Penumbra = min(1, pow((1-(-sunCosTheta)) * _SunDiskSize , -_PenumbraSize ));
|
||
|
float3 LunarEclipse = saturate(float3(Umbra, Umbra, Umbra) * (lerp(float3(1,1,1), _PenumbraColor,Penumbra * _Penumbra)));
|
||
|
|
||
|
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//--------------------------------------------Night Sky--------------------------------------------------
|
||
|
float nightIntensity = 0.25;
|
||
|
float3 nightSky = saturate((pow( 1-fex2, 2.0) * nightIntensity) * (1-IN.Fade.x)); // Defaut night sky color
|
||
|
nightSky *= saturate(pow((1-fex2),_SkyDarkness));
|
||
|
nightSky *= _SkyLuminance;
|
||
|
|
||
|
float3 groundColor = lerp(_GroundCloseColor, _GroundFarColor, (viewDir.y + _FarColorDistance));
|
||
|
nightSky = saturate(lerp(groundColor, nightSky, saturate(dot(viewDir.y + _FarColorIntensity, float3(0,1,0)))) * (1-fex));
|
||
|
// nightSky = saturate(lerp(groundColor, nightSky, viewDir.y + _LerpNightSkyDistance) * (1-fex));
|
||
|
|
||
|
////////////////
|
||
|
// Moon //
|
||
|
float4 moonSampler = tex2D(_MoonSampler, IN.moonPos.xy * _MoonSize + float2(0.5,0.5)) * IN.Fade.z * lerp(1, float4(LunarEclipse,1),_MoonEclipseShadow);
|
||
|
float4 moonColor = ( moonSampler ) * IN.Fade.w * cloudMask;
|
||
|
float moonMask = (1 - moonSampler.a); // To hide the stars that are behind the moon
|
||
|
float3 moonBright = saturate( (_MoonBrightColor.rgb * _MoonIntensity) * pow(dot(viewDir, _MoonDir),5.0) * IN.nightCompute.y ) * (1-(moonColor.b)) * 3 * IN.Fade.z;
|
||
|
|
||
|
////////////////
|
||
|
// Stars //
|
||
|
float fadeStar = IN.nightCompute.x * _StarsIntensity * (1.0 - moonBright * 10.0); // When the stars will emerge and fade.
|
||
|
float scintillation = texCUBE(_StarNoise, IN.noiseRot.xyz) * 2.0;
|
||
|
float3 stars = saturate(texCUBE(_StarField, IN.sunPos.xyz) * fadeStar * moonMask) * scintillation;
|
||
|
////////////////
|
||
|
// Milkyway //
|
||
|
float3 milkyWay = saturate(pow(texCUBE(_MilkyWay, mul((float3x3)_MilkyWayMatrix, IN.sunPos.xyz)), _MilkyWayPower) * fadeStar * moonMask) * _MilkyWayIntensity;
|
||
|
|
||
|
nightSky += (stars + milkyWay)* cloudMask + moonBright;
|
||
|
|
||
|
//*******************************************************************************************************
|
||
|
//-------------------------------------------------------------------------------------------------------
|
||
|
//------------------------------------------Sky finalization---------------------------------------------
|
||
|
inScatter += sunDisk;
|
||
|
float3 finalSky = (inScatter + nightSky);
|
||
|
|
||
|
////////////////
|
||
|
// tonemaping //
|
||
|
#ifndef HDR_ON
|
||
|
finalSky = saturate( 1.0 - exp( -_Exposure * finalSky ));
|
||
|
#endif
|
||
|
|
||
|
finalSky *= lerp(1, moonColor, moonColor.b);
|
||
|
finalSky += moonColor.rgb * 2;
|
||
|
|
||
|
//////////////////////
|
||
|
// Color Correction //
|
||
|
finalSky = pow(finalSky,_ColorCorrection);
|
||
|
return float4(finalSky,1.0);
|
||
|
}
|
||
|
ENDCG
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////
|
||
|
/////////CLOUDS//////////
|
||
|
Pass
|
||
|
{
|
||
|
Blend SrcAlpha OneMinusSrcAlpha
|
||
|
|
||
|
CGPROGRAM
|
||
|
#pragma target 3.0
|
||
|
#pragma vertex vert
|
||
|
#pragma fragment frag
|
||
|
|
||
|
uniform sampler2D _WispyCloudTexture;
|
||
|
// uniform float _CloudAlpha;
|
||
|
uniform float _WispyCovarage;
|
||
|
uniform float _ProceduralCloudAltitude;
|
||
|
uniform float _ProceduralCloudSpeed;
|
||
|
uniform float _WispyCloudDirection;
|
||
|
|
||
|
uniform float4 _WispyDarkness;
|
||
|
uniform float4 _WispyBright;
|
||
|
uniform float4 _WispyColor;
|
||
|
uniform float _WispyColorCorrection;
|
||
|
|
||
|
|
||
|
struct appdata{
|
||
|
float4 vertex : POSITION;
|
||
|
float2 uv : TEXCOORD0;
|
||
|
};
|
||
|
|
||
|
struct v2f
|
||
|
{
|
||
|
float4 Position : SV_POSITION;
|
||
|
float4 cloud_UV : TEXCOORD0;
|
||
|
float3 WorldPos : TEXCOORD1;
|
||
|
};
|
||
|
|
||
|
v2f vert(appdata v)
|
||
|
{
|
||
|
v2f o;
|
||
|
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||
|
o.Position = UnityObjectToClipPos(v.vertex);
|
||
|
o.WorldPos = normalize(mul((float4x4)unity_ObjectToWorld, v.vertex)).xyz;
|
||
|
|
||
|
float3 viewDir = normalize(o.WorldPos+float3(0.0,1,0.0));
|
||
|
|
||
|
//Wispy Cloud direction
|
||
|
float s = sin ( _WispyCloudDirection );
|
||
|
float c = cos ( _WispyCloudDirection );
|
||
|
float2x2 rotationMatrix = float2x2( c, -s, s, c);
|
||
|
|
||
|
o.WorldPos.y *= 1-dot(viewDir.y+_ProceduralCloudAltitude, float3(0,-0.15,0));
|
||
|
o.WorldPos.xz = mul( o.WorldPos.xz, rotationMatrix );
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
float4 frag(v2f IN) : SV_Target
|
||
|
{
|
||
|
float3 viewDir = normalize(IN.WorldPos);
|
||
|
|
||
|
float4 cloud_UV1;
|
||
|
float4 cloud_UV2;
|
||
|
|
||
|
cloud_UV1.xy = (viewDir.xz * 0.25) - (0.005 ) + float2(_ProceduralCloudSpeed/20, _ProceduralCloudSpeed);
|
||
|
cloud_UV2.xy = (viewDir.xz * 0.5) - (0.0065 ) + float2(_ProceduralCloudSpeed/20, _ProceduralCloudSpeed);
|
||
|
|
||
|
float4 col = tex2D(_WispyCloudTexture, cloud_UV1.xy );
|
||
|
col = pow(col,_WispyColorCorrection);
|
||
|
float4 col2 = tex2D(_WispyCloudTexture, cloud_UV2.xy );
|
||
|
col2 = pow(col2,_WispyColorCorrection);
|
||
|
float c1 = pow(col.g + col2.g, 0.1);
|
||
|
float c2 = pow(col2.b * col.r, 0.25);
|
||
|
|
||
|
float3 cloud1 = lerp(_WispyDarkness.rgb, _WispyBright.rgb, c1);
|
||
|
float3 cloud2 = lerp(_WispyDarkness.rgb, _WispyColor.rgb, c2) * 1.5;
|
||
|
float3 cloud3 = lerp(cloud1, cloud2, c1 * c2);
|
||
|
|
||
|
float cloudExtinction = pow(viewDir.y,5);
|
||
|
// col.rgb = float3(col.g,col.r,col.b)* (viewDir.y);
|
||
|
|
||
|
return float4(cloud3,saturate(cloudExtinction*pow(c1*c2,_WispyCovarage)));
|
||
|
}
|
||
|
ENDCG
|
||
|
}
|
||
|
}
|
||
|
}
|