Created
January 21, 2019 00:28
-
-
Save hvent90/fe8415ca205206c3836064b4e9bb58e3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' | |
Shader "Raymarch/clouds2" { | |
Properties { | |
_MainTex("main tex", 2D) = "white" {} | |
_ValueNoise("value noise", 2D) = "white" {} | |
} | |
HLSLINCLUDE | |
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl" | |
#include "HLSLSupport.cginc" | |
uniform sampler2D _CameraDepthTexture; | |
uniform sampler2D _MainTex; | |
uniform float4 _MainTex_TexelSize; | |
uniform sampler2D _ValueNoise; | |
uniform float _MinHeight= 0; | |
uniform float _MaxHeight = 1; | |
uniform float _FadeDist = 1; | |
uniform float _Scale = 1; | |
uniform float4 _SunDir = float4(1, 1, 1, 1); | |
uniform float4x4 _FrustumCornersWS; | |
uniform float4 _CameraWS; | |
uniform float4x4 _CameraInvViewMatrix; | |
float4 _Pos; | |
struct v2f { | |
float4 pos : SV_POSITION; | |
float2 uv : TEXCOORD0; | |
float4 ray : TEXCOORD1; | |
}; | |
struct AppData { | |
float4 vertex : SV_POSITION; | |
float2 texcoord : TEXCOORD0; | |
float3 ray : TEXCOORD1; | |
}; | |
float noise(in float3 x) { | |
x *= _Scale; | |
float3 p = floor(x); | |
float3 f = frac(x); | |
// f = f*f*(3.0 - 2.0*f); | |
float2 uv = (p.xy + float2(37.0, -17.0)*p.z) + f.xy; | |
float2 rg = tex2Dlod(_ValueNoise, float4((uv + 0.5) / 256.0, 0, 0)).rg; | |
float defaultUpperLimit = 2; | |
float upperLimit = lerp(1.6, 1.8, (sin(_Time * 5) + 1) / 2); | |
return -1.0 + defaultUpperLimit*lerp(rg.g, rg.r, f.z); | |
} | |
#define NOISEPROC(N, P) 1.75 * N * saturate((_MaxHeight-P.y) / _FadeDist) | |
float map5(in float3 q) | |
{ | |
float3 p = q; | |
float f; | |
f = 0.50000*noise(q); q = q*2.02; | |
f += 0.25000*noise(q); q = q*2.03; | |
f += 0.12500*noise(q); q = q*2.01; | |
f += 0.06250*noise(q); q = q*2.02; | |
f += 0.03125*noise(q); | |
return NOISEPROC(f, p); | |
} | |
float map4(in float3 q) | |
{ | |
float3 p = q; | |
float f; | |
f = 0.50000*noise(q); q = q*2.02; | |
f += 0.25000*noise(q); q = q*2.03; | |
f += 0.12500*noise(q); q = q*2.01; | |
f += 0.06250*noise(q); | |
return NOISEPROC(f, p); | |
} | |
float map3(in float3 q) | |
{ | |
float3 p = q; | |
float f; | |
f = 0.50000*noise(q); q = q*2.02; | |
f += 0.25000*noise(q); q = q*2.03; | |
f += 0.12500*noise(q); | |
return NOISEPROC(f, p); | |
} | |
float map2(in float3 q) | |
{ | |
float3 p = q; | |
float f; | |
f = 0.50000*noise(q); q = q*2.02; | |
f += 0.25000*noise(q);; | |
return NOISEPROC(f, p); | |
} | |
fixed4 integrate(in fixed4 sum, in float dif, in float den, in fixed3 bgcol, in float t, in float3 pos) | |
{ | |
// lighting | |
fixed3 lin = fixed3(0.65, 0.68, 0.7)*1.3 + 0.5*fixed3(0.7, 0.5, 0.3)*dif; | |
fixed3 colrgb = lerp(1.15*fixed3(1.0, 0.95, 0.8), fixed3(0.65, 0.65, 0.65), den); | |
fixed4 col = fixed4(colrgb.r, colrgb.g, colrgb.b, (fixed)den); | |
col.xyz *= lin; | |
col.xyz = lerp(col.xyz, bgcol, 1.0 - exp(-0.003*t*t)); | |
// front to back blending | |
col.a *= 0.4; | |
col.rgb *= col.a; | |
float _dist = 5; | |
return sum + col*(1.0 - sum.a); | |
} | |
#define MARCH(steps, map, ro, rd, bgcol, sum, depth, t) { \ | |
for (int i = 0; i<steps; i++) { \ | |
if(t > depth) \ | |
break; \ | |
float3 pos = ro + t*rd; \ | |
if (pos.y<_MinHeight || pos.y>_MaxHeight || sum.a > 0.99) { \ | |
t += max(0.1, 0.02*t); \ | |
continue; \ | |
} \ | |
float den = map(pos); \ | |
if (den>0.01) \ | |
{ \ | |
float dif = clamp((den - map(pos + 0.3*_SunDir)) / 0.6, 0.0, 1.0); \ | |
sum = integrate(sum, dif, den, bgcol, t, pos); \ | |
} \ | |
t += max(0.1, 0.02*t); \ | |
} \ | |
} | |
fixed4 raymarch(in float3 ro, in float3 rd, in fixed3 bgcol, in float depth) | |
{ | |
fixed4 sum = fixed4(0.0, 0.0, 0.0, 0.0); | |
float ct = 0.0; | |
depth = 1000; | |
ro = (0, 0, 0); | |
MARCH(1000, map5, ro, rd, bgcol, sum, depth, ct) | |
MARCH(1000, map4, ro, rd, bgcol, sum, depth, ct) | |
MARCH(1000, map3, ro, rd, bgcol, sum, depth, ct) | |
MARCH(1000, map2, ro, rd, bgcol, sum, depth, ct) | |
return clamp(sum, 0.0, 1.0); | |
} | |
v2f vert(AppData v) { | |
v2f o; | |
// Vertex.z is populated by Clouds.cs (companion script) with the current frustum corner | |
half index = v.vertex.z; | |
v.vertex.z = 0.1; | |
//o.pos = UnityObjectToClipPos(v.vertex); | |
o.pos = v.vertex; | |
o.uv = v.texcoord.xy; | |
#if UNITY_UV_STARTS_AT_TOP | |
if(_MainTex_TexelSize.y < 0) | |
o.uv.y = 1 - o.uv.y; | |
#endif | |
o.ray = _FrustumCornersWS[(int)index]; | |
o.ray /= abs(o.ray.z); | |
o.ray = mul(_CameraInvViewMatrix, o.ray); | |
return o; | |
} | |
fixed4 frag(v2f i) : SV_Target { | |
float3 eyeVec = normalize(i.ray.xyz); | |
float3 start = _CameraWS; | |
float2 duv = i.uv; | |
#if UNITY_UV_STARTS_AT_TOP | |
if (_MainTex_TexelSize.y < 0) | |
duv.y = 1 - duv.y; | |
#endif | |
// if(start.y > _MaxHeight+0.001) | |
// start += eyeVec / abs(eyeVec.y) * abs(start.y - _MaxHeight); | |
// else if(start.y < _MinHeight-0.001) | |
// start += eyeVec / abs(eyeVec.y) * abs(start.y - _MinHeight); | |
float depth = LinearEyeDepth(tex2D(_CameraDepthTexture, duv).r); | |
depth *= length(i.ray); | |
fixed3 col = tex2D(_MainTex,i.uv); | |
col = float3(0, 0, 0); | |
fixed4 add = raymarch(start, eyeVec, col, depth); | |
return fixed4(col*(1.0-add.w)+add.xyz,1.0); | |
} | |
ENDHLSL | |
SubShader { | |
Pass { | |
Cull Off ZWrite Off ZTest Always | |
HLSLPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
ENDHLSL | |
} | |
} | |
FallBack Off | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment