FluidMeshShader.shader 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. Shader "Hidden/ZibraEffects/Liquid/LiquidMeshShader"
  2. {
  3. SubShader
  4. {
  5. Pass
  6. {
  7. Cull Off
  8. ZTest Always
  9. ZWrite On
  10. HLSLPROGRAM
  11. #pragma multi_compile_local __ CUSTOM_REFLECTION_PROBE HDRP
  12. #pragma multi_compile_local __ USE_CUBEMAP_REFRACTION HDRP
  13. #pragma multi_compile_local __ VISUALIZE_SDF
  14. #pragma multi_compile_local __ FLIP_NATIVE_TEXTURES FLIP_BACKGROUND_TEXTURE
  15. #pragma multi_compile_local __ FLIP_PARTICLES_TEXTURE
  16. #pragma multi_compile_local __ UNDERWATER_RENDER
  17. #pragma multi_compile_local __ RAYMARCH_DISABLED
  18. #pragma multi_compile_local __ FOAM_DISABLED
  19. #pragma instancing_options procedural:setup
  20. #pragma vertex VSMain
  21. #pragma fragment PSMain
  22. #pragma target 3.5
  23. #include "UnityCG.cginc"
  24. #include "UnityStandardBRDF.cginc"
  25. #include "UnityImageBasedLighting.cginc"
  26. struct VSIn
  27. {
  28. uint vertexID : SV_VertexID;
  29. };
  30. struct VSOut
  31. {
  32. float4 position : POSITION;
  33. float3 raydir : TEXCOORD1;
  34. float2 uv : TEXCOORD0;
  35. };
  36. struct PSOut
  37. {
  38. float4 color : COLOR;
  39. float depth : DEPTH;
  40. };
  41. // Fluid material parameters, see SetMaterialParams()
  42. float4x4 ProjectionInverse;
  43. float4x4 ViewProjectionInverse;
  44. float4x4 EyeRayCameraCoeficients;
  45. float Roughness;
  46. float AbsorptionAmount;
  47. float ScatteringAmount;
  48. float RefractionDistortion;
  49. float4 RefractionColor;
  50. float4 ReflectionColor;
  51. float4 EmissiveColor;
  52. float Metalness;
  53. float3 GridSize;
  54. float3 ContainerScale;
  55. float3 ContainerPosition;
  56. float LiquidIOR;
  57. #ifdef HDRP
  58. float3 LightColor;
  59. float3 LightDirection;
  60. #endif
  61. // Light and reflection params
  62. UNITY_DECLARE_TEXCUBE(ReflectionProbe);
  63. float4 ReflectionProbe_BoxMax;
  64. float4 ReflectionProbe_BoxMin;
  65. float4 ReflectionProbe_ProbePosition;
  66. float4 ReflectionProbe_HDR;
  67. float4 WorldSpaceLightPos;
  68. UNITY_DECLARE_TEXCUBE(RefractionProbe);
  69. // Camera params
  70. float2 TextureScale;
  71. float4 Background_TexelSize;
  72. float2 GetFlippedUV(float2 uv)
  73. {
  74. if (_ProjectionParams.x > 0)
  75. return float2(uv.x, 1 - uv.y);
  76. return uv;
  77. }
  78. float2 GetFlippedUVBackground(float2 uv)
  79. {
  80. uv = GetFlippedUV(uv);
  81. #ifdef FLIP_BACKGROUND_TEXTURE
  82. // Temporary fix for flipped reflection on iOS
  83. uv.y = 1 - uv.y;
  84. #else
  85. if (Background_TexelSize.y < 0)
  86. {
  87. uv.y = 1 - uv.y;
  88. }
  89. #endif
  90. return uv;
  91. }
  92. float2 GetFlippedEffectParticlesUV(float2 uv)
  93. {
  94. #ifdef FLIP_PARTICLES_TEXTURE
  95. uv.y = 1 - uv.y;
  96. #endif
  97. return uv;
  98. }
  99. // Input resources
  100. Texture2D<float4> Background;
  101. SamplerState samplerBackground;
  102. float4 FetchBackground(float2 uv)
  103. {
  104. return Background.Sample(samplerBackground, GetFlippedUVBackground(uv));
  105. }
  106. StructuredBuffer<int> Quads;
  107. StructuredBuffer<int> VertexIDGrid;
  108. StructuredBuffer<float4> Vertices;
  109. // built-in Unity sampler name - do not change
  110. Texture2D<float4> _CameraDepthTexture;
  111. SamplerState sampler_CameraDepthTexture;
  112. float FetchCameraDepth(float2 uv)
  113. {
  114. float depth = _CameraDepthTexture.Sample(sampler_CameraDepthTexture, GetFlippedUV(uv)).x;
  115. #if !defined(UNITY_REVERSED_Z)
  116. depth = 1.0 - depth;
  117. #endif
  118. return depth;
  119. }
  120. float4 ComputeClipSpacePosition(float2 positionNDC, float deviceDepth)
  121. {
  122. #if !UNITY_REVERSED_Z
  123. deviceDepth = 1 - deviceDepth;
  124. deviceDepth = lerp(UNITY_NEAR_CLIP_VALUE, 1, deviceDepth);
  125. #endif
  126. float4 positionCS = float4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
  127. positionCS.y = -positionCS.y;
  128. return positionCS;
  129. }
  130. float3 ComputeWorldSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invViewProjMatrix)
  131. {
  132. float4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
  133. float4 hpositionWS = mul(invViewProjMatrix, positionCS);
  134. return hpositionWS.xyz / hpositionWS.w;
  135. }
  136. float3 DepthToWorld(float2 uv, float depth)
  137. {
  138. return ComputeWorldSpacePosition(uv, depth, ViewProjectionInverse);
  139. }
  140. float4 GetDepthAndPos(float2 uv)
  141. {
  142. float depth = FetchCameraDepth(uv);
  143. float3 pos = DepthToWorld(uv, depth);
  144. return float4(pos, depth);
  145. }
  146. float PositionToDepth(float3 pos)
  147. {
  148. float4 clipPos = mul(UNITY_MATRIX_VP, float4(pos, 1));
  149. return (1.0 / clipPos.w - _ZBufferParams.w) / _ZBufferParams.z; //inverse of linearEyeDepth
  150. }
  151. float3 PositionToScreen(float3 pos)
  152. {
  153. float4 clipPos = mul(UNITY_MATRIX_VP, float4(pos, 1));
  154. #if !UNITY_UV_STARTS_AT_TOP
  155. clipPos.y = -clipPos.y;
  156. #endif
  157. clipPos = ComputeScreenPos(clipPos);
  158. return float3(clipPos.xy/clipPos.w, (1.0 / clipPos.w - _ZBufferParams.w) / _ZBufferParams.z);
  159. }
  160. float3 BoxProjection(float3 rayOrigin, float3 rayDir, float3 cubemapPosition, float3 boxMin, float3 boxMax)
  161. {
  162. float3 tMin = (boxMin - rayOrigin) / rayDir;
  163. float3 tMax = (boxMax - rayOrigin) / rayDir;
  164. float3 t1 = min(tMin, tMax);
  165. float3 t2 = max(tMin, tMax);
  166. float tFar = min(min(t2.x, t2.y), t2.z);
  167. return normalize(rayOrigin + rayDir*tFar - cubemapPosition);
  168. };
  169. float3 SampleCubemap(float3 pos, float3 ray, float roughness)
  170. {
  171. Unity_GlossyEnvironmentData g;
  172. g.roughness = roughness;
  173. #if defined(CUSTOM_REFLECTION_PROBE) || defined(HDRP)
  174. g.reflUVW = BoxProjection(pos, ray,
  175. ReflectionProbe_ProbePosition,
  176. ReflectionProbe_BoxMin, ReflectionProbe_BoxMax
  177. );
  178. float3 reflection = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(ReflectionProbe), ReflectionProbe_HDR, g);
  179. #else
  180. g.reflUVW = ray;
  181. g.reflUVW.y = g.reflUVW.y; //don't render the bottom part of the cubemap
  182. g.roughness = roughness;
  183. float3 reflection = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, g);
  184. #endif
  185. return reflection;
  186. }
  187. float3 ComputeMaterial(float3 cameraPos, float3 cameraRay, float3 normal, float3 lightDirection, float3 lightColor, float roughness = 0.05)
  188. {
  189. float3 worldView = -cameraRay;
  190. float4 reflColor = ReflectionColor;
  191. float3 H = normalize(lightDirection + worldView);
  192. float NH = BlinnTerm(normal, H);
  193. float NL = DotClamped(normal, lightDirection);
  194. float NV = abs(dot(normal, worldView));
  195. half V = SmithBeckmannVisibilityTerm(NL, NV, roughness);
  196. half D = NDFBlinnPhongNormalizedTerm(NH, RoughnessToSpecPower(roughness));
  197. float3 spec = reflColor.xyz * (V * D) * (UNITY_PI / 4);
  198. return lightColor * max(0, spec * NL);
  199. }
  200. float Average(float3 x)
  201. {
  202. return (x.x + x.y + x.z) / 3.0;
  203. }
  204. float RefractionMinimumDepth;
  205. float RefractionDepthBias;
  206. float3 RefractSample(float3 pos, float3 ray, float2 uv)
  207. {
  208. #ifdef USE_CUBEMAP_REFRACTION
  209. return SampleCubemap(pos, ray, 0.05);
  210. #endif
  211. #ifdef FLIP_NATIVE_TEXTURES
  212. uv.y = 1 - uv.y;
  213. #endif
  214. float3 uvz = PositionToScreen(pos);
  215. if (any(uvz.xy < 0.0f) || any(uvz.xy > 1.0f))
  216. {
  217. uvz.xy = uv;
  218. }
  219. return FetchBackground(uvz.xy).xyz;
  220. }
  221. float3 ReflectSample(float3 pos, float3 ray, float roughness = 0.05)
  222. {
  223. return Average(ReflectionColor.xyz) * SampleCubemap(pos, ray, roughness);
  224. }
  225. #define SHADING
  226. #include <RenderingUtils.cginc>
  227. // See Raytracing Gems 1 20.3.2.1 EYE RAY SETUP
  228. float3 GetCameraRay(float2 uv)
  229. {
  230. #ifdef FLIP_NATIVE_TEXTURES
  231. uv.y = 1 - uv.y;
  232. #elif !UNITY_UV_STARTS_AT_TOP
  233. uv.y = 1 - uv.y;
  234. #endif
  235. float2 c = float2(2.0f * uv.x - 1.0f, -2.0f * uv.y + 1.0f);
  236. float3 r = EyeRayCameraCoeficients[0].xyz;
  237. float3 u = EyeRayCameraCoeficients[1].xyz;
  238. float3 v = EyeRayCameraCoeficients[2].xyz;
  239. float3 direction = c.x * r + c.y * u + v;
  240. return normalize(direction);
  241. }
  242. float2 Resolution;
  243. uint getHashPixelID(uint2 pix)
  244. {
  245. pix = clamp(pix, 0, uint2(Resolution.xy - 1));
  246. return pix.x + uint(Resolution.x) * pix.y;
  247. }
  248. #ifndef FOAM_DISABLED
  249. Texture2D<float4> ParticlesTex;
  250. SamplerState sampler_ParticlesTex;
  251. #endif
  252. VSOut VSMain(VSIn input)
  253. {
  254. VSOut output;
  255. float2 vertexBuffer[4] = {
  256. float2(0.0f, 0.0f),
  257. float2(0.0f, 1.0f),
  258. float2(1.0f, 0.0f),
  259. float2(1.0f, 1.0f),
  260. };
  261. uint indexBuffer[6] = { 0, 1, 2, 2, 1, 3 };
  262. uint indexID = indexBuffer[input.vertexID];
  263. float2 uv = vertexBuffer[indexID];
  264. output.position = float4(2 * uv.x - 1, 1 - 2 * uv.y, 0.5, 1.0);
  265. output.uv = uv;
  266. output.raydir = GetCameraRay(uv);
  267. return output;
  268. }
  269. float4 MeshRenderData_TexelSize;
  270. Texture2D<float4> MeshRenderData;
  271. float4 FetchMeshRenderData(int2 cords)
  272. {
  273. #if UNITY_UV_STARTS_AT_TOP
  274. if (_ProjectionParams.x > 0)
  275. {
  276. cords.y = MeshRenderData_TexelSize.w - cords.y;
  277. }
  278. #endif
  279. return MeshRenderData.Load(int3(cords, 0));
  280. }
  281. Texture2D<float> MeshDepth;
  282. float FetchMeshDepth(int2 cords)
  283. {
  284. #if UNITY_UV_STARTS_AT_TOP
  285. if (_ProjectionParams.x > 0)
  286. {
  287. cords.y = MeshRenderData_TexelSize.w - cords.y;
  288. }
  289. #endif
  290. float depth = MeshDepth.Load(int3(cords, 0));
  291. #if !defined(UNITY_REVERSED_Z)
  292. depth = 1.0 - depth;
  293. #endif
  294. return depth;
  295. }
  296. float RayMarchResolutionDownscale;
  297. #ifndef RAYMARCH_DISABLED
  298. Texture2D<float4> RayMarchData;
  299. float4 RayMarchData_TexelSize;
  300. float4 FetchRayMarchData(int2 cords)
  301. {
  302. #ifdef FLIP_NATIVE_TEXTURES
  303. cords.y = RayMarchData_TexelSize.w * RayMarchResolutionDownscale - cords.y;
  304. #else
  305. if (RayMarchData_TexelSize.y < 0)
  306. {
  307. cords.y = RayMarchData_TexelSize.w * RayMarchResolutionDownscale - cords.y;
  308. }
  309. #endif
  310. return RayMarchData.Load(int3(cords, 0));
  311. }
  312. Texture2D<float4> MaterialData;
  313. SamplerState samplerMaterialData;
  314. float4 MaterialData_TexelSize;
  315. float4 FetchMaterialData(float2 uv)
  316. {
  317. #ifdef FLIP_NATIVE_TEXTURES
  318. uv.y = RayMarchResolutionDownscale - uv.y;
  319. #else
  320. if (MaterialData_TexelSize.y < 0)
  321. {
  322. uv.y = RayMarchResolutionDownscale - uv.y;
  323. }
  324. #endif
  325. return MaterialData.Sample(samplerMaterialData, uv);
  326. }
  327. //required to work with custom depth formats
  328. LightPath GetLiquidDepth(float2 pixelCoord)
  329. {
  330. float2 rayMarchPixel = pixelCoord * RayMarchResolutionDownscale;
  331. LightPath path;
  332. //custom bilinear interpolation
  333. float2 intPixel = floor(rayMarchPixel);
  334. float2 fracPixel = frac(rayMarchPixel);
  335. float3 data00 = FetchRayMarchData(int3(intPixel, 0) + int3(0,0,0)).xyz;
  336. float3 data10 = FetchRayMarchData(int3(intPixel, 0) + int3(1,0,0)).xyz;
  337. data00 = lerp(data00, data10, fracPixel.x);
  338. float3 data01 = FetchRayMarchData(int3(intPixel, 0) + int3(0,1,0)).xyz;
  339. float3 data11 = FetchRayMarchData(int3(intPixel, 0) + int3(1,1,0)).xyz;
  340. data01 = lerp(data01, data11, fracPixel.x);
  341. path.depth = lerp(data00, data01, fracPixel.y);
  342. path.material = FetchMaterialData(rayMarchPixel/MeshRenderData_TexelSize.zw).xyz;
  343. return path;
  344. }
  345. #endif
  346. PSOut PSMain(VSOut input)
  347. {
  348. PSOut output;
  349. float3 cameraPos = _WorldSpaceCameraPos;
  350. float3 cameraRay = normalize(input.raydir);
  351. int3 pixelCoord = int3(input.position.xy, 0);
  352. float4 data = FetchMeshRenderData(pixelCoord.xy);
  353. uint encodedNormal = asuint(data.w);
  354. float liquidDepth = FetchMeshDepth(pixelCoord.xy);
  355. float sceneDepth = FetchCameraDepth(input.uv);
  356. #ifdef FOAM_DISABLED
  357. float3 foamParticles = 0.;
  358. #else
  359. float3 foamParticles =
  360. ParticlesTex
  361. .Sample(sampler_ParticlesTex, GetFlippedEffectParticlesUV(input.uv * TextureScale))
  362. .x;
  363. #endif
  364. bool hasParticles = any(foamParticles > 0.0);
  365. float3 incomingLight = foamParticles;
  366. bool hasFluid = true;
  367. if (!any(data.xyz) && !encodedNormal)
  368. {
  369. hasFluid = false;
  370. if (!hasParticles)
  371. discard;
  372. }
  373. #ifndef UNDERWATER_RENDER
  374. if (liquidDepth < sceneDepth)
  375. {
  376. hasFluid = false;
  377. if (!hasParticles)
  378. discard;
  379. }
  380. #endif
  381. #ifndef RAYMARCH_DISABLED
  382. LightPath path = GetLiquidDepth(pixelCoord.xy);
  383. RayDepths = path.depth;
  384. Material = path.material;
  385. #endif
  386. Depths = RayDepths;
  387. float3 normal = DecodeDirection(asuint(encodedNormal));
  388. #ifdef FLIP_NATIVE_TEXTURES
  389. float3 worldPos = DepthToWorld(float2(input.uv.x, 1 - input.uv.y), liquidDepth);
  390. #else
  391. float3 worldPos = DepthToWorld(input.uv, liquidDepth);
  392. #endif
  393. float4 weights = MaterialWeights(Material.xyz);
  394. float3 materialEmission = Material1Emission* weights.x + Material2Emission * weights.y +
  395. Material3Emission * weights.z + EmissiveColor.rgb * weights.w;
  396. float materialMetalness = Sum(float4(MatMetalness, Metalness) * weights);
  397. float materialRoughness = Sum(float4(MatRoughness, Roughness) * weights);
  398. float ndotv = dot(normal, -cameraRay);
  399. float NV = abs(ndotv);
  400. float fresnel = FresnelTermLiquid(materialMetalness, NV);
  401. #ifdef HDRP
  402. float3 lightColor = LightColor;
  403. float3 lightDirWorld = LightDirection;
  404. #else
  405. float3 lightColor = _LightColor0;
  406. float3 lightDirWorld = normalize(_WorldSpaceLightPos0.xyz);
  407. #endif
  408. #ifdef UNDERWATER_RENDER
  409. float CameraDensity = 0.0f;
  410. if(insideGrid(cameraPos))
  411. CameraDensity = SampleDensity(cameraPos);
  412. bool isUnderwater = (step(ndotv, 0.0)) && (CameraDensity > 0.0);
  413. if (!isUnderwater && liquidDepth < sceneDepth)
  414. {
  415. hasFluid = false;
  416. if (!hasParticles)
  417. discard;
  418. }
  419. #endif
  420. if (hasFluid)
  421. {
  422. #ifdef UNDERWATER_RENDER
  423. if (isUnderwater)
  424. {
  425. float3 background_color = 0.0f;
  426. float opticalDensity = 0.0f;
  427. if (liquidDepth < sceneDepth)
  428. {
  429. background_color = FetchBackground(input.uv).xyz;
  430. liquidDepth = sceneDepth;
  431. worldPos = DepthToWorld(input.uv, liquidDepth);
  432. }
  433. else
  434. {
  435. #ifndef RAYMARCH_DISABLED
  436. background_color =
  437. RefractionRay(worldPos, cameraRay, -normal, input.uv, true);
  438. #else
  439. background_color = RefractionColor;
  440. #endif
  441. }
  442. float liquidWorldSpaceDepth = length(cameraPos - worldPos);
  443. opticalDensity += liquidWorldSpaceDepth;
  444. #ifdef HDRP
  445. float3 lightColor = LightColor;
  446. #else
  447. float3 lightColor = _LightColor0;
  448. #endif
  449. incomingLight = IntegrateAbsorptionScattering(opticalDensity,
  450. background_color, lightColor);
  451. }
  452. else
  453. #endif
  454. {
  455. ////
  456. ////compute reflected color
  457. ////
  458. float3 ReflectRay = reflect(cameraRay, normal);
  459. float3 ReflectedColor = ReflectSample(worldPos, ReflectRay, materialRoughness);
  460. incomingLight += ReflectionColor.xyz * fresnel * ReflectedColor / Average(ReflectionColor.xyz);
  461. ////
  462. ////compute light from light sources
  463. ////
  464. incomingLight += fresnel*ComputeMaterial(cameraPos, cameraRay, normal, lightDirWorld, lightColor, materialRoughness);
  465. incomingLight += materialEmission;
  466. ////
  467. ////compute refracted color
  468. ////
  469. #ifndef RAYMARCH_DISABLED
  470. incomingLight += (1.0 - fresnel) * RefractionRay(worldPos, cameraRay,
  471. normal, input.uv, false);
  472. #else
  473. incomingLight += (1.0 - fresnel) * RefractionColor;
  474. #endif
  475. }
  476. }
  477. else
  478. {
  479. incomingLight += FetchBackground(input.uv).xyz;
  480. }
  481. output.color = float4(clamp(incomingLight , 0., 10000.0), 1.0);
  482. output.depth = liquidDepth;
  483. return output;
  484. }
  485. ENDHLSL
  486. }
  487. }
  488. }