WuhuIslandTesting/Library/PackageCache/com.unity.render-pipelines.universal@8148.0.7-4/Shaders/Volumetrics/Mip3DTexture.compute
2025-01-07 02:06:59 +01:00

119 lines
No EOL
4.5 KiB
Text

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CalculateMip
#pragma kernel CalculateMipBuffer
#pragma kernel CopyTexToBuffer
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
uint4 _OutputDim;
Texture3D<float4> _Input;
RWTexture3D<float4> _Output;
SamplerState sampler_LinearClamp;
[numthreads(4,4,4)]
void CalculateMip(uint3 id : SV_DispatchThreadID)
{
//id.xyz = min(id.xyz, _OutputDim.xyz - (1).xxx);
const float3 samplePoints[8] = {
float3(0.25, 0.25, 0.25),
float3(0.75, 0.25, 0.25),
float3(0.25, 0.75, 0.25),
float3(0.75, 0.75, 0.25),
float3(0.25, 0.25, 0.75),
float3(0.75, 0.25, 0.75),
float3(0.25, 0.75, 0.75),
float3(0.75, 0.75, 0.75),
};
float4 output = float4(0,0,0,0);
float3 coordsFloat = (float3)min(id.xyz, _OutputDim.xyz - (1).xxx);
float3 dimFloat = (float3)_OutputDim.xyz;
[unroll] for (int i = 0; i < 8; i++)
{
float3 voxelCenter = (coordsFloat + samplePoints[i]) / dimFloat;
output += 0.125 * _Input.SampleLevel(sampler_LinearClamp, voxelCenter, 0);
}
_Output[id.xyz] = output;
}
RWStructuredBuffer<uint2> _Buffer;
int4 _PrevMipDimOffset;
int4 _MipDimOffset;
[numthreads(4,4,4)]
void CalculateMipBuffer(uint3 id : SV_DispatchThreadID)
{
if (id.x < (uint)_MipDimOffset.x && id.y < (uint)_MipDimOffset.y && id.z < (uint)_MipDimOffset.z)
{
//id.xyz = min(id.xyz, _OutputDim.xyz - (1).xxx);
const int3 samplePoints[8] =
{
int3(0, 0, 0),
int3(1, 0, 0),
int3(0, 1, 0),
int3(1, 1, 0),
int3(0, 0, 1),
int3(1, 0, 1),
int3(0, 1, 1),
int3(1, 1, 1),
};
float4 output = float4(0, 0, 0, 0);
int3 coords = (int3)id.xyz;
int3 prevCoords = 2 * coords;
int prevMipAdr = prevCoords.x + prevCoords.y * _PrevMipDimOffset.x + (prevCoords.z * _PrevMipDimOffset.x * _PrevMipDimOffset.y) + _PrevMipDimOffset.w;
int sliceSize = _PrevMipDimOffset.x * _PrevMipDimOffset.y;
//int sampleAddress[8] =
//{
// prevMipAdr,
// prevMipAdr + 1,
// prevMipAdr + _PrevMipDimOffset.x,
// prevMipAdr + 1 + _PrevMipDimOffset.x,
// prevMipAdr + sliceSize,
// prevMipAdr + 1 + sliceSize,
// prevMipAdr + _PrevMipDimOffset.x + sliceSize,
// prevMipAdr + 1 + _PrevMipDimOffset.x + sliceSize,
//};
int3 maxCoord = _PrevMipDimOffset.xyz - (1).xxx;
[unroll]
for (int i = 0; i < 8; i++)
{
int sampleAddress =
min(prevCoords.x + samplePoints[i].x, maxCoord.x) +
min(prevCoords.y + samplePoints[i].y, maxCoord.y) * _PrevMipDimOffset.x +
min(prevCoords.z + samplePoints[i].z, maxCoord.z) * _PrevMipDimOffset.x * _PrevMipDimOffset.y +
+ _PrevMipDimOffset.w;
uint2 dataHalf4 = _Buffer.Load(sampleAddress);
float4 dataFloat = float4(0, 0, 0, 0);
dataFloat.x = f16tof32(dataHalf4.x & 0xFFFF);
dataFloat.y = f16tof32(dataHalf4.x >> 16);
dataFloat.z = f16tof32(dataHalf4.y & 0xFFFF);
dataFloat.w = f16tof32(dataHalf4.y >> 16);
output += 0.125 * dataFloat;
}
//output = float4(1,0,1,1);
uint2 outputHalf = uint2(0,0);
outputHalf.x = (f32tof16(output.x) & 0xFFFF) | (f32tof16(output.y) << 16);
outputHalf.y = (f32tof16(output.z) & 0xFFFF) | (f32tof16(output.w) << 16);
int mipAdr = coords.x + coords.y * _MipDimOffset.x + (coords.z * _MipDimOffset.x * _MipDimOffset.y) + _MipDimOffset.w;
_Buffer[mipAdr] = outputHalf;
}
}
[numthreads(4,4,4)]
void CopyTexToBuffer(uint3 id : SV_DispatchThreadID)
{
if (id.x < (uint)_MipDimOffset.x && id.y < (uint)_MipDimOffset.y && id.z < (uint)_MipDimOffset.z)
{
int3 coords = (int3)id.xyz;
float4 output = _Input.Load(int4(coords, 0));
uint2 outputHalf = uint2(0,0);
outputHalf.x = (f32tof16(output.x) & 0xFFFF) | (f32tof16(output.y) << 16);
outputHalf.y = (f32tof16(output.z) & 0xFFFF) | (f32tof16(output.w) << 16);
uint mipAdr = id.x + (id.y * _MipDimOffset.x) + (id.z * _MipDimOffset.x * _MipDimOffset.y); // + _MipDimOffset.w; // offset is 0 for first mip
_Buffer[mipAdr] = outputHalf;
}
}