Guest User

Untitled

a guest
Oct 13th, 2019
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.70 KB | None | 0 0
  1. #include "common/TextureSamplers.hlsl"
  2. #include "common/States11.hlsl"
  3. #include "common/samplers11.hlsl"
  4. #include "common/context.hlsl"
  5. #include "common/ambientCube.hlsl"
  6.  
  7. #define FOG_ENABLE
  8. #include "common/fog2.hlsl"
  9.  
  10. #include "deferred/atmosphere.hlsl"
  11.  
  12. Texture2D DiffTex;
  13. Texture2D DiffTex2;
  14.  
  15. float4 cv4;
  16. float4 cldclr;
  17.  
  18. #define time gModelTime
  19. #define phase cv4.y
  20. #define cam gOrigin
  21.  
  22. static const float cirrusAltitude = 13000.0;
  23.  
  24. static const float quadSize = 550000.0;//размер квадрата облаков
  25. static const float fadeInv = 1.0 / 600.0;//затухании облаков при приближении к ним
  26.  
  27. static const float earthRadiusBottom = 6360.0 * 0.25;//радиус земли при расчете кривизны купола когда камера под ним
  28. static const float earthRadiusTop = 6360.0;//радиус земли при расчете кривизны купола когда камера над ним
  29.  
  30. static const float rangeInv = 2.0 / quadSize;
  31. static const float rangeTopInv = 2.0 / 450000.0;
  32.  
  33. static const float tile = 13;
  34.  
  35. static const float brightness = 0.6 / 3.1415;
  36. static const float opacity = 0.35;
  37.  
  38. struct VS_INPUT
  39. {
  40. float2 vPos : POSITION0;
  41. float2 vTex : TEXCOORD0;
  42. };
  43.  
  44. struct VS_OUTPUT
  45. {
  46. float4 oPos : SV_POSITION;
  47. float4 oT0 : TEXCOORD0;
  48. float4 params: TEXCOORD1;
  49. float3 inscatter: TEXCOORD2;
  50. float3 sunColor: TEXCOORD3;
  51. };
  52.  
  53. #define mieG 0.7
  54. #define M_PI 3.14159265
  55.  
  56. float phaseFunctionM(float mu)
  57. {
  58. return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow( abs(1.0 + (mieG*mieG) - 2.0*mieG*mu ), -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
  59. }
  60.  
  61. float distanceToCirrus(float r, float mu)
  62. {
  63. const float rg = 6360.0;
  64. float rc = cirrusAltitude*0.001 + rg;
  65. Area discriminant = r * r * (mu * mu - 1.0) + rc * rc;
  66. float dist;
  67. if(rc>r)
  68. dist = ClampDistance(-r * mu + SafeSqrt(discriminant));
  69. else
  70. dist = ClampDistance(-r * mu - SafeSqrt(discriminant));
  71. return dist;
  72. }
  73.  
  74. //считаем точку от камеры камеры до пересечения с реальным радиусом облаков
  75. float3 getRealCirrusPos(float3 camera, float3 pos)
  76. {
  77. float3 cpos = (pos-camera)*0.001; // in km
  78. float d = length(cpos);
  79. float3 view = cpos/d;
  80. float mu = view.y;
  81. float r = length(gEarthCenter);
  82. return gEarthCenter + view*distanceToCirrus(r, view.y);
  83. }
  84.  
  85. float3 calculateAtmosphereForCirrus(float3 pos, out float3 transmittance)
  86. {
  87. #if defined(TRANSMITTANCE_VOLUME_TEXTURE) && !defined(SKY_RADIANCE_TEXTURE)
  88. return GetSkyRadianceToPoint3D(gEarthCenter, pos, 0.0/*shadow*/, gSunDir, transmittance) * gAtmIntensity;
  89. #else
  90. return GetSkyRadianceToPoint(gEarthCenter, pos, 0.0/*shadow*/, gSunDir, transmittance) * gAtmIntensity;
  91. #endif
  92. }
  93.  
  94. VS_OUTPUT VertOut(VS_INPUT i)
  95. {
  96. float ex = i.vPos.x * quadSize * 0.001;
  97. float ez = i.vPos.y * quadSize * 0.001;
  98.  
  99. float cameraAboveCirrus = step(cirrusAltitude, cam.y);
  100.  
  101. float r0 = earthRadiusBottom + cirrusAltitude*0.001;
  102. float r1 = earthRadiusTop + cirrusAltitude*0.001;
  103.  
  104. float ey0 = sqrt(r0*r0 - ex*ex - ez*ez) - earthRadiusBottom;
  105. float ey1 = sqrt(r1*r1 - ex*ex - ez*ez) - earthRadiusTop;
  106.  
  107. float4 tw;
  108. tw.xz = i.vPos.xy * quadSize;
  109. tw.y = lerp(ey0, ey1, cameraAboveCirrus) * 1000.0 - cam.y;
  110. tw.w=1.0;
  111.  
  112. VS_OUTPUT o;
  113. o.oPos = mul(tw, gViewProj);
  114. o.oT0.xy = (i.vTex.xy + cam.xz / quadSize) * tile;
  115.  
  116. float nDist=length(tw.xz) * lerp(rangeInv, rangeTopInv, cameraAboveCirrus);
  117. o.oT0.z = pow(nDist, 3);
  118. float fadeFactor = min(abs(cirrusAltitude-cam.y)* fadeInv, 1);
  119. o.oT0.w=fadeFactor;
  120.  
  121. float2 density = sin((time + phase).xx / float2(60.0, 80.0));
  122. float visibility = sin(o.oT0.x*2 + phase + time/100+density.x*0.5) * sin(o.oT0.y*2+phase*4.231 + time/100-density.y*0.5);
  123.  
  124. o.params.xy = saturate( density * pow(saturate(visibility+0.5), 0.7) );
  125. o.params.z = saturate(sin(time / 120.0)+0.5); // lerp factor
  126.  
  127. float3 view = normalize(tw.xyz - gViewInv._41_42_43);
  128. o.params.w = phaseFunctionM(dot(gSunDir, view));
  129.  
  130. float3 transmittance;
  131. float3 pos = float3((tw.x-gCameraPos.x) * 0.001, 6360.0 + (tw.y + gOrigin.y) * 0.001, (tw.z-gCameraPos.z) * 0.001);
  132. float3 realPos = getRealCirrusPos(gEarthCenter, pos);
  133. o.inscatter = calculateAtmosphereForCirrus(realPos, transmittance);
  134. o.sunColor = GetSunRadiance(realPos, gSunDir);
  135. o.sunColor = lerp(o.sunColor, dot(o.sunColor, 0.333).xxx, saturate(1-gSunDir)*0.3);//чутка обесцвечиваем красноту солнца
  136. o.sunColor *= transmittance * gSunIntensity;
  137.  
  138. //todo: надо семплировать не из предрасчитанной текстуры skyRadiance, а из inscatterTex, т.к. у каждой точки дожен быть взят свой muS
  139. // float3 posOnGround = float3(pos.x, 6360.0, pos.z);
  140. // o.sunColor += GetSkyRadiance(posOnGround, normalize(gSunDir + normalize(posOnGround)), 0.0, gSunDir, transmittance) * gAtmIntensity;
  141. return o;
  142. }
  143.  
  144. float4 psCirrus(VS_OUTPUT i): SV_TARGET0
  145. {
  146. float psDistSq = i.oT0.z;
  147. float psFadeFactor = i.oT0.w;
  148. float2 psVisibility = i.params.xy;
  149. float psLerpFactor = i.params.z;
  150. float psHaloFactor = i.params.w;
  151.  
  152. clip(0.99 - psDistSq);
  153.  
  154. float2 shift = float2(time / 300.0, 0.0);
  155. float4 r = DiffTex.Sample(WrapLinearSampler, i.oT0 + shift) * float4(1,1,1, psVisibility.x);
  156. float4 r1 = DiffTex2.Sample(WrapLinearSampler, i.oT0) * float4(1,1,1, psVisibility.y);
  157.  
  158. r = lerp(r, r1, psLerpFactor);
  159. float alpha = r.a;
  160. r.a = saturate(r.a-psDistSq*0.7) * psFadeFactor * (1-psDistSq);
  161. clip(r.a-0.002);
  162.  
  163. float3 norm = r.xzy*2-1;
  164. float sunDot = max(0, dot(normalize(norm), gSunDir)*0.8 + 0.2) * 2;
  165.  
  166. float4 color = float4(brightness.rrr, r.a * opacity);
  167. float sunFactor = max(0,1-gSunDir.y);
  168. color.rgb *= i.sunColor * (1 + 3 * psHaloFactor * max(0, 1 - alpha) * (sunDot*0.7+0.3) * sunFactor * sunFactor);
  169. color.rgb += i.inscatter;
  170. return color;
  171. }
  172.  
  173. RasterizerState cirrusRS
  174. {
  175. CullMode = None;
  176. FillMode = Solid;
  177. MultisampleEnable = false;
  178. DepthClipEnable = false;
  179. };
  180.  
  181. VertexShader vsComp = CompileShader(vs_4_0, VertOut());
  182.  
  183. technique10 T0
  184. {
  185. pass under
  186. {
  187. SetVertexShader(vsComp);
  188. SetGeometryShader(NULL);
  189. SetPixelShader(CompileShader(ps_4_0, psCirrus()));
  190. SetBlendState(enableAlphaBlend, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
  191. SetDepthStencilState(enableDepthBufferNoWrite, 0);
  192. SetRasterizerState(cirrusRS);
  193. }
  194. pass above
  195. {
  196. SetVertexShader(vsComp);
  197. SetGeometryShader(NULL);
  198. SetPixelShader(CompileShader(ps_4_0, psCirrus()));
  199. SetBlendState(enableAlphaBlend, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
  200. SetDepthStencilState(enableDepthBufferNoWrite, 0);
  201. SetRasterizerState(cullFront);
  202. }
  203. }
Add Comment
Please, Sign In to add comment