I am wondering if this gaussian blur for voxels is correct when applied to directions, and not simple scalars…
Main kernel:
#pragma kernel Zero
#pragma kernel gaussianBlur
#include ”./ShaderUtils.hlsl”
RWTexture3D bufferA;
RWTexture3D bufferB;
[numthreads(8, 8, 8)]
void Zero(uint3 id : SV_DispatchThreadID)
{
bufferA[id.xyz] = 0;
bufferB[id.xyz] = 0;
}
[numthreads(8, 8, 8)]
void gaussianBlur(uint3 id : SV_DispatchThreadID)
{
bufferB[id.xyz] = gaussian5x5(int3(id.xyz), bufferA);
}
Shader Utils:
#include ”./GaussianConstants.hlsl”
float3 unlerp(float3 a, float3 b, float3 x)
{
return (x - a) / (b - a);
}
float unlerp(float a, float b, float x)
{
return (x - a) / (b - a);
}
float3 remap(float3 a, float3 b, float3 c, float3 d, float3 x)
{
return lerp(c, d, unlerp(a, b, x));
}
float remap(float a, float b, float c, float d, float x)
{
return lerp(c, d, unlerp(a, b, x));
}
float3 toNormalizedCoordinates(float3 xyz, float3 size, float3 minCorner )
{
float maxSize = max(max(size.x, size.y), size.z);
float3 scalingFactor = size.xyz / maxSize;
float3 offset = minCorner;
return ((xyz - offset) / maxSize) / scalingFactor;
}
// from https://beta.observablehq.com/@jrus/plastic-sequence
float2 plastic(float index)
{
return float2(0.5 + frac(0.7548776662466927 * index), 0.5 + frac(0.5698402909980532 * index));
}
// sample num, triangle basis vectors
float3 triangleSample(int n, float3 A, float3 B)
{
float2 s = plastic((half)n);
s = s.x + s.y > 1.0 ? 1.0 - s : s;
return s.x * A + s.y * B;
}
// Hash function from H. Schechter & R. Bridson, goo.gl/RXiKaH
uint Hash(uint s)
{
s ^= 2747636419u;
s *= 2654435769u;
s ^= s >> 16;
s *= 2654435769u;
s ^= s >> 16;
s *= 2654435769u;
return s;
}////1
float3 slerp(float3 start, float3 end, float percent)
{
// Dot product - the cosine of the angle between 2 vectors.
float _dot = dot(start, end);
// Clamp it to be in the range of Acos()
// This may be unnecessary, but floating point
// precision can be a fickle mistress.
_dot = clamp(_dot, -1.0, 1.0);
// Acos(dot) returns the angle between start and end,
// And multiplying that by percent returns the angle between
// start and the final result.
float theta = acos(_dot)percent;
float3 RelativeVec = normalize(end - start_dot); // Orthonormal basis
// The final result.
return ((startcos(theta)) + (RelativeVecsin(theta)));
}
float4 gaussian5x5(int3 id, RWTexture3D bufferC)
{
float4 _01 = bufferC[id + GAUSSIAN_5X5_OFFSETS[0]] * GAUSSIAN_5X5_WEIGHTS[0];
float4 _02 = bufferC[id + GAUSSIAN_5X5_OFFSETS[1]] * GAUSSIAN_5X5_WEIGHTS[1];
float4 _03 = bufferC[id + GAUSSIAN_5X5_OFFSETS[2]] * GAUSSIAN_5X5_WEIGHTS[2];
float4 _04 = bufferC[id + GAUSSIAN_5X5_OFFSETS[3]] * GAUSSIAN_5X5_WEIGHTS[3];
float4 _05 = bufferC[id + GAUSSIAN_5X5_OFFSETS[4]] * GAUSSIAN_5X5_WEIGHTS[4];
float4 _06 = bufferC[id + GAUSSIAN_5X5_OFFSETS[5]] * GAUSSIAN_5X5_WEIGHTS[5];
float4 _07 = bufferC[id + GAUSSIAN_5X5_OFFSETS[6]] * GAUSSIAN_5X5_WEIGHTS[6];
float4 _08 = bufferC[id + GAUSSIAN_5X5_OFFSETS[7]] * GAUSSIAN_5X5_WEIGHTS[7];
float4 _09 = bufferC[id + GAUSSIAN_5X5_OFFSETS[8]] * GAUSSIAN_5X5_WEIGHTS[8];
float4 _10 = bufferC[id + GAUSSIAN_5X5_OFFSETS[9]] * GAUSSIAN_5X5_WEIGHTS[9];
float4 _11 = bufferC[id + GAUSSIAN_5X5_OFFSETS[10]] * GAUSSIAN_5X5_WEIGHTS[10];
float4 _12 = bufferC[id + GAUSSIAN_5X5_OFFSETS[11]] * GAUSSIAN_5X5_WEIGHTS[11];
float4 _13 = bufferC[id + GAUSSIAN_5X5_OFFSETS[12]] * GAUSSIAN_5X5_WEIGHTS[12];
float4 _14 = bufferC[id + GAUSSIAN_5X5_OFFSETS[13]] * GAUSSIAN_5X5_WEIGHTS[13];
float4 _15 = bufferC[id + GAUSSIAN_5X5_OFFSETS[14]] * GAUSSIAN_5X5_WEIGHTS[14];
float4 _16 = bufferC[id + GAUSSIAN_5X5_OFFSETS[15]] * GAUSSIAN_5X5_WEIGHTS[15];
float4 _17 = bufferC[id + GAUSSIAN_5X5_OFFSETS[16]] * GAUSSIAN_5X5_WEIGHTS[16];
float4 _18 = bufferC[id + GAUSSIAN_5X5_OFFSETS[17]] * GAUSSIAN_5X5_WEIGHTS[17];
float4 _19 = bufferC[id + GAUSSIAN_5X5_OFFSETS[18]] * GAUSSIAN_5X5_WEIGHTS[18];
float4 _20 = bufferC[id + GAUSSIAN_5X5_OFFSETS[19]] * GAUSSIAN_5X5_WEIGHTS[19];
float4 _21 = bufferC[id + GAUSSIAN_5X5_OFFSETS[20]] * GAUSSIAN_5X5_WEIGHTS[20];
float4 _22 = bufferC[id + GAUSSIAN_5X5_OFFSETS[21]] * GAUSSIAN_5X5_WEIGHTS[21];
float4 _23 = bufferC[id + GAUSSIAN_5X5_OFFSETS[22]] * GAUSSIAN_5X5_WEIGHTS[22];
float4 _24 = bufferC[id + GAUSSIAN_5X5_OFFSETS[23]] * GAUSSIAN_5X5_WEIGHTS[23];
float4 _25 = bufferC[id + GAUSSIAN_5X5_OFFSETS[24]] * GAUSSIAN_5X5_WEIGHTS[24];
return _01 + _02 + _03 + _04 + _05 + _06 + _07 + _08 + _09 + _10 + _11 + _12 + _13 + _14 + _15 + _16 + _17 + _18 + _19 + _20 + _21 + _22 + _23 + _24 + _25;
return (bufferC[int3(id.x - 2, id.y, id.z + 2)] + bufferC[int3(id.x - 1, id.y, id.z + 2)] * 4.0 + bufferC[int3(id.x, id.y, id.z + 2)] * 6.0 + bufferC[int3(id.x + 1, id.y, id.z + 2)] * 4.0 + bufferC[int3(id.x + 2, id.y, id.z + 2)] +
bufferC[int3(id.x - 2, id.y, id.z + 1)] * 4.0 + bufferC[int3(id.x - 1, id.y, id.z + 1)] * 16.0 + bufferC[int3(id.x, id.y, id.z + 1)] * 24.0 + bufferC[int3(id.x + 1, id.y, id.z + 1)] * 16.0 + bufferC[int3(id.x + 2, id.y, id.z + 1)] * 4.0 +
bufferC[int3(id.x - 2, id.y, id.z)] * 6.0 + bufferC[int3(id.x - 1, id.y, id.z)] * 24.0 + bufferC[int3(id.x, id.y, id.z)] * 36.0 + bufferC[int3(id.x + 1, id.y, id.z)] * 24.0 + bufferC[int3(id.x + 2, id.y, id.z)] * 6.0 +
bufferC[int3(id.x - 2, id.y, id.z - 1)] * 4.0 + bufferC[int3(id.x - 1, id.y, id.z - 1)] * 16.0 + bufferC[int3(id.x, id.y, id.z - 1)] * 24.0 + bufferC[int3(id.x + 1, id.y, id.z - 1)] * 16.0 + bufferC[int3(id.x + 2, id.y, id.z - 1)] * 4.0 +
bufferC[int3(id.x - 2, id.y, id.z - 2)] + bufferC[int3(id.x - 1, id.y, id.z - 2)] * 4.0 + bufferC[int3(id.x, id.y, id.z - 2)] * 6.0 + bufferC[int3(id.x + 1, id.y, id.z - 2)] * 4.0 + bufferC[int3(id.x + 2, id.y, id.z - 2)]
}