#include "fluid_common.hlsli" #define Texture_phi_n Texture_color #define Texture_phi_n_hat Texture_tempscalar // Advect MCCormack // Pixel float4 main(p_fluidsim input) : SV_Target { if (IsNonEmptyCell(input.texcoords.xyz)) { return 0; } // get advected new position float3 npos = input.cell0 - timestep * forward * Texture_velocity0.SampleLevel(samPointClamp, input.texcoords, 0).xyz; // convert new position to texture coordinates float3 nposTC = float3(npos.x / textureWidth, npos.y / textureHeight, (npos.z + 0.5) / textureDepth); // find the texel corner closest to the semi-Lagrangian "particle" float3 nposTexel = floor(npos + float3(0.5f, 0.5f, 0.5f)); float3 nposTexelTC = float3(nposTexel.x / textureWidth, nposTexel.y / textureHeight, (nposTexel.z + 0.5) / textureDepth); // ht (float-texel) float3 ht = float3(0.5f / textureWidth, 0.5f / textureHeight, 0.5f / textureDepth); // get the values of nodes that contribute to the interpolated value // (texel centers are at float-integer locations) float4 nodeValues[8]; nodeValues[0] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, -ht.y, -ht.z), 0); nodeValues[1] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, -ht.y, ht.z), 0); nodeValues[2] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, ht.y, -ht.z), 0); nodeValues[3] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, ht.y, ht.z), 0); nodeValues[4] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, -ht.y, -ht.z), 0); nodeValues[5] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, -ht.y, ht.z), 0); nodeValues[6] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, ht.y, -ht.z), 0); nodeValues[7] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, ht.y, ht.z), 0); // determine a valid range for the result float4 phiMin = min(min(min(nodeValues[0], nodeValues[1]), nodeValues[2]), nodeValues[3]); phiMin = min(min(min(min(phiMin, nodeValues[4]), nodeValues[5]), nodeValues[6]), nodeValues[7]); float4 phiMax = max(max(max(nodeValues[0], nodeValues[1]), nodeValues[2]), nodeValues[3]); phiMax = max(max(max(max(phiMax, nodeValues[4]), nodeValues[5]), nodeValues[6]), nodeValues[7]); float4 r; // Perform final MACCORMACK advection step: // You can use point sampling and keep Texture_phi_n_1_hat // r = Texture_phi_n_1_hat.SampleLevel( samPointClamp, input.texcoords, 0 ) // OR use bilerp to avoid the need to keep a separate texture for phi_n_1_hat r = Texture_phi_n.SampleLevel(samLinear, nposTC, 0) + 0.5 * (Texture_phi_n.SampleLevel(samPointClamp, input.texcoords, 0) - Texture_phi_n_hat.SampleLevel(samPointClamp, input.texcoords, 0)); // clamp result to the desired range r = max(min(r, phiMax), phiMin); float4 ret = r * modulate - k; ret = clamp(ret, float4(0, 0, 0, 0), float4(5, 5, 5, 5)); return ret; }