Advertisement
Guest User

Updated Shader 1

a guest
Aug 5th, 2014
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.20 KB | None | 0 0
  1.  
  2. // Real-time Realistic Ocean Lighting using Seamless Transitions from Geometry to BRDF
  3. // Copyright (c) 2009 INRIA
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions
  8. // are met:
  9. // 1. Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // 2. Redistributions in binary form must reproduce the above copyright
  12. // notice, this list of conditions and the following disclaimer in the
  13. // documentation and/or other materials provided with the distribution.
  14. // 3. Neither the name of the copyright holders nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  22. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  23. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  24. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  25. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  27. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  28. // THE POSSIBILITY OF SUCH DAMAGE.
  29. //
  30. // Author: Eric Bruneton
  31. //
  32. // Modified and ported to Unity by Justin hawkins 04/06/2013
  33.  
  34. Shader "Ocean/OceanWhiteCaps"
  35. {
  36. Properties
  37. {
  38. _InvFadeParemeter ("Auto blend parameter (Edge, Shore, Distance scale)", Vector) = (0.5 ,0.5, 0.5, 1.0)
  39. }
  40. SubShader
  41. {
  42.  
  43. Pass
  44. {
  45. Tags { "RenderType"="Opaque" }
  46.  
  47. ZTest LEqual
  48. ZWrite Off
  49. Cull Off
  50.  
  51. CGPROGRAM
  52. #include "UnityCG.cginc"
  53. #pragma target 4.0
  54. #pragma vertex vert
  55. #pragma fragment frag
  56. #include "Atmosphere.cginc"
  57.  
  58. uniform sampler2D _Map0, _Map1, _Map2, _Map3, _Map4;
  59. uniform sampler2D _SkyMap, _Foam0, _Foam1;
  60. uniform sampler3D _Variance;
  61. sampler2D_float _CameraDepthTexture; // Edgeblend Stuff
  62. uniform float4 _InvFadeParemeter; // edge & shore fading
  63. uniform float4 _GridSizes, _Choppyness;
  64. uniform float3 _SeaColor;
  65. uniform float _MaxLod, _LodFadeDist, _WhiteCapStr;
  66.  
  67. struct v2f
  68. {
  69. float4 pos : SV_POSITION;
  70. float3 worldPos : TEXCOORD;
  71.  
  72. // Edge Blend
  73. float4 viewInterpolator : TEXCOORD1;
  74. float4 screenPos : TEXCOORD3;
  75. };
  76.  
  77. v2f vert(appdata_base v)
  78. {
  79. float3 worldPos = mul(_Object2World, v.vertex).xyz;
  80.  
  81. float dist = clamp(distance(_WorldSpaceCameraPos.xyz, worldPos) / _LodFadeDist, 0.0, 1.0);
  82. float lod = _MaxLod * dist;
  83. //lod = 0.0;
  84.  
  85. float2 uv = worldPos.xz;
  86.  
  87. v.vertex.y += tex2Dlod(_Map0, float4(uv/_GridSizes.x, 0, lod)).x;
  88. v.vertex.y += tex2Dlod(_Map0, float4(uv/_GridSizes.y, 0, lod)).y;
  89. v.vertex.y += tex2Dlod(_Map0, float4(uv/_GridSizes.z, 0, lod)).z;
  90. v.vertex.y += tex2Dlod(_Map0, float4(uv/_GridSizes.w, 0, lod)).w;
  91.  
  92. v.vertex.xz += tex2Dlod(_Map3, float4(uv/_GridSizes.x, 0, lod)).xy * _Choppyness.x;
  93. v.vertex.xz += tex2Dlod(_Map3, float4(uv/_GridSizes.y, 0, lod)).zw * _Choppyness.y;
  94. v.vertex.xz += tex2Dlod(_Map4, float4(uv/_GridSizes.z, 0, lod)).xy * _Choppyness.z;
  95. v.vertex.xz += tex2Dlod(_Map4, float4(uv/_GridSizes.w, 0, lod)).zw * _Choppyness.w;
  96.  
  97. v2f OUT;
  98. OUT.worldPos = mul(_Object2World, v.vertex).xyz;
  99. OUT.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  100. return OUT;
  101. }
  102.  
  103. float meanFresnel(float cosThetaV, float sigmaV)
  104. {
  105. return pow(1.0 - cosThetaV, 5.0 * exp(-2.69 * sigmaV)) / (1.0 + 22.7 * pow(sigmaV, 1.5));
  106. }
  107.  
  108. // V, N in world space
  109. float MeanFresnel(float3 V, float3 N, float2 sigmaSq)
  110. {
  111. float2 v = V.xz; // view direction in wind space
  112. float2 t = v * v / (1.0 - V.y * V.y); // cos^2 and sin^2 of view direction
  113. float sigmaV2 = dot(t, sigmaSq); // slope variance in view direction
  114. return meanFresnel(dot(V, N), sqrt(sigmaV2));
  115. }
  116.  
  117. // assumes x>0
  118. float erfc(float x)
  119. {
  120. return 2.0 * exp(-x * x) / (2.319 * x + sqrt(4.0 + 1.52 * x * x));
  121. }
  122.  
  123. float erf(float x)
  124. {
  125. float a = 0.140012;
  126. float x2 = x*x;
  127. float ax2 = a*x2;
  128. return sign(x) * sqrt( 1.0 - exp(-x2*(4.0/M_PI + ax2)/(1.0 + ax2)) );
  129. }
  130.  
  131. float Lambda(float cosTheta, float sigmaSq)
  132. {
  133. float v = cosTheta / sqrt((1.0 - cosTheta * cosTheta) * (2.0 * sigmaSq));
  134. return max(0.0, (exp(-v * v) - v * sqrt(M_PI) * erfc(v)) / (2.0 * v * sqrt(M_PI)));
  135. //return (exp(-v * v)) / (2.0 * v * sqrt(M_PI)); // approximate, faster formula
  136. }
  137.  
  138. // L, V, N, Tx, Ty in world space
  139. float ReflectedSunRadiance(float3 L, float3 V, float3 N, float3 Tx, float3 Ty, float2 sigmaSq)
  140. {
  141. float3 H = normalize(L + V);
  142. float zetax = dot(H, Tx) / dot(H, N);
  143. float zetay = dot(H, Ty) / dot(H, N);
  144.  
  145. float zL = dot(L, N); // cos of source zenith angle
  146. float zV = dot(V, N); // cos of receiver zenith angle
  147. float zH = dot(H, N); // cos of facet normal zenith angle
  148. float zH2 = zH * zH;
  149.  
  150. float p = exp(-0.5 * (zetax * zetax / sigmaSq.x + zetay * zetay / sigmaSq.y)) / (2.0 * M_PI * sqrt(sigmaSq.x * sigmaSq.y));
  151.  
  152. float tanV = atan2(dot(V, Ty), dot(V, Tx));
  153. float cosV2 = 1.0 / (1.0 + tanV * tanV);
  154. float sigmaV2 = sigmaSq.x * cosV2 + sigmaSq.y * (1.0 - cosV2);
  155.  
  156. float tanL = atan2(dot(L, Ty), dot(L, Tx));
  157. float cosL2 = 1.0 / (1.0 + tanL * tanL);
  158. float sigmaL2 = sigmaSq.x * cosL2 + sigmaSq.y * (1.0 - cosL2);
  159.  
  160. float fresnel = 0.02 + 0.98 * pow(1.0 - dot(V, H), 5.0);
  161.  
  162. zL = max(zL, 0.01);
  163. zV = max(zV, 0.01);
  164.  
  165. return fresnel * p / ((1.0 + Lambda(zL, sigmaL2) + Lambda(zV, sigmaV2)) * zV * zH2 * zH2 * 4.0);
  166.  
  167. }
  168.  
  169. // V, N, Tx, Ty in world space
  170. float2 U(float2 zeta, float3 V, float3 N, float3 Tx, float3 Ty)
  171. {
  172. float3 f = normalize(float3(-zeta, 1.0)); // tangent space
  173. float3 F = f.x * Tx + f.y * Ty + f.z * N; // world space
  174. float3 R = 2.0 * dot(F, V) * F - V;
  175. return R.xz / (1.0 + R.y);
  176. }
  177.  
  178. // V, N, Tx, Ty in world space;
  179. float3 MeanSkyRadiance(float3 V, float3 N, float3 Tx, float3 Ty, float2 sigmaSq)
  180. {
  181. float4 result;
  182.  
  183. const float eps = 0.001;
  184. float2 u0 = U(float2(0,0), V, N, Tx, Ty);
  185. float2 dux = 2.0 * (U(float2(eps, 0.0), V, N, Tx, Ty) - u0) / eps * sqrt(sigmaSq.x);
  186. float2 duy = 2.0 * (U(float2(0.0, eps), V, N, Tx, Ty) - u0) / eps * sqrt(sigmaSq.y);
  187.  
  188. result = tex2D(_SkyMap, u0 * (0.5 / 1.1) + 0.5, dux * (0.5 / 1.1), duy * (0.5 / 1.1));
  189.  
  190. //if texture2DLod and texture2DGrad are not defined, you can use this (no filtering):
  191. //result = tex2D(_SkyMap, u0 * (0.5 / 1.1) + 0.5);
  192.  
  193. return result.rgb;
  194. }
  195.  
  196. float whitecapCoverage(float epsilon, float mu, float sigma2) {
  197. return 0.5*erf((0.5*sqrt(2.0)*(epsilon-mu)*(1.0/sqrt(sigma2)))) + 0.5;
  198. }
  199.  
  200. float4 frag(v2f IN) : COLOR
  201. {
  202.  
  203. float2 uv = IN.worldPos.xz;
  204.  
  205. float2 slope = float2(0,0);
  206. slope += tex2D(_Map1, uv/_GridSizes.x).xy;
  207. slope += tex2D(_Map1, uv/_GridSizes.y).zw;
  208. slope += tex2D(_Map2, uv/_GridSizes.z).xy;
  209. slope += tex2D(_Map2, uv/_GridSizes.w).zw;
  210.  
  211. float3 V = normalize(_WorldSpaceCameraPos-IN.worldPos);
  212.  
  213. float3 N = normalize(float3(-slope.x, 1.0, -slope.y));
  214.  
  215. if (dot(V, N) < 0.0) {
  216. N = reflect(N, V); // reflects backfacing normals
  217. }
  218.  
  219. float Jxx, Jxy, Jyy, Jyx;
  220.  
  221. Jxx = ddx(uv.x);
  222. Jxy = ddy(uv.x);
  223. Jyx = ddx(uv.y);
  224. Jyy = ddy(uv.y);
  225. float A = Jxx * Jxx + Jyx * Jyx;
  226. float B = Jxx * Jxy + Jyx * Jyy;
  227. float C = Jxy * Jxy + Jyy * Jyy;
  228. const float SCALE = 10.0;
  229. float ua = pow(A / SCALE, 0.25);
  230. float ub = 0.5 + 0.5 * B / sqrt(A * C);
  231. float uc = pow(C / SCALE, 0.25);
  232. float2 sigmaSq = tex3D(_Variance, float3(ua, ub, uc)).xy;
  233.  
  234. sigmaSq = max(sigmaSq, 2e-5);
  235.  
  236. float3 Ty = normalize(float3(0.0, N.z, -N.y));
  237. float3 Tx = cross(Ty, N);
  238.  
  239. float fresnel = 0.02 + 0.98 * MeanFresnel(V, N, sigmaSq);
  240.  
  241. float3 Lsun = SunRadiance(_WorldSpaceCameraPos);
  242. float3 Esky = SkyIrradiance(_WorldSpaceCameraPos);
  243.  
  244. float3 col = float3(0,0,0);
  245.  
  246. col += ReflectedSunRadiance(SUN_DIR, V, N, Tx, Ty, sigmaSq) * Lsun;
  247.  
  248. col += MeanSkyRadiance(V, N, Tx, Ty, sigmaSq) * fresnel;
  249.  
  250. float3 Lsea = _SeaColor * Esky / M_PI;
  251. col += Lsea * (1.0 - fresnel);
  252.  
  253. // extract mean and variance of the jacobian matrix determinant
  254. float2 jm1 = tex2D(_Foam0, uv/_GridSizes.x).xy;
  255. float2 jm2 = tex2D(_Foam0, uv/_GridSizes.y).zw;
  256. float2 jm3 = tex2D(_Foam1, uv/_GridSizes.z).xy;
  257. float2 jm4 = tex2D(_Foam1, uv/_GridSizes.w).zw;
  258. float2 jm = jm1+jm2+jm3+jm4;
  259. float jSigma2 = max(jm.y - (jm1.x*jm1.x + jm2.x*jm2.x + jm3.x*jm3.x + jm4.x*jm4.x), 0.0);
  260.  
  261. // get coverage
  262. float W = whitecapCoverage(_WhiteCapStr,jm.x,jSigma2);
  263.  
  264. // compute and add whitecap radiance
  265. float3 l = (Lsun * (max(dot(N, SUN_DIR), 0.0)) + Esky) / M_PI;
  266. float3 R_ftot = float3(W * l * 0.4);
  267. col += R_ftot;
  268.  
  269.  
  270. // EDGE BLEND
  271. half4 edgeBlendFactors = half4(1.0, 0.0, 0.0, 0.0);
  272.  
  273. half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
  274. depth = LinearEyeDepth(depth);
  275. edgeBlendFactors = saturate(_InvFadeParemeter * (depth-IN.screenPos.w));
  276. edgeBlendFactors.y = 1.0-edgeBlendFactors.y;
  277. col.rgb += (edgeBlendFactors.y + saturate(IN.viewInterpolator.w));
  278.  
  279. return float4(hdr(col),1.0);
  280. }
  281.  
  282. ENDCG
  283.  
  284. }
  285. }
  286. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement