|
| 1 | + |
| 2 | +Shader "FishManShaderTutorial/MyShader"{ |
| 3 | + Properties{ |
| 4 | + _MainTex ("MainTex", 2D) = "white" {} |
| 5 | + } |
| 6 | + |
| 7 | + SubShader |
| 8 | + { |
| 9 | + Tags { "RenderType" = "Transparent" "Queue" = "Transparent" } |
| 10 | + |
| 11 | + Pass |
| 12 | + { |
| 13 | + ZWrite Off |
| 14 | + Blend SrcAlpha OneMinusSrcAlpha |
| 15 | + |
| 16 | + CGPROGRAM |
| 17 | + #pragma vertex vert |
| 18 | + #pragma fragment frag |
| 19 | + #include "UnityCG.cginc" |
| 20 | + |
| 21 | + struct v2f { |
| 22 | + fixed4 pos : SV_POSITION; |
| 23 | + fixed2 uv : TEXCOORD0; |
| 24 | + fixed2 uv_depth : TEXCOORD1; |
| 25 | + fixed4 interpolatedRay : TEXCOORD2; |
| 26 | + }; |
| 27 | + |
| 28 | + fixed4x4 _FrustumCornersRay; |
| 29 | + fixed4 _MainTex_TexelSize; |
| 30 | + sampler2D _CameraDepthTexture; |
| 31 | + //Variables |
| 32 | +float4 _iMouse; |
| 33 | +sampler2D _SecondTex; |
| 34 | +sampler2D _MainTex; |
| 35 | + |
| 36 | + |
| 37 | + v2f vert(appdata_img v) { |
| 38 | + v2f o; |
| 39 | + o.pos = UnityObjectToClipPos(v.vertex); |
| 40 | + |
| 41 | + o.uv = v.texcoord; |
| 42 | + o.uv_depth = v.texcoord; |
| 43 | + |
| 44 | + #if UNITY_UV_STARTS_AT_TOP |
| 45 | + if (_MainTex_TexelSize.y < 0) |
| 46 | + o.uv_depth.y = 1 - o.uv_depth.y; |
| 47 | + #endif |
| 48 | + |
| 49 | + int index = 0; |
| 50 | + if (v.texcoord.x < 0.5 && v.texcoord.y < 0.5) { |
| 51 | + index = 0; |
| 52 | + } |
| 53 | + else if (v.texcoord.x > 0.5 && v.texcoord.y < 0.5) { |
| 54 | + index = 1; |
| 55 | + } |
| 56 | + else if (v.texcoord.x > 0.5 && v.texcoord.y > 0.5) { |
| 57 | + index = 2; |
| 58 | + } |
| 59 | + else { |
| 60 | + index = 3; |
| 61 | + } |
| 62 | + |
| 63 | + #if UNITY_UV_STARTS_AT_TOP |
| 64 | + if (_MainTex_TexelSize.y < 0) |
| 65 | + index = 3 - index; |
| 66 | + #endif |
| 67 | + o.interpolatedRay = _FrustumCornersRay[index]; |
| 68 | + //VertexFactory |
| 69 | + return o; |
| 70 | + }//end fixedt |
| 71 | + |
| 72 | + fixed4 ProcessFrag(v2f i); |
| 73 | + |
| 74 | + |
| 75 | + fixed4 frag(v2f i) : SV_Target |
| 76 | + { |
| 77 | + fixed linearDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv_depth)); |
| 78 | + fixed3 worldPos = _WorldSpaceCameraPos + linearDepth * i.interpolatedRay.xyz; |
| 79 | + //get Unity world pos |
| 80 | + fixed4 finalColor = tex2D(_MainTex, i.uv); |
| 81 | + |
| 82 | + fixed4 processCol = ProcessFrag(i); |
| 83 | + if(processCol.w < linearDepth){ |
| 84 | + finalColor = processCol; |
| 85 | + finalColor.w =1.0; |
| 86 | + } |
| 87 | + |
| 88 | + return finalColor; |
| 89 | + }//end frag |
| 90 | + |
| 91 | +//----------------------------------------------------- |
| 92 | + |
| 93 | + |
| 94 | +const fixed2x2 m2 = fixed2x2(0.8,-0.6,0.6,0.8); |
| 95 | + |
| 96 | +fixed fbm( fixed2 p ) |
| 97 | +{ |
| 98 | + fixed f = 0.0; |
| 99 | + f += 0.5000*tex2D( _MainTex, p/256.0, -100. ).x; p = m2*p*2.02; |
| 100 | + f += 0.2500*tex2D( _MainTex, p/256.0, -100. ).x; p = m2*p*2.03; |
| 101 | + f += 0.1250*tex2D( _MainTex, p/256.0, -100. ).x; p = m2*p*2.01; |
| 102 | + f += 0.0625*tex2D( _MainTex, p/256.0, -100. ).x; |
| 103 | + return f/0.9375; |
| 104 | +} |
| 105 | + |
| 106 | +fixed2 map (in fixed3 p) { |
| 107 | + fixed mountains = 19. * fbm(p.xz*0.091); |
| 108 | + fixed trees = -.35 * fbm(p.xz*10.); |
| 109 | + fixed rocks = -.002 * fbm(p.xz*100.); |
| 110 | + fixed result = p.y + mountains + trees + rocks; |
| 111 | + |
| 112 | + return fixed2(result, 1.0); |
| 113 | +} |
| 114 | + |
| 115 | +fixed3 mapColour (in fixed3 pos, in fixed3 nor) { |
| 116 | + fixed darken = (1.0 - 0.5 * length(normalize(pos))); |
| 117 | + fixed3 tint = fixed3(.7, .7, .6); |
| 118 | + fixed3 tex2D = tex2D( _SecondTex, 0.006125*pos.xz, -100. ).xyz; |
| 119 | + |
| 120 | + return tex2D * tint; |
| 121 | +} |
| 122 | + |
| 123 | +fixed2 raymarch (in fixed3 ro, in fixed3 rd) { |
| 124 | + fixed2 h = fixed2(0.001, 0.); |
| 125 | + fixed t = 0.; |
| 126 | + fixed tmax = 100.; |
| 127 | + |
| 128 | + for (int i = 0; i < 100; i++){ |
| 129 | + if (h.x < 0.0001 || t > tmax) break; |
| 130 | + h = map(ro + t * rd); |
| 131 | + t += 0.25 * h.x; |
| 132 | + } |
| 133 | + |
| 134 | + if(t > tmax) h.y = -1.; |
| 135 | + |
| 136 | + return fixed2(t, h.y); |
| 137 | +} |
| 138 | + |
| 139 | +fixed shadow( in fixed3 ro, in fixed3 rd, in fixed maxt) |
| 140 | +{ |
| 141 | + fixed res = 1.0; |
| 142 | + fixed dt = 0.04; |
| 143 | + fixed t = .02; |
| 144 | + [unroll(100)] |
| 145 | +for( int i=0; i < 20; i++ ) |
| 146 | + { |
| 147 | + fixed h = map(ro + rd*t).x; |
| 148 | + if( h<0.001 ) |
| 149 | + return 0.0; |
| 150 | + res = min( res, maxt*h/t ); |
| 151 | + t += h; |
| 152 | + } |
| 153 | + return res; |
| 154 | +} |
| 155 | + |
| 156 | +fixed3 calcNormal( in fixed3 pos, in fixed t ) |
| 157 | +{ |
| 158 | + // show more detail the closer we are to the object |
| 159 | + fixed3 eps = fixed3(0.002 * t,0.0,0.0); |
| 160 | + fixed3 nor; |
| 161 | + nor.x = map(pos+eps.xyy).x - map(pos-eps.xyy).x; |
| 162 | + nor.y = map(pos+eps.yxy).x - map(pos-eps.yxy).x; |
| 163 | + nor.z = map(pos+eps.yyx).x - map(pos-eps.yyx).x; |
| 164 | + return normalize(nor); |
| 165 | +} |
| 166 | + |
| 167 | + |
| 168 | + |
| 169 | +//----------------------------------------------------- |
| 170 | + |
| 171 | +fixed4 ProcessFrag(v2f i) { |
| 172 | + |
| 173 | + fixed2 q = i.uv / 1; |
| 174 | + fixed2 p = -1.0 + 2.0 * q; |
| 175 | + p.x *= 1/1; |
| 176 | + fixed2 mo = _iMouse.xy/1; |
| 177 | + |
| 178 | + // camera |
| 179 | + fixed an1 = 0.2*_Time.y-6.2831*mo.x; |
| 180 | + fixed an2 = clamp( 0.8 + 0.6*sin(2.2+_Time.y*0.11) + 1.0*mo.y, 0.3, 1.35 ); |
| 181 | + fixed3 ro = 10.0*normalize(fixed3(sin(an2)*cos(an1), cos(an2)-0.5, sin(an2)*sin(an1) )); |
| 182 | + fixed3 ww = normalize(fixed3(0.0,0.0,0.0) - ro); |
| 183 | + fixed3 uu = normalize(cross( fixed3(0.0,1.0,0.0), ww )); |
| 184 | + fixed3 vv = normalize(cross(ww,uu)); |
| 185 | + fixed3 rd = normalize( p.x*uu + p.y*vv - 1.4*ww ); |
| 186 | + |
| 187 | + // raymarch |
| 188 | + fixed3 col = fixed3(0.,0.,0.);//tex2D( _MainTex, rd ).xyz; |
| 189 | + fixed2 march = raymarch(ro, rd); |
| 190 | + |
| 191 | + fixed3 light = normalize(fixed3(0.9, 0.1, 0.9)); |
| 192 | + fixed3 ambient = 5. * fixed3(0.1, 0.15, 0.2); |
| 193 | + fixed sundot = clamp(dot(rd,light),0.0,1.0); |
| 194 | + fixed3 pos = ro + march.x * rd; |
| 195 | + |
| 196 | + // if we hit geometry |
| 197 | + if(march.y > 0.) { |
| 198 | + fixed3 nor = calcNormal(pos, march.x); |
| 199 | + |
| 200 | + fixed lambert = clamp(dot(nor, light), 0., 1.); |
| 201 | + col = mapColour(pos, nor); |
| 202 | + col = lerp( col, mapColour(pos, nor) * lambert, 0.8); |
| 203 | + |
| 204 | + //snow |
| 205 | + //fixed snow = clamp(dot(normalize(nor), fixed3(0., 1., 0.)), 0., 1.); |
| 206 | + //snow = pow(snow, 5.); |
| 207 | + //col = lerp(col, fixed3(1.,1.,1.)*snow, clamp(rd.y + 1., 0., 1.)*0.5); |
| 208 | + |
| 209 | + // fog |
| 210 | + fixed fo = 1.-exp(-0.04*march.x ); |
| 211 | + fixed3 fco = 0.9*fixed3(0.5,0.7,0.9) + 0.1*fixed3(1.0,0.8,0.5)*pow( sundot, 4.0 ); |
| 212 | + col = lerp( col, fco, fo ); |
| 213 | + |
| 214 | + fixed sh = shadow( pos, light, 10.); |
| 215 | + col = 0.8*col + 0.2* col* sh ;// + ambient * (1.0 - sh); |
| 216 | + |
| 217 | + } |
| 218 | + // sky |
| 219 | + if(march.y < 0.){ |
| 220 | + // sky colour |
| 221 | + float3 blueSky = float3(0.3,.55,0.8); |
| 222 | + float3 redSky = float3(0.8,0.8,0.6); |
| 223 | + |
| 224 | + float3 sky = lerp(blueSky, redSky, 1.5*pow(sundot, 8.)); |
| 225 | + |
| 226 | + col = sky*(1.0-0.8*rd.y); |
| 227 | + |
| 228 | + // stars |
| 229 | + float s = texture( iChannel0, rd.xz * 1.25, -100. ).x; |
| 230 | + s += texture( iChannel0, rd.xz* 4., -100. ).x; |
| 231 | + |
| 232 | + s = pow(s, 17.0) * 0.00005 * max(rd.y, -0.2) * pow((1. - max(sundot, 0.)), 2.); |
| 233 | + if (s > .0) |
| 234 | + { |
| 235 | + float3 backStars = float3(s); |
| 236 | + col += backStars; |
| 237 | + } |
| 238 | + |
| 239 | + // sun |
| 240 | + col += 0.1*float3(0.9, 0.3, 0.9)*pow(sundot, 0.5); |
| 241 | + col += 0.2*float3(1., 0.7, 0.7)*pow(sundot, 1.); |
| 242 | + col += 0.95*float3(1.)*pow(sundot, 256.); |
| 243 | + |
| 244 | + // clouds |
| 245 | + float cloudSpeed = 0.01; |
| 246 | + float cloudFlux = 0.5; |
| 247 | + |
| 248 | + // layer 1 |
| 249 | + float3 cloudColour = lerp(float3(1.0,0.95,1.0), 0.35*redSky,pow(sundot, 2.)); |
| 250 | + |
| 251 | + float2 sc = cloudSpeed * 50.*iTime * ro.xz + rd.xz*(1000.0-ro.y)/rd.y; |
| 252 | + col = lerp( col, cloudColour, 0.5*smoothstep(0.5,0.8,fbm(0.0005*sc+fbm(0.0005*sc+iTime*cloudFlux)))); |
| 253 | + |
| 254 | + // cloud layer 2 |
| 255 | + sc = cloudSpeed * 30.*iTime * ro.xz + rd.xz*(500.0-ro.y)/rd.y; |
| 256 | + col = lerp( col, cloudColour, 0.5*smoothstep(0.5,0.8,fbm(0.0002*sc+fbm(0.0005*sc+iTime*cloudFlux)))); |
| 257 | + |
| 258 | + // horizon |
| 259 | + col = lerp( col, 0.9*float3(0.9,0.75,0.8), pow( 1.-max(rd.y+0.1,0.0), 8.0)); |
| 260 | + |
| 261 | + |
| 262 | + } |
| 263 | + // contrast |
| 264 | + col = clamp(col, 0., 1.); |
| 265 | + col = col*col*(3.0-2.0*col); |
| 266 | + |
| 267 | + |
| 268 | + // saturation (amplify colour, subtract grayscale) |
| 269 | + float sat = 0.2; |
| 270 | + col = col * (1. + sat) - sat*dot(col, float3(0.33)); |
| 271 | + |
| 272 | + // vignette |
| 273 | + col = col * (1.0 - dot(p, p) * 0.1); |
| 274 | + |
| 275 | + fragColor = float4(col,1.0); |
| 276 | + } |
| 277 | +//----------------------------------------------------- |
| 278 | + ENDCG |
| 279 | + }//end pass |
| 280 | + }//end SubShader |
| 281 | +}//end Shader |
| 282 | + |
0 commit comments