124 lines
5.1 KiB
GLSL
124 lines
5.1 KiB
GLSL
Shader "Aerosol/Skybox"
|
|
{
|
|
Properties
|
|
{
|
|
transmittance_texture("Transimittance Texture", 2D) = "" {}
|
|
scattering_texture("Scattering Texture", 3D) = "" {}
|
|
single_mie_scattering_texture("Single Mie Scattering Texture", 3D) = "" {}
|
|
irradiance_texture("Irradiance Texture", 2D) = "" {}
|
|
unit_scale("Unit Scale", Float) = 0.001
|
|
white_point("White Point", Vector) = (1, 1, 1, 0)
|
|
exposure("Exposure", Float) = 0.0001
|
|
ground_albedo("Ground Albedo", Vector) = (0.1, 0.1, 0.1, 0)
|
|
}
|
|
SubShader
|
|
{
|
|
Tags {"Queue"="Background" "RenderType"="Background"}
|
|
Cull Off ZWrite Off ZTest Less
|
|
|
|
Pass
|
|
{
|
|
HLSLPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma multi_compile_instancing
|
|
|
|
#include "UnityCG.cginc"
|
|
#include "atmosphere.hlsl"
|
|
|
|
const static float3 earth_center = float3(0, -ATMOSPHERE.bottom_radius, 0);
|
|
const static float2 sun_size = float2(
|
|
tan(ATMOSPHERE.sun_angular_radius), cos(ATMOSPHERE.sun_angular_radius));
|
|
|
|
float unit_scale;
|
|
float3 white_point;
|
|
float exposure;
|
|
float3 ground_albedo;
|
|
|
|
struct appdata
|
|
{
|
|
float4 vertex : POSITION;
|
|
};
|
|
|
|
struct v2f
|
|
{
|
|
float4 pos : SV_POSITION;
|
|
float3 view_ray : TEXCOORD0;
|
|
};
|
|
|
|
v2f vert (appdata v)
|
|
{
|
|
v2f output;
|
|
output.pos = UnityObjectToClipPos(v.vertex);
|
|
output.view_ray = mul((float3x3)unity_ObjectToWorld, v.vertex.xyz);
|
|
return output;
|
|
}
|
|
|
|
half4 frag (v2f i) : SV_Target
|
|
{
|
|
float3 view_direction = normalize(i.view_ray);
|
|
float3 sun_direction = normalize(_WorldSpaceLightPos0.xyz);
|
|
float3 camera = _WorldSpaceCameraPos * unit_scale;
|
|
float3 p = camera - earth_center;
|
|
float lightshaft_fadein_hack = smoothstep(
|
|
0.02, 0.04, dot(normalize(p), sun_direction));
|
|
|
|
// TODO: shadow
|
|
float shadow_out = 0;
|
|
float shadow_in = 0;
|
|
|
|
// Compute the radiance reflected by the ground, if the ray intersects it.
|
|
// Compute the distance between the view ray line and the Earth center,
|
|
// and the distance between the camera and the intersection of the view
|
|
// ray with the ground (or NaN if there is no intersection).
|
|
float ground_alpha = 0.0;
|
|
float3 ground_luminance = 0.0;
|
|
float p_dot_v = dot(p, view_direction);
|
|
float p_dot_p = dot(p, p);
|
|
float ray_earth_center_squared_distance = p_dot_p - p_dot_v * p_dot_v;
|
|
float delta_intersection_square = earth_center.y * earth_center.y - ray_earth_center_squared_distance;
|
|
float distance_to_intersection = -p_dot_v - sqrt(delta_intersection_square);
|
|
if (delta_intersection_square > 0 && distance_to_intersection > 0) {
|
|
float3 pnt = p + view_direction * distance_to_intersection;
|
|
float3 normal = normalize(pnt);
|
|
|
|
// Compute the radiance reflected by the ground.
|
|
float3 sky_illuminance;
|
|
float3 sun_illuminance = GetSunAndSkyIlluminance(
|
|
pnt, normal, sun_direction, sky_illuminance);
|
|
// TODO: visibility term
|
|
float visibility = 1;
|
|
ground_luminance = ground_albedo * (1.0 / PI) *
|
|
(sun_illuminance + sky_illuminance) * visibility;
|
|
|
|
float shadow_length =
|
|
max(0.0, min(shadow_out, distance_to_intersection) - shadow_in) *
|
|
lightshaft_fadein_hack;
|
|
float3 transmittance;
|
|
float3 in_scatter = GetSkyLuminanceToPoint(p, pnt,
|
|
shadow_length, sun_direction, transmittance);
|
|
ground_luminance = ground_luminance * transmittance + in_scatter;
|
|
ground_alpha = 1.0;
|
|
}
|
|
|
|
// Compute the radiance of the sky.
|
|
float shadow_length = max(0, shadow_out - shadow_in) * lightshaft_fadein_hack;
|
|
float3 transmittance;
|
|
float3 luminance = GetSkyLuminance(
|
|
p, view_direction, shadow_length, sun_direction, transmittance);
|
|
|
|
// If the view ray intersects the Sun, add the Sun radiance.
|
|
if (dot(view_direction, sun_direction) > sun_size.y) {
|
|
luminance = luminance + transmittance * GetSolarLuminance();
|
|
}
|
|
luminance = lerp(luminance, ground_luminance, ground_alpha);
|
|
|
|
// tone mapping & sRGB -> linearRGB (gamma)
|
|
float3 rgb = pow(1 - exp(-luminance / white_point * exposure), 2.2);
|
|
return half4(rgb , 1);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
}
|