Today I implemented some of the del operators in HLSL.
To make the sampling look nicer, use the following macro:
#define sample(sampler, position, offset) tex2D(sampler, position + offset * pixelSize)
Here is a listing of the resulting functions:
- // Finite Difference Form of the Gradient operator
- float3 Gradient(sampler field, float3 u, float3 du)
- {
- // Note: we multiply the denominator of each partial derivative by 2 because we sample at -1 and +1
- // Partial derivative df/dx
- float f100 = sample(field, u, float3(-1.0f, 0.0f, 0.0f));
- float f200 = sample(field, u, float3(1.0f, 0.0f, 0.0f));
- float fd00 = (f200 - f100) / (2.0f * du.x);
- // Partial derivative df/dy
- float f010 = sample(field, u, float3(0.0f, -1.0f, 0.0f));
- float f020 = sample(field, u, float3(0.0f, 1.0f, 0.0f));
- float f0d0 = (f020 - f010) / (2.0f * du.y);
- // Partial derivative df/dz
- float f001 = sample(field, u, float3(0.0f, 0.0f, -1.0f));
- float f002 = sample(field, u, float3(0.0f, 0.0f, 1.0f));
- float f00d = (f002 - f001) / (2.0f * du.z);
- return float3(fd00, f0d0, f00d);
- }
- // Finite Difference Form of the Divergence operator
- float Divergence(sampler field, float3 u, float3 du)
- {
- // Note: we multiply the denominator of each partial derivative by 2 because we sample at -1 and +1
- // Partial derivative dvx/dx
- float3 v100 = sample(field, u, float3(-1.0f, 0.0f, 0.0f));
- float3 v200 = sample(field, u, float3(1.0f, 0.0f, 0.0f));
- float vd00 = (v200.x - v100.x) / (2.0f * du.x);
- // Partial derivative dvy/dy
- float3 v010 = sample(field, u, float3(0.0f, -1.0f, 0.0f));
- float3 v020 = sample(field, u, float3(0.0f, 1.0f, 0.0f));
- float v0d0 = (v020.y - v010.y) / (2.0f * du.y);
- // Partial derivative dvz/dz
- float3 v001 = sample(field, u, float3(0.0f, 0.0f, -1.0f));
- float3 v002 = sample(field, u, float3(0.0f, 0.0f, 1.0f));
- float v00d = (v002.z - v001.z) / (2.0f * du.z);
- return vd00 + v0d0 + v00d;
- }
- // Finite Difference Form of the Laplace operator
- float Laplacian(sampler field, float3 u, float3 du)
- {
- // Partial derivative d2f/dx2
- float f100 = sample(field, u, float3(-1.0f, 0.0f, 0.0f));
- float f200 = sample(field, u, float3(0.0f, 0.0f, 0.0f));
- float f300 = sample(field, u, float3(1.0f, 0.0f, 0.0f));
- float fd00 = (f100 + f300 - 2.0f * f200) / (du.x * du.x);
- // Partial derivative d2f/dy2
- float f010 = sample(field, u, float3(0.0f, -1.0f, 0.0f));
- float f020 = sample(field, u, float3(0.0f, 0.0f, 0.0f));
- float f030 = sample(field, u, float3(0.0f, 1.0f, 0.0f));
- float f0d0 = (f010 + f030 - 2.0f * f020) / (du.y * du.y);
- // Partial derivative d2f/dz2
- float f001 = sample(field, u, float3(0.0f, 0.0f, -1.0f));
- float f002 = sample(field, u, float3(0.0f, 0.0f, 0.0f));
- float f003 = sample(field, u, float3(0.0f, 0.0f, 1.0f));
- float f00d = (f001 + f003 - 2.0f * f002) / (du.z * du.z);
- return fd00 + f0d0 + f00d;
- }
If you spot any errors feel free to let me know ;-)