project-aster/samples/03_model_render/shader/eqrectToCube.cs.hlsl

55 lines
1.4 KiB
HLSL

#include "bindless_structs.hlsli"
struct Block
{
uint HdrEnvHandle;
uint OutputTextureHandle;
int CubeSize;
};
[[vk::push_constant]]
Block pcb;
float2 SampleSphericalMap(float3 v)
{
const float2 invAtan = float2(0.1591f, 0.3183f);
float2 uv = float2(atan2(v.x, v.z), asin(v.y));
uv *= invAtan;
uv += 0.5;
return uv;
}
/*
| Axis | Layer | Up |
|:----:|:-----:|:--:|
| +x | 0 | -y |
| -x | 1 | -y |
| +y | 2 | +z |
| -y | 3 | -z |
| -z | 4 | -y |
| +z | 5 | -y |
*/
[numthreads(16, 16, 1)]
void main(uint3 GlobalInvocationID : SV_DispatchThreadID)
{
float3 LocalDir;
float HalfSide = pcb.CubeSize / 2;
float AxisSign = 2.0f * (0.5f - (GlobalInvocationID.z % 2));
if (GlobalInvocationID.z < 2)
{
LocalDir = float3(AxisSign * HalfSide, GlobalInvocationID.y - HalfSide, (GlobalInvocationID.x - HalfSide) * AxisSign);
}
else if (GlobalInvocationID.z < 4)
{
LocalDir = float3(GlobalInvocationID.x - HalfSide, -AxisSign * HalfSide, -AxisSign * (GlobalInvocationID.y - HalfSide));
}
else
{
LocalDir = float3((GlobalInvocationID.x - HalfSide) * AxisSign, GlobalInvocationID.y - HalfSide, -AxisSign * HalfSide);
}
float2 UV = SampleSphericalMap(normalize(LocalDir));
StorageTextureArrays[pcb.OutputTextureHandle][GlobalInvocationID.xyz] = Textures[pcb.HdrEnvHandle].SampleLevel(ImmutableSamplers[pcb.HdrEnvHandle], UV, 0);
}