#include "UnityCG.cginc" #include "BeautifyAdvancedParams.cginc" #include "BeautifyOrtho.cginc" UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); #if defined(BEAUTIFY_SUN_FLARES_OCCLUSION_DEPTH) UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); #endif uniform sampler2D _FlareTex; uniform float4 _MainTex_ST; uniform float4 _MainTex_TexelSize; uniform float4 _SunPos; uniform float4 _SunData; // x = sunIntensity, y = disk size, z = ray difraction, w = ray difraction amount uniform float4 _SunCoronaRays1; // x = length, y = streaks, z = spread, w = angle offset uniform float4 _SunCoronaRays2; // x = length, y = streaks, z = spread, w = angle offset uniform float4 _SunGhosts1; // x = reserved, y = size, 2 = pos offset, 3 = brightness uniform float4 _SunGhosts2; // x = reserved, y = size, 2 = pos offset, 3 = brightness uniform float4 _SunGhosts3; // x = reserved, y = size, 2 = pos offset, 3 = brightness uniform float4 _SunGhosts4; // x = reserved, y = size, 2 = pos offset, 3 = brightness uniform float3 _SunHalo; // x = offset, y = amplitude, z = intensity uniform float3 _SunTint; uniform float3 _SunPosRightEye; struct appdata { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 pos : SV_POSITION; float2 uv: TEXCOORD0; float2 uvNonStereo: TEXCOORD1; UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; v2f vert(appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.pos = UnityObjectToClipPos(v.vertex); o.uvNonStereo = v.texcoord; o.uv = UnityStereoScreenSpaceUVAdjust(v.texcoord, _MainTex_ST); return o; } void rotate(inout float2 uv, float ang) { float2 sico; sincos(ang, sico.x, sico.y); float2 cosi = float2(sico.y, -sico.x); uv = float2(dot(cosi, uv), dot(sico, uv)); } float3 sunflare(float2 uv) { // general params float2 sunPos = unity_StereoEyeIndex == 0 ? _SunPos.xy : _SunPosRightEye.xy; #if defined(BEAUTIFY_SUN_FLARES_OCCLUSION_DEPTH) float4 depthSunPos = float4(sunPos, 0, 0); #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) { // Depth texture is inverted WRT the main texture depthSunPos.y = 1.0 - depthSunPos.y; } #endif //float depth = BEAUTIFY_GET_DEPTH_01(UNITY_SAMPLE_DEPTH(SAMPLE_RAW_DEPTH_TEXTURE_LOD(_CameraDepthTexture, depthSunPos))); float depth = Linear01Depth(BEAUTIFY_DEPTH_LOD(_CameraDepthTexture, depthSunPos)); if (depth<1) return 0; #endif float2 grd = uv - sunPos; float aspectRatio = _ScreenParams.y / _ScreenParams.x; grd.y *= aspectRatio; float len = length(grd); // sun disk float s0 = pow( 1.0 + saturate(_SunData.y - len), 75) - 1.0; // corona rays float gang = _SunPos.w; //atan2(0.5 - sunPos.y, sunPos.x - 0.5); float ang = atan2(grd.y, grd.x) + gang; float ray1 = _SunCoronaRays1.z + abs(_SunCoronaRays1.x * cos(_SunCoronaRays1.w + ang * _SunCoronaRays1.y)); // design ray1 *= pow( 1.0 + len, 1.0/_SunCoronaRays1.x); s0 += 1.0 / ray1; float ray2 = _SunCoronaRays2.z + abs(_SunCoronaRays2.x * sin(_SunCoronaRays2.w + ang * _SunCoronaRays2.y)); // design ray2 *= pow( 1.0 + len, 1.0/_SunCoronaRays2.x); s0 += 1.0 / ray2; s0 *= _SunData.x; // ghosts hexagonal // float gang = atan2( (sunPos.y * _ScreenParams.y / _ScreenParams.x) - 0.5, sunPos.x - 0.5); // this angle should be passed by uniform // grd = uv - ghost1Pos + (ghost1Pos - 0.5) * ghost1PosOffset; // grd.y *= _ScreenParams.y / _ScreenParams.x; // rotate(grd, gang); // grd *= ghost1Size; // s0 += tex2D(_FlareTex, grd + 0.5.xx).r * ghost1Brighness; // // grd = uv - ghost2Pos + (ghost2Pos - 0.5) * ghost2PosOffset; // grd.y *= _ScreenParams.y / _ScreenParams.x; // rotate(grd, gang); // grd *= ghost2Size; // s0 += tex2D(_FlareTex, grd + 0.5.xx).r * ghost2Brighness; float3 flare = s0.xxx; // ghosts circular float2 ghost1Pos = 1.0 - sunPos; grd = uv - ghost1Pos + (ghost1Pos - 0.5) * _SunGhosts1.z; grd.y *= aspectRatio; float g0 = saturate(_SunGhosts1.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts1.w / len; float2 ghost2Pos = 1.0 - sunPos; grd = uv - ghost2Pos + (ghost2Pos - 0.5) * _SunGhosts2.z; grd.y *= aspectRatio; g0 = saturate(_SunGhosts2.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts2.w / len; float2 ghost3Pos = 1.0 - sunPos; grd = uv - ghost3Pos + (ghost3Pos - 0.5) * _SunGhosts3.z; grd.y *= aspectRatio; g0 = saturate(_SunGhosts3.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts3.w / len; float2 ghost4Pos = 1.0 - sunPos; grd = uv - ghost4Pos + (ghost4Pos - 0.5) * _SunGhosts4.z; grd.y *= aspectRatio; g0 = saturate(_SunGhosts4.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts4.w / len; // light rays float2 uv2 = uv - sunPos; float clen = length(uv2); rotate(uv2, gang); uv2.x *= aspectRatio; uv2.x *= 0.1; uv2 /= len; float lr = saturate(tex2D(_FlareTex, uv2 + _SunPos.zz).r - _SunData.w); float3 rays = lr * sin(float3(len, len + 0.1, len + 0.2) * 3.1415927); float atten = pow(1.0 + clen, 13.0); rays *= _SunData.z / atten; flare += rays; // halo float hlen = clamp( (len - _SunHalo.x) * _SunHalo.y, 0, 3.1415927); float3 halo = pow(sin(float3(hlen, hlen + 0.1, hlen + 0.2)), 12.0.xxx); halo *= _SunHalo.z / atten; flare += halo; return flare * _SunTint; } float3 sunflareFast(float2 uv) { // general params float2 sunPos = unity_StereoEyeIndex == 0 ? _SunPos.xy : _SunPosRightEye.xy; float2 grd = uv - sunPos; float aspectRatio = _ScreenParams.y / _ScreenParams.x; grd.y *= aspectRatio; float len = length(grd); // corona rays float ang = atan2(grd.y, grd.x); float ray1 = _SunCoronaRays1.z + abs(_SunCoronaRays1.x * cos(_SunCoronaRays1.w + ang * _SunCoronaRays1.y)); // design ray1 *= pow( 1.0 + len, 1.0/_SunCoronaRays1.x); float s0 = 1.0 / ray1; s0 *= _SunData.x; float3 flare = s0.xxx; // ghosts circular float2 ghost1Pos = 1.0 - sunPos; grd = uv - ghost1Pos + (ghost1Pos - 0.5) * _SunGhosts1.z; grd.y *= aspectRatio; float g0 = saturate(_SunGhosts1.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts1.w / len; float2 ghost2Pos = 1.0 - sunPos; grd = uv - ghost2Pos + (ghost2Pos - 0.5) * _SunGhosts2.z; grd.y *= aspectRatio; g0 = saturate(_SunGhosts2.y / length(grd)); g0 = pow(g0, 12); flare += g0 * _SunGhosts2.w / len; // halo float hlen = clamp( (len - _SunHalo.x) * _SunHalo.y, 0, 3.1415927); float3 halo = pow(sin(float3(hlen, hlen + 0.1, hlen + 0.2)), 12.0.xxx); float clen = length(uv - 0.5.xx); float atten = pow(1.0 + clen, 13.0); halo *= _SunHalo.z / atten; flare += halo; return flare * _SunTint; } float4 fragSF (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); return float4(sunflare(i.uvNonStereo), 1.0); } float4 fragSFAdditive (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); float4 p = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); return p + float4(sunflare(i.uvNonStereo), 1.0); } float4 fragSFFast (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); return float4(sunflareFast(i.uvNonStereo), 1.0); } float4 fragSFFastAdditive (v2f i) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); float4 p = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv); return p + float4(sunflareFast(i.uvNonStereo), 1.0); }