Files
ichni_Official/Assets/ThemeBundles/DepartureToMultiverse/Shaders/RetrowaveSkybox_Mobile.shader
SoulliesOfficial f4068baf4a GPU优化
2026-04-06 09:32:56 -04:00

221 lines
9.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Shader "Soullies/RetrowaveSkybox_Mobile"
{
Properties
{
[Header(Sky and Horizon)]
_SkyColor("Sky Color", Color) = (1, 0.15, 0, 1)
_HorizonColor("Horizon Color", Color) = (0.42, 0.10, 0.65, 1)
_HorizonStrength("Horizon Strength", Float) = 1.0
_HorizonHeight("Horizon/Sky Height Offset", Range(-1, 1)) = 0.0
[Header(Procedural Sun)]
[Toggle(_HAVESUN_ON)] _HaveSun("Have Sun", Float) = 1
_SunSize("Sun Disc Size", Range(0.001, 1)) = 0.05
[HDR]_SunColorOne("Sun Color Top", Color) = (0.95, 0.82, 0.29, 1)
[HDR]_SunColorTwo("Sun Color Bottom", Color) = (0.87, 0.39, 0.61, 1)
_SunGradStrength("Sun Gradient Strength", Float) = 10
_SunGradHeight("Sun Gradient Height", Range(-1, 5)) = 2
[NoScaleOffset] _SunMask("Sun Mask (Grid Map)", 2D) = "white" {}
_SunMaskSize("Sun Mask Size", Range(-5, 1)) = 0
[Header(Fog Equivalent Horizon Blending)]
_FogHeight("Fog Height", Range(-10, 10)) = 1.0
_FogPower("Fog Power", Range(0, 5)) = 1.0
_FogContrast("Fog Contrast", Float) = 5.0
[Header(Procedural Stars)]
_StarDensity("Star Density", Float) = 150.0
_StarSize("Star Size / Contrast", Range(0, 300)) = 150
[HDR]_StarColor("Star Color", Color) = (0.9, 0.9, 0.9, 1)
[Toggle(_PREVENTSTARS_ON)] _PreventStars("Prevent Stars on Sun", Float) = 1
}
SubShader
{
Tags
{
"RenderType"="Background"
"Queue"="Background"
"PreviewType"="Skybox"
"RenderPipeline" = "UniversalPipeline"
}
Pass
{
Name "Skybox"
ZWrite Off
Cull Off
ZTest LEqual
HLSLPROGRAM
#pragma target 3.5
#pragma prefer_hlslcc gles
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature_local _HAVESUN_ON
#pragma shader_feature_local _PREVENTSTARS_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 viewDirWS : TEXCOORD0;
};
CBUFFER_START(UnityPerMaterial)
half4 _SkyColor;
half4 _HorizonColor;
half _HorizonStrength;
half _HorizonHeight;
half _SunSize;
half4 _SunColorOne;
half4 _SunColorTwo;
half _SunGradStrength;
half _SunGradHeight;
half _SunMaskSize;
half _FogHeight;
half _FogPower;
half _FogContrast;
half _StarDensity;
half _StarSize;
half4 _StarColor;
CBUFFER_END
TEXTURE2D(_SunMask); SAMPLER(sampler_SunMask);
// [TA Optimize] Fast 3D Hash returning float3 for Star Placement
float3 FastHash3D_vec3(float3 p)
{
p = frac(p * float3(0.1031, 0.1030, 0.0973));
p += dot(p, p.yxz + 33.33);
return frac((p.xxy + p.yxx) * p.zyx);
}
Varyings vert(Attributes input)
{
Varyings output;
// Unity standard skybox space
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.viewDirWS = input.positionOS.xyz;
return output;
}
half4 frag(Varyings input) : SV_Target
{
// Must normalize local vertex pos to form spherical ray
float3 vDir = normalize(input.viewDirWS);
// ===================================
// 1. SKY & HORIZON (Restored mapping scale)
// ===================================
// 恢复使用 asin 以保证与原版天空盒参数的非线性渐变弧度绝对一致
// 半个圆周的 asin 值域映射常数: 1.0 / (PI / 2.0) = 0.63661977
float skyY = asin(clamp(vDir.y, -1.0, 1.0)) * 0.63661977;
// 去除此处的 saturate使得 _HorizonStrength>1 时可以向天空顶部延展色彩 (原版默认行为)
float skyMask = skyY * _HorizonStrength + _HorizonHeight;
half3 finalColor = lerp(_HorizonColor.rgb, _SkyColor.rgb, skyMask);
// ===================================
// 2. PROCEDURAL SUN (Zero Acos)
// ===================================
half3 sunColor = half3(0,0,0);
float sunOpacity = 0;
#if defined(_HAVESUN_ON)
Light mainLight = GetMainLight();
float3 lDir = normalize(mainLight.direction);
// [TA Optimize] Replace acos(dot) with raw dot + smoothstep
float NdotL = dot(vDir, lDir);
// Maps [0.001, 1.0] scale to a reasonable threshold for Dot Product
float sunThreshold = lerp(1.0, 0.8, _SunSize);
// Anti-aliased disc edge
float sunFw = fwidth(NdotL);
float sunMask = smoothstep(sunThreshold - sunFw, sunThreshold + sunFw, NdotL);
// Vertical Local Gradient
float localSunY = saturate(((vDir.y - lDir.y + (1.0 - sunThreshold)) / ((1.0 - sunThreshold) * 2.0)) * _SunGradStrength - _SunGradHeight);
half3 rawSunColor = lerp(_SunColorTwo.rgb, _SunColorOne.rgb, localSunY);
// [TA Optimize] Planar Projection UV for Sun Mask (Zero Trigo, No Spherical Math)
float3 up = abs(lDir.y) > 0.999 ? float3(0,0,1) : float3(0,1,0); // Prevent gimbal lock
float3 right = normalize(cross(up, lDir));
float3 sunUp = cross(lDir, right);
float2 sunUV = float2(dot(vDir, right), dot(vDir, sunUp));
// 修正点根据太阳真实的半径跨度进行缩放映射到完美填充正负1的圆形
float sunRadius = sqrt(max(0.0001, 1.0 - sunThreshold * sunThreshold));
float2 sunUVNorm = sunUV / sunRadius;
// 应用暴露出的原生 Mask 控制参数
sunUVNorm = sunUVNorm * (1.0 - _SunMaskSize) * 0.5 + 0.5;
half gridMask = SAMPLE_TEXTURE2D(_SunMask, sampler_SunMask, sunUVNorm).r;
sunOpacity = gridMask * sunMask;
sunColor = rawSunColor * sunOpacity;
#endif
// ===================================
// 3. PROCEDURAL STARS (Single-Tap Cellular Noise)
// ===================================
half3 starFinal = half3(0,0,0);
// [TA Optimize] 用单次计算的 3D Cell Noise 平替 9-Tap Voronoi
// 乘以 8 是为了还原老版本在 X轴上乘 8 带来的高密度视觉错觉
float3 scaledPos = vDir * (_StarDensity * 8.0);
float3 cell = floor(scaledPos);
float3 local = frac(scaledPos);
// 获取晶格内随机星星偏移点与亮暗随机种子
float3 randProps = FastHash3D_vec3(cell);
// 计算当前像素到该单个星星的距离
float dist = length(local - randProps);
// 构造出锐利的星星斑点 (类似 Voronoi 的山峰距离场)
float starVal = max(0.0, 1.0 - dist * 1.5); // 1.5 增强锐利度
starVal = pow(starVal, max(1.0, max(75, _StarSize) / 10));
// 随机让 40% 的晶格变空或变亮,使其显得自然参差不齐
float brightness = FastHash3D_vec3(cell + 123.0).x;
starVal *= (brightness > 0.4 ? brightness : 0.0);
starFinal = starVal * _StarColor.rgb;
#if defined(_PREVENTSTARS_ON)
starFinal *= (1.0 - sunOpacity);
#endif
// Add everything up
finalColor += starFinal;
finalColor += sunColor;
// ===================================
// 4. GLOBAL FOG BLEND (Restored)
// ===================================
// 还原原版 Shader Graph 在地平线处覆盖的全局雾气混合机制
float fogVal = saturate(_FogHeight - skyY * _FogContrast) * _FogPower;
finalColor = lerp(finalColor, unity_FogColor.rgb, saturate(fogVal));
return half4(finalColor, 1.0);
}
ENDHLSL
}
}
}