cvr-props/Assets/sunset_box/sunset_env_dynamic.shader

203 lines
5.6 KiB
Text
Raw Normal View History

Shader "CrispyPin/Sunset Environment (Dynamic)"
{
Properties
{
[Header(Sky)]
_SkyCol ("Sky color", Color) = (0.22, 0.23, 0.58, 1.0)
2023-02-12 19:13:24 +01:00
_HorizonTint ("Horizon tint", Range(0, 1)) = 0.1
[Header(Sun)]
_SunCol ("Sun color", Color) = (1.0, 0.65, 0.05, 1.0)
_SunAngle ("Sun angle", Range(0, 6.28)) = 0
_SunRadius ("Sun radius", Range(0, 0.3)) = 0.06
_SunCutoff ("Sun cutoff", Range(0, 0.5)) = 0.08
[Header(Star Layout)]
[NoScaleOffset]
_NoiseTex ("Noise source", 2D) = "white" {}
_StarDensity ("Star density", Range(4, 50)) = 20
_StarRandom ("Star randomness", Range(0, 1)) = 0.85
[Header(Star)]
_StarsMissing ("Stars missing", Range(0, 1)) = 0.75
_StarSize ("Star size", Range(0, 0.1)) = 0.06
_StarSizeRandom ("Star size randomness", Range(0, 1)) = 0.5
_StarTint ("Star tint", Range(0, 1)) = 0.4
[Header(Water)]
2023-02-12 16:34:03 +01:00
_WaterCol ("Water color", Color) = (0.03, 0.08, 0.12, 1.0)
2023-02-12 17:02:21 +01:00
_WaveStrength ("Wave scale", Range(0, 1)) = 1
2023-02-12 16:50:08 +01:00
[NoScaleOffset]
_WaterSurface ("Surface Normal", 2D) = "white" {}
[Header(Debug)]
_Grid ("Grid visibility", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Cull back
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define PI 3.1416f
2023-02-14 20:04:51 +01:00
#define WHITE 1
2023-02-12 16:13:50 +01:00
#define UP float3(0, 1, 0)
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
2023-02-12 16:34:03 +01:00
float3 cam_pos : TEXCOORD0;
float3 hit_pos : TEXCOORD1;
};
sampler2D _NoiseTex;
2023-02-14 20:04:51 +01:00
float3 _SkyCol;
2023-02-12 19:13:24 +01:00
float _HorizonTint;
float _StarsMissing;
float _StarDensity;
float _StarRandom;
float _StarSize;
float _StarSizeRandom;
float _StarTint;
2023-02-14 20:04:51 +01:00
float3 _SunCol;
float _SunAngle;
float _SunRadius;
float _SunCutoff;
2023-02-12 16:34:03 +01:00
sampler2D _WaterSurface;
2023-02-14 20:04:51 +01:00
float3 _WaterCol;
2023-02-12 17:02:21 +01:00
float _WaveStrength;
float _Grid;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
2023-02-12 16:34:03 +01:00
o.cam_pos = _WorldSpaceCameraPos;
o.hit_pos = mul(unity_ObjectToWorld, v.vertex);
return o;
}
2023-02-14 20:04:51 +01:00
float3 get_water_normal(float2 pos) {
float3 normal = 0;
2023-02-12 17:02:21 +01:00
float t1 = _Time.x * 0.18;
normal += (tex2D(_WaterSurface, pos * 1.04 + float2(t1, t1 * 0.5)) - 0.5);
float t2 = _Time.x * 0.37;
normal += (tex2D(_WaterSurface, pos * 0.276 + float2(t2 * 0.8, t2)) - 0.5);
float t3 = _Time.x * 0.08;
normal += (tex2D(_WaterSurface, pos * 0.07 + float2(t3 * 0.8, -t3)) - 0.5);
2023-02-12 16:50:08 +01:00
// return UP;
2023-02-14 20:04:51 +01:00
return lerp(UP, normalize(normal.zxy), _WaveStrength);
2023-02-12 16:50:08 +01:00
}
inline float smin(float a, float b, float k)
2023-02-12 19:13:24 +01:00
{
2023-02-14 20:04:51 +01:00
float h = max(k - abs(a - b), 0) / k;
return min(a, b) - h * h * h * k * 1/6;
2023-02-12 19:13:24 +01:00
}
inline float smax(float a, float b, float k)
2023-02-12 19:13:24 +01:00
{
float h = max(k - abs(a - b), 0) / k;
2023-02-14 20:04:51 +01:00
return max(a, b) + h * h * h * k * 1/6;
2023-02-12 19:13:24 +01:00
}
2023-02-14 20:04:51 +01:00
float3 sky(float3 dir, float theta, float phi, float3 sun_dir) {
/// background
float factor = smoothstep(0, 0.5, dir.y + 0.2);
float3 horizon_col = lerp(_SkyCol, _SunCol, _HorizonTint);
float3 col = lerp(horizon_col, _SkyCol, factor);
/// stars
float2 cells = float2(-1, floor(_StarDensity));
float cell_x_base = floor(cells.y * PI);
float celly = phi * cells.y;
// cells per ring depend on y pos, to reduce warping around the poles:
2023-02-14 20:04:51 +01:00
cells.x = floor(cos(floor(celly) / _StarDensity) * cell_x_base);
float cellx = (theta / PI * cells.x);
2023-02-14 20:04:51 +01:00
float2 pos = float2(cellx, celly); // cell-space pos of this pixel
float2 cell_pos = float2(floor(cellx), floor(celly)); // position of this cell
2023-02-14 20:04:51 +01:00
float2 cell_center = cell_pos + 0.5;
2023-02-14 20:04:51 +01:00
float2 star_pos = cell_center + (tex2D(_NoiseTex, cell_pos / cells + float2(0, 0.1)) - 0.5) * _StarRandom;
/// star color
float3 r = tex2D(_NoiseTex, cell_pos / cells);
float rnum = frac((r.r + r.g - r.b) * 10);
float rnum2 = frac((r.r - r.g + r.b) * 10);
float star_size = _StarSize * (rnum * _StarSizeRandom + (1 - _StarSizeRandom));
float distance = length(pos - star_pos);
2023-02-12 17:02:21 +01:00
float star_strength = max(min(star_size / distance * 0.5, 1.25) - 0.25, 0); // star glow
star_strength *= clamp(sin(phi * 2) - 0.1, 0, 1); // fade stars near/under horizon
2023-02-12 17:02:21 +01:00
star_strength *= length(r) / 2; // fade stars
star_strength *= rnum2 > _StarsMissing; // remove stars
2023-02-14 20:04:51 +01:00
float3 star_col = lerp(WHITE, r, _StarTint);
2023-02-14 20:04:51 +01:00
col = lerp(col, star_col, star_strength);
/// debug grid
2023-02-12 17:02:21 +01:00
col = lerp(col, WHITE, _Grid * (frac(cellx) < 0.04 || frac(celly) < 0.04));
/// sun
float alignment = min(acos(dot(dir, sun_dir)), 1);
2023-02-12 19:13:24 +01:00
float sun_amount = smax(min(_SunRadius / alignment, 5) - _SunCutoff, 0, 0.15);
col = lerp(col, _SunCol, sun_amount);
2023-02-14 20:04:51 +01:00
return col;
}
float3 frag(v2f i) : SV_Target
{
float3 sun_dir = float3(sin(_SunAngle), 0, cos(_SunAngle));
float water_mod = 0;
// float water_reflection = 0;
float3 dir = normalize(i.hit_pos - i.cam_pos);
float theta = atan2(dir.x, dir.z); // latitude
float phi = asin(dir.y); // longitude
if (phi < 0) {
float3 object_pos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float3 camera_local_pos = i.cam_pos - object_pos;
float3 surface_pos = float3 (
camera_local_pos.x - camera_local_pos.y / (dir.y / dir.x),
0,
camera_local_pos.z - camera_local_pos.y / (dir.y / dir.z)
);
float3 water_normal = get_water_normal(surface_pos.xz);
dir = reflect(dir, water_normal);
phi = asin(dir.y);
water_mod = dot(dir, water_normal);
// water_reflection = 1;
}
float3 col = sky(dir, theta, phi, sun_dir);
2023-02-12 16:34:03 +01:00
col = lerp(col, _WaterCol, water_mod);
return col;
}
ENDCG
}
}
}