diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b633b6..d8c3bef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -279,6 +279,7 @@ set(SKATE3_NATIVE_SHADER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/native/shaders/overlay2d.hlsl ${CMAKE_CURRENT_SOURCE_DIR}/src/native/shaders/spline.hlsl ${CMAKE_CURRENT_SOURCE_DIR}/src/native/shaders/photo_fx.hlsl + ${CMAKE_CURRENT_SOURCE_DIR}/src/native/shaders/ssao.hlsl ) set(SKATE3_NATIVE_SHADER_HEADER ${CMAKE_CURRENT_BINARY_DIR}/include/skate3_native_shaders.h) diff --git a/cmake/EmbedShaders.cmake b/cmake/EmbedShaders.cmake index 12c8fa5..2eda25a 100644 --- a/cmake/EmbedShaders.cmake +++ b/cmake/EmbedShaders.cmake @@ -14,6 +14,7 @@ set(SHADER_VARS kShader2dSource kShaderSplineSource kPhotoFxShaderSource + kSsaoShaderSource ) set(SHADER_FILES scene.hlsl @@ -24,6 +25,7 @@ set(SHADER_FILES overlay2d.hlsl spline.hlsl photo_fx.hlsl + ssao.hlsl ) set(content "// Generated by cmake/EmbedShaders.cmake from src/native/shaders/*.hlsl.\n") diff --git a/src/native/shaders/spirv/skate3_native_shaders_spirv.h b/src/native/shaders/spirv/skate3_native_shaders_spirv.h index 7d5e2b7..6bd1a68 100644 --- a/src/native/shaders/spirv/skate3_native_shaders_spirv.h +++ b/src/native/shaders/spirv/skate3_native_shaders_spirv.h @@ -4743,6 +4743,672 @@ static const uint32_t k_photo_fx_ps_pfx_debug[] = { 0x0003003e, 0x00000004, 0x0000004f, 0x000100fd, 0x00010038, }; +// ssao.hlsl : vs_main (800 bytes) +static const uint32_t k_ssao_vs_main[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x00000024, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, + 0x00000000, 0x00000001, 0x0008000f, 0x00000000, 0x00000001, 0x6d5f7376, 0x006e6961, 0x00000002, + 0x00000003, 0x00000004, 0x00030003, 0x00000005, 0x00000258, 0x00070005, 0x00000004, 0x2e74756f, + 0x2e726176, 0x43584554, 0x44524f4f, 0x00000030, 0x00040005, 0x00000001, 0x6d5f7376, 0x006e6961, + 0x00040047, 0x00000002, 0x0000000b, 0x0000002a, 0x00040047, 0x00000003, 0x0000000b, 0x00000000, + 0x00040047, 0x00000004, 0x0000001e, 0x00000000, 0x00030016, 0x00000005, 0x00000020, 0x00040015, + 0x00000006, 0x00000020, 0x00000000, 0x0004002b, 0x00000006, 0x00000007, 0x00000001, 0x0004002b, + 0x00000006, 0x00000008, 0x00000002, 0x0004002b, 0x00000005, 0x00000009, 0x40000000, 0x0004002b, + 0x00000005, 0x0000000a, 0xc0000000, 0x00040017, 0x0000000b, 0x00000005, 0x00000002, 0x0005002c, + 0x0000000b, 0x0000000c, 0x00000009, 0x0000000a, 0x0004002b, 0x00000005, 0x0000000d, 0xbf800000, + 0x0004002b, 0x00000005, 0x0000000e, 0x3f800000, 0x0005002c, 0x0000000b, 0x0000000f, 0x0000000d, + 0x0000000e, 0x0004002b, 0x00000005, 0x00000010, 0x00000000, 0x00040017, 0x00000011, 0x00000005, + 0x00000004, 0x00040020, 0x00000012, 0x00000001, 0x00000006, 0x00040020, 0x00000013, 0x00000003, + 0x00000011, 0x00040020, 0x00000014, 0x00000003, 0x0000000b, 0x00020013, 0x00000015, 0x00030021, + 0x00000016, 0x00000015, 0x0004003b, 0x00000012, 0x00000002, 0x00000001, 0x0004003b, 0x00000013, + 0x00000003, 0x00000003, 0x0004003b, 0x00000014, 0x00000004, 0x00000003, 0x00050036, 0x00000015, + 0x00000001, 0x00000000, 0x00000016, 0x000200f8, 0x00000017, 0x0004003d, 0x00000006, 0x00000018, + 0x00000002, 0x000500c4, 0x00000006, 0x00000019, 0x00000018, 0x00000007, 0x000500c7, 0x00000006, + 0x0000001a, 0x00000019, 0x00000008, 0x00040070, 0x00000005, 0x0000001b, 0x0000001a, 0x000500c7, + 0x00000006, 0x0000001c, 0x00000018, 0x00000008, 0x00040070, 0x00000005, 0x0000001d, 0x0000001c, + 0x00050050, 0x0000000b, 0x0000001e, 0x0000001b, 0x0000001d, 0x00050085, 0x0000000b, 0x0000001f, + 0x0000001e, 0x0000000c, 0x00050081, 0x0000000b, 0x00000020, 0x0000001f, 0x0000000f, 0x00050051, + 0x00000005, 0x00000021, 0x00000020, 0x00000000, 0x00050051, 0x00000005, 0x00000022, 0x00000020, + 0x00000001, 0x00070050, 0x00000011, 0x00000023, 0x00000021, 0x00000022, 0x00000010, 0x0000000e, + 0x0003003e, 0x00000003, 0x00000023, 0x0003003e, 0x00000004, 0x0000001e, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_linearize (1376 bytes) +static const uint32_t k_ssao_ps_linearize[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x00000030, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0009000f, 0x00000004, 0x00000002, 0x6c5f7370, 0x61656e69, 0x657a6972, 0x00000000, 0x00000003, + 0x00000004, 0x00030010, 0x00000002, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00040005, + 0x00000005, 0x65707974, 0x0000432e, 0x00050006, 0x00000005, 0x00000000, 0x657a6973, 0x00000000, + 0x00050006, 0x00000005, 0x00000001, 0x6a6f7270, 0x00000000, 0x00040006, 0x00000005, 0x00000002, + 0x00003070, 0x00040006, 0x00000005, 0x00000003, 0x00003170, 0x00030005, 0x00000006, 0x00000043, + 0x00060005, 0x00000007, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000008, + 0x30786574, 0x00000000, 0x00070005, 0x00000004, 0x2e74756f, 0x2e726176, 0x545f5653, 0x65677261, + 0x00000074, 0x00060005, 0x00000002, 0x6c5f7370, 0x61656e69, 0x657a6972, 0x00000000, 0x00040047, + 0x00000003, 0x0000000b, 0x0000000f, 0x00040047, 0x00000004, 0x0000001e, 0x00000000, 0x00040047, + 0x00000006, 0x00000022, 0x00000000, 0x00040047, 0x00000006, 0x00000021, 0x00000000, 0x00040047, + 0x00000008, 0x00000022, 0x00000001, 0x00040047, 0x00000008, 0x00000021, 0x00000000, 0x00050048, + 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000005, 0x00000001, 0x00000023, + 0x00000010, 0x00050048, 0x00000005, 0x00000002, 0x00000023, 0x00000020, 0x00050048, 0x00000005, + 0x00000003, 0x00000023, 0x00000030, 0x00030047, 0x00000005, 0x00000002, 0x00030016, 0x00000009, + 0x00000020, 0x00040015, 0x0000000a, 0x00000020, 0x00000001, 0x0004002b, 0x0000000a, 0x0000000b, + 0x00000000, 0x0004002b, 0x0000000a, 0x0000000c, 0x00000001, 0x0004002b, 0x0000000a, 0x0000000d, + 0x00000003, 0x0004002b, 0x0000000a, 0x0000000e, 0x00000002, 0x0004002b, 0x00000009, 0x0000000f, + 0xb58637bd, 0x0004002b, 0x00000009, 0x00000010, 0x3d4ccccd, 0x0004002b, 0x00000009, 0x00000011, + 0x48c35000, 0x00040017, 0x00000012, 0x00000009, 0x00000004, 0x0006001e, 0x00000005, 0x00000012, + 0x00000012, 0x00000012, 0x00000012, 0x00040020, 0x00000013, 0x00000002, 0x00000005, 0x00090019, + 0x00000007, 0x00000009, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x00040020, 0x00000014, 0x00000000, 0x00000007, 0x00040020, 0x00000015, 0x00000001, 0x00000012, + 0x00040017, 0x00000016, 0x00000009, 0x00000002, 0x00040020, 0x00000017, 0x00000003, 0x00000009, + 0x00020013, 0x00000018, 0x00030021, 0x00000019, 0x00000018, 0x00040017, 0x0000001a, 0x0000000a, + 0x00000002, 0x00040017, 0x0000001b, 0x0000000a, 0x00000003, 0x00040020, 0x0000001c, 0x00000002, + 0x00000009, 0x0004003b, 0x00000013, 0x00000006, 0x00000002, 0x0004003b, 0x00000014, 0x00000008, + 0x00000000, 0x0004003b, 0x00000015, 0x00000003, 0x00000001, 0x0004003b, 0x00000017, 0x00000004, + 0x00000003, 0x00050036, 0x00000018, 0x00000002, 0x00000000, 0x00000019, 0x000200f8, 0x0000001d, + 0x0004003d, 0x00000012, 0x0000001e, 0x00000003, 0x0007004f, 0x00000016, 0x0000001f, 0x0000001e, + 0x0000001e, 0x00000000, 0x00000001, 0x0004006e, 0x0000001a, 0x00000020, 0x0000001f, 0x00050051, + 0x0000000a, 0x00000021, 0x00000020, 0x00000000, 0x00050051, 0x0000000a, 0x00000022, 0x00000020, + 0x00000001, 0x00060050, 0x0000001b, 0x00000023, 0x00000021, 0x00000022, 0x0000000b, 0x0007004f, + 0x0000001a, 0x00000024, 0x00000023, 0x00000023, 0x00000000, 0x00000001, 0x0004003d, 0x00000007, + 0x00000025, 0x00000008, 0x0007005f, 0x00000012, 0x00000026, 0x00000025, 0x00000024, 0x00000002, + 0x0000000b, 0x00050051, 0x00000009, 0x00000027, 0x00000026, 0x00000000, 0x00060041, 0x0000001c, + 0x00000028, 0x00000006, 0x0000000c, 0x0000000d, 0x0004003d, 0x00000009, 0x00000029, 0x00000028, + 0x00060041, 0x0000001c, 0x0000002a, 0x00000006, 0x0000000c, 0x0000000e, 0x0004003d, 0x00000009, + 0x0000002b, 0x0000002a, 0x00050083, 0x00000009, 0x0000002c, 0x00000027, 0x0000002b, 0x0007000c, + 0x00000009, 0x0000002d, 0x00000001, 0x0000004f, 0x0000002c, 0x0000000f, 0x00050088, 0x00000009, + 0x0000002e, 0x00000029, 0x0000002d, 0x0008000c, 0x00000009, 0x0000002f, 0x00000001, 0x0000002b, + 0x0000002e, 0x00000010, 0x00000011, 0x0003003e, 0x00000004, 0x0000002f, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_linearize [AO_MSAA=1] (1272 bytes) +static const uint32_t k_ssao_ps_linearize_AO_MSAA_1[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x0000002b, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0009000f, 0x00000004, 0x00000002, 0x6c5f7370, 0x61656e69, 0x657a6972, 0x00000000, 0x00000003, + 0x00000004, 0x00030010, 0x00000002, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00040005, + 0x00000005, 0x65707974, 0x0000432e, 0x00050006, 0x00000005, 0x00000000, 0x657a6973, 0x00000000, + 0x00050006, 0x00000005, 0x00000001, 0x6a6f7270, 0x00000000, 0x00040006, 0x00000005, 0x00000002, + 0x00003070, 0x00040006, 0x00000005, 0x00000003, 0x00003170, 0x00030005, 0x00000006, 0x00000043, + 0x00060005, 0x00000007, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00050005, 0x00000008, + 0x74706564, 0x736d5f68, 0x00000000, 0x00070005, 0x00000004, 0x2e74756f, 0x2e726176, 0x545f5653, + 0x65677261, 0x00000074, 0x00060005, 0x00000002, 0x6c5f7370, 0x61656e69, 0x657a6972, 0x00000000, + 0x00040047, 0x00000003, 0x0000000b, 0x0000000f, 0x00040047, 0x00000004, 0x0000001e, 0x00000000, + 0x00040047, 0x00000006, 0x00000022, 0x00000000, 0x00040047, 0x00000006, 0x00000021, 0x00000000, + 0x00040047, 0x00000008, 0x00000022, 0x00000001, 0x00040047, 0x00000008, 0x00000021, 0x00000000, + 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000005, 0x00000001, + 0x00000023, 0x00000010, 0x00050048, 0x00000005, 0x00000002, 0x00000023, 0x00000020, 0x00050048, + 0x00000005, 0x00000003, 0x00000023, 0x00000030, 0x00030047, 0x00000005, 0x00000002, 0x00030016, + 0x00000009, 0x00000020, 0x00040015, 0x0000000a, 0x00000020, 0x00000001, 0x0004002b, 0x0000000a, + 0x0000000b, 0x00000000, 0x0004002b, 0x0000000a, 0x0000000c, 0x00000001, 0x0004002b, 0x0000000a, + 0x0000000d, 0x00000003, 0x0004002b, 0x0000000a, 0x0000000e, 0x00000002, 0x0004002b, 0x00000009, + 0x0000000f, 0xb58637bd, 0x0004002b, 0x00000009, 0x00000010, 0x3d4ccccd, 0x0004002b, 0x00000009, + 0x00000011, 0x48c35000, 0x00040017, 0x00000012, 0x00000009, 0x00000004, 0x0006001e, 0x00000005, + 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00040020, 0x00000013, 0x00000002, 0x00000005, + 0x00090019, 0x00000007, 0x00000009, 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000001, + 0x00000000, 0x00040020, 0x00000014, 0x00000000, 0x00000007, 0x00040020, 0x00000015, 0x00000001, + 0x00000012, 0x00040017, 0x00000016, 0x00000009, 0x00000002, 0x00040020, 0x00000017, 0x00000003, + 0x00000009, 0x00020013, 0x00000018, 0x00030021, 0x00000019, 0x00000018, 0x00040017, 0x0000001a, + 0x0000000a, 0x00000002, 0x00040020, 0x0000001b, 0x00000002, 0x00000009, 0x0004003b, 0x00000013, + 0x00000006, 0x00000002, 0x0004003b, 0x00000014, 0x00000008, 0x00000000, 0x0004003b, 0x00000015, + 0x00000003, 0x00000001, 0x0004003b, 0x00000017, 0x00000004, 0x00000003, 0x00050036, 0x00000018, + 0x00000002, 0x00000000, 0x00000019, 0x000200f8, 0x0000001c, 0x0004003d, 0x00000012, 0x0000001d, + 0x00000003, 0x0007004f, 0x00000016, 0x0000001e, 0x0000001d, 0x0000001d, 0x00000000, 0x00000001, + 0x0004006e, 0x0000001a, 0x0000001f, 0x0000001e, 0x0004003d, 0x00000007, 0x00000020, 0x00000008, + 0x0007005f, 0x00000012, 0x00000021, 0x00000020, 0x0000001f, 0x00000040, 0x0000000b, 0x00050051, + 0x00000009, 0x00000022, 0x00000021, 0x00000000, 0x00060041, 0x0000001b, 0x00000023, 0x00000006, + 0x0000000c, 0x0000000d, 0x0004003d, 0x00000009, 0x00000024, 0x00000023, 0x00060041, 0x0000001b, + 0x00000025, 0x00000006, 0x0000000c, 0x0000000e, 0x0004003d, 0x00000009, 0x00000026, 0x00000025, + 0x00050083, 0x00000009, 0x00000027, 0x00000022, 0x00000026, 0x0007000c, 0x00000009, 0x00000028, + 0x00000001, 0x0000004f, 0x00000027, 0x0000000f, 0x00050088, 0x00000009, 0x00000029, 0x00000024, + 0x00000028, 0x0008000c, 0x00000009, 0x0000002a, 0x00000001, 0x0000002b, 0x00000029, 0x00000010, + 0x00000011, 0x0003003e, 0x00000004, 0x0000002a, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_gtao (8788 bytes) +static const uint32_t k_ssao_ps_gtao[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x0000018a, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0008000f, 0x00000004, 0x00000002, 0x675f7370, 0x006f6174, 0x00000003, 0x00000004, 0x00000005, + 0x00030010, 0x00000002, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00040005, 0x00000006, + 0x65707974, 0x0000432e, 0x00050006, 0x00000006, 0x00000000, 0x657a6973, 0x00000000, 0x00050006, + 0x00000006, 0x00000001, 0x6a6f7270, 0x00000000, 0x00040006, 0x00000006, 0x00000002, 0x00003070, + 0x00040006, 0x00000006, 0x00000003, 0x00003170, 0x00030005, 0x00000007, 0x00000043, 0x00060005, + 0x00000008, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000009, 0x30786574, + 0x00000000, 0x00040005, 0x0000000a, 0x31786574, 0x00000000, 0x00060005, 0x0000000b, 0x65707974, + 0x6d61732e, 0x72656c70, 0x00000000, 0x00050005, 0x0000000c, 0x5f706d73, 0x6e696f70, 0x00000074, + 0x00070005, 0x00000004, 0x762e6e69, 0x542e7261, 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, + 0x00000005, 0x2e74756f, 0x2e726176, 0x545f5653, 0x65677261, 0x00000074, 0x00040005, 0x00000002, + 0x675f7370, 0x006f6174, 0x00070005, 0x0000000d, 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, + 0x00006567, 0x00040047, 0x00000003, 0x0000000b, 0x0000000f, 0x00040047, 0x00000004, 0x0000001e, + 0x00000000, 0x00040047, 0x00000005, 0x0000001e, 0x00000000, 0x00040047, 0x00000007, 0x00000022, + 0x00000000, 0x00040047, 0x00000007, 0x00000021, 0x00000000, 0x00040047, 0x00000009, 0x00000022, + 0x00000001, 0x00040047, 0x00000009, 0x00000021, 0x00000000, 0x00040047, 0x0000000a, 0x00000022, + 0x00000002, 0x00040047, 0x0000000a, 0x00000021, 0x00000000, 0x00040047, 0x0000000c, 0x00000022, + 0x00000000, 0x00040047, 0x0000000c, 0x00000021, 0x00000001, 0x00050048, 0x00000006, 0x00000000, + 0x00000023, 0x00000000, 0x00050048, 0x00000006, 0x00000001, 0x00000023, 0x00000010, 0x00050048, + 0x00000006, 0x00000002, 0x00000023, 0x00000020, 0x00050048, 0x00000006, 0x00000003, 0x00000023, + 0x00000030, 0x00030047, 0x00000006, 0x00000002, 0x00030016, 0x0000000e, 0x00000020, 0x00040015, + 0x0000000f, 0x00000020, 0x00000001, 0x0004002b, 0x0000000f, 0x00000010, 0x00000001, 0x0004002b, + 0x0000000f, 0x00000011, 0x00000002, 0x0004002b, 0x0000000f, 0x00000012, 0x00000003, 0x0004002b, + 0x0000000e, 0x00000013, 0x00000000, 0x0004002b, 0x0000000e, 0x00000014, 0x3f800000, 0x00020014, + 0x00000015, 0x00030029, 0x00000015, 0x00000016, 0x0004002b, 0x0000000e, 0x00000017, 0x3f7fbe77, + 0x0004002b, 0x0000000e, 0x00000018, 0x3c75c28f, 0x0004002b, 0x0000000f, 0x00000019, 0x00000000, + 0x0004002b, 0x0000000e, 0x0000001a, 0x3f000000, 0x0004002b, 0x0000000e, 0x0000001b, 0x40000000, + 0x0004002b, 0x0000000e, 0x0000001c, 0x42800000, 0x0004002b, 0x0000000e, 0x0000001d, 0x4224851f, + 0x00040017, 0x0000001e, 0x0000000e, 0x00000002, 0x0005002c, 0x0000001e, 0x0000001f, 0x0000001d, + 0x0000001d, 0x0004002b, 0x0000000e, 0x00000020, 0x38d1b717, 0x0004002b, 0x0000000e, 0x00000021, + 0xbf800000, 0x0005002c, 0x0000001e, 0x00000022, 0x00000021, 0x00000021, 0x0004002b, 0x0000000e, + 0x00000023, 0x322bcc77, 0x0004002b, 0x0000000e, 0x00000024, 0x40554fdf, 0x0004002b, 0x0000000e, + 0x00000025, 0x40154fdf, 0x0004002b, 0x0000000e, 0x00000026, 0x3e800000, 0x0004002b, 0x0000000e, + 0x00000027, 0x4253ee82, 0x0004002b, 0x0000000e, 0x00000028, 0x3d897143, 0x0004002b, 0x0000000e, + 0x00000029, 0x3bbf4590, 0x0005002c, 0x0000001e, 0x0000002a, 0x00000028, 0x00000029, 0x00040017, + 0x0000002b, 0x0000000e, 0x00000004, 0x0006001e, 0x00000006, 0x0000002b, 0x0000002b, 0x0000002b, + 0x0000002b, 0x00040020, 0x0000002c, 0x00000002, 0x00000006, 0x00090019, 0x00000008, 0x0000000e, + 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x0000002d, + 0x00000000, 0x00000008, 0x0002001a, 0x0000000b, 0x00040020, 0x0000002e, 0x00000000, 0x0000000b, + 0x00040020, 0x0000002f, 0x00000001, 0x0000002b, 0x00040020, 0x00000030, 0x00000001, 0x0000001e, + 0x00040020, 0x00000031, 0x00000003, 0x0000000e, 0x00020013, 0x00000032, 0x00030021, 0x00000033, + 0x00000032, 0x00040020, 0x00000034, 0x00000007, 0x0000000e, 0x00040020, 0x00000035, 0x00000007, + 0x0000001e, 0x00040017, 0x00000036, 0x0000000e, 0x00000003, 0x00040020, 0x00000037, 0x00000002, + 0x0000002b, 0x00040020, 0x00000038, 0x00000002, 0x0000000e, 0x0003001b, 0x0000000d, 0x00000008, + 0x00040015, 0x00000039, 0x00000020, 0x00000000, 0x0004003b, 0x0000002c, 0x00000007, 0x00000002, + 0x0004003b, 0x0000002d, 0x00000009, 0x00000000, 0x0004003b, 0x0000002d, 0x0000000a, 0x00000000, + 0x0004003b, 0x0000002e, 0x0000000c, 0x00000000, 0x0004003b, 0x0000002f, 0x00000003, 0x00000001, + 0x0004003b, 0x00000030, 0x00000004, 0x00000001, 0x0004003b, 0x00000031, 0x00000005, 0x00000003, + 0x0004002b, 0x00000039, 0x0000003a, 0x00000000, 0x0004002b, 0x0000000e, 0x0000003b, 0x3f860a92, + 0x0004002b, 0x0000000e, 0x0000003c, 0xbfc90fdb, 0x0004002b, 0x0000000e, 0x0000003d, 0x3fc90fdb, + 0x0004002b, 0x0000000e, 0x0000003e, 0x3eaaaaab, 0x00050036, 0x00000032, 0x00000002, 0x00000000, + 0x00000033, 0x000200f8, 0x0000003f, 0x0004003b, 0x00000035, 0x00000040, 0x00000007, 0x0004003d, + 0x0000002b, 0x00000041, 0x00000003, 0x0004003d, 0x0000001e, 0x00000042, 0x00000004, 0x000300f7, + 0x00000043, 0x00000000, 0x000300fb, 0x0000003a, 0x00000044, 0x000200f8, 0x00000044, 0x0004003d, + 0x00000008, 0x00000045, 0x00000009, 0x0004003d, 0x0000000b, 0x00000046, 0x0000000c, 0x00050056, + 0x0000000d, 0x00000047, 0x00000045, 0x00000046, 0x00070058, 0x0000002b, 0x00000048, 0x00000047, + 0x00000042, 0x00000002, 0x00000013, 0x00050051, 0x0000000e, 0x00000049, 0x00000048, 0x00000000, + 0x00060041, 0x00000038, 0x0000004a, 0x00000007, 0x00000011, 0x00000011, 0x0004003d, 0x0000000e, + 0x0000004b, 0x0000004a, 0x00050083, 0x0000000e, 0x0000004c, 0x00000049, 0x0000004b, 0x00060041, + 0x00000038, 0x0000004d, 0x00000007, 0x00000011, 0x00000012, 0x0004003d, 0x0000000e, 0x0000004e, + 0x0000004d, 0x00050085, 0x0000000e, 0x0000004f, 0x0000004c, 0x0000004e, 0x0008000c, 0x0000000e, + 0x00000050, 0x00000001, 0x0000002b, 0x0000004f, 0x00000013, 0x00000014, 0x0004003d, 0x00000008, + 0x00000051, 0x0000000a, 0x0004003d, 0x0000000b, 0x00000052, 0x0000000c, 0x00050056, 0x0000000d, + 0x00000053, 0x00000051, 0x00000052, 0x00070058, 0x0000002b, 0x00000054, 0x00000053, 0x00000042, + 0x00000002, 0x00000013, 0x00050051, 0x0000000e, 0x00000055, 0x00000054, 0x00000000, 0x00060041, + 0x00000038, 0x00000056, 0x00000007, 0x00000012, 0x00000011, 0x0004003d, 0x0000000e, 0x00000057, + 0x00000056, 0x00050085, 0x0000000e, 0x00000058, 0x00000055, 0x00000057, 0x0008000c, 0x0000000e, + 0x00000059, 0x00000001, 0x0000002b, 0x00000058, 0x00000013, 0x00000014, 0x00050085, 0x0000000e, + 0x0000005a, 0x00000059, 0x00000059, 0x000500b9, 0x00000015, 0x0000005b, 0x00000050, 0x00000014, + 0x000300f7, 0x0000005c, 0x00000000, 0x000400fa, 0x0000005b, 0x0000005d, 0x0000005c, 0x000200f8, + 0x0000005d, 0x000500be, 0x00000015, 0x0000005e, 0x0000005a, 0x00000017, 0x000200f9, 0x0000005c, + 0x000200f8, 0x0000005c, 0x000700f5, 0x00000015, 0x0000005f, 0x00000016, 0x00000044, 0x0000005e, + 0x0000005d, 0x000400a8, 0x00000015, 0x00000060, 0x0000005f, 0x000300f7, 0x00000061, 0x00000000, + 0x000400fa, 0x00000060, 0x00000062, 0x00000061, 0x000200f8, 0x00000062, 0x000500b8, 0x00000015, + 0x00000063, 0x00000055, 0x00000018, 0x000200f9, 0x00000061, 0x000200f8, 0x00000061, 0x000700f5, + 0x00000015, 0x00000064, 0x00000016, 0x0000005c, 0x00000063, 0x00000062, 0x000300f7, 0x00000065, + 0x00000000, 0x000400fa, 0x00000064, 0x00000066, 0x00000065, 0x000200f8, 0x00000066, 0x000200f9, + 0x00000043, 0x000200f8, 0x00000065, 0x00050051, 0x0000000e, 0x00000067, 0x00000042, 0x00000000, + 0x00050085, 0x0000000e, 0x00000068, 0x00000067, 0x0000001b, 0x00050083, 0x0000000e, 0x00000069, + 0x00000068, 0x00000014, 0x00050051, 0x0000000e, 0x0000006a, 0x00000042, 0x00000001, 0x00050085, + 0x0000000e, 0x0000006b, 0x0000006a, 0x0000001b, 0x00050083, 0x0000000e, 0x0000006c, 0x00000014, + 0x0000006b, 0x00050085, 0x0000000e, 0x0000006d, 0x00000069, 0x00000049, 0x00060041, 0x00000038, + 0x0000006e, 0x00000007, 0x00000010, 0x00000019, 0x0004003d, 0x0000000e, 0x0000006f, 0x0000006e, + 0x00050088, 0x0000000e, 0x00000070, 0x0000006d, 0x0000006f, 0x00050085, 0x0000000e, 0x00000071, + 0x0000006c, 0x00000049, 0x00060041, 0x00000038, 0x00000072, 0x00000007, 0x00000010, 0x00000010, + 0x0004003d, 0x0000000e, 0x00000073, 0x00000072, 0x00050088, 0x0000000e, 0x00000074, 0x00000071, + 0x00000073, 0x00060050, 0x00000036, 0x00000075, 0x00000070, 0x00000074, 0x00000049, 0x00050041, + 0x00000037, 0x00000076, 0x00000007, 0x00000019, 0x00060041, 0x00000038, 0x00000077, 0x00000007, + 0x00000019, 0x00000011, 0x0004003d, 0x0000000e, 0x00000078, 0x00000077, 0x00050050, 0x0000001e, + 0x00000079, 0x00000078, 0x00000013, 0x00060041, 0x00000038, 0x0000007a, 0x00000007, 0x00000019, + 0x00000012, 0x0004003d, 0x0000000e, 0x0000007b, 0x0000007a, 0x00050050, 0x0000001e, 0x0000007c, + 0x00000013, 0x0000007b, 0x00050083, 0x0000001e, 0x0000007d, 0x00000042, 0x00000079, 0x0004003d, + 0x00000008, 0x0000007e, 0x00000009, 0x0004003d, 0x0000000b, 0x0000007f, 0x0000000c, 0x00050056, + 0x0000000d, 0x00000080, 0x0000007e, 0x0000007f, 0x00070058, 0x0000002b, 0x00000081, 0x00000080, + 0x0000007d, 0x00000002, 0x00000013, 0x00050051, 0x0000000e, 0x00000082, 0x00000081, 0x00000000, + 0x00050081, 0x0000001e, 0x00000083, 0x00000042, 0x00000079, 0x0004003d, 0x00000008, 0x00000084, + 0x00000009, 0x0004003d, 0x0000000b, 0x00000085, 0x0000000c, 0x00050056, 0x0000000d, 0x00000086, + 0x00000084, 0x00000085, 0x00070058, 0x0000002b, 0x00000087, 0x00000086, 0x00000083, 0x00000002, + 0x00000013, 0x00050051, 0x0000000e, 0x00000088, 0x00000087, 0x00000000, 0x00050083, 0x0000001e, + 0x00000089, 0x00000042, 0x0000007c, 0x0004003d, 0x00000008, 0x0000008a, 0x00000009, 0x0004003d, + 0x0000000b, 0x0000008b, 0x0000000c, 0x00050056, 0x0000000d, 0x0000008c, 0x0000008a, 0x0000008b, + 0x00070058, 0x0000002b, 0x0000008d, 0x0000008c, 0x00000089, 0x00000002, 0x00000013, 0x00050051, + 0x0000000e, 0x0000008e, 0x0000008d, 0x00000000, 0x00050081, 0x0000001e, 0x0000008f, 0x00000042, + 0x0000007c, 0x0004003d, 0x00000008, 0x00000090, 0x00000009, 0x0004003d, 0x0000000b, 0x00000091, + 0x0000000c, 0x00050056, 0x0000000d, 0x00000092, 0x00000090, 0x00000091, 0x00070058, 0x0000002b, + 0x00000093, 0x00000092, 0x0000008f, 0x00000002, 0x00000013, 0x00050051, 0x0000000e, 0x00000094, + 0x00000093, 0x00000000, 0x00050083, 0x0000000e, 0x00000095, 0x00000088, 0x00000049, 0x0006000c, + 0x0000000e, 0x00000096, 0x00000001, 0x00000004, 0x00000095, 0x00050083, 0x0000000e, 0x00000097, + 0x00000082, 0x00000049, 0x0006000c, 0x0000000e, 0x00000098, 0x00000001, 0x00000004, 0x00000097, + 0x000500b8, 0x00000015, 0x00000099, 0x00000096, 0x00000098, 0x000300f7, 0x0000009a, 0x00000000, + 0x000400fa, 0x00000099, 0x0000009b, 0x0000009c, 0x000200f8, 0x0000009b, 0x00050051, 0x0000000e, + 0x0000009d, 0x00000083, 0x00000000, 0x00050085, 0x0000000e, 0x0000009e, 0x0000009d, 0x0000001b, + 0x00050083, 0x0000000e, 0x0000009f, 0x0000009e, 0x00000014, 0x00050051, 0x0000000e, 0x000000a0, + 0x00000083, 0x00000001, 0x00050085, 0x0000000e, 0x000000a1, 0x000000a0, 0x0000001b, 0x00050083, + 0x0000000e, 0x000000a2, 0x00000014, 0x000000a1, 0x00050085, 0x0000000e, 0x000000a3, 0x0000009f, + 0x00000088, 0x00050088, 0x0000000e, 0x000000a4, 0x000000a3, 0x0000006f, 0x00050085, 0x0000000e, + 0x000000a5, 0x000000a2, 0x00000088, 0x00050088, 0x0000000e, 0x000000a6, 0x000000a5, 0x00000073, + 0x00060050, 0x00000036, 0x000000a7, 0x000000a4, 0x000000a6, 0x00000088, 0x00050083, 0x00000036, + 0x000000a8, 0x000000a7, 0x00000075, 0x000200f9, 0x0000009a, 0x000200f8, 0x0000009c, 0x00050051, + 0x0000000e, 0x000000a9, 0x0000007d, 0x00000000, 0x00050085, 0x0000000e, 0x000000aa, 0x000000a9, + 0x0000001b, 0x00050083, 0x0000000e, 0x000000ab, 0x000000aa, 0x00000014, 0x00050051, 0x0000000e, + 0x000000ac, 0x0000007d, 0x00000001, 0x00050085, 0x0000000e, 0x000000ad, 0x000000ac, 0x0000001b, + 0x00050083, 0x0000000e, 0x000000ae, 0x00000014, 0x000000ad, 0x00050085, 0x0000000e, 0x000000af, + 0x000000ab, 0x00000082, 0x00050088, 0x0000000e, 0x000000b0, 0x000000af, 0x0000006f, 0x00050085, + 0x0000000e, 0x000000b1, 0x000000ae, 0x00000082, 0x00050088, 0x0000000e, 0x000000b2, 0x000000b1, + 0x00000073, 0x00060050, 0x00000036, 0x000000b3, 0x000000b0, 0x000000b2, 0x00000082, 0x00050083, + 0x00000036, 0x000000b4, 0x00000075, 0x000000b3, 0x000200f9, 0x0000009a, 0x000200f8, 0x0000009a, + 0x000700f5, 0x00000036, 0x000000b5, 0x000000a8, 0x0000009b, 0x000000b4, 0x0000009c, 0x00050083, + 0x0000000e, 0x000000b6, 0x00000094, 0x00000049, 0x0006000c, 0x0000000e, 0x000000b7, 0x00000001, + 0x00000004, 0x000000b6, 0x00050083, 0x0000000e, 0x000000b8, 0x0000008e, 0x00000049, 0x0006000c, + 0x0000000e, 0x000000b9, 0x00000001, 0x00000004, 0x000000b8, 0x000500b8, 0x00000015, 0x000000ba, + 0x000000b7, 0x000000b9, 0x000300f7, 0x000000bb, 0x00000000, 0x000400fa, 0x000000ba, 0x000000bc, + 0x000000bd, 0x000200f8, 0x000000bc, 0x00050051, 0x0000000e, 0x000000be, 0x0000008f, 0x00000000, + 0x00050085, 0x0000000e, 0x000000bf, 0x000000be, 0x0000001b, 0x00050083, 0x0000000e, 0x000000c0, + 0x000000bf, 0x00000014, 0x00050051, 0x0000000e, 0x000000c1, 0x0000008f, 0x00000001, 0x00050085, + 0x0000000e, 0x000000c2, 0x000000c1, 0x0000001b, 0x00050083, 0x0000000e, 0x000000c3, 0x00000014, + 0x000000c2, 0x00050085, 0x0000000e, 0x000000c4, 0x000000c0, 0x00000094, 0x00050088, 0x0000000e, + 0x000000c5, 0x000000c4, 0x0000006f, 0x00050085, 0x0000000e, 0x000000c6, 0x000000c3, 0x00000094, + 0x00050088, 0x0000000e, 0x000000c7, 0x000000c6, 0x00000073, 0x00060050, 0x00000036, 0x000000c8, + 0x000000c5, 0x000000c7, 0x00000094, 0x00050083, 0x00000036, 0x000000c9, 0x000000c8, 0x00000075, + 0x000200f9, 0x000000bb, 0x000200f8, 0x000000bd, 0x00050051, 0x0000000e, 0x000000ca, 0x00000089, + 0x00000000, 0x00050085, 0x0000000e, 0x000000cb, 0x000000ca, 0x0000001b, 0x00050083, 0x0000000e, + 0x000000cc, 0x000000cb, 0x00000014, 0x00050051, 0x0000000e, 0x000000cd, 0x00000089, 0x00000001, + 0x00050085, 0x0000000e, 0x000000ce, 0x000000cd, 0x0000001b, 0x00050083, 0x0000000e, 0x000000cf, + 0x00000014, 0x000000ce, 0x00050085, 0x0000000e, 0x000000d0, 0x000000cc, 0x0000008e, 0x00050088, + 0x0000000e, 0x000000d1, 0x000000d0, 0x0000006f, 0x00050085, 0x0000000e, 0x000000d2, 0x000000cf, + 0x0000008e, 0x00050088, 0x0000000e, 0x000000d3, 0x000000d2, 0x00000073, 0x00060050, 0x00000036, + 0x000000d4, 0x000000d1, 0x000000d3, 0x0000008e, 0x00050083, 0x00000036, 0x000000d5, 0x00000075, + 0x000000d4, 0x000200f9, 0x000000bb, 0x000200f8, 0x000000bb, 0x000700f5, 0x00000036, 0x000000d6, + 0x000000c9, 0x000000bc, 0x000000d5, 0x000000bd, 0x0007000c, 0x00000036, 0x000000d7, 0x00000001, + 0x00000044, 0x000000d6, 0x000000b5, 0x0006000c, 0x00000036, 0x000000d8, 0x00000001, 0x00000045, + 0x000000d7, 0x0004007f, 0x00000036, 0x000000d9, 0x00000075, 0x00050094, 0x0000000e, 0x000000da, + 0x000000d8, 0x000000d9, 0x000500b8, 0x00000015, 0x000000db, 0x000000da, 0x00000013, 0x000300f7, + 0x000000dc, 0x00000000, 0x000400fa, 0x000000db, 0x000000dd, 0x000000de, 0x000200f8, 0x000000dd, + 0x0004007f, 0x00000036, 0x000000df, 0x000000d8, 0x000200f9, 0x000000dc, 0x000200f8, 0x000000de, + 0x000200f9, 0x000000dc, 0x000200f8, 0x000000dc, 0x000700f5, 0x00000036, 0x000000e0, 0x000000df, + 0x000000dd, 0x000000d8, 0x000000de, 0x0006000c, 0x00000036, 0x000000e1, 0x00000001, 0x00000045, + 0x00000075, 0x0004007f, 0x00000036, 0x000000e2, 0x000000e1, 0x00060041, 0x00000038, 0x000000e3, + 0x00000007, 0x00000011, 0x00000019, 0x0004003d, 0x0000000e, 0x000000e4, 0x000000e3, 0x00050085, + 0x0000000e, 0x000000e5, 0x000000e4, 0x00000073, 0x00050088, 0x0000000e, 0x000000e6, 0x000000e5, + 0x00000049, 0x00060041, 0x00000038, 0x000000e7, 0x00000007, 0x00000019, 0x00000010, 0x0004003d, + 0x0000000e, 0x000000e8, 0x000000e7, 0x00050085, 0x0000000e, 0x000000e9, 0x000000e6, 0x000000e8, + 0x00050085, 0x0000000e, 0x000000ea, 0x000000e9, 0x0000001a, 0x0008000c, 0x0000000e, 0x000000eb, + 0x00000001, 0x0000002b, 0x000000ea, 0x0000001b, 0x0000001c, 0x0007004f, 0x0000001e, 0x000000ec, + 0x00000041, 0x00000041, 0x00000000, 0x00000001, 0x00050094, 0x0000000e, 0x000000ed, 0x000000ec, + 0x0000002a, 0x0006000c, 0x0000000e, 0x000000ee, 0x00000001, 0x0000000a, 0x000000ed, 0x00050085, + 0x0000000e, 0x000000ef, 0x00000027, 0x000000ee, 0x0006000c, 0x0000000e, 0x000000f0, 0x00000001, + 0x0000000a, 0x000000ef, 0x00050081, 0x0000001e, 0x000000f1, 0x000000ec, 0x0000001f, 0x00050094, + 0x0000000e, 0x000000f2, 0x000000f1, 0x0000002a, 0x0006000c, 0x0000000e, 0x000000f3, 0x00000001, + 0x0000000a, 0x000000f2, 0x00050085, 0x0000000e, 0x000000f4, 0x00000027, 0x000000f3, 0x0006000c, + 0x0000000e, 0x000000f5, 0x00000001, 0x0000000a, 0x000000f4, 0x0007000c, 0x0000000e, 0x000000f6, + 0x00000001, 0x00000050, 0x000000e4, 0x00000020, 0x00050088, 0x0000000e, 0x000000f7, 0x00000014, + 0x000000f6, 0x000200f9, 0x000000f8, 0x000200f8, 0x000000f8, 0x000700f5, 0x0000000e, 0x000000f9, + 0x00000013, 0x000000dc, 0x000000fa, 0x000000fb, 0x000700f5, 0x0000000f, 0x000000fc, 0x00000019, + 0x000000dc, 0x000000fd, 0x000000fb, 0x000500b1, 0x00000015, 0x000000fe, 0x000000fc, 0x00000012, + 0x000400f6, 0x000000ff, 0x000000fb, 0x00000001, 0x000400fa, 0x000000fe, 0x00000100, 0x000000ff, + 0x000200f8, 0x00000100, 0x0004006f, 0x0000000e, 0x00000101, 0x000000fc, 0x00050081, 0x0000000e, + 0x00000102, 0x00000101, 0x000000f0, 0x00050085, 0x0000000e, 0x00000103, 0x00000102, 0x0000003b, + 0x0006000c, 0x0000000e, 0x00000104, 0x00000001, 0x0000000e, 0x00000103, 0x0006000c, 0x0000000e, + 0x00000105, 0x00000001, 0x0000000d, 0x00000103, 0x00050050, 0x0000001e, 0x00000106, 0x00000104, + 0x00000105, 0x00050085, 0x0000000e, 0x00000107, 0x00000104, 0x00000078, 0x00050088, 0x0000000e, + 0x00000108, 0x00000107, 0x0000006f, 0x0004007f, 0x0000000e, 0x00000109, 0x00000105, 0x00050085, + 0x0000000e, 0x0000010a, 0x00000109, 0x0000007b, 0x00050088, 0x0000000e, 0x0000010b, 0x0000010a, + 0x00000073, 0x00060050, 0x00000036, 0x0000010c, 0x00000108, 0x0000010b, 0x00000013, 0x0006000c, + 0x00000036, 0x0000010d, 0x00000001, 0x00000045, 0x0000010c, 0x0007000c, 0x00000036, 0x0000010e, + 0x00000001, 0x00000044, 0x0000010d, 0x000000e2, 0x0006000c, 0x00000036, 0x0000010f, 0x00000001, + 0x00000045, 0x0000010e, 0x00050094, 0x0000000e, 0x00000110, 0x0000010d, 0x000000e2, 0x0005008e, + 0x00000036, 0x00000111, 0x000000e2, 0x00000110, 0x00050083, 0x00000036, 0x00000112, 0x0000010d, + 0x00000111, 0x0006000c, 0x00000036, 0x00000113, 0x00000001, 0x00000045, 0x00000112, 0x00050094, + 0x0000000e, 0x00000114, 0x000000e0, 0x0000010f, 0x0005008e, 0x00000036, 0x00000115, 0x0000010f, + 0x00000114, 0x00050083, 0x00000036, 0x00000116, 0x000000e0, 0x00000115, 0x0006000c, 0x0000000e, + 0x00000117, 0x00000001, 0x00000042, 0x00000116, 0x000500b8, 0x00000015, 0x00000118, 0x00000117, + 0x00000020, 0x000300f7, 0x00000119, 0x00000000, 0x000400fa, 0x00000118, 0x0000011a, 0x00000119, + 0x000200f8, 0x0000011a, 0x00050081, 0x0000000e, 0x0000011b, 0x000000f9, 0x00000014, 0x000200f9, + 0x000000fb, 0x000200f8, 0x00000119, 0x00050094, 0x0000000e, 0x0000011c, 0x00000116, 0x000000e2, + 0x00050088, 0x0000000e, 0x0000011d, 0x0000011c, 0x00000117, 0x0008000c, 0x0000000e, 0x0000011e, + 0x00000001, 0x0000002b, 0x0000011d, 0x00000021, 0x00000014, 0x00050094, 0x0000000e, 0x0000011f, + 0x00000116, 0x00000113, 0x0006000c, 0x0000000e, 0x00000120, 0x00000001, 0x00000006, 0x0000011f, + 0x0004006e, 0x0000000f, 0x00000121, 0x00000120, 0x0004006f, 0x0000000e, 0x00000122, 0x00000121, + 0x0006000c, 0x0000000e, 0x00000123, 0x00000001, 0x00000011, 0x0000011e, 0x00050085, 0x0000000e, + 0x00000124, 0x00000122, 0x00000123, 0x0003003e, 0x00000040, 0x00000022, 0x000200f9, 0x00000125, + 0x000200f8, 0x00000125, 0x000700f5, 0x0000000f, 0x00000126, 0x00000019, 0x00000119, 0x00000127, + 0x00000128, 0x000500b1, 0x00000015, 0x00000129, 0x00000126, 0x00000011, 0x000400f6, 0x0000012a, + 0x00000128, 0x00000001, 0x000400fa, 0x00000129, 0x0000012b, 0x0000012a, 0x000200f8, 0x0000012b, + 0x000500aa, 0x00000015, 0x0000012c, 0x00000126, 0x00000019, 0x000600a9, 0x0000000e, 0x0000012d, + 0x0000012c, 0x00000021, 0x00000014, 0x000200f9, 0x0000012e, 0x000200f8, 0x0000012e, 0x000700f5, + 0x0000000f, 0x0000012f, 0x00000019, 0x0000012b, 0x00000130, 0x00000131, 0x000500b1, 0x00000015, + 0x00000132, 0x0000012f, 0x00000012, 0x000400f6, 0x00000133, 0x00000131, 0x00000002, 0x000400fa, + 0x00000132, 0x00000131, 0x00000133, 0x000200f8, 0x00000131, 0x0004006f, 0x0000000e, 0x00000134, + 0x0000012f, 0x00050081, 0x0000000e, 0x00000135, 0x00000134, 0x000000f5, 0x00050085, 0x0000000e, + 0x00000136, 0x00000135, 0x0000003e, 0x00050085, 0x0000000e, 0x00000137, 0x000000eb, 0x00000136, + 0x0006000c, 0x0000000e, 0x00000138, 0x00000001, 0x0000001f, 0x00000136, 0x00050085, 0x0000000e, + 0x00000139, 0x00000137, 0x00000138, 0x00050081, 0x0000000e, 0x0000013a, 0x00000139, 0x00000014, + 0x0005008e, 0x0000001e, 0x0000013b, 0x00000106, 0x0000012d, 0x0005008e, 0x0000001e, 0x0000013c, + 0x0000013b, 0x0000013a, 0x0004003d, 0x0000002b, 0x0000013d, 0x00000076, 0x0007004f, 0x0000001e, + 0x0000013e, 0x0000013d, 0x0000013d, 0x00000002, 0x00000003, 0x00050085, 0x0000001e, 0x0000013f, + 0x0000013c, 0x0000013e, 0x00050081, 0x0000001e, 0x00000140, 0x00000042, 0x0000013f, 0x0004003d, + 0x00000008, 0x00000141, 0x00000009, 0x0004003d, 0x0000000b, 0x00000142, 0x0000000c, 0x00050056, + 0x0000000d, 0x00000143, 0x00000141, 0x00000142, 0x00070058, 0x0000002b, 0x00000144, 0x00000143, + 0x00000140, 0x00000002, 0x00000013, 0x00050051, 0x0000000e, 0x00000145, 0x00000144, 0x00000000, + 0x00050051, 0x0000000e, 0x00000146, 0x00000140, 0x00000000, 0x00050085, 0x0000000e, 0x00000147, + 0x00000146, 0x0000001b, 0x00050083, 0x0000000e, 0x00000148, 0x00000147, 0x00000014, 0x00050051, + 0x0000000e, 0x00000149, 0x00000140, 0x00000001, 0x00050085, 0x0000000e, 0x0000014a, 0x00000149, + 0x0000001b, 0x00050083, 0x0000000e, 0x0000014b, 0x00000014, 0x0000014a, 0x00050085, 0x0000000e, + 0x0000014c, 0x00000148, 0x00000145, 0x00050088, 0x0000000e, 0x0000014d, 0x0000014c, 0x0000006f, + 0x00050085, 0x0000000e, 0x0000014e, 0x0000014b, 0x00000145, 0x00050088, 0x0000000e, 0x0000014f, + 0x0000014e, 0x00000073, 0x00060050, 0x00000036, 0x00000150, 0x0000014d, 0x0000014f, 0x00000145, + 0x00050083, 0x00000036, 0x00000151, 0x00000150, 0x00000075, 0x00050094, 0x0000000e, 0x00000152, + 0x00000151, 0x00000151, 0x0007000c, 0x0000000e, 0x00000153, 0x00000001, 0x00000050, 0x00000152, + 0x00000023, 0x0006000c, 0x0000000e, 0x00000154, 0x00000001, 0x00000020, 0x00000153, 0x00050094, + 0x0000000e, 0x00000155, 0x00000151, 0x000000e2, 0x00050085, 0x0000000e, 0x00000156, 0x00000155, + 0x00000154, 0x00050085, 0x0000000e, 0x00000157, 0x00000153, 0x00000154, 0x00050085, 0x0000000e, + 0x00000158, 0x00000157, 0x000000f7, 0x00050085, 0x0000000e, 0x00000159, 0x00000158, 0x00000024, + 0x00050083, 0x0000000e, 0x0000015a, 0x00000159, 0x00000025, 0x0008000c, 0x0000000e, 0x0000015b, + 0x00000001, 0x0000002b, 0x0000015a, 0x00000013, 0x00000014, 0x0008000c, 0x0000000e, 0x0000015c, + 0x00000001, 0x0000002e, 0x00000156, 0x00000021, 0x0000015b, 0x0004007c, 0x00000039, 0x0000015d, + 0x00000126, 0x00050041, 0x00000034, 0x0000015e, 0x00000040, 0x0000015d, 0x0004003d, 0x0000000e, + 0x0000015f, 0x0000015e, 0x0007000c, 0x0000000e, 0x00000160, 0x00000001, 0x00000050, 0x0000015f, + 0x0000015c, 0x0003003e, 0x0000015e, 0x00000160, 0x00050080, 0x0000000f, 0x00000130, 0x0000012f, + 0x00000010, 0x000200f9, 0x0000012e, 0x000200f8, 0x00000133, 0x000200f9, 0x00000128, 0x000200f8, + 0x00000128, 0x00050080, 0x0000000f, 0x00000127, 0x00000126, 0x00000010, 0x000200f9, 0x00000125, + 0x000200f8, 0x0000012a, 0x00050041, 0x00000034, 0x00000161, 0x00000040, 0x00000019, 0x0004003d, + 0x0000000e, 0x00000162, 0x00000161, 0x0008000c, 0x0000000e, 0x00000163, 0x00000001, 0x0000002b, + 0x00000162, 0x00000021, 0x00000014, 0x0006000c, 0x0000000e, 0x00000164, 0x00000001, 0x00000011, + 0x00000163, 0x0004007f, 0x0000000e, 0x00000165, 0x00000164, 0x00050083, 0x0000000e, 0x00000166, + 0x00000165, 0x00000124, 0x0007000c, 0x0000000e, 0x00000167, 0x00000001, 0x00000050, 0x00000166, + 0x0000003c, 0x00050081, 0x0000000e, 0x00000168, 0x00000124, 0x00000167, 0x00050041, 0x00000034, + 0x00000169, 0x00000040, 0x00000010, 0x0004003d, 0x0000000e, 0x0000016a, 0x00000169, 0x0008000c, + 0x0000000e, 0x0000016b, 0x00000001, 0x0000002b, 0x0000016a, 0x00000021, 0x00000014, 0x0006000c, + 0x0000000e, 0x0000016c, 0x00000001, 0x00000011, 0x0000016b, 0x00050083, 0x0000000e, 0x0000016d, + 0x0000016c, 0x00000124, 0x0007000c, 0x0000000e, 0x0000016e, 0x00000001, 0x0000004f, 0x0000016d, + 0x0000003d, 0x00050081, 0x0000000e, 0x0000016f, 0x00000124, 0x0000016e, 0x00050085, 0x0000000e, + 0x00000170, 0x0000001b, 0x00000168, 0x00050083, 0x0000000e, 0x00000171, 0x00000170, 0x00000124, + 0x0006000c, 0x0000000e, 0x00000172, 0x00000001, 0x0000000e, 0x00000171, 0x00050083, 0x0000000e, + 0x00000173, 0x0000011e, 0x00000172, 0x0006000c, 0x0000000e, 0x00000174, 0x00000001, 0x0000000d, + 0x00000124, 0x00050085, 0x0000000e, 0x00000175, 0x00000170, 0x00000174, 0x00050081, 0x0000000e, + 0x00000176, 0x00000173, 0x00000175, 0x00050085, 0x0000000e, 0x00000177, 0x0000001b, 0x0000016f, + 0x00050083, 0x0000000e, 0x00000178, 0x00000177, 0x00000124, 0x0006000c, 0x0000000e, 0x00000179, + 0x00000001, 0x0000000e, 0x00000178, 0x00050083, 0x0000000e, 0x0000017a, 0x0000011e, 0x00000179, + 0x00050085, 0x0000000e, 0x0000017b, 0x00000177, 0x00000174, 0x00050081, 0x0000000e, 0x0000017c, + 0x0000017a, 0x0000017b, 0x00050081, 0x0000000e, 0x0000017d, 0x00000176, 0x0000017c, 0x00050085, + 0x0000000e, 0x0000017e, 0x00000026, 0x0000017d, 0x00050085, 0x0000000e, 0x0000017f, 0x00000117, + 0x0000017e, 0x00050081, 0x0000000e, 0x00000180, 0x000000f9, 0x0000017f, 0x000200f9, 0x000000fb, + 0x000200f8, 0x000000fb, 0x000700f5, 0x0000000e, 0x000000fa, 0x0000011b, 0x0000011a, 0x00000180, + 0x0000012a, 0x00050080, 0x0000000f, 0x000000fd, 0x000000fc, 0x00000010, 0x000200f9, 0x000000f8, + 0x000200f8, 0x000000ff, 0x00050085, 0x0000000e, 0x00000181, 0x000000f9, 0x0000003e, 0x0008000c, + 0x0000000e, 0x00000182, 0x00000001, 0x0000002b, 0x00000181, 0x00000013, 0x00000014, 0x00060041, + 0x00000038, 0x00000183, 0x00000007, 0x00000011, 0x00000010, 0x0004003d, 0x0000000e, 0x00000184, + 0x00000183, 0x00050085, 0x0000000e, 0x00000185, 0x00000184, 0x0000001a, 0x0007000c, 0x0000000e, + 0x00000186, 0x00000001, 0x0000001a, 0x00000182, 0x00000185, 0x0008000c, 0x0000000e, 0x00000187, + 0x00000001, 0x0000002e, 0x00000186, 0x00000014, 0x0000005a, 0x0008000c, 0x0000000e, 0x00000188, + 0x00000001, 0x0000002e, 0x00000187, 0x00000014, 0x00000050, 0x000200f9, 0x00000043, 0x000200f8, + 0x00000043, 0x000700f5, 0x0000000e, 0x00000189, 0x00000014, 0x00000066, 0x00000188, 0x000000ff, + 0x0003003e, 0x00000005, 0x00000189, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_blur (5368 bytes) +static const uint32_t k_ssao_ps_blur[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x000000ed, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0007000f, 0x00000004, 0x00000002, 0x625f7370, 0x0072756c, 0x00000003, 0x00000004, 0x00030010, + 0x00000002, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00040005, 0x00000005, 0x65707974, + 0x0000432e, 0x00050006, 0x00000005, 0x00000000, 0x657a6973, 0x00000000, 0x00050006, 0x00000005, + 0x00000001, 0x6a6f7270, 0x00000000, 0x00040006, 0x00000005, 0x00000002, 0x00003070, 0x00040006, + 0x00000005, 0x00000003, 0x00003170, 0x00030005, 0x00000006, 0x00000043, 0x00060005, 0x00000007, + 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000008, 0x30786574, 0x00000000, + 0x00040005, 0x00000009, 0x31786574, 0x00000000, 0x00060005, 0x0000000a, 0x65707974, 0x6d61732e, + 0x72656c70, 0x00000000, 0x00050005, 0x0000000b, 0x5f706d73, 0x6e696f70, 0x00000074, 0x00070005, + 0x00000003, 0x762e6e69, 0x542e7261, 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, 0x00000004, + 0x2e74756f, 0x2e726176, 0x545f5653, 0x65677261, 0x00000074, 0x00040005, 0x00000002, 0x625f7370, + 0x0072756c, 0x00070005, 0x0000000c, 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, 0x00006567, + 0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00040047, 0x00000004, 0x0000001e, 0x00000000, + 0x00040047, 0x00000006, 0x00000022, 0x00000000, 0x00040047, 0x00000006, 0x00000021, 0x00000000, + 0x00040047, 0x00000008, 0x00000022, 0x00000001, 0x00040047, 0x00000008, 0x00000021, 0x00000000, + 0x00040047, 0x00000009, 0x00000022, 0x00000002, 0x00040047, 0x00000009, 0x00000021, 0x00000000, + 0x00040047, 0x0000000b, 0x00000022, 0x00000000, 0x00040047, 0x0000000b, 0x00000021, 0x00000001, + 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000005, 0x00000001, + 0x00000023, 0x00000010, 0x00050048, 0x00000005, 0x00000002, 0x00000023, 0x00000020, 0x00050048, + 0x00000005, 0x00000003, 0x00000023, 0x00000030, 0x00030047, 0x00000005, 0x00000002, 0x00030016, + 0x0000000d, 0x00000020, 0x0004002b, 0x0000000d, 0x0000000e, 0x3f800000, 0x0004002b, 0x0000000d, + 0x0000000f, 0x3f61eb85, 0x0004002b, 0x0000000d, 0x00000010, 0x3f1b4396, 0x0004002b, 0x0000000d, + 0x00000011, 0x3ea63f14, 0x0004002b, 0x0000000d, 0x00000012, 0x3e0a8c15, 0x00040015, 0x00000013, + 0x00000020, 0x00000001, 0x0004002b, 0x0000000d, 0x00000014, 0x00000000, 0x0004002b, 0x00000013, + 0x00000015, 0x00000000, 0x0004002b, 0x00000013, 0x00000016, 0x00000003, 0x0004002b, 0x0000000d, + 0x00000017, 0x3d4ccccd, 0x00040017, 0x00000018, 0x0000000d, 0x00000004, 0x0006001e, 0x00000005, + 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00040020, 0x00000019, 0x00000002, 0x00000005, + 0x00090019, 0x00000007, 0x0000000d, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x0000001a, 0x00000000, 0x00000007, 0x0002001a, 0x0000000a, 0x00040020, + 0x0000001b, 0x00000000, 0x0000000a, 0x00040017, 0x0000001c, 0x0000000d, 0x00000002, 0x00040020, + 0x0000001d, 0x00000001, 0x0000001c, 0x00040020, 0x0000001e, 0x00000003, 0x0000000d, 0x00020013, + 0x0000001f, 0x00030021, 0x00000020, 0x0000001f, 0x0003001b, 0x0000000c, 0x00000007, 0x00040020, + 0x00000021, 0x00000002, 0x00000018, 0x0004003b, 0x00000019, 0x00000006, 0x00000002, 0x0004003b, + 0x0000001a, 0x00000008, 0x00000000, 0x0004003b, 0x0000001a, 0x00000009, 0x00000000, 0x0004003b, + 0x0000001b, 0x0000000b, 0x00000000, 0x0004003b, 0x0000001d, 0x00000003, 0x00000001, 0x0004003b, + 0x0000001e, 0x00000004, 0x00000003, 0x0004002b, 0x0000000d, 0x00000022, 0xbf800000, 0x0004002b, + 0x0000000d, 0x00000023, 0x40000000, 0x0004002b, 0x0000000d, 0x00000024, 0x40400000, 0x0004002b, + 0x0000000d, 0x00000025, 0x40800000, 0x00050036, 0x0000001f, 0x00000002, 0x00000000, 0x00000020, + 0x000200f8, 0x00000026, 0x0004003d, 0x0000001c, 0x00000027, 0x00000003, 0x0004003d, 0x00000007, + 0x00000028, 0x00000009, 0x0004003d, 0x0000000a, 0x00000029, 0x0000000b, 0x00050056, 0x0000000c, + 0x0000002a, 0x00000028, 0x00000029, 0x00070058, 0x00000018, 0x0000002b, 0x0000002a, 0x00000027, + 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x0000002c, 0x0000002b, 0x00000000, 0x0004003d, + 0x00000007, 0x0000002d, 0x00000008, 0x0004003d, 0x0000000a, 0x0000002e, 0x0000000b, 0x00050056, + 0x0000000c, 0x0000002f, 0x0000002d, 0x0000002e, 0x00070058, 0x00000018, 0x00000030, 0x0000002f, + 0x00000027, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x00000031, 0x00000030, 0x00000000, + 0x00050041, 0x00000021, 0x00000032, 0x00000006, 0x00000016, 0x0004003d, 0x00000018, 0x00000033, + 0x00000032, 0x0007004f, 0x0000001c, 0x00000034, 0x00000033, 0x00000033, 0x00000000, 0x00000001, + 0x0005008e, 0x0000001c, 0x00000035, 0x00000034, 0x00000022, 0x0005008e, 0x0000001c, 0x00000036, + 0x00000035, 0x0000000e, 0x00050041, 0x00000021, 0x00000037, 0x00000006, 0x00000015, 0x0004003d, + 0x00000018, 0x00000038, 0x00000037, 0x0007004f, 0x0000001c, 0x00000039, 0x00000038, 0x00000038, + 0x00000002, 0x00000003, 0x00050085, 0x0000001c, 0x0000003a, 0x00000036, 0x00000039, 0x00050081, + 0x0000001c, 0x0000003b, 0x00000027, 0x0000003a, 0x0004003d, 0x00000007, 0x0000003c, 0x00000009, + 0x0004003d, 0x0000000a, 0x0000003d, 0x0000000b, 0x00050056, 0x0000000c, 0x0000003e, 0x0000003c, + 0x0000003d, 0x00070058, 0x00000018, 0x0000003f, 0x0000003e, 0x0000003b, 0x00000002, 0x00000014, + 0x00050051, 0x0000000d, 0x00000040, 0x0000003f, 0x00000000, 0x00050083, 0x0000000d, 0x00000041, + 0x00000040, 0x0000002c, 0x0006000c, 0x0000000d, 0x00000042, 0x00000001, 0x00000004, 0x00000041, + 0x00050085, 0x0000000d, 0x00000043, 0x0000002c, 0x00000017, 0x00050081, 0x0000000d, 0x00000044, + 0x00000043, 0x00000017, 0x00050088, 0x0000000d, 0x00000045, 0x00000042, 0x00000044, 0x00050083, + 0x0000000d, 0x00000046, 0x0000000e, 0x00000045, 0x0008000c, 0x0000000d, 0x00000047, 0x00000001, + 0x0000002b, 0x00000046, 0x00000014, 0x0000000e, 0x00050085, 0x0000000d, 0x00000048, 0x0000000f, + 0x00000047, 0x0004003d, 0x00000007, 0x00000049, 0x00000008, 0x0004003d, 0x0000000a, 0x0000004a, + 0x0000000b, 0x00050056, 0x0000000c, 0x0000004b, 0x00000049, 0x0000004a, 0x00070058, 0x00000018, + 0x0000004c, 0x0000004b, 0x0000003b, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x0000004d, + 0x0000004c, 0x00000000, 0x00050085, 0x0000000d, 0x0000004e, 0x0000004d, 0x00000048, 0x00050081, + 0x0000000d, 0x0000004f, 0x00000031, 0x0000004e, 0x00050081, 0x0000000d, 0x00000050, 0x0000000e, + 0x00000048, 0x0005008e, 0x0000001c, 0x00000051, 0x00000034, 0x0000000e, 0x0005008e, 0x0000001c, + 0x00000052, 0x00000051, 0x0000000e, 0x00050085, 0x0000001c, 0x00000053, 0x00000052, 0x00000039, + 0x00050081, 0x0000001c, 0x00000054, 0x00000027, 0x00000053, 0x0004003d, 0x00000007, 0x00000055, + 0x00000009, 0x0004003d, 0x0000000a, 0x00000056, 0x0000000b, 0x00050056, 0x0000000c, 0x00000057, + 0x00000055, 0x00000056, 0x00070058, 0x00000018, 0x00000058, 0x00000057, 0x00000054, 0x00000002, + 0x00000014, 0x00050051, 0x0000000d, 0x00000059, 0x00000058, 0x00000000, 0x00050083, 0x0000000d, + 0x0000005a, 0x00000059, 0x0000002c, 0x0006000c, 0x0000000d, 0x0000005b, 0x00000001, 0x00000004, + 0x0000005a, 0x00050088, 0x0000000d, 0x0000005c, 0x0000005b, 0x00000044, 0x00050083, 0x0000000d, + 0x0000005d, 0x0000000e, 0x0000005c, 0x0008000c, 0x0000000d, 0x0000005e, 0x00000001, 0x0000002b, + 0x0000005d, 0x00000014, 0x0000000e, 0x00050085, 0x0000000d, 0x0000005f, 0x0000000f, 0x0000005e, + 0x0004003d, 0x00000007, 0x00000060, 0x00000008, 0x0004003d, 0x0000000a, 0x00000061, 0x0000000b, + 0x00050056, 0x0000000c, 0x00000062, 0x00000060, 0x00000061, 0x00070058, 0x00000018, 0x00000063, + 0x00000062, 0x00000054, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x00000064, 0x00000063, + 0x00000000, 0x00050085, 0x0000000d, 0x00000065, 0x00000064, 0x0000005f, 0x00050081, 0x0000000d, + 0x00000066, 0x0000004f, 0x00000065, 0x00050081, 0x0000000d, 0x00000067, 0x00000050, 0x0000005f, + 0x0005008e, 0x0000001c, 0x00000068, 0x00000035, 0x00000023, 0x00050085, 0x0000001c, 0x00000069, + 0x00000068, 0x00000039, 0x00050081, 0x0000001c, 0x0000006a, 0x00000027, 0x00000069, 0x0004003d, + 0x00000007, 0x0000006b, 0x00000009, 0x0004003d, 0x0000000a, 0x0000006c, 0x0000000b, 0x00050056, + 0x0000000c, 0x0000006d, 0x0000006b, 0x0000006c, 0x00070058, 0x00000018, 0x0000006e, 0x0000006d, + 0x0000006a, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x0000006f, 0x0000006e, 0x00000000, + 0x00050083, 0x0000000d, 0x00000070, 0x0000006f, 0x0000002c, 0x0006000c, 0x0000000d, 0x00000071, + 0x00000001, 0x00000004, 0x00000070, 0x00050088, 0x0000000d, 0x00000072, 0x00000071, 0x00000044, + 0x00050083, 0x0000000d, 0x00000073, 0x0000000e, 0x00000072, 0x0008000c, 0x0000000d, 0x00000074, + 0x00000001, 0x0000002b, 0x00000073, 0x00000014, 0x0000000e, 0x00050085, 0x0000000d, 0x00000075, + 0x00000010, 0x00000074, 0x0004003d, 0x00000007, 0x00000076, 0x00000008, 0x0004003d, 0x0000000a, + 0x00000077, 0x0000000b, 0x00050056, 0x0000000c, 0x00000078, 0x00000076, 0x00000077, 0x00070058, + 0x00000018, 0x00000079, 0x00000078, 0x0000006a, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, + 0x0000007a, 0x00000079, 0x00000000, 0x00050085, 0x0000000d, 0x0000007b, 0x0000007a, 0x00000075, + 0x00050081, 0x0000000d, 0x0000007c, 0x00000066, 0x0000007b, 0x00050081, 0x0000000d, 0x0000007d, + 0x00000067, 0x00000075, 0x0005008e, 0x0000001c, 0x0000007e, 0x00000051, 0x00000023, 0x00050085, + 0x0000001c, 0x0000007f, 0x0000007e, 0x00000039, 0x00050081, 0x0000001c, 0x00000080, 0x00000027, + 0x0000007f, 0x0004003d, 0x00000007, 0x00000081, 0x00000009, 0x0004003d, 0x0000000a, 0x00000082, + 0x0000000b, 0x00050056, 0x0000000c, 0x00000083, 0x00000081, 0x00000082, 0x00070058, 0x00000018, + 0x00000084, 0x00000083, 0x00000080, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x00000085, + 0x00000084, 0x00000000, 0x00050083, 0x0000000d, 0x00000086, 0x00000085, 0x0000002c, 0x0006000c, + 0x0000000d, 0x00000087, 0x00000001, 0x00000004, 0x00000086, 0x00050088, 0x0000000d, 0x00000088, + 0x00000087, 0x00000044, 0x00050083, 0x0000000d, 0x00000089, 0x0000000e, 0x00000088, 0x0008000c, + 0x0000000d, 0x0000008a, 0x00000001, 0x0000002b, 0x00000089, 0x00000014, 0x0000000e, 0x00050085, + 0x0000000d, 0x0000008b, 0x00000010, 0x0000008a, 0x0004003d, 0x00000007, 0x0000008c, 0x00000008, + 0x0004003d, 0x0000000a, 0x0000008d, 0x0000000b, 0x00050056, 0x0000000c, 0x0000008e, 0x0000008c, + 0x0000008d, 0x00070058, 0x00000018, 0x0000008f, 0x0000008e, 0x00000080, 0x00000002, 0x00000014, + 0x00050051, 0x0000000d, 0x00000090, 0x0000008f, 0x00000000, 0x00050085, 0x0000000d, 0x00000091, + 0x00000090, 0x0000008b, 0x00050081, 0x0000000d, 0x00000092, 0x0000007c, 0x00000091, 0x00050081, + 0x0000000d, 0x00000093, 0x0000007d, 0x0000008b, 0x0005008e, 0x0000001c, 0x00000094, 0x00000035, + 0x00000024, 0x00050085, 0x0000001c, 0x00000095, 0x00000094, 0x00000039, 0x00050081, 0x0000001c, + 0x00000096, 0x00000027, 0x00000095, 0x0004003d, 0x00000007, 0x00000097, 0x00000009, 0x0004003d, + 0x0000000a, 0x00000098, 0x0000000b, 0x00050056, 0x0000000c, 0x00000099, 0x00000097, 0x00000098, + 0x00070058, 0x00000018, 0x0000009a, 0x00000099, 0x00000096, 0x00000002, 0x00000014, 0x00050051, + 0x0000000d, 0x0000009b, 0x0000009a, 0x00000000, 0x00050083, 0x0000000d, 0x0000009c, 0x0000009b, + 0x0000002c, 0x0006000c, 0x0000000d, 0x0000009d, 0x00000001, 0x00000004, 0x0000009c, 0x00050088, + 0x0000000d, 0x0000009e, 0x0000009d, 0x00000044, 0x00050083, 0x0000000d, 0x0000009f, 0x0000000e, + 0x0000009e, 0x0008000c, 0x0000000d, 0x000000a0, 0x00000001, 0x0000002b, 0x0000009f, 0x00000014, + 0x0000000e, 0x00050085, 0x0000000d, 0x000000a1, 0x00000011, 0x000000a0, 0x0004003d, 0x00000007, + 0x000000a2, 0x00000008, 0x0004003d, 0x0000000a, 0x000000a3, 0x0000000b, 0x00050056, 0x0000000c, + 0x000000a4, 0x000000a2, 0x000000a3, 0x00070058, 0x00000018, 0x000000a5, 0x000000a4, 0x00000096, + 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x000000a6, 0x000000a5, 0x00000000, 0x00050085, + 0x0000000d, 0x000000a7, 0x000000a6, 0x000000a1, 0x00050081, 0x0000000d, 0x000000a8, 0x00000092, + 0x000000a7, 0x00050081, 0x0000000d, 0x000000a9, 0x00000093, 0x000000a1, 0x0005008e, 0x0000001c, + 0x000000aa, 0x00000051, 0x00000024, 0x00050085, 0x0000001c, 0x000000ab, 0x000000aa, 0x00000039, + 0x00050081, 0x0000001c, 0x000000ac, 0x00000027, 0x000000ab, 0x0004003d, 0x00000007, 0x000000ad, + 0x00000009, 0x0004003d, 0x0000000a, 0x000000ae, 0x0000000b, 0x00050056, 0x0000000c, 0x000000af, + 0x000000ad, 0x000000ae, 0x00070058, 0x00000018, 0x000000b0, 0x000000af, 0x000000ac, 0x00000002, + 0x00000014, 0x00050051, 0x0000000d, 0x000000b1, 0x000000b0, 0x00000000, 0x00050083, 0x0000000d, + 0x000000b2, 0x000000b1, 0x0000002c, 0x0006000c, 0x0000000d, 0x000000b3, 0x00000001, 0x00000004, + 0x000000b2, 0x00050088, 0x0000000d, 0x000000b4, 0x000000b3, 0x00000044, 0x00050083, 0x0000000d, + 0x000000b5, 0x0000000e, 0x000000b4, 0x0008000c, 0x0000000d, 0x000000b6, 0x00000001, 0x0000002b, + 0x000000b5, 0x00000014, 0x0000000e, 0x00050085, 0x0000000d, 0x000000b7, 0x00000011, 0x000000b6, + 0x0004003d, 0x00000007, 0x000000b8, 0x00000008, 0x0004003d, 0x0000000a, 0x000000b9, 0x0000000b, + 0x00050056, 0x0000000c, 0x000000ba, 0x000000b8, 0x000000b9, 0x00070058, 0x00000018, 0x000000bb, + 0x000000ba, 0x000000ac, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x000000bc, 0x000000bb, + 0x00000000, 0x00050085, 0x0000000d, 0x000000bd, 0x000000bc, 0x000000b7, 0x00050081, 0x0000000d, + 0x000000be, 0x000000a8, 0x000000bd, 0x00050081, 0x0000000d, 0x000000bf, 0x000000a9, 0x000000b7, + 0x0005008e, 0x0000001c, 0x000000c0, 0x00000035, 0x00000025, 0x00050085, 0x0000001c, 0x000000c1, + 0x000000c0, 0x00000039, 0x00050081, 0x0000001c, 0x000000c2, 0x00000027, 0x000000c1, 0x0004003d, + 0x00000007, 0x000000c3, 0x00000009, 0x0004003d, 0x0000000a, 0x000000c4, 0x0000000b, 0x00050056, + 0x0000000c, 0x000000c5, 0x000000c3, 0x000000c4, 0x00070058, 0x00000018, 0x000000c6, 0x000000c5, + 0x000000c2, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x000000c7, 0x000000c6, 0x00000000, + 0x00050083, 0x0000000d, 0x000000c8, 0x000000c7, 0x0000002c, 0x0006000c, 0x0000000d, 0x000000c9, + 0x00000001, 0x00000004, 0x000000c8, 0x00050088, 0x0000000d, 0x000000ca, 0x000000c9, 0x00000044, + 0x00050083, 0x0000000d, 0x000000cb, 0x0000000e, 0x000000ca, 0x0008000c, 0x0000000d, 0x000000cc, + 0x00000001, 0x0000002b, 0x000000cb, 0x00000014, 0x0000000e, 0x00050085, 0x0000000d, 0x000000cd, + 0x00000012, 0x000000cc, 0x0004003d, 0x00000007, 0x000000ce, 0x00000008, 0x0004003d, 0x0000000a, + 0x000000cf, 0x0000000b, 0x00050056, 0x0000000c, 0x000000d0, 0x000000ce, 0x000000cf, 0x00070058, + 0x00000018, 0x000000d1, 0x000000d0, 0x000000c2, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, + 0x000000d2, 0x000000d1, 0x00000000, 0x00050085, 0x0000000d, 0x000000d3, 0x000000d2, 0x000000cd, + 0x00050081, 0x0000000d, 0x000000d4, 0x000000be, 0x000000d3, 0x00050081, 0x0000000d, 0x000000d5, + 0x000000bf, 0x000000cd, 0x0005008e, 0x0000001c, 0x000000d6, 0x00000051, 0x00000025, 0x00050085, + 0x0000001c, 0x000000d7, 0x000000d6, 0x00000039, 0x00050081, 0x0000001c, 0x000000d8, 0x00000027, + 0x000000d7, 0x0004003d, 0x00000007, 0x000000d9, 0x00000009, 0x0004003d, 0x0000000a, 0x000000da, + 0x0000000b, 0x00050056, 0x0000000c, 0x000000db, 0x000000d9, 0x000000da, 0x00070058, 0x00000018, + 0x000000dc, 0x000000db, 0x000000d8, 0x00000002, 0x00000014, 0x00050051, 0x0000000d, 0x000000dd, + 0x000000dc, 0x00000000, 0x00050083, 0x0000000d, 0x000000de, 0x000000dd, 0x0000002c, 0x0006000c, + 0x0000000d, 0x000000df, 0x00000001, 0x00000004, 0x000000de, 0x00050088, 0x0000000d, 0x000000e0, + 0x000000df, 0x00000044, 0x00050083, 0x0000000d, 0x000000e1, 0x0000000e, 0x000000e0, 0x0008000c, + 0x0000000d, 0x000000e2, 0x00000001, 0x0000002b, 0x000000e1, 0x00000014, 0x0000000e, 0x00050085, + 0x0000000d, 0x000000e3, 0x00000012, 0x000000e2, 0x0004003d, 0x00000007, 0x000000e4, 0x00000008, + 0x0004003d, 0x0000000a, 0x000000e5, 0x0000000b, 0x00050056, 0x0000000c, 0x000000e6, 0x000000e4, + 0x000000e5, 0x00070058, 0x00000018, 0x000000e7, 0x000000e6, 0x000000d8, 0x00000002, 0x00000014, + 0x00050051, 0x0000000d, 0x000000e8, 0x000000e7, 0x00000000, 0x00050085, 0x0000000d, 0x000000e9, + 0x000000e8, 0x000000e3, 0x00050081, 0x0000000d, 0x000000ea, 0x000000d4, 0x000000e9, 0x00050081, + 0x0000000d, 0x000000eb, 0x000000d5, 0x000000e3, 0x00050088, 0x0000000d, 0x000000ec, 0x000000ea, + 0x000000eb, 0x0003003e, 0x00000004, 0x000000ec, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_luma (920 bytes) +static const uint32_t k_ssao_ps_luma[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x00000020, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, + 0x00000000, 0x00000001, 0x0007000f, 0x00000004, 0x00000001, 0x6c5f7370, 0x00616d75, 0x00000002, + 0x00000003, 0x00030010, 0x00000001, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00060005, + 0x00000004, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000005, 0x30786574, + 0x00000063, 0x00060005, 0x00000006, 0x65707974, 0x6d61732e, 0x72656c70, 0x00000000, 0x00050005, + 0x00000007, 0x5f706d73, 0x656e696c, 0x00007261, 0x00070005, 0x00000002, 0x762e6e69, 0x542e7261, + 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, 0x00000003, 0x2e74756f, 0x2e726176, 0x545f5653, + 0x65677261, 0x00000074, 0x00040005, 0x00000001, 0x6c5f7370, 0x00616d75, 0x00070005, 0x00000008, + 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, 0x00006567, 0x00040047, 0x00000002, 0x0000001e, + 0x00000000, 0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00040047, 0x00000005, 0x00000022, + 0x00000001, 0x00040047, 0x00000005, 0x00000021, 0x00000000, 0x00040047, 0x00000007, 0x00000022, + 0x00000000, 0x00040047, 0x00000007, 0x00000021, 0x00000002, 0x00030016, 0x00000009, 0x00000020, + 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x0004002b, 0x00000009, 0x0000000b, 0x3e991687, + 0x0004002b, 0x00000009, 0x0000000c, 0x3f1645a2, 0x0004002b, 0x00000009, 0x0000000d, 0x3de978d5, + 0x00040017, 0x0000000e, 0x00000009, 0x00000003, 0x0006002c, 0x0000000e, 0x0000000f, 0x0000000b, + 0x0000000c, 0x0000000d, 0x00040017, 0x00000010, 0x00000009, 0x00000004, 0x00090019, 0x00000004, + 0x00000009, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, + 0x00000011, 0x00000000, 0x00000004, 0x0002001a, 0x00000006, 0x00040020, 0x00000012, 0x00000000, + 0x00000006, 0x00040017, 0x00000013, 0x00000009, 0x00000002, 0x00040020, 0x00000014, 0x00000001, + 0x00000013, 0x00040020, 0x00000015, 0x00000003, 0x00000009, 0x00020013, 0x00000016, 0x00030021, + 0x00000017, 0x00000016, 0x0003001b, 0x00000008, 0x00000004, 0x0004003b, 0x00000011, 0x00000005, + 0x00000000, 0x0004003b, 0x00000012, 0x00000007, 0x00000000, 0x0004003b, 0x00000014, 0x00000002, + 0x00000001, 0x0004003b, 0x00000015, 0x00000003, 0x00000003, 0x00050036, 0x00000016, 0x00000001, + 0x00000000, 0x00000017, 0x000200f8, 0x00000018, 0x0004003d, 0x00000013, 0x00000019, 0x00000002, + 0x0004003d, 0x00000004, 0x0000001a, 0x00000005, 0x0004003d, 0x00000006, 0x0000001b, 0x00000007, + 0x00050056, 0x00000008, 0x0000001c, 0x0000001a, 0x0000001b, 0x00070058, 0x00000010, 0x0000001d, + 0x0000001c, 0x00000019, 0x00000002, 0x0000000a, 0x0008004f, 0x0000000e, 0x0000001e, 0x0000001d, + 0x0000001d, 0x00000000, 0x00000001, 0x00000002, 0x00050094, 0x00000009, 0x0000001f, 0x0000001e, + 0x0000000f, 0x0003003e, 0x00000003, 0x0000001f, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_composite (844 bytes) +static const uint32_t k_ssao_ps_composite[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x0000001b, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, + 0x00000000, 0x00000001, 0x0009000f, 0x00000004, 0x00000001, 0x635f7370, 0x6f706d6f, 0x65746973, + 0x00000000, 0x00000002, 0x00000003, 0x00030010, 0x00000001, 0x00000007, 0x00030003, 0x00000005, + 0x00000258, 0x00060005, 0x00000004, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, + 0x00000005, 0x30786574, 0x00000000, 0x00060005, 0x00000006, 0x65707974, 0x6d61732e, 0x72656c70, + 0x00000000, 0x00050005, 0x00000007, 0x5f706d73, 0x656e696c, 0x00007261, 0x00070005, 0x00000002, + 0x762e6e69, 0x542e7261, 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, 0x00000003, 0x2e74756f, + 0x2e726176, 0x545f5653, 0x65677261, 0x00000074, 0x00060005, 0x00000001, 0x635f7370, 0x6f706d6f, + 0x65746973, 0x00000000, 0x00070005, 0x00000008, 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, + 0x00006567, 0x00040047, 0x00000002, 0x0000001e, 0x00000000, 0x00040047, 0x00000003, 0x0000001e, + 0x00000000, 0x00040047, 0x00000005, 0x00000022, 0x00000001, 0x00040047, 0x00000005, 0x00000021, + 0x00000000, 0x00040047, 0x00000007, 0x00000022, 0x00000000, 0x00040047, 0x00000007, 0x00000021, + 0x00000002, 0x00030016, 0x00000009, 0x00000020, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, + 0x00040017, 0x0000000b, 0x00000009, 0x00000004, 0x00090019, 0x00000004, 0x00000009, 0x00000001, + 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, 0x0000000c, 0x00000000, + 0x00000004, 0x0002001a, 0x00000006, 0x00040020, 0x0000000d, 0x00000000, 0x00000006, 0x00040017, + 0x0000000e, 0x00000009, 0x00000002, 0x00040020, 0x0000000f, 0x00000001, 0x0000000e, 0x00040020, + 0x00000010, 0x00000003, 0x0000000b, 0x00020013, 0x00000011, 0x00030021, 0x00000012, 0x00000011, + 0x0003001b, 0x00000008, 0x00000004, 0x0004003b, 0x0000000c, 0x00000005, 0x00000000, 0x0004003b, + 0x0000000d, 0x00000007, 0x00000000, 0x0004003b, 0x0000000f, 0x00000002, 0x00000001, 0x0004003b, + 0x00000010, 0x00000003, 0x00000003, 0x00050036, 0x00000011, 0x00000001, 0x00000000, 0x00000012, + 0x000200f8, 0x00000013, 0x0004003d, 0x0000000e, 0x00000014, 0x00000002, 0x0004003d, 0x00000004, + 0x00000015, 0x00000005, 0x0004003d, 0x00000006, 0x00000016, 0x00000007, 0x00050056, 0x00000008, + 0x00000017, 0x00000015, 0x00000016, 0x00070058, 0x0000000b, 0x00000018, 0x00000017, 0x00000014, + 0x00000002, 0x0000000a, 0x00050051, 0x00000009, 0x00000019, 0x00000018, 0x00000000, 0x00070050, + 0x0000000b, 0x0000001a, 0x0000000a, 0x0000000a, 0x0000000a, 0x00000019, 0x0003003e, 0x00000003, + 0x0000001a, 0x000100fd, 0x00010038, +}; + +// ssao.hlsl : ps_debug (852 bytes) +static const uint32_t k_ssao_ps_debug[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x0000001c, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, + 0x00000000, 0x00000001, 0x0008000f, 0x00000004, 0x00000001, 0x645f7370, 0x67756265, 0x00000000, + 0x00000002, 0x00000003, 0x00030010, 0x00000001, 0x00000007, 0x00030003, 0x00000005, 0x00000258, + 0x00060005, 0x00000004, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000005, + 0x30786574, 0x00000000, 0x00060005, 0x00000006, 0x65707974, 0x6d61732e, 0x72656c70, 0x00000000, + 0x00050005, 0x00000007, 0x5f706d73, 0x656e696c, 0x00007261, 0x00070005, 0x00000002, 0x762e6e69, + 0x542e7261, 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, 0x00000003, 0x2e74756f, 0x2e726176, + 0x545f5653, 0x65677261, 0x00000074, 0x00050005, 0x00000001, 0x645f7370, 0x67756265, 0x00000000, + 0x00070005, 0x00000008, 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, 0x00006567, 0x00040047, + 0x00000002, 0x0000001e, 0x00000000, 0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00040047, + 0x00000005, 0x00000022, 0x00000001, 0x00040047, 0x00000005, 0x00000021, 0x00000000, 0x00040047, + 0x00000007, 0x00000022, 0x00000000, 0x00040047, 0x00000007, 0x00000021, 0x00000002, 0x00030016, + 0x00000009, 0x00000020, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x0004002b, 0x00000009, + 0x0000000b, 0x3f800000, 0x00040017, 0x0000000c, 0x00000009, 0x00000004, 0x00090019, 0x00000004, + 0x00000009, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00040020, + 0x0000000d, 0x00000000, 0x00000004, 0x0002001a, 0x00000006, 0x00040020, 0x0000000e, 0x00000000, + 0x00000006, 0x00040017, 0x0000000f, 0x00000009, 0x00000002, 0x00040020, 0x00000010, 0x00000001, + 0x0000000f, 0x00040020, 0x00000011, 0x00000003, 0x0000000c, 0x00020013, 0x00000012, 0x00030021, + 0x00000013, 0x00000012, 0x0003001b, 0x00000008, 0x00000004, 0x0004003b, 0x0000000d, 0x00000005, + 0x00000000, 0x0004003b, 0x0000000e, 0x00000007, 0x00000000, 0x0004003b, 0x00000010, 0x00000002, + 0x00000001, 0x0004003b, 0x00000011, 0x00000003, 0x00000003, 0x00050036, 0x00000012, 0x00000001, + 0x00000000, 0x00000013, 0x000200f8, 0x00000014, 0x0004003d, 0x0000000f, 0x00000015, 0x00000002, + 0x0004003d, 0x00000004, 0x00000016, 0x00000005, 0x0004003d, 0x00000006, 0x00000017, 0x00000007, + 0x00050056, 0x00000008, 0x00000018, 0x00000016, 0x00000017, 0x00070058, 0x0000000c, 0x00000019, + 0x00000018, 0x00000015, 0x00000002, 0x0000000a, 0x00050051, 0x00000009, 0x0000001a, 0x00000019, + 0x00000000, 0x00070050, 0x0000000c, 0x0000001b, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000000b, + 0x0003003e, 0x00000003, 0x0000001b, 0x000100fd, 0x00010038, +}; + struct NativeSpirvBlob { const char* file; // e.g. "scene.hlsl" const char* entry; // e.g. "vs_main" @@ -4791,6 +5457,14 @@ static const NativeSpirvBlob kNativeSpirvBlobs[] = { {"photo_fx.hlsl", "ps_fisheye", "", k_photo_fx_ps_fisheye, sizeof(k_photo_fx_ps_fisheye)}, {"photo_fx.hlsl", "ps_blit", "", k_photo_fx_ps_blit, sizeof(k_photo_fx_ps_blit)}, {"photo_fx.hlsl", "ps_pfx_debug", "", k_photo_fx_ps_pfx_debug, sizeof(k_photo_fx_ps_pfx_debug)}, + {"ssao.hlsl", "vs_main", "", k_ssao_vs_main, sizeof(k_ssao_vs_main)}, + {"ssao.hlsl", "ps_linearize", "", k_ssao_ps_linearize, sizeof(k_ssao_ps_linearize)}, + {"ssao.hlsl", "ps_linearize", "AO_MSAA=1", k_ssao_ps_linearize_AO_MSAA_1, sizeof(k_ssao_ps_linearize_AO_MSAA_1)}, + {"ssao.hlsl", "ps_gtao", "", k_ssao_ps_gtao, sizeof(k_ssao_ps_gtao)}, + {"ssao.hlsl", "ps_blur", "", k_ssao_ps_blur, sizeof(k_ssao_ps_blur)}, + {"ssao.hlsl", "ps_luma", "", k_ssao_ps_luma, sizeof(k_ssao_ps_luma)}, + {"ssao.hlsl", "ps_composite", "", k_ssao_ps_composite, sizeof(k_ssao_ps_composite)}, + {"ssao.hlsl", "ps_debug", "", k_ssao_ps_debug, sizeof(k_ssao_ps_debug)}, }; static const size_t kNativeSpirvBlobCount = diff --git a/src/native/shaders/ssao.hlsl b/src/native/shaders/ssao.hlsl new file mode 100644 index 0000000..c06f2e7 --- /dev/null +++ b/src/native/shaders/ssao.hlsl @@ -0,0 +1,246 @@ +// Screen-space ambient occlusion (GTAO) over the resolved native scene. +// Ground-truth ambient occlusion after Jimenez et al.: per pixel, a few +// screen-space slices each march the depth buffer both ways to find the +// horizon angles, and the cosine-weighted arc between them integrates to a +// visibility term. Normals are reconstructed from depth (no G-buffer), so +// the pass needs only the scene depth + the projection constants. +// +// Pass chain (all fullscreen triangles, own binding layout): +// ps_linearize scene depth (sample 0 when MSAA; AO_MSAA=1 variant) +// -> view-space Z, R32_FLOAT, full res +// ps_luma scene color -> luminance, R8_UNORM, AO raster (the +// sun-lit protection mask input) +// ps_gtao linear depth + luma -> the final gamma-encoded AO +// multiplier, R8_UNORM (fully-protected pixels skip the +// march, most of a daytime frame) +// ps_blur depth-aware separable gaussian (2 passes), R8_UNORM +// ps_composite AO onto the guest output via dst.rgb * src.a blending +// (RGB write mask; the output has no usable alpha anyway) +// ps_debug AO greyscale replace, for tuning +// +// Color space note: the scene target is gamma-encoded (the material shaders +// linearize by squaring and return via sqrt), so the composite applies +// sqrt(ao_linear): a linear-space multiply expressed in gamma space. +cbuffer C : register(b0) { + float4 size; // xy = output size in px, zw = 1 / size + float4 proj; // x = |m00|, y = |m11|, z = m22, w = m32 (row-vector proj) + float4 p0; // x = radius (view units), y = intensity, + // z = fade start (view Z), w = 1 / fade range + float4 p1; // xy = blur axis in px, z = sun-lit luma protection scale +}; +// t0 is the per-pass primary input: the scene depth for ps_linearize, the +// linear-depth / AO intermediates for the march/blur, the scene color for +// copy/composite. Each entry references exactly one of the overlapping t0 +// declarations; the others drop out at compile. +#ifdef AO_MSAA +Texture2DMS depth_ms : register(t0); +#endif +Texture2D tex0 : register(t0); +Texture2D tex0c : register(t0); // ps_luma scene color +Texture2D tex1 : register(t1); // gtao: luma; blur: linear depth +SamplerState smp_point : register(s0); +SamplerState smp_linear : register(s1); + +static const float kPi = 3.14159265f; +// 3 slices x 3 steps/side = 18 taps: the reference GTAO "high" budget. The +// per-pixel rotation + depth-aware blur integrate the dither; the nonlinear +// step distribution below spends the taps near the contact zone where the +// occlusion signal lives. (6 steps was ~2x the cost for a difference the +// blur erased; at night, where no pixel early-outs, that doubled the whole +// pass.) +#define AO_SLICES 3 +#define AO_STEPS 3 + +struct VSOut { + float4 pos : SV_Position; + float2 uv : TEXCOORD0; +}; +VSOut vs_main(uint id : SV_VertexID) { + VSOut o; + float2 uv = float2((id << 1) & 2, id & 2); + o.pos = float4(uv * float2(2, -2) + float2(-1, 1), 0, 1); + o.uv = uv; + return o; +} + +// Device depth -> view-space Z. Row-vector projection with m23 = 1: +// ndc_z = m22 + m32 / z_view. +float LinearZ(float d) { + return clamp(proj.w / min(d - proj.z, -1e-6), 0.05f, 4e5f); +} + +float ps_linearize(VSOut i) : SV_Target { +#ifdef AO_MSAA + float d = depth_ms.Load(int2(i.pos.xy), 0); +#else + float d = tex0.Load(int3(int2(i.pos.xy), 0)); +#endif + return LinearZ(d); +} + +// View-space position from UV + linear Z. |m00|/|m11| make the space a +// (possibly mirrored) view space; every AO quantity is invariant under a +// mirrored axis, so the projection's negative x scale needs no special +// handling. +float3 ViewPos(float2 uv, float z) { + float2 ndc = float2(uv.x * 2.0f - 1.0f, 1.0f - uv.y * 2.0f); + return float3(ndc.x * z / proj.x, ndc.y * z / proj.y, z); +} + +float SampleZ(float2 uv) { + return tex0.SampleLevel(smp_point, uv, 0); +} + +// Normal from depth: for each axis take the neighbor with the smaller depth +// delta (avoids smeared normals across silhouette edges), cross the two +// tangents, and face the camera. +float3 ReconstructNormal(float2 uv, float3 P) { + float2 dx = float2(size.z, 0.0f); + float2 dy = float2(0.0f, size.w); + float zl = SampleZ(uv - dx), zr = SampleZ(uv + dx); + float zu = SampleZ(uv - dy), zd = SampleZ(uv + dy); + float3 th = (abs(zr - P.z) < abs(zl - P.z)) + ? (ViewPos(uv + dx, zr) - P) + : (P - ViewPos(uv - dx, zl)); + float3 tv = (abs(zd - P.z) < abs(zu - P.z)) + ? (ViewPos(uv + dy, zd) - P) + : (P - ViewPos(uv - dy, zu)); + float3 n = normalize(cross(tv, th)); + return (dot(n, -P) < 0.0f) ? -n : n; +} + +// Spatial rotation/offset noise (interleaved gradient noise); the blur +// integrates the resulting high-frequency dither. +float Ign(float2 p) { + return frac(52.9829189f * frac(dot(p, float2(0.06711056f, 0.00583715f)))); +} + +// Half-res scene luminance for the sun-lit protection mask (low-frequency +// by nature, so the AO raster resolution is plenty; bilinear at the 2x +// reduction is an exact 2x2 box). +float ps_luma(VSOut i) : SV_Target { + float3 scene = tex0c.SampleLevel(smp_linear, i.uv, 0).rgb; + return dot(scene, float3(0.299f, 0.587f, 0.114f)); +} + +float ps_gtao(VSOut i) : SV_Target { + float zc = SampleZ(i.uv); + float fade = saturate((zc - p0.z) * p0.w); + // Sun-lit protection: real AO attenuates only ambient light; direct sun + // is unaffected, but this chain runs post-tonemap where the two are + // already summed. Approximate the split by luminance: bright pixels are + // sun-lit and resist the darkening (keeping characters from dragging a + // gray pool across lit pavement), dim pixels are ambient/shade-lit and + // keep it. Fully-protected or fully-faded pixels skip the march. + float luma = tex1.SampleLevel(smp_point, i.uv, 0); + float protect = saturate(luma * p1.z); + protect *= protect; + // Skip fully-protected (sun-lit), fully-faded, and near-black pixels; a + // multiplier on near-zero color is invisible, so night skies and deep + // shadow don't pay for the march either. + if (fade >= 1.0f || protect >= 0.999f || luma < 0.015f) { + return 1.0f; + } + float3 P = ViewPos(i.uv, zc); + float3 N = ReconstructNormal(i.uv, P); + float3 V = -normalize(P); + + // World-space radius projected to pixels at this depth (vertical FOV + // scale), bounded so near surfaces don't walk the whole screen (large + // scattered footprints also thrash the texture cache; the dominant cost + // of this pass is tap locality, not ALU). + float radius_px = clamp(p0.x * proj.y / zc * size.y * 0.5f, 2.0f, 64.0f); + float noise_dir = Ign(i.pos.xy); + float noise_off = Ign(i.pos.xy + 41.13f); + float inv_r = 1.0f / max(p0.x, 1e-4f); + + float vis = 0.0f; + [unroll] for (int s = 0; s < AO_SLICES; ++s) { + float phi = (float(s) + noise_dir) * (kPi / float(AO_SLICES)); + float2 sdir = float2(cos(phi), sin(phi)); + // The view-space direction a +sdir pixel step moves the surface point + // (screen y runs down, view y up; aspect via the per-axis pixel sizes). + float3 D = normalize(float3(sdir.x * size.z / proj.x, + -sdir.y * size.w / proj.y, 0.0f)); + float3 axis = normalize(cross(D, V)); + float3 ortho = normalize(D - dot(D, V) * V); + // Normal projected into the slice plane; its signed angle from V decides + // the hemisphere the horizon arc is clamped to. + float3 Np = N - axis * dot(N, axis); + float npl = length(Np); + if (npl < 1e-4f) { + vis += 1.0f; + continue; + } + float cos_n = clamp(dot(Np, V) / npl, -1.0f, 1.0f); + float n = sign(dot(Np, ortho)) * acos(cos_n); + + // March both sides, tracking the max cos(angle to V) with a smooth + // range falloff so geometry near the radius edge fades instead of pops. + float2 hcos = float2(-1.0f, -1.0f); + [unroll] for (int side = 0; side < 2; ++side) { + float sgn = side == 0 ? -1.0f : 1.0f; + [loop] for (int j = 0; j < AO_STEPS; ++j) { + // Nonlinear step distribution: taps cluster toward the contact + // zone; the falloff discounts the far ones anyway. + float fj = (float(j) + noise_off) / float(AO_STEPS); + float t = radius_px * fj * sqrt(fj) + 1.0f; + float2 suv = i.uv + sgn * sdir * t * size.zw; + float3 Ps = ViewPos(suv, SampleZ(suv)); + float3 d3 = Ps - P; + float dist2 = max(dot(d3, d3), 1e-8f); + float rinv = rsqrt(dist2); + float c = dot(d3, V) * rinv; + float dist = dist2 * rinv; + c = lerp(c, -1.0f, saturate(dist * inv_r * 3.333f - 2.333f)); + hcos[side] = max(hcos[side], c); + } + } + float h1 = n + max(-acos(clamp(hcos.x, -1.0f, 1.0f)) - n, -0.5f * kPi); + float h2 = n + min(acos(clamp(hcos.y, -1.0f, 1.0f)) - n, 0.5f * kPi); + // Cosine-weighted arc integral between the two horizons (GTAO). + float a = + 0.25f * ((-cos(2.0f * h1 - n) + cos_n + 2.0f * h1 * sin(n)) + + (-cos(2.0f * h2 - n) + cos_n + 2.0f * h2 * sin(n))); + vis += npl * a; + } + vis = saturate(vis / float(AO_SLICES)); + // Bake the full multiplier here so the blur smooths the finished term and + // the composite is a plain blend: intensity exponent on the linear + // visibility, the extra 0.5 converting the multiply into the target's + // gamma-2 encoding, then the protection and distance fades toward 1. + float a = pow(vis, p0.y * 0.5f); + a = lerp(a, 1.0f, protect); + return lerp(a, 1.0f, fade); +} + +// Depth-aware separable gaussian (sigma 2, radius 4): integrates the slice +// dither without bleeding AO across depth edges. +float ps_blur(VSOut i) : SV_Target { + const float w[5] = {1.0f, 0.8825f, 0.6065f, 0.3247f, 0.1353f}; + float zc = tex1.SampleLevel(smp_point, i.uv, 0); + float acc = tex0.SampleLevel(smp_point, i.uv, 0); + float wsum = 1.0f; + [unroll] for (int k = 1; k <= 4; ++k) { + [unroll] for (int s = 0; s < 2; ++s) { + float2 suv = i.uv + (s == 0 ? -1.0f : 1.0f) * p1.xy * float(k) * size.zw; + float zs = tex1.SampleLevel(smp_point, suv, 0); + float wz = saturate(1.0f - abs(zs - zc) / (zc * 0.05f + 0.05f)); + float wk = w[k] * wz; + acc += tex0.SampleLevel(smp_point, suv, 0) * wk; + wsum += wk; + } + } + return acc / wsum; +} + +// dst.rgb * src.a blend (RGB write mask): the AO plane already carries the +// finished gamma-encoded, luma-protected, distance-faded multiplier. +float4 ps_composite(VSOut i) : SV_Target { + return float4(0.0f, 0.0f, 0.0f, tex0.SampleLevel(smp_linear, i.uv, 0)); +} + +float4 ps_debug(VSOut i) : SV_Target { + float ao = tex0.SampleLevel(smp_linear, i.uv, 0); + return float4(ao, ao, ao, 1.0f); +} diff --git a/src/skate3_native_scene.cpp b/src/skate3_native_scene.cpp index 3a7383b..4d55956 100644 --- a/src/skate3_native_scene.cpp +++ b/src/skate3_native_scene.cpp @@ -82,6 +82,38 @@ REXCVAR_DEFINE_INT32(skate3_native_render_scene_msaa, 4, "Skate 3", "fix texture aliasing.") .range(1, 8) .lifecycle(rex::cvar::Lifecycle::kRequiresRestart); +REXCVAR_DEFINE_BOOL(skate3_native_render_scene_ssao, true, "Skate 3", + "Screen-space ambient occlusion (GTAO) in the native renderer: soft " + "contact shading where surfaces meet (under ledges, rails, vehicles, " + "the skater). A post pass over the resolved scene depth, an " + "enhancement beyond the original game's shading.") + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_DOUBLE(skate3_native_render_scene_ssao_radius, 0.8, "Skate 3", + "SSAO sample radius in world units. Larger radii darken bigger " + "cavities but read as wide soft pools around characters; small " + "radii keep it to contact shading.") + .range(0.1, 8.0) + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_DOUBLE(skate3_native_render_scene_ssao_luma_protect, 1.2, "Skate 3", + "How strongly bright (sun-lit) surfaces resist SSAO darkening, " + "a post-tonemap approximation of ambient-only occlusion (direct " + "sunlight is not occluded by nearby geometry). 0 = AO applies " + "uniformly regardless of lighting.") + .range(0.0, 4.0) + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_DOUBLE(skate3_native_render_scene_ssao_intensity, 1.4, "Skate 3", + "SSAO strength: exponent on the linear visibility term (0 = " + "invisible, 1 = physical, >1 = accentuated).") + .range(0.0, 4.0) + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_BOOL(skate3_native_render_scene_ssao_full_res, false, "Skate 3", + "Evaluate SSAO at full output resolution instead of half. Roughly " + "4x the GPU cost for a subtle sharpening of the smallest contact " + "shadows; the depth-aware blur hides most of the difference.") + .lifecycle(rex::cvar::Lifecycle::kHotReload); +REXCVAR_DEFINE_BOOL(skate3_native_render_scene_ssao_debug, false, "Skate 3", + "Replace the frame with the SSAO visibility term (tuning aid).") + .lifecycle(rex::cvar::Lifecycle::kHotReload); REXCVAR_DEFINE_BOOL(skate3_native_render_scene_2d, true, "Skate 3", "Replay the game's 2D/APT (Flash HUD) draws as a native overlay pass " "on top of the 3D scene") @@ -8424,6 +8456,12 @@ void BuildFrameScene(uint8_t* base, const SubmitRecord* records, size_t count) { for (int i = 0; i < 16; ++i) { scene.view_proj[i] = LoadGuestF32(base, viewcam + kViewCamViewProj + i * 4); } + // The raw projection (+0x60) rides along for the depth-based post passes + // (SSAO linearize/unproject). Camera smoothing below replaces only the + // view; the projection is whatever the game rendered this frame with. + for (int i = 0; i < 16; ++i) { + scene.proj[i] = LoadGuestF32(base, viewcam + 0x60 + i * 4); + } // RAW guest view*proj, the pose the game culled its submissions with, // kept for the off-screen retention frustum tests below (smoothing // replaces scene.view_proj with the re-timed pose). @@ -10159,6 +10197,36 @@ struct RendererState { uint32_t pfx_width = 0, pfx_height = 0; bool pfx_ready = false; bool pfx_failed = false; + // Screen-space ambient occlusion (ssao.hlsl: GTAO over the resolved + // scene; see ApplySsaoPass). Own binding layout: root constants b0 + two + // single-texture tables t0/t1 + point/linear clamp samplers. Full-res + // intermediates: linearized view-Z (R32F) + two AO ping-pong planes + // (R8), idle in RENDER_TARGET state. PSOs rebuild when the MSAA level + // (depth SRV dimension / linearize variant) or the output format + // (composite target) changes. + nrhi::BindingLayout* ao_layout = nullptr; + nrhi::Pipeline* pso_ao_linearize = nullptr; + nrhi::Pipeline* pso_ao_gtao = nullptr; + nrhi::Pipeline* pso_ao_blur = nullptr; + nrhi::Pipeline* pso_ao_luma = nullptr; + nrhi::Pipeline* pso_ao_composite = nullptr; + nrhi::Pipeline* pso_ao_debug = nullptr; + nrhi::Texture* ao_lin_depth = nullptr; + nrhi::Texture* ao_tex[2] = {}; + // Scene luminance at the AO raster: the sun-lit protection mask input + // (bright pixels resist AO and skip the march entirely). + nrhi::Texture* ao_luma = nullptr; + nrhi::TextureView* ao_lin_srv = nullptr; + nrhi::TextureView* ao_srv[2] = {}; + nrhi::TextureView* ao_luma_srv = nullptr; + // View of the scene depth buffer, re-pointed when depth is rebuilt. + nrhi::TextureView* ao_depth_srv = nullptr; + nrhi::Texture* ao_depth_srv_of = nullptr; + uint32_t ao_width = 0, ao_height = 0; // AO raster (half or full res) + uint32_t ao_lin_width = 0, ao_lin_height = 0; // linear depth (always full) + uint32_t ao_msaa = 0; + nrhi::Format ao_rtv_format = nrhi::Format::kUnknown; + bool ao_failed = false; std::unordered_map meshes; // (The old D3D12 bookkeeping, the retired-resource vector, the CPU SRV // staging heap and its slot allocator/recycling lists, is gone: resource @@ -13516,6 +13584,342 @@ bool EnsureOutputSizedTargets(const NativeGuestOutputRenderContext& context) { return true; } +// ---- Screen-space ambient occlusion (ssao.hlsl: GTAO) -------------------- +// Layout + PSOs, built lazily on the first enabled frame and rebuilt when +// the MSAA level (linearize shader variant) or the output format (composite +// target) changes. Failure disables the effect only. +bool EnsureSsaoPipeline(const NativeGuestOutputRenderContext& context) { + if (g_r.ao_failed) { + return false; + } + if (g_r.pso_ao_linearize != nullptr && g_r.ao_msaa == g_r.msaa && + g_r.ao_rtv_format == context.guest_output->format()) { + return true; + } + nrhi::Device* device = context.device; + const auto fail = [&](const char* what) { + REXLOG_ERROR("native-scene: ssao pipeline setup failed ({})", what); + g_r.ao_failed = true; + return false; + }; + if (g_r.ao_layout == nullptr) { + nrhi::BindingLayoutDesc ld; + ld.param_count = 3; + ld.params[0] = {nrhi::BindingParamKind::kConstants, /*b*/ 0, 16, + nrhi::Visibility::kAll}; + ld.params[1] = {nrhi::BindingParamKind::kTextureTable, /*t*/ 0, 1, + nrhi::Visibility::kPixel}; + ld.params[2] = {nrhi::BindingParamKind::kTextureTable, 1, 1, + nrhi::Visibility::kPixel}; + ld.static_sampler_count = 2; + ld.static_samplers[0] = {/*s*/ 0, nrhi::Filter::kPoint, + nrhi::AddressMode::kClamp, 1}; + ld.static_samplers[1] = {1, nrhi::Filter::kLinear, + nrhi::AddressMode::kClamp, 1}; + ld.allow_input_layout = false; + g_r.ao_layout = device->CreateBindingLayout(ld); + if (g_r.ao_layout == nullptr) { + return fail("binding layout"); + } + } + nrhi::Pipeline** psos[6] = {&g_r.pso_ao_linearize, &g_r.pso_ao_gtao, + &g_r.pso_ao_blur, &g_r.pso_ao_luma, + &g_r.pso_ao_composite, &g_r.pso_ao_debug}; + for (nrhi::Pipeline** p : psos) { + if (*p != nullptr) { + device->DestroyDeferred(*p); + *p = nullptr; + } + } + const bool msaa = g_r.msaa > 1; + const nrhi::ShaderMacro msaa_defs[] = {{"AO_MSAA", "1"}, {nullptr, nullptr}}; + nrhi::Shader* vs = device->CreateShader( + MakeShaderDesc(nrhi::ShaderStage::kVertex, "ssao.hlsl", + kSsaoShaderSource, "vs_main", nullptr, "")); + const char* ps_entries[6] = {"ps_linearize", "ps_gtao", "ps_blur", + "ps_luma", "ps_composite", "ps_debug"}; + nrhi::Shader* ps[6] = {}; + bool ok = vs != nullptr; + for (int i = 0; i < 6; ++i) { + const bool msaa_entry = i == 0 && msaa; + ps[i] = device->CreateShader(MakeShaderDesc( + nrhi::ShaderStage::kPixel, "ssao.hlsl", kSsaoShaderSource, + ps_entries[i], msaa_entry ? msaa_defs : nullptr, + msaa_entry ? "AO_MSAA=1" : "")); + ok = ok && ps[i] != nullptr; + } + if (!ok) { + device->DestroyDeferred(vs); + for (nrhi::Shader* s : ps) { + device->DestroyDeferred(s); + } + return fail("shader compile"); + } + nrhi::GraphicsPipelineDesc pso; + pso.layout = g_r.ao_layout; + pso.vs = vs; + pso.cull = nrhi::CullMode::kNone; + pso.sample_count = 1; + pso.ps = ps[0]; + pso.rtv_format = nrhi::Format::kR32_FLOAT; + g_r.pso_ao_linearize = device->CreateGraphicsPipeline(pso); + pso.ps = ps[1]; + pso.rtv_format = nrhi::Format::kR8_UNORM; + g_r.pso_ao_gtao = device->CreateGraphicsPipeline(pso); + pso.ps = ps[2]; + g_r.pso_ao_blur = device->CreateGraphicsPipeline(pso); + pso.ps = ps[3]; + g_r.pso_ao_luma = device->CreateGraphicsPipeline(pso); + // Composite: dst.rgb * src.a; the AO plane carries the finished + // multiplier, and the RGB-only write mask keeps the output's 2-bit alpha + // untouched. + pso.ps = ps[4]; + pso.rtv_format = context.guest_output->format(); + pso.blend.enable = true; + pso.blend.src = nrhi::BlendFactor::kZero; + pso.blend.dst = nrhi::BlendFactor::kSrcAlpha; + pso.blend.op = nrhi::BlendOp::kAdd; + pso.blend.src_alpha = nrhi::BlendFactor::kZero; + pso.blend.dst_alpha = nrhi::BlendFactor::kOne; + pso.blend.op_alpha = nrhi::BlendOp::kAdd; + pso.blend.write_mask = 0x7; + g_r.pso_ao_composite = device->CreateGraphicsPipeline(pso); + pso.blend = {}; + pso.ps = ps[5]; + g_r.pso_ao_debug = device->CreateGraphicsPipeline(pso); + device->DestroyDeferred(vs); + for (nrhi::Shader* s : ps) { + device->DestroyDeferred(s); + } + if (g_r.pso_ao_linearize == nullptr || g_r.pso_ao_gtao == nullptr || + g_r.pso_ao_blur == nullptr || g_r.pso_ao_luma == nullptr || + g_r.pso_ao_composite == nullptr || g_r.pso_ao_debug == nullptr) { + return fail("pso"); + } + g_r.ao_msaa = g_r.msaa; + g_r.ao_rtv_format = context.guest_output->format(); + REXLOG_INFO("native-scene: ssao pipeline created (MSAA x{})", g_r.msaa); + return true; +} + +// GTAO chain over the resolved scene (see ssao.hlsl): linearize depth, +// horizon-based AO, depth-aware separable blur, multiply-composite onto the +// guest output (which must be in RENDER_TARGET state). Returns true when it +// drew; binding layout/state was changed and the caller restores the main +// pass's bindings. +bool ApplySsaoPass(const NativeGuestOutputRenderContext& context, + nrhi::Cmd* cmd, const FrameScene& scene, + const nrhi::Viewport& viewport, const nrhi::Rect& scissor) { + // The published projection must be the live perspective matrix (row-vector + // m23 == 1; all zeros until the first publish). + const float* pr = scene.proj; + if (pr[11] != 1.0f || pr[0] == 0.0f || pr[5] == 0.0f || pr[14] == 0.0f) { + return false; + } + if (!EnsureSsaoPipeline(context)) { + return false; + } + if (g_r.output_srv_slot == nullptr) { + return false; // composite samples the guest output through this view + } + nrhi::Device* device = context.device; + const uint32_t width = context.guest_output_width; + const uint32_t height = context.guest_output_height; + // AO raster: half the output resolution by default: for a low-frequency + // term the depth-aware blur + bilinear upsample hide it, at 1/4 the march + // cost (full-res GTAO at 4K x 300+ uncapped fps pegged the GPU). The + // linearized depth stays full res: the march samples it at arbitrary UVs + // either way, and it keeps silhouette depth exact. + const bool ao_full = + REXCVAR_GET(skate3_native_render_scene_ssao_full_res); + const uint32_t aw = ao_full ? width : std::max(1u, (width + 1) / 2); + const uint32_t ah = ao_full ? height : std::max(1u, (height + 1) / 2); + // Intermediates (steady state RENDER_TARGET), rebuilt on either size. + if (g_r.ao_width != aw || g_r.ao_height != ah || + g_r.ao_lin_width != width || g_r.ao_lin_height != height || + g_r.ao_lin_depth == nullptr || g_r.ao_luma == nullptr) { + nrhi::Texture** res[4] = {&g_r.ao_lin_depth, &g_r.ao_tex[0], + &g_r.ao_tex[1], &g_r.ao_luma}; + nrhi::TextureView** views[4] = {&g_r.ao_lin_srv, &g_r.ao_srv[0], + &g_r.ao_srv[1], &g_r.ao_luma_srv}; + for (int i = 0; i < 4; ++i) { + if (*views[i] != nullptr) { + device->DestroyDeferred(*views[i]); + *views[i] = nullptr; + } + if (*res[i] != nullptr) { + device->DestroyDeferred(*res[i]); + *res[i] = nullptr; + } + nrhi::TextureDesc desc; + desc.width = i == 0 ? width : aw; + desc.height = i == 0 ? height : ah; + desc.mip_levels = 1; + desc.format = + i == 0 ? nrhi::Format::kR32_FLOAT : nrhi::Format::kR8_UNORM; + desc.usage = nrhi::kTextureUsageRenderTarget; + desc.initial_state = nrhi::ResourceState::kRenderTarget; + *res[i] = device->CreateTexture(desc); + if (*res[i] == nullptr) { + g_r.ao_failed = true; + return false; + } + nrhi::TextureViewDesc vd; + vd.mip_levels = 1; + *views[i] = device->CreateTextureView(*res[i], vd); + if (*views[i] == nullptr) { + g_r.ao_failed = true; + return false; + } + } + g_r.ao_width = aw; + g_r.ao_height = ah; + g_r.ao_lin_width = width; + g_r.ao_lin_height = height; + } + // Scene-depth SRV, re-pointed when the depth buffer is rebuilt (resize / + // MSAA change). D32 textures view as R32_FLOAT automatically. + if (g_r.ao_depth_srv == nullptr || g_r.ao_depth_srv_of != g_r.depth) { + if (g_r.ao_depth_srv != nullptr) { + device->DestroyDeferred(g_r.ao_depth_srv); + g_r.ao_depth_srv = nullptr; + } + nrhi::TextureViewDesc sd; + if (g_r.msaa > 1) { + sd.dimension = nrhi::ViewDimension::k2DMS; + } else { + sd.dimension = nrhi::ViewDimension::k2D; + sd.mip_levels = 1; + } + g_r.ao_depth_srv = device->CreateTextureView(g_r.depth, sd); + if (g_r.ao_depth_srv == nullptr) { + g_r.ao_failed = true; + return false; + } + g_r.ao_depth_srv_of = g_r.depth; + } + + // b0 rows (see ssao.hlsl cbuffer C): size, projection, tuning, blur axis. + // size = the AO raster the march/blur passes run at; every shader use is + // UV-relative, so half res needs no shader-side changes. + float c[16]; + c[0] = float(aw); + c[1] = float(ah); + c[2] = 1.0f / float(aw); + c[3] = 1.0f / float(ah); + c[4] = std::fabs(pr[0]); // |m00|: the guest projection's x scale is + // negative; AO is mirror-invariant + c[5] = std::fabs(pr[5]); // |m11| + c[6] = pr[10]; // m22 + c[7] = pr[14]; // m32 + c[8] = float(REXCVAR_GET(skate3_native_render_scene_ssao_radius)); + c[9] = float(REXCVAR_GET(skate3_native_render_scene_ssao_intensity)); + // Distance fade 150..250 view units: fog owns the far field and the + // horizon-search precision degrades with depth anyway. + c[10] = 150.0f; + c[11] = 1.0f / 100.0f; + c[12] = 1.0f; // blur axis (horizontal first) + c[13] = 0.0f; + c[14] = float(REXCVAR_GET(skate3_native_render_scene_ssao_luma_protect)); + c[15] = 0.0f; + + const nrhi::Viewport ao_vp{0.0f, 0.0f, float(aw), float(ah), 0.0f, 1.0f}; + const nrhi::Rect ao_sc{0, 0, int32_t(aw), int32_t(ah)}; + + cmd->SetBindingLayout(g_r.ao_layout); + cmd->SetPrimitiveTopology(nrhi::PrimitiveTopology::kTriangleList); + cmd->SetViewport(viewport); + cmd->SetScissor(scissor); + cmd->SetRootConstants(0, 16, c, 0); + + // 1) Scene depth -> linear view Z (sample 0 when MSAA). Full res. + cmd->Barrier(g_r.depth, nrhi::ResourceState::kDepthWrite, + nrhi::ResourceState::kPixelShaderResource); + cmd->FlushBarriers(); + cmd->SetRenderTargets(g_r.ao_lin_depth, nullptr); + cmd->SetPipeline(g_r.pso_ao_linearize); + cmd->SetTexture(1, g_r.ao_depth_srv); + cmd->Draw(3, 0); + cmd->Barrier(g_r.depth, nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kDepthWrite); + cmd->Barrier(g_r.ao_lin_depth, nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->FlushBarriers(); + + // 1b) Scene luminance -> ao_luma (AO raster): the sun-lit protection + // mask. The guest output pauses as a sampled source for one draw. + cmd->Barrier(context.guest_output, nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->FlushBarriers(); + cmd->SetViewport(ao_vp); + cmd->SetScissor(ao_sc); + cmd->SetRenderTargets(g_r.ao_luma, nullptr); + cmd->SetPipeline(g_r.pso_ao_luma); + cmd->SetTexture(1, g_r.output_srv_slot); + cmd->Draw(3, 0); + cmd->Barrier(g_r.ao_luma, nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->Barrier(context.guest_output, nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->FlushBarriers(); + + // 2) GTAO -> ao_tex[0], at the AO raster size. + cmd->SetRenderTargets(g_r.ao_tex[0], nullptr); + cmd->SetPipeline(g_r.pso_ao_gtao); + cmd->SetTexture(1, g_r.ao_lin_srv); + cmd->SetTexture(2, g_r.ao_luma_srv); + cmd->Draw(3, 0); + cmd->Barrier(g_r.ao_tex[0], nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->FlushBarriers(); + + // 3) Depth-aware blur, horizontal -> ao_tex[1]. + cmd->SetRenderTargets(g_r.ao_tex[1], nullptr); + cmd->SetPipeline(g_r.pso_ao_blur); + cmd->SetTexture(1, g_r.ao_srv[0]); + cmd->SetTexture(2, g_r.ao_lin_srv); + cmd->Draw(3, 0); + cmd->Barrier(g_r.ao_tex[1], nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->Barrier(g_r.ao_tex[0], nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->FlushBarriers(); + + // 4) Vertical -> ao_tex[0]. + const float dir_v[2] = {0.0f, 1.0f}; + cmd->SetRootConstants(0, 2, dir_v, 12); + cmd->SetRenderTargets(g_r.ao_tex[0], nullptr); + cmd->SetTexture(1, g_r.ao_srv[1]); + cmd->SetTexture(2, g_r.ao_lin_srv); + cmd->Draw(3, 0); + cmd->Barrier(g_r.ao_tex[0], nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kPixelShaderResource); + cmd->FlushBarriers(); + + // 5) Composite onto the guest output (full res; s1 bilinearly upsamples + // the finished multiplier plane). Debug replaces the frame with it. + cmd->SetViewport(viewport); + cmd->SetScissor(scissor); + cmd->SetRenderTargets(context.guest_output, nullptr); + cmd->SetPipeline(REXCVAR_GET(skate3_native_render_scene_ssao_debug) + ? g_r.pso_ao_debug + : g_r.pso_ao_composite); + cmd->SetTexture(1, g_r.ao_srv[0]); + cmd->Draw(3, 0); + + // Restore intermediate steady states. + cmd->Barrier(g_r.ao_tex[0], nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->Barrier(g_r.ao_tex[1], nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->Barrier(g_r.ao_lin_depth, nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->Barrier(g_r.ao_luma, nrhi::ResourceState::kPixelShaderResource, + nrhi::ResourceState::kRenderTarget); + cmd->FlushBarriers(); + return true; +} + bool EnsurePipeline(const NativeGuestOutputRenderContext& context) { if (g_r.failed) return false; nrhi::Device* device = context.device; @@ -18195,6 +18599,27 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat scissor); } + // ---- Screen-space ambient occlusion (ssao.hlsl: GTAO) ---- + // Multiplies the resolved scene by a horizon-based visibility term before + // any downstream consumer (photo chain, 2D overlay, blur). Runs after the + // outline composite, which relies on the main layout latched from the + // scene pass. + if (use_depth && !loading_native && + REXCVAR_GET(skate3_native_render_scene_ssao) && + ApplySsaoPass(context, cmd, scene, viewport, scissor)) { + // The AO chain switched binding layouts; restore the main-pass root + // bindings the later passes latch (same restore as the photo chain's). + cmd->SetViewport(viewport); + cmd->SetScissor(scissor); + cmd->SetBindingLayout(g_r.layout); + if (g_r.shadow_cb != nullptr) { + const uint32_t cb_offset = + uint32_t(frame_number % RendererState::kShadowCbRegions) * 256u; + cmd->SetConstantBuffer(6, g_r.shadow_cb, cb_offset); + cmd->SetConstantBuffer(9, g_r.bone_ring, bone_region); + } + } + // ---- Photo-editor postfx chain (photo_fx.hlsl: exact ucode ports) ---- // While the photo-mission photo editor is up and every pass's live // constants were captured this frame, apply the game's own chain over the diff --git a/src/skate3_native_scene.h b/src/skate3_native_scene.h index 2f69677..db96594 100644 --- a/src/skate3_native_scene.h +++ b/src/skate3_native_scene.h @@ -264,6 +264,11 @@ struct FrameScene { uint64_t generation = 0; float view_proj[16] = {}; float cam_pos[3] = {}; + // Raw guest projection matrix (viewcam +0x60, row-vector, m23 = 1), + // published alongside view_proj. Consumed by depth-based post passes + // (SSAO linearize/unproject via m00/m11/m22/m32). Zeros until the first + // publish; camera smoothing replaces only the view, never this. + float proj[16] = {}; // Global distance-fog parameter rows, captured once per frame from the // first main-pass draw's VS constant bank (main-pass layout: c4 = camera, // the validation key; c5 = fog ramp scale/bias/exponent, c6 = linear-space diff --git a/third_party/rexglue-sdk b/third_party/rexglue-sdk index 2cab1be..7f6a5b5 160000 --- a/third_party/rexglue-sdk +++ b/third_party/rexglue-sdk @@ -1 +1 @@ -Subproject commit 2cab1be8eb99ad8b8d8b00a36558850191f34d3e +Subproject commit 7f6a5b5b7c846616c19cd2a9efac586de6175bd6