UnityGame/Library/PackageCache/com.unity.rendering.light-transport/Runtime/UnifiedRayTracing/Common/GeometryPool/GeometryPool.hlsl
2024-10-27 10:53:47 +03:00

114 lines
3.2 KiB
HLSL

#ifndef GEOMETRY_POOL_H
#define GEOMETRY_POOL_H
namespace GeometryPool
{
float2 msign(float2 v)
{
return float2(
(v.x >= 0.0) ? 1.0 : -1.0,
(v.y >= 0.0) ? 1.0 : -1.0);
}
uint NormalToOctahedral32(float3 normal)
{
normal.xy /= (abs(normal.x) + abs(normal.y) + abs(normal.z));
normal.xy = (normal.z >= 0.0) ? normal.xy : (1.0 - abs(normal.yx)) * msign(normal.xy);
uint2 d = uint2(round(32767.5 + normal.xy * 32767.5));
return d.x | (d.y << 16u);
}
float3 Octahedral32ToNormal(uint data)
{
uint2 iv = uint2(data, data >> 16u) & 65535u;
float2 v = float2(iv) / 32767.5 - 1.0;
float3 normal = float3(v, 1.0 - abs(v.x) - abs(v.y));
float t = max(-normal.z, 0.0);
normal.x += (normal.x > 0.0) ? -t : t;
normal.y += (normal.y > 0.0) ? -t : t;
return normalize(normal);
}
uint UvsToUint32(float2 uv)
{
return (uint(uv.x * 65535.0f) & 0xFFFF) | (uint(uv.y * 65535.0f) << 16);
}
float2 Uint32ToUvs(uint data)
{
return float2((data & 0xFFFF) * (1.0f/65535.0f), (data >> 16u) * (1.0f/65535.0f));
}
void StoreUvs(RWStructuredBuffer<uint> output, uint index, float2 uv)
{
#ifdef GEOMETRY_POOL_USE_COMPRESSED_UVS
output[index] = UvsToUint32(uv);
#else
output[index] = asuint(uv.x);
output[index + 1] = asuint(uv.y);
#endif
}
float2 LoadUvs(StructuredBuffer<uint> vertexBuffer, uint index)
{
#ifdef GEOMETRY_POOL_USE_COMPRESSED_UVS
return Uint32ToUvs(vertexBuffer[index]);
#else
return asfloat(uint2(vertexBuffer[index], vertexBuffer[index + 1]));
#endif
}
void StoreVertex(
uint vertexIndex,
in GeoPoolVertex vertex,
int outputBufferSize,
RWStructuredBuffer<uint> output)
{
uint posIndex = vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE / 4;
output[posIndex] = asuint(vertex.pos.x);
output[posIndex+1] = asuint(vertex.pos.y);
output[posIndex+2] = asuint(vertex.pos.z);
uint uv0Index = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_UV0BYTE_OFFSET) / 4;
StoreUvs(output, uv0Index, vertex.uv0);
uint uv1Index = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_UV1BYTE_OFFSET) / 4;
StoreUvs(output, uv1Index, vertex.uv1);
uint normalIndex = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_NORMAL_BYTE_OFFSET) / 4;
output[normalIndex] = NormalToOctahedral32(vertex.N);
}
void LoadVertex(
uint vertexIndex,
int vertexFlags,
StructuredBuffer<uint> vertexBuffer,
out GeoPoolVertex outputVertex)
{
uint posIndex = vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE / 4;
float3 pos = asfloat(uint3(vertexBuffer[posIndex], vertexBuffer[posIndex + 1], vertexBuffer[posIndex + 2]));
uint uv0Index = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_UV0BYTE_OFFSET) / 4;
float2 uv0 = LoadUvs(vertexBuffer, uv0Index);
uint uv1Index = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_UV1BYTE_OFFSET) / 4;
float2 uv1 = LoadUvs(vertexBuffer, uv1Index);
uint normalIndex = (vertexIndex * GEO_POOL_VERTEX_BYTE_SIZE + GEO_POOL_NORMAL_BYTE_OFFSET) / 4;
uint normal = uint(vertexBuffer[normalIndex]);
outputVertex.pos = pos;
outputVertex.uv0 = uv0;
outputVertex.uv1 = uv1;
outputVertex.N = Octahedral32ToNormal(normal);
}
}
#endif