2021-06-18 12:32:03 +01:00
|
|
|
Shader "VolSample/Volume Render Auto" {
|
2021-03-07 01:10:31 +00:00
|
|
|
Properties {
|
2020-12-01 00:16:11 +00:00
|
|
|
_MainTex( "", 2D ) = "white" {}
|
2020-12-01 20:38:28 +00:00
|
|
|
_StepExponent("Step Exponent", float) = 1
|
2020-11-27 22:47:33 +00:00
|
|
|
//_GridTransform("Grid Transform", Vector) = (0,0,0,0)
|
2021-06-01 10:59:45 +01:00
|
|
|
_Exposure("Exposure", float) = 1
|
2020-11-27 22:47:33 +00:00
|
|
|
_Gamma("Gamma", float) = .5
|
|
|
|
|
_TintExponent("Tint Exponent", float) = .5
|
|
|
|
|
_DepthCeiling("Depth Ceiling", float) = 1000
|
|
|
|
|
_DepthBlend("Depth Blend", float) = 100
|
2020-12-03 17:32:34 +00:00
|
|
|
_SafetyDistance("Safety Distance", float) = 20
|
2021-04-09 14:01:34 +01:00
|
|
|
_Scattering("Scattering", float) = 1
|
|
|
|
|
_ScatteringMinDist("ScatteringMinDist", float) = 1
|
|
|
|
|
_ScatteringDistExponent("ScatteringDistExponent", float) = 1
|
|
|
|
|
_ScatteringDensityExponent("ScatteringDensityExponent", float) = 1
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CGINCLUDE;
|
|
|
|
|
|
|
|
|
|
uniform sampler2D _MainTex;
|
|
|
|
|
uniform sampler2D _CameraDepthTexture;
|
|
|
|
|
|
|
|
|
|
#include "UnityCG.cginc"
|
2021-05-30 05:54:28 +01:00
|
|
|
#include "Assets/Shaders/Volumetric.cginc"
|
2020-11-27 22:47:33 +00:00
|
|
|
|
|
|
|
|
// the number of volume samples to take
|
2021-06-01 08:16:36 +01:00
|
|
|
#define SAMPLE_COUNT 96
|
2020-11-27 22:47:33 +00:00
|
|
|
|
|
|
|
|
// Shared shader code for pixel view rays, given screen pos and camera frame vectors.
|
|
|
|
|
// Camera vectors are passed in as this shader is run from a post proc camera, so the unity built-in values are not useful.
|
|
|
|
|
uniform float4x4 _CamProj;
|
2020-12-01 00:16:11 +00:00
|
|
|
uniform float4x4 _CamInvProj;
|
2020-11-27 22:47:33 +00:00
|
|
|
uniform float3 _CamPos;
|
|
|
|
|
uniform float3 _CamForward;
|
|
|
|
|
uniform float3 _CamRight;
|
|
|
|
|
uniform float _HalfFov;
|
2021-04-12 14:36:32 +01:00
|
|
|
uniform int _FrameNumber;
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2020-12-01 20:38:28 +00:00
|
|
|
uniform float _StepExponent;
|
|
|
|
|
|
2021-05-30 05:54:28 +01:00
|
|
|
uniform half _Gamma,
|
2021-06-01 10:59:45 +01:00
|
|
|
_Exposure,
|
2020-11-27 22:47:33 +00:00
|
|
|
_DepthCeiling,
|
2021-06-01 08:16:36 +01:00
|
|
|
_DepthBlend,
|
2021-04-09 14:01:34 +01:00
|
|
|
_Scattering,
|
|
|
|
|
_ScatteringDensityExponent,
|
|
|
|
|
_ScatteringDistExponent,
|
2021-05-30 05:54:28 +01:00
|
|
|
_ScatteringMinDist;
|
2020-11-27 22:47:33 +00:00
|
|
|
|
|
|
|
|
// Dithering
|
|
|
|
|
sampler2D _DitheringTex;
|
|
|
|
|
float4 _DitheringCoords;
|
|
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
inline float nrand(float2 ScreenUVs)
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
|
|
|
|
return frac(sin(ScreenUVs.x * 12.9898 + ScreenUVs.y * 78.233) * 43758.5453);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
void RaymarchStep( in float3 pos, in float stepSize, in float weight, inout float4 sum, in float scatter, inout float scatterSum)
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
2021-05-30 05:54:28 +01:00
|
|
|
float4 col = VolumeSampleColor( pos );
|
2021-06-01 08:16:36 +01:00
|
|
|
col.a *= stepSize * weight;
|
|
|
|
|
sum.rgb += col.rgb * col.a * (1.0 - sum.a);
|
|
|
|
|
sum.a += col.a;
|
2021-06-18 12:32:03 +01:00
|
|
|
scatterSum += pow(sum.a, _ScatteringDensityExponent) * scatter;
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
float4 RayMarch( in float3 origin, in float3 direction, in float zbuf, in float2 screenUV, out float scatterSum )
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
2021-05-02 20:59:45 +01:00
|
|
|
scatterSum = 0;
|
2021-06-01 08:16:36 +01:00
|
|
|
float blue = tex2D(_DitheringTex, screenUV * _DitheringCoords.xy + _DitheringCoords.zw).r;
|
|
|
|
|
//float rand = frac(blue + _FrameNumber * 1.61803398875);
|
2021-05-02 20:59:45 +01:00
|
|
|
//return float4(rand, rand, rand, 1);
|
2021-04-18 05:13:20 +01:00
|
|
|
//half rand = frac(nrand(screenUV) + _FrameNumber * 1.61803398875);
|
2021-06-01 08:16:36 +01:00
|
|
|
//half rand = nrand(screenUV + frac(_Time.x));
|
|
|
|
|
half rand = blue;
|
2020-11-27 22:47:33 +00:00
|
|
|
float4 sum = (float4)0.;
|
2021-04-09 14:01:34 +01:00
|
|
|
scatterSum = 0.;
|
2020-11-27 22:47:33 +00:00
|
|
|
|
|
|
|
|
// setup sampling
|
|
|
|
|
|
2020-12-01 20:38:28 +00:00
|
|
|
float rayDist = 0;
|
2020-11-27 22:47:33 +00:00
|
|
|
for( int i = 0; i < SAMPLE_COUNT; i++ )
|
|
|
|
|
{
|
2021-04-09 14:01:34 +01:00
|
|
|
float prevRayDist = rayDist;
|
2021-06-01 08:16:36 +01:00
|
|
|
rayDist = pow((i+rand)/SAMPLE_COUNT,_StepExponent) * _DepthCeiling + 1;
|
2020-11-27 22:47:33 +00:00
|
|
|
float distToSurf = zbuf - rayDist;
|
|
|
|
|
if( distToSurf <= 0.001 || sum.a > .99) break;
|
|
|
|
|
|
2020-12-01 20:38:28 +00:00
|
|
|
float step = rayDist - prevRayDist;
|
|
|
|
|
//float wt = (distToSurf >= step) ? 1. : distToSurf / step;
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
RaymarchStep( origin + rayDist * direction, step, 1-rayDist/_DepthCeiling, sum, _Scattering/pow(max(rayDist,_ScatteringMinDist),_ScatteringDistExponent), scatterSum);
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
2021-06-18 12:32:03 +01:00
|
|
|
sum.rgb = pow( sum.rgb / pow(100,_TintExponent), 1 / _Gamma ) * _Exposure;
|
2020-12-01 20:38:28 +00:00
|
|
|
return sum;
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct v2f
|
|
|
|
|
{
|
|
|
|
|
float4 pos : SV_POSITION;
|
|
|
|
|
float4 screenPos : TEXCOORD1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
v2f vert( appdata_base v )
|
|
|
|
|
{
|
|
|
|
|
v2f o;
|
|
|
|
|
o.pos = UnityObjectToClipPos( v.vertex );
|
|
|
|
|
o.screenPos = ComputeScreenPos( o.pos );
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-10 02:53:09 +01:00
|
|
|
void computeCamera( in float2 q, out float3 rayOrigin, out float3 rayDirection )
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
|
|
|
|
rayOrigin = _WorldSpaceCameraPos;
|
|
|
|
|
|
|
|
|
|
float2 p = 2.0*(q - 0.5);
|
2020-12-01 00:16:11 +00:00
|
|
|
float4 d = mul(_CamProj, float4(p, 0, 1));
|
2020-11-27 22:47:33 +00:00
|
|
|
d.xyz /= d.w;
|
2020-12-01 00:16:11 +00:00
|
|
|
//rd = (d - rayOrigin);
|
2022-07-10 02:53:09 +01:00
|
|
|
rayDirection = normalize(d - rayOrigin);
|
2020-12-01 00:16:11 +00:00
|
|
|
rayOrigin = d;
|
|
|
|
|
//rayOrigin += _ProjectionParams.y * rd;
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-01 00:16:11 +00:00
|
|
|
inline float LinearEyeDepthToOutDepth(float z)
|
|
|
|
|
{
|
|
|
|
|
return (1 - _ZBufferParams.w * z) / (_ZBufferParams.z * z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float3 DepthToWorld(float2 uv, float depth) {
|
|
|
|
|
float z = (1-depth) * 2.0 - 1.0;
|
|
|
|
|
|
|
|
|
|
float4 clipSpacePosition = float4(uv * 2.0 - 1.0, z, 1.0);
|
|
|
|
|
|
|
|
|
|
float4 viewSpacePosition = mul(_CamInvProj,clipSpacePosition);
|
|
|
|
|
viewSpacePosition /= viewSpacePosition.w;
|
|
|
|
|
|
|
|
|
|
float4 worldSpacePosition = mul(unity_ObjectToWorld,viewSpacePosition);
|
|
|
|
|
|
|
|
|
|
return worldSpacePosition.xyz;
|
|
|
|
|
}
|
2021-04-09 14:01:34 +01:00
|
|
|
|
|
|
|
|
// MRT shader
|
|
|
|
|
struct FragmentOutput
|
|
|
|
|
{
|
|
|
|
|
half4 dest0 : COLOR0;
|
|
|
|
|
half4 dest1 : COLOR1;
|
|
|
|
|
};
|
2020-12-01 00:16:11 +00:00
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
FragmentOutput frag( v2f i ) : SV_Target //out float outDepth : SV_Depth
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
2021-04-09 14:01:34 +01:00
|
|
|
FragmentOutput o;
|
|
|
|
|
|
2020-11-27 22:47:33 +00:00
|
|
|
float2 q = i.screenPos.xy / i.screenPos.w;
|
|
|
|
|
|
|
|
|
|
// camera
|
|
|
|
|
float3 rayOrigin, rayDirection;
|
|
|
|
|
computeCamera( q, rayOrigin, rayDirection );
|
|
|
|
|
|
|
|
|
|
// z buffer / scene depth for this pixel
|
|
|
|
|
float4 screenPos = UNITY_PROJ_COORD( i.screenPos );
|
|
|
|
|
float2 screenUV = screenPos.xy / screenPos.w;
|
2020-12-01 20:38:28 +00:00
|
|
|
|
2020-12-01 00:16:11 +00:00
|
|
|
float depthSample = tex2Dproj( _CameraDepthTexture, screenPos ).r;
|
|
|
|
|
//float depthValue = LinearEyeDepth(depthSample);
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2020-12-01 00:16:11 +00:00
|
|
|
float3 worldDepth = DepthToWorld(screenPos, depthSample);
|
|
|
|
|
float depthValue = length(worldDepth-rayOrigin);
|
2020-12-01 20:38:28 +00:00
|
|
|
|
2020-11-27 22:47:33 +00:00
|
|
|
// march through volume
|
2021-04-09 14:01:34 +01:00
|
|
|
float scatter;
|
|
|
|
|
float4 clouds = RayMarch( rayOrigin, rayDirection, depthValue, screenUV, scatter );
|
|
|
|
|
o.dest1 = .5 + scatter*.5;//smoothstep(1,.99,clouds.a)*pow(clouds.a,1)*.5;
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
float3 bgcol = tex2Dlod( _MainTex, float4(q, 0., 0.) );
|
2020-11-27 22:47:33 +00:00
|
|
|
// add in camera render colours, if not zfar (so we exclude skybox)
|
2020-12-01 20:38:28 +00:00
|
|
|
if(clouds.a < .99 && depthValue < _DepthCeiling)
|
2020-11-27 22:47:33 +00:00
|
|
|
{
|
|
|
|
|
// Blend out camera render when outside marching range
|
2020-12-01 20:38:28 +00:00
|
|
|
if( depthValue >= _DepthCeiling - _DepthBlend )
|
|
|
|
|
clouds.a = lerp(clouds.a, 1, (depthValue - (_DepthCeiling - _DepthBlend)) / _DepthBlend);
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2020-12-01 20:38:28 +00:00
|
|
|
//clouds.xyz = lerp(clouds.xyz, bgcol, 1-clouds.a);
|
|
|
|
|
clouds.xyz += (1. - clouds.a) * bgcol;
|
2020-11-27 22:47:33 +00:00
|
|
|
// assume zbuffer represents opaque surface
|
2020-12-01 00:16:11 +00:00
|
|
|
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
2020-12-01 20:38:28 +00:00
|
|
|
clouds.a = 1.;
|
2020-12-01 00:16:11 +00:00
|
|
|
|
|
|
|
|
//outDepth = LinearEyeDepthToOutDepth(min(depthValue, rayDist));
|
2020-11-27 22:47:33 +00:00
|
|
|
|
2021-04-09 14:01:34 +01:00
|
|
|
o.dest0 = clouds;
|
|
|
|
|
return o;
|
2020-11-27 22:47:33 +00:00
|
|
|
}
|
2020-12-01 00:16:11 +00:00
|
|
|
|
2020-11-27 22:47:33 +00:00
|
|
|
|
|
|
|
|
ENDCG
|
|
|
|
|
|
|
|
|
|
Subshader
|
|
|
|
|
{
|
|
|
|
|
Pass
|
|
|
|
|
{
|
|
|
|
|
ZTest Always Cull Off ZWrite Off
|
|
|
|
|
|
|
|
|
|
CGPROGRAM
|
|
|
|
|
#pragma target 3.0
|
|
|
|
|
#pragma vertex vert
|
|
|
|
|
#pragma fragment frag
|
|
|
|
|
ENDCG
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fallback off
|
|
|
|
|
|
|
|
|
|
} // shader
|