ToriaAssets/Sources/Shaders/BeautifySF.cginc
2026-05-19 15:33:18 +02:00

236 lines
7.9 KiB
HLSL

#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);
}