115 lines
3.9 KiB
Plaintext
115 lines
3.9 KiB
Plaintext
// Equirectangular skybox with a blurred nadir, for hiding whoever was carrying the camera.
|
|
// Drop-in replacement for Skybox/Panoramic (mono, latitude-longitude layout).
|
|
//
|
|
// REQUIRED: the source texture must have mip maps enabled, or nothing will blur.
|
|
// RenderTexture: tick "Mip Maps" on the asset (auto-generate is on by default).
|
|
// Still image: tick "Generate Mip Maps" in the import settings.
|
|
|
|
Shader "Skybox/PanoramicNadirBlur"
|
|
{
|
|
Properties
|
|
{
|
|
[NoScaleOffset] _MainTex ("Equirectangular Texture", 2D) = "grey" {}
|
|
_Tint ("Tint Color", Color) = (0.5, 0.5, 0.5, 0.5)
|
|
[Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
|
|
_Rotation ("Rotation", Range(0, 360)) = 0
|
|
|
|
[Header(Nadir Blur)]
|
|
_BlurStartAngle ("Blur Starts (deg below horizon)", Range(0, 90)) = 40
|
|
_BlurFullAngle ("Fully Blurred (deg below horizon)", Range(0, 90)) = 65
|
|
_BlurStrength ("Blur Strength (mip level)", Range(0, 10)) = 6
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags { "Queue" = "Background" "RenderType" = "Background" "PreviewType" = "Skybox" }
|
|
Cull Off
|
|
ZWrite Off
|
|
|
|
Pass
|
|
{
|
|
CGPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma target 3.0
|
|
#include "UnityCG.cginc"
|
|
|
|
sampler2D _MainTex;
|
|
half4 _Tint;
|
|
half _Exposure;
|
|
float _Rotation;
|
|
float _BlurStartAngle;
|
|
float _BlurFullAngle;
|
|
float _BlurStrength;
|
|
|
|
float3 RotateAroundYInDegrees(float3 vertex, float degrees)
|
|
{
|
|
float alpha = degrees * UNITY_PI / 180.0;
|
|
float sina, cosa;
|
|
sincos(alpha, sina, cosa);
|
|
float2x2 m = float2x2(cosa, -sina, sina, cosa);
|
|
return float3(mul(m, vertex.xz), vertex.y).xzy;
|
|
}
|
|
|
|
struct appdata_t
|
|
{
|
|
float4 vertex : POSITION;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 vertex : SV_POSITION;
|
|
float3 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
v2f vert(appdata_t v)
|
|
{
|
|
v2f o;
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
|
|
|
float3 rotated = RotateAroundYInDegrees(v.vertex.xyz, _Rotation);
|
|
o.vertex = UnityObjectToClipPos(rotated);
|
|
o.texcoord = v.vertex.xyz;
|
|
return o;
|
|
}
|
|
|
|
// Matches Unity's Skybox/Panoramic mapping so orientation is unchanged.
|
|
inline float2 ToRadialCoords(float3 coords)
|
|
{
|
|
float3 nc = normalize(coords);
|
|
float latitude = acos(nc.y);
|
|
float longitude = atan2(nc.z, nc.x);
|
|
float2 sphereCoords = float2(longitude, latitude) * float2(0.5 / UNITY_PI, 1.0 / UNITY_PI);
|
|
return float2(0.5, 1.0) - sphereCoords;
|
|
}
|
|
|
|
fixed4 frag(v2f i) : SV_Target
|
|
{
|
|
float3 dir = normalize(i.texcoord);
|
|
float2 uv = ToRadialCoords(dir);
|
|
|
|
// Elevation in degrees: +90 straight up, 0 at the horizon, -90 straight down.
|
|
float elevation = degrees(asin(dir.y));
|
|
|
|
// 0 above the start angle, ramping to 1 by the full angle.
|
|
float t = 1.0 - smoothstep(-_BlurFullAngle, -_BlurStartAngle, elevation);
|
|
|
|
// Sampling a coarser mip is the cheap way to blur: no extra taps.
|
|
float lod = t * _BlurStrength;
|
|
|
|
half4 tex = tex2Dlod(_MainTex, float4(uv, 0.0, lod));
|
|
half3 col = tex.rgb * _Tint.rgb * unity_ColorSpaceDouble.rgb * _Exposure;
|
|
|
|
return half4(col, 1.0);
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
|
|
Fallback Off
|
|
}
|