276 lines
10 KiB
Plaintext
276 lines
10 KiB
Plaintext
#pragma kernel CubeMapToEquirectangular
|
|
#pragma kernel CubeMapToEquirectangularPositiveY
|
|
#pragma kernel CubeMapToEquirectangularNegativeY
|
|
|
|
RWStructuredBuffer<uint> result;
|
|
StructuredBuffer<uint> cameraPixels;
|
|
SamplerState MyLinearClampSampler;
|
|
uint equirectangularWidth;
|
|
uint equirectangularHeight;
|
|
uint ssaaFactor;
|
|
uint cameraWidth;
|
|
uint cameraHeight;
|
|
uint startY;
|
|
uint sliceHeight;
|
|
uint cameraPixelsSentinelIdx;
|
|
uint sentinelIdx;
|
|
|
|
[numthreads(32,32,1)] // Must match threadsX, threadsY in CapturePanorama.cs
|
|
void CubeMapToEquirectangular (uint3 dtid : SV_DispatchThreadID)
|
|
{
|
|
if (dtid.x >= equirectangularWidth || dtid.y >= sliceHeight) // In case width/height not multiple of numthreads
|
|
return;
|
|
if (dtid.x == 0u && dtid.y == 0u)
|
|
result[sentinelIdx] = cameraPixels[cameraPixelsSentinelIdx]; // Sentinel value - set correctly only if set correctly in input buffer
|
|
|
|
// Must match enum UnityEngine.CubemapFace
|
|
static const uint PositiveX = 0u;
|
|
static const uint NegativeX = 1u;
|
|
static const uint PositiveY = 2u;
|
|
static const uint NegativeY = 3u;
|
|
static const uint PositiveZ = 4u;
|
|
static const uint NegativeZ = 5u;
|
|
|
|
static const float pi = 3.14159265f;
|
|
float4 totalColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
uint2 pos = uint2(dtid.x, dtid.y + startY);
|
|
uint2 loopStart = pos * ssaaFactor;
|
|
uint2 loopEnd = loopStart + uint2(ssaaFactor, ssaaFactor);
|
|
|
|
for (uint y = loopStart.y; y < loopEnd.y; y++)
|
|
{
|
|
for (uint x = loopStart.x; x < loopEnd.x; x++)
|
|
{
|
|
float xcoord = (float)x / (equirectangularWidth * ssaaFactor);
|
|
float ycoord = (float)y / (equirectangularHeight * ssaaFactor);
|
|
float latitude = (ycoord - 0.5f) * pi;
|
|
float longitude = (xcoord * 2.0f - 1.0f) * pi;
|
|
|
|
float cosLat = cos(latitude);
|
|
float equirectRayDirectionX = cosLat * sin (longitude);
|
|
float equirectRayDirectionY = sin (latitude);
|
|
float equirectRayDirectionZ = cosLat * cos (longitude);
|
|
|
|
float distance;
|
|
float u, v;
|
|
uint cameraNum;
|
|
|
|
distance = 1.0f / equirectRayDirectionY;
|
|
u = equirectRayDirectionX * distance; v = equirectRayDirectionZ * distance;
|
|
if (u * u <= 1.0f && v * v <= 1.0f) {
|
|
if (equirectRayDirectionY > 0.0f) {
|
|
cameraNum = PositiveY;
|
|
} else {
|
|
u = -u;
|
|
cameraNum = NegativeY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
distance = 1.0f / equirectRayDirectionX;
|
|
u = -equirectRayDirectionZ * distance; v = equirectRayDirectionY * distance;
|
|
if (u * u <= 1.0f && v * v <= 1.0f) {
|
|
if (equirectRayDirectionX > 0.0f) {
|
|
v = -v;
|
|
cameraNum = PositiveX;
|
|
} else {
|
|
cameraNum = NegativeX;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
distance = 1.0f / equirectRayDirectionZ;
|
|
u = equirectRayDirectionX * distance; v = equirectRayDirectionY * distance;
|
|
if (u * u <= 1.0f && v * v <= 1.0f) {
|
|
if (equirectRayDirectionZ > 0.0f) {
|
|
v = -v;
|
|
cameraNum = PositiveZ;
|
|
} else {
|
|
cameraNum = NegativeZ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
u = (u + 1.0f) * 0.5f;
|
|
v = (v + 1.0f) * 0.5f;
|
|
|
|
// GetCameraPixelBilinear(cameraPixels, cameraNum, u, v);
|
|
|
|
u *= cameraWidth;
|
|
v *= cameraHeight;
|
|
uint left = min(cameraWidth - 1u, (uint)floor(u)); // Modified to add check
|
|
uint right = min(cameraWidth - 1u, left + 1u);
|
|
uint top = min(cameraHeight - 1u, (uint)floor(v)); // Modified to add check
|
|
uint bottom = min(cameraHeight - 1u, top + 1u);
|
|
float uFrac = frac(u);
|
|
float vFrac = frac(v);
|
|
|
|
uint baseIdx = cameraNum * cameraWidth * cameraHeight;
|
|
uint topRow = baseIdx + top * cameraWidth;
|
|
uint bottomRow = baseIdx + bottom * cameraWidth;
|
|
uint topLeft = cameraPixels[topRow + left ];
|
|
uint topRight = cameraPixels[topRow + right];
|
|
uint bottomLeft = cameraPixels[bottomRow + left ];
|
|
uint bottomRight = cameraPixels[bottomRow + right];
|
|
|
|
float r = lerp(lerp( topLeft >> 16u , bottomLeft >> 16u , vFrac),
|
|
lerp( topRight >> 16u , bottomRight >> 16u , vFrac), uFrac);
|
|
float g = lerp(lerp((topLeft >> 8u) & 0xFFu, (bottomLeft >> 8u) & 0xFFu, vFrac),
|
|
lerp((topRight >> 8u) & 0xFFu, (bottomRight >> 8u) & 0xFFu, vFrac), uFrac);
|
|
float b = lerp(lerp( topLeft & 0xFFu, bottomLeft & 0xFFu, vFrac),
|
|
lerp( topRight & 0xFFu, bottomRight & 0xFFu, vFrac), uFrac);
|
|
|
|
totalColor += float4(r, g, b, 255.0f);
|
|
}
|
|
}
|
|
|
|
totalColor /= ssaaFactor * ssaaFactor;
|
|
result[(dtid.y * equirectangularWidth) + dtid.x] =
|
|
((uint)totalColor.r << 16u) | ((uint)totalColor.g << 8u) | (uint)totalColor.b;
|
|
}
|
|
|
|
[numthreads(32,32,1)] // Must match threadsX, threadsY in CapturePanorama.cs
|
|
void CubeMapToEquirectangularPositiveY (uint3 dtid : SV_DispatchThreadID)
|
|
{
|
|
if (dtid.x >= equirectangularWidth || dtid.y >= sliceHeight) // In case width/height not multiple of numthreads
|
|
return;
|
|
if (dtid.x == 0u && dtid.y == 0u)
|
|
result[sentinelIdx] = cameraPixels[cameraPixelsSentinelIdx]; // Sentinel value - set correctly only if set correctly in input buffer
|
|
|
|
static const uint cameraNum = 2; /* PositiveY */
|
|
static const float pi = 3.14159265f;
|
|
float4 totalColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
uint2 pos = uint2(dtid.x, dtid.y + startY);
|
|
uint2 loopStart = pos * ssaaFactor;
|
|
uint2 loopEnd = loopStart + uint2(ssaaFactor, ssaaFactor);
|
|
|
|
for (uint y = loopStart.y; y < loopEnd.y; y++)
|
|
{
|
|
for (uint x = loopStart.x; x < loopEnd.x; x++)
|
|
{
|
|
float xcoord = (float)x / (equirectangularWidth * ssaaFactor);
|
|
float ycoord = (float)y / (equirectangularHeight * ssaaFactor);
|
|
float latitude = (ycoord - 0.5f) * pi;
|
|
float longitude = (xcoord * 2.0f - 1.0f) * pi;
|
|
|
|
float cosLat = cos(latitude);
|
|
float equirectRayDirectionX = cosLat * sin (longitude);
|
|
float equirectRayDirectionY = sin (latitude);
|
|
float equirectRayDirectionZ = cosLat * cos (longitude);
|
|
|
|
float distance = 1.0f / equirectRayDirectionY;
|
|
float u = equirectRayDirectionX * distance, v = equirectRayDirectionZ * distance;
|
|
|
|
u = (u + 1.0f) * 0.5f;
|
|
v = (v + 1.0f) * 0.5f;
|
|
|
|
// GetCameraPixelBilinear(cameraPixels, cameraNum, u, v);
|
|
|
|
u *= cameraWidth;
|
|
v *= cameraHeight;
|
|
uint left = (uint)floor(u);
|
|
uint right = min(cameraWidth - 1u, left + 1u);
|
|
uint top = (uint)floor(v);
|
|
uint bottom = min(cameraHeight - 1u, top + 1u);
|
|
float uFrac = frac(u);
|
|
float vFrac = frac(v);
|
|
|
|
uint baseIdx = cameraNum * cameraWidth * cameraHeight;
|
|
uint topRow = baseIdx + top * cameraWidth;
|
|
uint bottomRow = baseIdx + bottom * cameraWidth;
|
|
uint topLeft = cameraPixels[topRow + left ];
|
|
uint topRight = cameraPixels[topRow + right];
|
|
uint bottomLeft = cameraPixels[bottomRow + left ];
|
|
uint bottomRight = cameraPixels[bottomRow + right];
|
|
|
|
float r = lerp(lerp( topLeft >> 16u , bottomLeft >> 16u , vFrac),
|
|
lerp( topRight >> 16u , bottomRight >> 16u , vFrac), uFrac);
|
|
float g = lerp(lerp((topLeft >> 8u) & 0xFFu, (bottomLeft >> 8u) & 0xFFu, vFrac),
|
|
lerp((topRight >> 8u) & 0xFFu, (bottomRight >> 8u) & 0xFFu, vFrac), uFrac);
|
|
float b = lerp(lerp( topLeft & 0xFFu, bottomLeft & 0xFFu, vFrac),
|
|
lerp( topRight & 0xFFu, bottomRight & 0xFFu, vFrac), uFrac);
|
|
|
|
totalColor += float4(r, g, b, 255.0f);
|
|
}
|
|
}
|
|
|
|
totalColor /= ssaaFactor * ssaaFactor;
|
|
result[(dtid.y * equirectangularWidth) + dtid.x] =
|
|
((uint)totalColor.r << 16u) | ((uint)totalColor.g << 8u) | (uint)totalColor.b;
|
|
}
|
|
|
|
[numthreads(32,32,1)] // Must match threadsX, threadsY in CapturePanorama.cs
|
|
void CubeMapToEquirectangularNegativeY (uint3 dtid : SV_DispatchThreadID)
|
|
{
|
|
if (dtid.x >= equirectangularWidth || dtid.y >= sliceHeight) // In case width/height not multiple of numthreads
|
|
return;
|
|
if (dtid.x == 0u && dtid.y == 0u)
|
|
result[sentinelIdx] = cameraPixels[cameraPixelsSentinelIdx]; // Sentinel value - set correctly only if set correctly in input buffer
|
|
|
|
static const uint cameraNum = 3; /* NegativeY */
|
|
static const float pi = 3.14159265f;
|
|
float4 totalColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
uint2 pos = uint2(dtid.x, dtid.y + startY);
|
|
uint2 loopStart = pos * ssaaFactor;
|
|
uint2 loopEnd = loopStart + uint2(ssaaFactor, ssaaFactor);
|
|
|
|
for (uint y = loopStart.y; y < loopEnd.y; y++)
|
|
{
|
|
for (uint x = loopStart.x; x < loopEnd.x; x++)
|
|
{
|
|
float xcoord = (float)x / (equirectangularWidth * ssaaFactor);
|
|
float ycoord = (float)y / (equirectangularHeight * ssaaFactor);
|
|
float latitude = (ycoord - 0.5f) * pi;
|
|
float longitude = (xcoord * 2.0f - 1.0f) * pi;
|
|
|
|
float cosLat = cos(latitude);
|
|
float equirectRayDirectionX = cosLat * sin (longitude);
|
|
float equirectRayDirectionY = sin (latitude);
|
|
float equirectRayDirectionZ = cosLat * cos (longitude);
|
|
|
|
float distance = 1.0f / equirectRayDirectionY;
|
|
float u = equirectRayDirectionX * distance, v = equirectRayDirectionZ * distance;
|
|
u = -u;
|
|
|
|
u = (u + 1.0f) * 0.5f;
|
|
v = (v + 1.0f) * 0.5f;
|
|
|
|
// GetCameraPixelBilinear(cameraPixels, cameraNum, u, v);
|
|
|
|
u *= cameraWidth;
|
|
v *= cameraHeight;
|
|
uint left = (uint)floor(u);
|
|
uint right = min(cameraWidth - 1u, left + 1u);
|
|
uint top = (uint)floor(v);
|
|
uint bottom = min(cameraHeight - 1u, top + 1u);
|
|
float uFrac = frac(u);
|
|
float vFrac = frac(v);
|
|
|
|
uint baseIdx = cameraNum * cameraWidth * cameraHeight;
|
|
uint topRow = baseIdx + top * cameraWidth;
|
|
uint bottomRow = baseIdx + bottom * cameraWidth;
|
|
uint topLeft = cameraPixels[topRow + left ];
|
|
uint topRight = cameraPixels[topRow + right];
|
|
uint bottomLeft = cameraPixels[bottomRow + left ];
|
|
uint bottomRight = cameraPixels[bottomRow + right];
|
|
|
|
float r = lerp(lerp( topLeft >> 16u , bottomLeft >> 16u , vFrac),
|
|
lerp( topRight >> 16u , bottomRight >> 16u , vFrac), uFrac);
|
|
float g = lerp(lerp((topLeft >> 8u) & 0xFFu, (bottomLeft >> 8u) & 0xFFu, vFrac),
|
|
lerp((topRight >> 8u) & 0xFFu, (bottomRight >> 8u) & 0xFFu, vFrac), uFrac);
|
|
float b = lerp(lerp( topLeft & 0xFFu, bottomLeft & 0xFFu, vFrac),
|
|
lerp( topRight & 0xFFu, bottomRight & 0xFFu, vFrac), uFrac);
|
|
|
|
totalColor += float4(r, g, b, 255.0f);
|
|
}
|
|
}
|
|
|
|
totalColor /= ssaaFactor * ssaaFactor;
|
|
result[(dtid.y * equirectangularWidth) + dtid.x] =
|
|
((uint)totalColor.r << 16u) | ((uint)totalColor.g << 8u) | (uint)totalColor.b;
|
|
}
|