Shader "Hidden/RayCastCloud" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGINCLUDE #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile __ DEBUG #pragma multi_compile __ MIPMAP #pragma multi_compile __ MULTNOISE #include "UnityCG.cginc" #include "../RayCast.cginc" #pragma target 3.0 sampler2D _MainTex; sampler2D _CloudTex; sampler2D _CameraDepthTexture; float3 _SunGlareColor; float3 _Color1; float4 _SunSSSColor; float3 _Color3; float3 _Color4; float cloud_thickness; float cloud_position; float cloud_freq1; float cloud_freq2; float cloud_freq3; float cloud_freq4; float cloud_freq5; float near1; float far1; float near2; int rayIteratorCount; float4 _SunDirection; static float3 sundir = normalize( _SunDirection.xyz ); float3 winddir; float hash( float n ) { return frac(sin(n)*43758.5453); } float noise( in float3 x ) { float3 p = floor(x); float3 f = frac(x); f = f * f * (3.0 - 2.0 * f); float n = p.x + p.y * 57.0 + 113.0 * p.z; float rgx = lerp(lerp( hash(n + 0.0), hash(n + 1.0),f.x), lerp( hash(n + 57.0), hash(n + 58.0),f.x), f.y); float rgy = lerp(lerp( hash(n + 113.0), hash(n + 114.0),f.x), lerp( hash(n + 170.0), hash(n + 171.0),f.x), f.y); return -1.0 + 2.0 * lerp(rgx, rgy, f.z); } #if MULTNOISE #define FBM_O1 f += cloud_freq1 * noise( q - winddir * _Time.y ); q = q*2.02; #define FBM_O2 f += f * cloud_freq2 * noise( q - winddir * _Time.y ); q = q*2.03; #define FBM_O3 f += f * cloud_freq3 * noise( q - winddir * _Time.y ); q = q*2.01; #define FBM_O4 f += f * cloud_freq4 * noise( q - winddir * _Time.y ); q = q*2.02; #define FBM_O5 f += f * cloud_freq5 * noise( q - winddir * _Time.y ); #else #define FBM_O1 f += cloud_freq1 * noise( q - winddir * _Time.y ); q = q*2.02; #define FBM_O2 f += cloud_freq2 * noise( q - winddir * _Time.y ); q = q*2.03; #define FBM_O3 f += cloud_freq3 * noise( q - winddir * _Time.y ); q = q*2.01; #define FBM_O4 f += cloud_freq4 * noise( q - winddir * _Time.y ); q = q*2.02; #define FBM_O5 f += cloud_freq5 * noise( q - winddir * _Time.y ); #endif #define FBM5 FBM_O1 FBM_O2 FBM_O3 FBM_O4 FBM_O5 #define FBM4 FBM_O1 FBM_O2 FBM_O3 FBM_O4 #define FBM3 FBM_O1 FBM_O2 FBM_O3 #define FBM2 FBM_O1 FBM_O2 #define FBM(func) \ float3 q = p; \ q.y -= cloud_position; \ float f = 0; \ func \ return clamp( - abs(p.y - cloud_position) + cloud_thickness + 1.75 * f, 0.0, 1.0 ); float map5( in float3 p ) { FBM(FBM5) } float map4( in float3 p ) { FBM(FBM4) } float map3( in float3 p ) { FBM(FBM3) } float map2( in float3 p ) { FBM(FBM2) } float4 integrate( in float4 sum, in float dif, in float den, in float3 bgcol, in float t ) { // lighting float3 lin = _Color1 * 1.4 + _SunSSSColor.rgb * dif * _SunSSSColor.a; float4 col = float4( lerp( _Color3, _Color4, den ), 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; return sum + col*(1.0-sum.a); } #if DEBUG #define DEBUG_DEPTH sum.r = 1; #else #define DEBUG_DEPTH #endif #define MARCH(STEPS, MAPLOD) \ for(int i=0; i 0.99 ) break; \ float depth = toDepth(float4(pos, 1)); \ if( depth > bg_depth ) { DEBUG_DEPTH break; } \ float den = MAPLOD( pos ); \ float den2 = MAPLOD( pos + 0.3*sundir ); \ float dif = clamp((den - den2)/0.3, 0.0, 1.0 ); \ if((t>near1 && tnear2) \ sum = integrate( sum, dif, den, bgcol.rgb, t ); \ t += max(0.05, 0.02 * t); \ } float4 raymarch( in float3 ro, in float3 rd, in float4 bgcol ) { float4 sum = float4(0.0,0.0,0.0,0.0); float bg_depth = bgcol.a; float t = 0.0; #if MIPMAP int count = rayIteratorCount / 5; MARCH(count * 2, map5); MARCH(count, map4); MARCH(count, map3); MARCH(count, map2); #else MARCH(rayIteratorCount, map5); #endif return clamp( sum, 0.0, 1.0 ); } float2 castRay( in float3 ro, in float3 rd ) { float tmin = 1.0; float tmax = 20.0; float precis = 0.002; float t = tmin; float m = -1.0; for( int i=0; i<50; i++ ) { float3 pos = ro + rd*t; float d = length(pos) - 0.25; if( d < precis || t > tmax ) break; t += d; m = 1; } if( t > tmax ) m=-1.0; return float2( t, m ); } float3 renderxx( in float3 ro, in float3 rd ) { float3 col = float3(0.0, 0.0, 0.); float2 res = castRay(ro,rd); float m = res.y; if( m > -0.5 ) { col = 0.45 + 0.3 * sin( float3(0.05,0.08,0.10)*(m-1.0) ); } return float3( clamp(col,0.0,1.0) ); } float4 frag_vr_cloud(v2f_img i) : SV_Target { float bgDepth = LinearEyeDepth(tex2D(_CameraDepthTexture, float2(i.uv.x, i.uv.y)).r); // camera float3 ro = _WorldSpaceCameraPos; float3 rd = getRayDirection(i.uv); float4 scene_color = tex2D(_MainTex, i.uv); // clouds float4 res = raymarch( ro, rd, float4(float3(1.0, 1.0, 1.0), bgDepth) ); //float4 res = raymarch(ro, rd, float4(scene_color.rgb, bgDepth)); // sun glare float sun = clamp( dot(sundir,rd), 0.0, 1.0 ); res.rgb += 0.2 * _SunGlareColor * pow( sun, 3.0 ); //if(abs(ro.x - _WorldSpaceCameraPos.x) < 0.01 && abs(ro.y - _WorldSpaceCameraPos.y) < 0.01 && abs(ro.z - _WorldSpaceCameraPos.z) < 0.01) //if(coord.x < 0 && coord.y < 0) // col.r = 1; #if defined(DEBUG) res.rgb += renderxx(ro, rd); #endif //if (unity_CameraProjection[0][2] < 0) //if(abs(left) > abs(right)) //res.rgb = float3(1.0,0.0,0.0); /* float4x4 m = unity_CameraProjection; float near = m[2][3] / (m[2][2] - 1); float far = m[2][3] / (m[2][2] + 1); if (near <= far) res.rgb = float4(1,0,0,1); else res.rgb = float4(0, 1, 0, 1); */ return res; } float4 frag_vr_blendbg(v2f_img i) : SV_Target { // camera float4 scene_color = tex2D(_MainTex, i.uv); //scene_color = float4(0.0,0.0,0.0,1.0); // background sky float3 col = scene_color; //col = float3(0.6,0.71,0.75) - rd.y*0.2*float3(1.0,0.5,1.0) + 0.15*0.5; //col += 0.2 * float3(1.0,.6,0.1) * pow( sun, 8.0 ); // clouds float4 res = tex2D(_CloudTex, float2(i.uv.x, i.uv.y)); col = col * (1.0 - res.a) + res.rgb; //col = res.rgb; return float4( col, 1.0 ); } ENDCG // (0) VRRenderCloud Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag_vr_cloud ENDCG } // (0) VRBlendBg Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag_vr_blendbg ENDCG } } FallBack off }