123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- Shader "GapperGames/Skybox_Proc" {
- Properties
- {
- _SunSize("Sun Size", Range(0,1)) = 0.04
- _SunSizeConvergence("Sun Size Convergence", Range(1,10)) = 5
- }
- SubShader{
- Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
- Cull Off ZWrite Off
- Pass {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #include "Lighting.cginc"
- #pragma multi_compile_local _SUNDISK_NONE _SUNDISK_SIMPLE _SUNDISK_HIGH_QUALITY
- uniform half _Exposure;
- uniform half3 _GroundColor;
- uniform half _SunSize;
- uniform half _SunSizeConvergence;
- uniform half3 _SkyTint;
- uniform half _AtmosphereThickness;
- #if defined(UNITY_COLORSPACE_GAMMA)
- #define GAMMA 2
- #define COLOR_2_GAMMA(color) color
- #define COLOR_2_LINEAR(color) color*color
- #define LINEAR_2_OUTPUT(color) sqrt(color)
- #else
- #define GAMMA 2.2
-
- #define COLOR_2_GAMMA(color) ((unity_ColorSpaceDouble.r>2.0) ? pow(color,1.0/GAMMA) : color)
- #define COLOR_2_LINEAR(color) color
- #define LINEAR_2_LINEAR(color) color
- #endif
-
-
- static const float3 kDefaultScatteringWavelength = float3(.65, .57, .475);
- static const float3 kVariableRangeForScatteringWavelength = float3(.15, .15, .15);
- #define OUTER_RADIUS 1.025
- static const float kOuterRadius = OUTER_RADIUS;
- static const float kOuterRadius2 = OUTER_RADIUS * OUTER_RADIUS;
- static const float kInnerRadius = 1.0;
- static const float kInnerRadius2 = 1.0;
- static const float kCameraHeight = 0.0001;
- #define kRAYLEIGH (lerp(0.0, 0.0025, pow(_AtmosphereThickness,2.5)))
- #define kMIE 0.0010
- #define kSUN_BRIGHTNESS 20.0
- #define kMAX_SCATTER 50.0
- static const half kHDSundiskIntensityFactor = 15.0;
- static const half kSimpleSundiskIntensityFactor = 27.0;
- static const half kSunScale = 400.0 * kSUN_BRIGHTNESS;
- static const float kKmESun = kMIE * kSUN_BRIGHTNESS;
- static const float kKm4PI = kMIE * 4.0 * 3.14159265;
- static const float kScale = 1.0 / (OUTER_RADIUS - 1.0);
- static const float kScaleDepth = 0.25;
- static const float kScaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;
- static const float kSamples = 2.0;
- #define MIE_G (-0.990)
- #define MIE_G2 0.9801
- #define SKY_GROUND_THRESHOLD 0.02
-
-
-
-
-
-
-
- #define SKYBOX_SUNDISK_NONE 0
-
- #define SKYBOX_SUNDISK_SIMPLE 1
-
- #define SKYBOX_SUNDISK_HQ 2
-
-
- #ifndef SKYBOX_SUNDISK
- #if defined(_SUNDISK_NONE)
- #define SKYBOX_SUNDISK SKYBOX_SUNDISK_NONE
- #elif defined(_SUNDISK_SIMPLE)
- #define SKYBOX_SUNDISK SKYBOX_SUNDISK_SIMPLE
- #else
- #define SKYBOX_SUNDISK SKYBOX_SUNDISK_HQ
- #endif
- #endif
- #ifndef SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
- #if defined(SHADER_API_MOBILE)
- #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 1
- #else
- #define SKYBOX_COLOR_IN_TARGET_COLOR_SPACE 0
- #endif
- #endif
-
- half getRayleighPhase(half eyeCos2)
- {
- return 0.75 + 0.75 * eyeCos2;
- }
- half getRayleighPhase(half3 light, half3 ray)
- {
- half eyeCos = dot(light, ray);
- return getRayleighPhase(eyeCos * eyeCos);
- }
- struct appdata_t
- {
- float4 vertex : POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct v2f
- {
- float4 pos : SV_POSITION;
- #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
-
- float3 vertex : TEXCOORD0;
- #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
- half3 rayDir : TEXCOORD0;
- #else
-
- half skyGroundFactor : TEXCOORD0;
- #endif
-
- half3 groundColor : TEXCOORD1;
- half3 skyColor : TEXCOORD2;
- #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
- half3 sunColor : TEXCOORD3;
- #endif
- UNITY_VERTEX_OUTPUT_STEREO
- };
- float scale(float inCos)
- {
- float x = 1.0 - inCos;
- return 0.25 * exp(-0.00287 + x * (0.459 + x * (3.83 + x * (-6.80 + x * 5.25))));
- }
- v2f vert(appdata_t v)
- {
- v2f OUT;
- UNITY_SETUP_INSTANCE_ID(v);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
- OUT.pos = UnityObjectToClipPos(v.vertex);
- float3 lightPos = float3(_WorldSpaceLightPos0.x, abs(_WorldSpaceLightPos0.y), _WorldSpaceLightPos0.z);
- float skyTime = abs(dot(_WorldSpaceLightPos0.xyz, float3(0, 1, 0)));
- skyTime = pow(1 - skyTime, 3);
-
-
- float skyTime2 = dot(_WorldSpaceLightPos0.xyz, float3(0, 1, 0));
- skyTime2 = smoothstep(-0.2, 0.4, -skyTime2);
-
- _AtmosphereThickness = lerp(1, 1.5, skyTime);
-
- _AtmosphereThickness = max(_AtmosphereThickness, 0);
- _Exposure = lerp(4, 0.8, skyTime2);
- _SkyTint = 0.5;
- float3 kSkyTintInGammaSpace = COLOR_2_GAMMA(_SkyTint);
- float3 kScatteringWavelength = lerp(
- kDefaultScatteringWavelength - kVariableRangeForScatteringWavelength,
- kDefaultScatteringWavelength + kVariableRangeForScatteringWavelength,
- half3(1,1,1) - kSkyTintInGammaSpace);
- float3 kInvWavelength = 1.0 / pow(kScatteringWavelength, 4);
- float kKrESun = kRAYLEIGH * kSUN_BRIGHTNESS;
- float kKr4PI = kRAYLEIGH * 4.0 * 3.14159265;
- float3 cameraPos = float3(0,kInnerRadius + kCameraHeight,0);
-
- float3 eyeRay = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
- float far = 0.0;
- half3 cIn, cOut;
- if (eyeRay.y >= 0.0)
- {
-
-
- far = sqrt(kOuterRadius2 + kInnerRadius2 * eyeRay.y * eyeRay.y - kInnerRadius2) - kInnerRadius * eyeRay.y;
- float3 pos = cameraPos + far * eyeRay;
-
- float height = kInnerRadius + kCameraHeight;
- float depth = exp(kScaleOverScaleDepth * (-kCameraHeight));
- float startAngle = dot(eyeRay, cameraPos) / height;
- float startOffset = depth * scale(startAngle);
-
- float sampleLength = far / kSamples;
- float scaledLength = sampleLength * kScale;
- float3 sampleRay = eyeRay * sampleLength;
- float3 samplePoint = cameraPos + sampleRay * 0.5;
-
- float3 frontColor = float3(0.0, 0.0, 0.0);
-
-
-
-
- {
- float height = length(samplePoint);
- float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
- float lightAngle = dot(lightPos.xyz, samplePoint) / height;
- float cameraAngle = dot(eyeRay, samplePoint) / height;
- float scatter = (startOffset + depth * (scale(lightAngle) - scale(cameraAngle)));
- float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
- frontColor += attenuate * (depth * scaledLength);
- samplePoint += sampleRay;
- }
- {
- float height = length(samplePoint);
- float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
- float lightAngle = dot(lightPos.xyz, samplePoint) / height;
- float cameraAngle = dot(eyeRay, samplePoint) / height;
- float scatter = (startOffset + depth * (scale(lightAngle) - scale(cameraAngle)));
- float3 attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
- frontColor += attenuate * (depth * scaledLength);
- samplePoint += sampleRay;
- }
-
- cIn = frontColor * (kInvWavelength * kKrESun);
- cOut = frontColor * kKmESun;
- }
- else
- {
-
- far = (-kCameraHeight) / (min(-0.001, eyeRay.y));
- float3 pos = cameraPos + far * eyeRay;
-
- float depth = exp((-kCameraHeight) * (1.0 / kScaleDepth));
- float cameraAngle = dot(-eyeRay, pos);
- float lightAngle = dot(lightPos.xyz, pos);
- float cameraScale = scale(cameraAngle);
- float lightScale = scale(lightAngle);
- float cameraOffset = depth * cameraScale;
- float temp = (lightScale + cameraScale);
-
- float sampleLength = far / kSamples;
- float scaledLength = sampleLength * kScale;
- float3 sampleRay = eyeRay * sampleLength;
- float3 samplePoint = cameraPos + sampleRay * 0.5;
-
- float3 frontColor = float3(0.0, 0.0, 0.0);
- float3 attenuate;
-
- {
- float height = length(samplePoint);
- float depth = exp(kScaleOverScaleDepth * (kInnerRadius - height));
- float scatter = depth * temp - cameraOffset;
- attenuate = exp(-clamp(scatter, 0.0, kMAX_SCATTER) * (kInvWavelength * kKr4PI + kKm4PI));
- frontColor += attenuate * (depth * scaledLength);
- samplePoint += sampleRay;
- }
- cIn = frontColor * (kInvWavelength * kKrESun + kKmESun);
- cOut = clamp(attenuate, 0.0, 1.0);
- }
- #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
- OUT.vertex = -eyeRay;
- #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
- OUT.rayDir = half3(-eyeRay);
- #else
- OUT.skyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;
- #endif
-
-
-
-
- OUT.groundColor = 0;
-
- float brightness = dot(_WorldSpaceLightPos0.xyz, float3(0, 1, 0));
-
-
-
-
- brightness = 1 - max(-brightness, 0);
- brightness = pow(brightness, 5);
- brightness *= 0.85;
- brightness += 0.15;
- OUT.skyColor = _Exposure * (cIn * getRayleighPhase(lightPos, -eyeRay)) * brightness;
- #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
-
-
-
- half lightColorIntensity = clamp(length(_LightColor0.xyz), 0.25, 1);
- #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
- OUT.sunColor = kSimpleSundiskIntensityFactor * saturate(cOut * kSunScale) * _LightColor0.xyz / lightColorIntensity;
- #else
- OUT.sunColor = kHDSundiskIntensityFactor * saturate(cOut) * _LightColor0.xyz / lightColorIntensity;
- #endif
- #endif
- #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
- OUT.groundColor = sqrt(OUT.groundColor);
- OUT.skyColor = sqrt(OUT.skyColor);
- #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
- OUT.sunColor = sqrt(OUT.sunColor);
- #endif
- #endif
- return OUT;
- }
-
- half getMiePhase(half eyeCos, half eyeCos2)
- {
- half temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;
- temp = pow(temp, pow(_SunSize,0.65) * 10);
- temp = max(temp,1.0e-4);
- temp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;
- #if defined(UNITY_COLORSPACE_GAMMA) && SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
- temp = pow(temp, .454545);
- #endif
- return temp;
- }
-
- half calcSunAttenuation(half3 lightPos, half3 ray)
- {
- #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
- half3 delta = lightPos - ray;
- half dist = length(delta);
- half spot = 1.0 - smoothstep(0.0, _SunSize, dist);
- return spot * spot;
- #else
- half focusedEyeCos = pow(saturate(dot(lightPos, ray)), _SunSizeConvergence);
- return getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);
- #endif
- }
- float random(float2 uv)
- {
- float rnd = frac(sin(dot(uv.xy, float2(12.9898, 78.233))) * 43758.5453123);
- return rnd;
- }
- float cellular(float2 uv, float columns, float rows)
- {
- float2 index_uv = floor(float2(uv.x * columns, uv.y * rows));
- float2 fract_uv = frac(float2(uv.x * columns, uv.y * rows));
- float minimum_dist = 1.0;
- [unroll]
- for (int y = -1; y <= 1; y++)
- {
- for (int x = -1; x <= 1; x++)
- {
- float2 neighbor = float2(float(x), float(y));
- float2 _point = random(index_uv + neighbor);
- float2 diff = neighbor + _point - fract_uv;
- float dist = length(diff);
- minimum_dist = min(minimum_dist, dist);
- }
- }
- return minimum_dist;
- }
- half4 frag(v2f IN) : SV_Target
- {
- half3 col = half3(0.0, 0.0, 0.0);
-
-
-
- #if SKYBOX_SUNDISK == SKYBOX_SUNDISK_HQ
- half3 ray = normalize(IN.vertex.xyz);
- half y = ray.y / SKY_GROUND_THRESHOLD;
- #elif SKYBOX_SUNDISK == SKYBOX_SUNDISK_SIMPLE
- half3 ray = IN.rayDir.xyz;
- half y = ray.y / SKY_GROUND_THRESHOLD;
- #else
- half y = IN.skyGroundFactor;
- #endif
- float uvY = (normalize(ray).y * 0.65) + 0.35;
- float2 uv = normalize(ray).xz / uvY;
- float stars = step(cellular((uv * 0.1) + (_Time * 0.005), 10, 10), 0.01);
- float starTime = dot(_WorldSpaceLightPos0.xyz, float3(0, 1, 0));
- starTime = max(starTime, 0);
- starTime = pow(1 - starTime, 5);
- stars *= starTime;
-
- col = lerp(IN.skyColor, IN.groundColor, saturate(y));
- col += stars;
- #if SKYBOX_SUNDISK != SKYBOX_SUNDISK_NONE
- if (y < 0.0)
- {
- col += IN.sunColor * calcSunAttenuation(_WorldSpaceLightPos0.xyz, -ray);
- }
- #endif
- #if defined(UNITY_COLORSPACE_GAMMA) && !SKYBOX_COLOR_IN_TARGET_COLOR_SPACE
- col = LINEAR_2_OUTPUT(col);
- #endif
- return half4(col,1.0);
- }
- ENDCG
- }
- }
- Fallback Off
- }
|