diff --git a/README.txt b/README.txt index a8d73ce..32206a2 100644 --- a/README.txt +++ b/README.txt @@ -1,3 +1,42 @@ +============================================================ +SUN / MOON (build=sun-moon) +============================================================ +Sun disc 15% smaller: SUN_DISC_RADIUS_PX 110 -> 93.5 (sky disc and the lens +flare's visibility rays). Moon disc = the sun's radius (was 0.75 x radius^2): +same apparent size - 400x smaller, 400x closer. Moonlight -10%: night light +magnitude MOON_LIGHT 0.621 (was 0.69); the moon's placement factor (0.69) is +unchanged. No asset changed. + +============================================================ +LOGO 2048 + SATIN + LENS FLARE (build=logo-satin-flare) +============================================================ +PS4 bc-tiled run: 15712 frames at 16.67 ms, no stall, model path on at f=120; +floor pass ~200k GPU ticks (was ~520k with RGBA8). The staged start is removed +(model path from the first frame again); checkpoints and rts= stay. +(The first 2048 build used shadPS4 src/resources/shadps4.png for the badge - a +different version: cyan triangle, teal bracket. Replaced by the original's.) +Logo (tools/logo_2048.png, used by gen_model.py): the badge rebuilt at 1024 px +from the original ShadPS4 logo artwork (shad.png: all four symbols azure +(20, 159, 251), vertical linear gradient; layered coverage, crisp edges; back at +256 px mean error 1.4/255) + "ShadPS4" set in URW +Gothic Demi - the logo's font (Avant Garde Gothic Demi; picked by fitting 21 fonts +to the 256 px logo: NCC 0.79, next 0.50); outline, drop shadow and badge halo +fitted by least squares to that logo. Cube maps now 2048: albedo BC1 (49.4 dB), +normal BC5, height BC4; engraving = distance-field bevel (10 px) on the logo +ink, depth 25% of before (MODEL_POM_DEPTH = D_UV = 0.003125). +Satin (ps_model, CAFE0134, RSRC1 0x318): GGX specular (MODEL_ROUGHNESS 0.45), +Schlick-Smith visibility, Schlick Fresnel (MODEL_F0 0.04) x shadow x relief x +sun colour, plus a sky reflection (horizon..zenith by R.y) x roughness-aware +Fresnel. Fresnel weights 0 -> bit-identical; term vs float64 within 2.1e-6. +Lens flare (ps_post_final, CAFE0214, RSRC1 0x148): six ghosts on the +sun-centre axis, a horizontal streak and a halo, in linear light before the +clamp; strength = sun colour x FLARE_STRENGTH x visibility x edge fade +(FLARE_EDGE). Visibility (CPU, exact for this scene): 29 rays through the sun +disc weighted by ps_dark's disc profile, against the floor as generated +(paraboloid, +-300) and the prop's box through its transform. Strength 0 -> +bit-identical; shader term vs float64 within 1.4e-6; occlusion test = float64 +on 200k rays; post table + 1 block (final pass dwords 28..35). + ============================================================ BC TEXTURES TILED (PS4 HANG FIX) (build=bc-tiled) ============================================================ diff --git a/assets/images/cube/albedo.dds b/assets/images/cube/albedo.dds index 01af6ea..4dd4267 100644 Binary files a/assets/images/cube/albedo.dds and b/assets/images/cube/albedo.dds differ diff --git a/assets/images/cube/height.dds b/assets/images/cube/height.dds index 772d322..7fdf157 100644 Binary files a/assets/images/cube/height.dds and b/assets/images/cube/height.dds differ diff --git a/assets/images/cube/normal.dds b/assets/images/cube/normal.dds index 16515ee..907b88d 100644 Binary files a/assets/images/cube/normal.dds and b/assets/images/cube/normal.dds differ diff --git a/shaders/ps_model.h b/shaders/ps_model.h index b33557e..259a714 100644 --- a/shaders/ps_model.h +++ b/shaders/ps_model.h @@ -14,28 +14,43 @@ // Shadow map at world + N * desc[150], depth - desc[151] (8-bit shadow map). // lit = 0.0707 + 0.9293 * max(0, n.L) * shadow * relief (shadow and relief // darken the direct light only), x albedo (desc[0]) x light colour (desc[32]). +// Satin finish (desc[152..157]): sun specular GGX D = a2 / (pi t^2), t = (N.H)^2 +// (a2 - 1) + 1, Schlick-Smith visibility 1 / (4 (N.L (1-k) + k) (N.V (1-k) + k)), +// Fresnel desc[154] + desc[155] (1 - V.H)^5, times pi (the diffuse convention), +// N.L, |L|, shadow, relief and the light colour; sky reflection: horizon desc[28] + +// (zenith desc[24] - horizon) clamp(R.y), R = reflect(-V, N), times desc[156] + +// desc[157] (1 - N.V)^5. desc[152] = a^2, desc[153] = k = a / 2 (a = roughness^2). +// With desc[154..157] = 0 the output is bit-identical to the shader without it. // Fog as ps_shader / ps_floor. // With every feature off the output is bit-identical to ps_shader without fog // (float32 emulation). Inputs: attr0..2, PERSP_CENTER + POS_Y_FLOAT (v2). // Normal map: BC5 (x, y); z = sqrt(max(0, 1 - x^2 - y^2)) (an RGB map gives the same // result for unit normals). -// PGM_RSRC1 0x2d8 (98 VGPRs, 90 SGPRs incl. VCC). Hash CAFE0133. +// PGM_RSRC1 0x318 (100 VGPRs, 98 SGPRs incl. VCC). Hash CAFE0134. static const uint32_t ps_model_binary[] __attribute__((aligned(256))) = { - 0xBEEB03FF, 0x00000170, 0xBEFC0302, 0xBED4047E, 0xBEFE0A7E, 0xC0820108, 0xC0C40100, 0xC0C80180, + 0xBEEB03FF, 0x0000019F, 0xBEFC0302, 0xBED4047E, 0xBEFE0A7E, 0xC0820108, 0xC0C40100, 0xC0C80180, 0xC0CC0188, 0xC0900164, 0xC0920168, 0xC0940190, 0xC0960194, 0xC098010C, 0xC09A0120, 0xC0DC0128, - 0xC0A00150, 0xC1220130, 0xC8280000, 0xC8290001, 0xC82C0100, 0xC82D0101, 0xC8640200, 0xC8650201, - 0xC8680300, 0xC8690301, 0xC8300400, 0xC8310401, 0xC8340500, 0xC8350501, 0xC8380600, 0xC8390601, - 0xC8600700, 0xC8610701, 0xC86C0800, 0xC86D0801, 0xC8700900, 0xC8710901, 0xC8740A00, 0xC8750A01, - 0xC8780B00, 0xC8790B01, 0xBF8C007F, 0x10063118, 0x3E063319, 0x3E06351A, 0x7E065D03, 0x10300718, - 0x10320719, 0x1034071A, 0x10063718, 0x3E063919, 0x3E063B1A, 0x10080718, 0x0836091B, 0x10080719, - 0x0838091C, 0x1008071A, 0x083A091D, 0x1006371B, 0x3E06391C, 0x3E063B1D, 0x7E065D03, 0x1036071B, - 0x1038071C, 0x103A071D, 0x103E3B19, 0x1006391A, 0x083E071F, 0x1040371A, 0x10063B18, 0x08400720, - 0x10423918, 0x10063719, 0x08420721, 0x103E3D1F, 0x10403D20, 0x10423D21, 0x08441824, 0x08461A25, - 0x08481C26, 0x104A4522, 0x3E4A4723, 0x3E4A4924, 0x7E065D25, 0x104C0725, 0x10440722, 0x10460723, - 0x10480724, 0x10083722, 0x3E083923, 0x3E083B24, 0x100A3F22, 0x3E0A4123, 0x3E0A4324, 0x100C3122, - 0x3E0C3323, 0x3E0C3524, 0x20100CFF, 0x3DCCCCCD, 0x7E105508, 0x10101028, 0x101010FF, 0x3D800000, - 0x10501104, 0x10521105, 0x7E58030A, 0x7E5A030B, 0x7E5C030A, 0x7E5E030B, 0x7E560280, 0x7E600280, - 0x7E620280, 0xBED6047E, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, + 0xC0A00150, 0xC1220130, 0xC0EC0198, 0xC8280000, 0xC8290001, 0xC82C0100, 0xC82D0101, 0xC8640200, + 0xC8650201, 0xC8680300, 0xC8690301, 0xC8300400, 0xC8310401, 0xC8340500, 0xC8350501, 0xC8380600, + 0xC8390601, 0xC8600700, 0xC8610701, 0xC86C0800, 0xC86D0801, 0xC8700900, 0xC8710901, 0xC8740A00, + 0xC8750A01, 0xC8780B00, 0xC8790B01, 0xBF8C007F, 0x10063118, 0x3E063319, 0x3E06351A, 0x7E065D03, + 0x10300718, 0x10320719, 0x1034071A, 0x10063718, 0x3E063919, 0x3E063B1A, 0x10080718, 0x0836091B, + 0x10080719, 0x0838091C, 0x1008071A, 0x083A091D, 0x1006371B, 0x3E06391C, 0x3E063B1D, 0x7E065D03, + 0x1036071B, 0x1038071C, 0x103A071D, 0x103E3B19, 0x1006391A, 0x083E071F, 0x1040371A, 0x10063B18, + 0x08400720, 0x10423918, 0x10063719, 0x08420721, 0x103E3D1F, 0x10403D20, 0x10423D21, 0x08441824, + 0x08461A25, 0x08481C26, 0x104A4522, 0x3E4A4723, 0x3E4A4924, 0x7E065D25, 0x104C0725, 0x10440722, + 0x10460723, 0x10480724, 0x10083722, 0x3E083923, 0x3E083B24, 0x100A3F22, 0x3E0A4123, 0x3E0A4324, + 0x100C3122, 0x3E0C3323, 0x3E0C3524, 0x20100CFF, 0x3DCCCCCD, 0x7E105508, 0x10101028, 0x101010FF, + 0x3D800000, 0x10501104, 0x10521105, 0x7E58030A, 0x7E5A030B, 0x7E5C030A, 0x7E5E030B, 0x7E560280, + 0x7E600280, 0x7E620280, 0xBED6047E, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, + 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, + 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, + 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, + 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, + 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, + 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, + 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, + 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, @@ -69,50 +84,53 @@ static const uint32_t ps_model_binary[] __attribute__((aligned(256))) = { 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, - 0x066856FF, 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, - 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, - 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, - 0xF0800100, 0x0106322C, 0xBF8C0F70, 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, - 0x87EA6A56, 0xBED6046A, 0x00626333, 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, - 0x0868532D, 0x005A692D, 0x066856FF, 0x3D800000, 0x0056692B, 0xF0800100, 0x0106322C, 0xBF8C0F70, - 0x10646429, 0x0664642A, 0x086464F2, 0x08665732, 0x7C026680, 0x87EA6A56, 0xBED6046A, 0x00626333, - 0x005C592E, 0x005E5B2F, 0x00606730, 0x0868512C, 0x0058692C, 0x0868532D, 0x005A692D, 0x066856FF, - 0x3D800000, 0x0056692B, 0x08686131, 0x1E6868FF, 0xB58637BD, 0x7E685534, 0x10686931, 0x20686880, - 0x1E6868F2, 0x086A592E, 0x3E586935, 0x086A5B2F, 0x3E5A6935, 0x106A68FF, 0x3D800000, 0x086A6B2B, - 0x086A6AF2, 0x7E6E0230, 0x7E700231, 0x7E720232, 0x10066F37, 0x3E067138, 0x3E067339, 0x7E065D03, - 0x106E0737, 0x10700738, 0x10720739, 0x10743737, 0x3E743938, 0x3E743B39, 0x10763F37, 0x3E764138, - 0x3E764339, 0x10783137, 0x3E783338, 0x3E783539, 0x207A78FF, 0x3D4CCCCD, 0x7E7A553D, 0x087C6AF2, - 0x107C7CFF, 0x3E000000, 0x107E7D3D, 0x107E7E28, 0x10807F3A, 0x10827F3B, 0x7E94032C, 0x7E96032D, - 0x3E9480F2, 0x3E9682F2, 0x7E98032C, 0x7E9A032D, 0x3E9880F4, 0x3E9A82F4, 0x7E9C032C, 0x7E9E032D, - 0x3E9C80FF, 0x40400000, 0x3E9E82FF, 0x40400000, 0x7EA0032C, 0x7EA2032D, 0x3EA080F6, 0x3EA282F6, - 0x7EA4032C, 0x7EA6032D, 0x3EA480FF, 0x40A00000, 0x3EA682FF, 0x40A00000, 0x7EA8032C, 0x7EAA032D, - 0x3EA880FF, 0x40C00000, 0x3EAA82FF, 0x40C00000, 0x7EAC032C, 0x7EAE032D, 0x3EAC80FF, 0x40E00000, - 0x3EAE82FF, 0x40E00000, 0x7EB0032C, 0x7EB2032D, 0x3EB080FF, 0x41000000, 0x3EB282FF, 0x41000000, - 0xF0800F00, 0x0022102C, 0xF0800F00, 0x0024142C, 0xF0800100, 0x01065A4A, 0xF0800100, 0x01065B4C, - 0xF0800100, 0x01065C4E, 0xF0800100, 0x01065D50, 0xF0800100, 0x01065E52, 0xF0800100, 0x01065F54, - 0xF0800100, 0x01066056, 0xF0800100, 0x01066158, 0xC08C0118, 0xC08E011C, 0xBF8C0F70, 0xC010016D, - 0xC0108173, 0x7E840280, 0x10B4B429, 0x06B4B42A, 0x7E860335, 0x3E867CF2, 0x08B4875A, 0x2084B542, - 0x10B6B629, 0x06B6B62A, 0x7E860335, 0x3E867CF4, 0x08B6875B, 0x2084B742, 0x10B8B829, 0x06B8B82A, - 0x7E860335, 0x3E867CFF, 0x40400000, 0x08B8875C, 0x2084B942, 0x10BABA29, 0x06BABA2A, 0x7E860335, - 0x3E867CF6, 0x08BA875D, 0x2084BB42, 0x10BCBC29, 0x06BCBC2A, 0x7E860335, 0x3E867CFF, 0x40A00000, - 0x08BC875E, 0x2084BD42, 0x10BEBE29, 0x06BEBE2A, 0x7E860335, 0x3E867CFF, 0x40C00000, 0x08BE875F, - 0x2084BF42, 0x10C0C029, 0x06C0C02A, 0x7E860335, 0x3E867CFF, 0x40E00000, 0x08C08760, 0x2084C142, - 0x10C2C229, 0x06C2C22A, 0x7E860335, 0x3E867CFF, 0x41000000, 0x08C28761, 0x2084C342, 0x108484F6, - 0x1E8484F2, 0x1084842B, 0x088484F2, 0x102828F4, 0x062828F3, 0x102A2AF4, 0x062A2AF3, 0x102C2914, - 0x3E2C2B15, 0x082C2CF2, 0x202C2C80, 0x7E2C6716, 0x1028282C, 0x102A2A2D, 0x1088291B, 0x3E882B1F, - 0x3E882D18, 0x108A291C, 0x3E8A2B20, 0x3E8A2D19, 0x108C291D, 0x3E8C2B21, 0x3E8C2D1A, 0x10068944, - 0x3E068B45, 0x3E068D46, 0x7E065D03, 0x10880744, 0x108A0745, 0x108C0746, 0x108E8830, 0x10908A31, - 0x068E9147, 0x10908C32, 0x068E9147, 0x208E8E80, 0x7E90030C, 0x3E90302E, 0x7E92030D, 0x3E92322E, - 0x7E94030E, 0x3E94342E, 0x10989044, 0x3E989245, 0x3E989446, 0x06989847, 0x109A9048, 0x3E9A9249, - 0x3E9A944A, 0x069A9A4B, 0x109C904C, 0x3E9C924D, 0x3E9C944E, 0x069C9C4F, 0x109E9050, 0x3E9E9251, - 0x3E9E9452, 0x069E9E53, 0x7EA0554F, 0x1098A14C, 0x109AA14D, 0x109CA14E, 0x10A298F0, 0x06A2A2F0, - 0x10A49AF0, 0x06A4A4F0, 0x1CA69C80, 0x1AA6A6F2, 0x0AA6A62F, 0xF0800100, 0x020E5451, 0xBF8C0070, - 0x7C02A754, 0x7EAA0280, 0x00A8AAF2, 0x7C029E80, 0x00A8A8F2, 0x10AAA8FF, 0x3F4848E6, 0x06AAAAFF, - 0x3E5EDC67, 0x108EAB47, 0x108E8547, 0x10AC8EFF, 0x3F6DE3F7, 0x06ACACFF, 0x3D90E047, 0x1050AD10, - 0x1052AD11, 0x1054AD12, 0x10505034, 0x10525235, 0x10545436, 0x10AE4C20, 0x06AEAE27, 0x7EAE4B57, - 0x1EAEAEF2, 0x08AEAEF2, 0x10B00421, 0x7E70021C, 0x0A707018, 0x1070B138, 0x06707018, 0x7E72021D, - 0x0A727219, 0x1072B139, 0x06727219, 0x7E74021E, 0x0A74741A, 0x1074B13A, 0x0674741A, 0x08B27128, - 0x3E70AF59, 0x08B27329, 0x3E72AF59, 0x08B2752A, 0x3E74AF59, 0x7E5602F2, 0xBEFE0454, 0xF800180F, - 0x2B3A3938, 0xBF810000, 0x5362724F, 0x00726468, 0x000B8800, 0x00000000, 0xDEADBEEF, 0xCAFE0133, - 0x00000000, + 0x066856FF, 0x3D800000, 0x0056692B, 0x08686131, 0x1E6868FF, 0xB58637BD, 0x7E685534, 0x10686931, + 0x20686880, 0x1E6868F2, 0x086A592E, 0x3E586935, 0x086A5B2F, 0x3E5A6935, 0x106A68FF, 0x3D800000, + 0x086A6B2B, 0x086A6AF2, 0x7E6E0230, 0x7E700231, 0x7E720232, 0x10066F37, 0x3E067138, 0x3E067339, + 0x7E065D03, 0x106E0737, 0x10700738, 0x10720739, 0x10743737, 0x3E743938, 0x3E743B39, 0x10763F37, + 0x3E764138, 0x3E764339, 0x10783137, 0x3E783338, 0x3E783539, 0x207A78FF, 0x3D4CCCCD, 0x7E7A553D, + 0x087C6AF2, 0x107C7CFF, 0x3E000000, 0x107E7D3D, 0x107E7E28, 0x10807F3A, 0x10827F3B, 0x7E94032C, + 0x7E96032D, 0x3E9480F2, 0x3E9682F2, 0x7E98032C, 0x7E9A032D, 0x3E9880F4, 0x3E9A82F4, 0x7E9C032C, + 0x7E9E032D, 0x3E9C80FF, 0x40400000, 0x3E9E82FF, 0x40400000, 0x7EA0032C, 0x7EA2032D, 0x3EA080F6, + 0x3EA282F6, 0x7EA4032C, 0x7EA6032D, 0x3EA480FF, 0x40A00000, 0x3EA682FF, 0x40A00000, 0x7EA8032C, + 0x7EAA032D, 0x3EA880FF, 0x40C00000, 0x3EAA82FF, 0x40C00000, 0x7EAC032C, 0x7EAE032D, 0x3EAC80FF, + 0x40E00000, 0x3EAE82FF, 0x40E00000, 0x7EB0032C, 0x7EB2032D, 0x3EB080FF, 0x41000000, 0x3EB282FF, + 0x41000000, 0xF0800F00, 0x0022102C, 0xF0800F00, 0x0024142C, 0xF0800100, 0x01065A4A, 0xF0800100, + 0x01065B4C, 0xF0800100, 0x01065C4E, 0xF0800100, 0x01065D50, 0xF0800100, 0x01065E52, 0xF0800100, + 0x01065F54, 0xF0800100, 0x01066056, 0xF0800100, 0x01066158, 0xC08C0118, 0xC08E011C, 0xBF8C0F70, + 0xC010016D, 0xC0108173, 0x7E840280, 0x10B4B429, 0x06B4B42A, 0x7E860335, 0x3E867CF2, 0x08B4875A, + 0x2084B542, 0x10B6B629, 0x06B6B62A, 0x7E860335, 0x3E867CF4, 0x08B6875B, 0x2084B742, 0x10B8B829, + 0x06B8B82A, 0x7E860335, 0x3E867CFF, 0x40400000, 0x08B8875C, 0x2084B942, 0x10BABA29, 0x06BABA2A, + 0x7E860335, 0x3E867CF6, 0x08BA875D, 0x2084BB42, 0x10BCBC29, 0x06BCBC2A, 0x7E860335, 0x3E867CFF, + 0x40A00000, 0x08BC875E, 0x2084BD42, 0x10BEBE29, 0x06BEBE2A, 0x7E860335, 0x3E867CFF, 0x40C00000, + 0x08BE875F, 0x2084BF42, 0x10C0C029, 0x06C0C02A, 0x7E860335, 0x3E867CFF, 0x40E00000, 0x08C08760, + 0x2084C142, 0x10C2C229, 0x06C2C22A, 0x7E860335, 0x3E867CFF, 0x41000000, 0x08C28761, 0x2084C342, + 0x108484F6, 0x1E8484F2, 0x1084842B, 0x088484F2, 0x102828F4, 0x062828F3, 0x102A2AF4, 0x062A2AF3, + 0x102C2914, 0x3E2C2B15, 0x082C2CF2, 0x202C2C80, 0x7E2C6716, 0x1028282C, 0x102A2A2D, 0x1088291B, + 0x3E882B1F, 0x3E882D18, 0x108A291C, 0x3E8A2B20, 0x3E8A2D19, 0x108C291D, 0x3E8C2B21, 0x3E8C2D1A, + 0x10068944, 0x3E068B45, 0x3E068D46, 0x7E065D03, 0x10880744, 0x108A0745, 0x108C0746, 0x108E8830, + 0x10908A31, 0x068E9147, 0x10908C32, 0x068E9147, 0x208E8E80, 0x7E90030C, 0x3E90302E, 0x7E92030D, + 0x3E92322E, 0x7E94030E, 0x3E94342E, 0x10989044, 0x3E989245, 0x3E989446, 0x06989847, 0x109A9048, + 0x3E9A9249, 0x3E9A944A, 0x069A9A4B, 0x109C904C, 0x3E9C924D, 0x3E9C944E, 0x069C9C4F, 0x109E9050, + 0x3E9E9251, 0x3E9E9452, 0x069E9E53, 0x7EA0554F, 0x1098A14C, 0x109AA14D, 0x109CA14E, 0x10A298F0, + 0x06A2A2F0, 0x10A49AF0, 0x06A4A4F0, 0x1CA69C80, 0x1AA6A6F2, 0x0AA6A62F, 0xF0800100, 0x020E5451, + 0xBF8C0070, 0x7C02A754, 0x7EAA0280, 0x00A8AAF2, 0x7C029E80, 0x00A8A8F2, 0x10AAA8FF, 0x3F4848E6, + 0x06AAAAFF, 0x3E5EDC67, 0x108EAB47, 0x108E8547, 0x10AC8EFF, 0x3F6DE3F7, 0x06ACACFF, 0x3D90E047, + 0x1050AD10, 0x1052AD11, 0x1054AD12, 0x10505034, 0x10525235, 0x10545436, 0x7E740230, 0x1074753A, + 0x7E760231, 0x3E74773B, 0x7E760232, 0x3E74773B, 0x7E74673A, 0x06B44537, 0x06B64738, 0x06B84939, + 0x1006B55A, 0x3E06B75B, 0x3E06B95C, 0x7E065D03, 0x10B4075A, 0x10B6075B, 0x10B8075C, 0x10BAB544, + 0x3EBAB745, 0x3EBAB946, 0x20BABA80, 0x10BC6F44, 0x3EBC7145, 0x3EBC7346, 0x20BCBC80, 0x10BE4544, + 0x3EBE4745, 0x3EBE4946, 0x20BEBEFF, 0x38D1B717, 0x10C0B522, 0x3EC0B723, 0x3EC0B924, 0x20C0C080, + 0x10C2BB5D, 0x7E760258, 0x067676F3, 0x10C27761, 0x06C2C2F2, 0x10C2C361, 0x7EC25561, 0x10C2C258, + 0x7E760259, 0x087876F2, 0x107A795E, 0x067A7A59, 0x107C795F, 0x067C7C59, 0x107A7D3D, 0x7E7A553D, + 0x107A7AFF, 0x3E800000, 0x087CC0F2, 0x107E7D3E, 0x107E7F3F, 0x107E7D3F, 0x107E7E5B, 0x067E7E5A, + 0x10C27B61, 0x10C27F61, 0x10C2BD61, 0x10C27561, 0x10C2AB61, 0x10C28561, 0x3E50C234, 0x3E52C235, + 0x3E54C236, 0x107C8B5F, 0x067C7D3E, 0x087C473E, 0x207C7C80, 0x1E7C7CF2, 0x087EBEF2, 0x10807F3F, + 0x10808140, 0x10807F40, 0x1080805D, 0x0680805C, 0x7E820218, 0x0A82821C, 0x10827D41, 0x0682821C, + 0x3E508141, 0x7E820219, 0x0A82821D, 0x10827D41, 0x0682821D, 0x3E528141, 0x7E82021A, 0x0A82821E, + 0x10827D41, 0x0682821E, 0x3E548141, 0x10AE4C20, 0x06AEAE27, 0x7EAE4B57, 0x1EAEAEF2, 0x08AEAEF2, + 0x10B00421, 0x7E70021C, 0x0A707018, 0x1070B138, 0x06707018, 0x7E72021D, 0x0A727219, 0x1072B139, + 0x06727219, 0x7E74021E, 0x0A74741A, 0x1074B13A, 0x0674741A, 0x08B27128, 0x3E70AF59, 0x08B27329, + 0x3E72AF59, 0x08B2752A, 0x3E74AF59, 0x7E5602F2, 0xBEFE0454, 0xF800180F, 0x2B3A3938, 0xBF810000, + 0x5362724F, 0x00726468, 0x000D0000, 0x00000000, 0xDEADBEEF, 0xCAFE0134, 0x00000000, }; diff --git a/shaders/ps_model.s b/shaders/ps_model.s index 2500785..98cfc39 100644 --- a/shaders/ps_model.s +++ b/shaders/ps_model.s @@ -14,6 +14,7 @@ s_load_dwordx4 s[52:55], s[0:1], 0x20 s_load_dwordx8 s[56:63], s[0:1], 0x28 s_load_dwordx4 s[64:67], s[0:1], 0x50 s_load_dwordx16 s[68:83], s[0:1], 0x30 +s_load_dwordx8 s[88:95], s[0:1], 0x98 v_interp_p1_f32 v10, v0, attr0.x v_interp_p2_f32 v10, v1, attr0.x v_interp_p1_f32 v11, v0, attr0.y @@ -637,6 +638,97 @@ v_mul_f32 v42, v18, v86 v_mul_f32 v40, s52, v40 v_mul_f32 v41, s53, v41 v_mul_f32 v42, s54, v42 +v_mov_b32 v58, s48 +v_mul_f32 v58, v58, v58 +v_mov_b32 v59, s49 +v_mac_f32 v58, v59, v59 +v_mov_b32 v59, s50 +v_mac_f32 v58, v59, v59 +v_sqrt_f32 v58, v58 +v_add_f32 v90, v55, v34 +v_add_f32 v91, v56, v35 +v_add_f32 v92, v57, v36 +v_mul_f32 v3, v90, v90 +v_mac_f32 v3, v91, v91 +v_mac_f32 v3, v92, v92 +v_rsq_f32 v3, v3 +v_mul_f32 v90, v90, v3 +v_mul_f32 v91, v91, v3 +v_mul_f32 v92, v92, v3 +v_mul_f32 v93, v68, v90 +v_mac_f32 v93, v69, v91 +v_mac_f32 v93, v70, v92 +v_max_f32 v93, 0, v93 +v_mul_f32 v94, v68, v55 +v_mac_f32 v94, v69, v56 +v_mac_f32 v94, v70, v57 +v_max_f32 v94, 0, v94 +v_mul_f32 v95, v68, v34 +v_mac_f32 v95, v69, v35 +v_mac_f32 v95, v70, v36 +v_max_f32 v95, 0x38d1b717, v95 +v_mul_f32 v96, v34, v90 +v_mac_f32 v96, v35, v91 +v_mac_f32 v96, v36, v92 +v_max_f32 v96, 0, v96 +v_mul_f32 v97, v93, v93 +v_mov_b32 v59, s88 +v_add_f32 v59, -1.0, v59 +v_mul_f32 v97, v97, v59 +v_add_f32 v97, 1.0, v97 +v_mul_f32 v97, v97, v97 +v_rcp_f32 v97, v97 +v_mul_f32 v97, s88, v97 +v_mov_b32 v59, s89 +v_sub_f32 v60, 1.0, v59 +v_mul_f32 v61, v94, v60 +v_add_f32 v61, s89, v61 +v_mul_f32 v62, v95, v60 +v_add_f32 v62, s89, v62 +v_mul_f32 v61, v61, v62 +v_rcp_f32 v61, v61 +v_mul_f32 v61, 0x3e800000, v61 +v_sub_f32 v62, 1.0, v96 +v_mul_f32 v63, v62, v62 +v_mul_f32 v63, v63, v63 +v_mul_f32 v63, v63, v62 +v_mul_f32 v63, s91, v63 +v_add_f32 v63, s90, v63 +v_mul_f32 v97, v97, v61 +v_mul_f32 v97, v97, v63 +v_mul_f32 v97, v97, v94 +v_mul_f32 v97, v97, v58 +v_mul_f32 v97, v97, v85 +v_mul_f32 v97, v97, v66 +v_mac_f32 v40, s52, v97 +v_mac_f32 v41, s53, v97 +v_mac_f32 v42, s54, v97 +v_mul_f32 v62, v95, v69 +v_add_f32 v62, v62, v62 +v_sub_f32 v62, v62, v35 +v_max_f32 v62, 0, v62 +v_min_f32 v62, 1.0, v62 +v_sub_f32 v63, 1.0, v95 +v_mul_f32 v64, v63, v63 +v_mul_f32 v64, v64, v64 +v_mul_f32 v64, v64, v63 +v_mul_f32 v64, s93, v64 +v_add_f32 v64, s92, v64 +v_mov_b32 v65, s24 +v_subrev_f32 v65, s28, v65 +v_mul_f32 v65, v65, v62 +v_add_f32 v65, s28, v65 +v_mac_f32 v40, v65, v64 +v_mov_b32 v65, s25 +v_subrev_f32 v65, s29, v65 +v_mul_f32 v65, v65, v62 +v_add_f32 v65, s29, v65 +v_mac_f32 v41, v65, v64 +v_mov_b32 v65, s26 +v_subrev_f32 v65, s30, v65 +v_mul_f32 v65, v65, v62 +v_add_f32 v65, s30, v65 +v_mac_f32 v42, v65, v64 v_mul_f32 v87, s32, v38 v_add_f32 v87, s39, v87 v_exp_f32 v87, v87 diff --git a/shaders/ps_post_final.h b/shaders/ps_post_final.h index fcc9e5c..afe0605 100644 --- a/shaders/ps_post_final.h +++ b/shaders/ps_post_final.h @@ -7,19 +7,46 @@ // +-0.5/255 (interleaved gradient noise on the pixel position) before the // UNORM display write - 8-bit output of smooth gradients no longer bands. // desc: scene T# [0] + point S# [8], {1/w, 1/h, bloom, exposure} [12], -// bloom T# [16] + bilinear S# [24]. PGM_RSRC1 0x105 (22 VGPRs, 40 SGPRs). -// Hash CAFE0213. +// bloom T# [16] + bilinear S# [24]. +// Lens flare (added in linear light before the clamp): table dwords 28..29 = sun +// (u, v) = pixel / size, 30..32 = strength RGB (sun colour x FLARE_STRENGTH x +// visibility x edge fade, 0 = off; set per frame by main.c). e = (uv - 0.5) (A, 1), +// d = (sun - 0.5) (A, 1), A = 1920/1080. Six ghosts at e - t d (t -0.25 -0.5 -0.8 +// -1.1 0.4 0.7): max(0, 1 - r^2 / R^2)^2 x intensity x tint; a streak exp2(-(uy^2 / +// 0.006^2 + 4 |ux|)) x 0.25 x (0.55, 0.75, 1.0); a halo max(0, 1 - ((|u| - 0.30) / +// 0.03)^2)^2 x 0.05 x (1.0, 0.85, 0.7), u = e - d. Strength 0: bit-identical output. +// PGM_RSRC1 0x148 (36 VGPRs, 42 SGPRs incl. VCC). Hash CAFE0214. static const uint32_t ps_post_final_binary[] __attribute__((aligned(256))) = { - 0xBEEB03FF, 0x00000029, 0xC0C20100, 0xC0860108, 0xC088010C, 0xC0CA0110, 0xC08E0118, 0xBF8C007F, - 0x10080410, 0x100A0611, 0xF09C0F00, 0x00610804, 0xF09C0F00, 0x00E50C04, 0x102804FF, 0x3D897143, - 0x3E2806FF, 0x3BBF4590, 0x7E284114, 0x102828FF, 0x4253EE82, 0x7E284114, 0x0A2828F0, 0x102828FF, - 0x3B808081, 0xBF8C0F70, 0x3E101812, 0x3E121A12, 0x3E141C12, 0x10101013, 0x10121213, 0x10141413, - 0x20101080, 0x1E1010F2, 0x20121280, 0x1E1212F2, 0x20141480, 0x1E1414F2, 0x7E204F08, 0x102020FF, - 0x3ED55555, 0x7E204B10, 0x102020FF, 0x3F870A3D, 0x0A2020FF, 0x3D6147AE, 0x102A10FF, 0x414EB852, - 0x7C0C10FF, 0x3B4D2E1C, 0x00202B10, 0x7E224F09, 0x102222FF, 0x3ED55555, 0x7E224B11, 0x102222FF, - 0x3F870A3D, 0x0A2222FF, 0x3D6147AE, 0x102A12FF, 0x414EB852, 0x7C0C12FF, 0x3B4D2E1C, 0x00222B11, - 0x7E244F0A, 0x102424FF, 0x3ED55555, 0x7E244B12, 0x102424FF, 0x3F870A3D, 0x0A2424FF, 0x3D6147AE, - 0x102A14FF, 0x414EB852, 0x7C0C14FF, 0x3B4D2E1C, 0x00242B12, 0x06202910, 0x06222911, 0x06242912, - 0x7E2602F2, 0xF800180F, 0x13121110, 0xBF810000, 0x5362724F, 0x00726468, 0x00015000, 0x00000000, - 0xDEADBEEF, 0xCAFE0213, 0x00000000, + 0xBEEB03FF, 0x0000007A, 0xC0C20100, 0xC0860108, 0xC088010C, 0xC0CA0110, 0xC08E0118, 0xC0D0011C, + 0xBF8C007F, 0x10080410, 0x100A0611, 0xF09C0F00, 0x00610804, 0xF09C0F00, 0x00E50C04, 0x102804FF, + 0x3D897143, 0x3E2806FF, 0x3BBF4590, 0x7E284114, 0x102828FF, 0x4253EE82, 0x7E284114, 0x0A2828F0, + 0x102828FF, 0x3B808081, 0xBF8C0F70, 0x3E101812, 0x3E121A12, 0x3E141C12, 0x10101013, 0x10121213, + 0x10141413, 0x063008F1, 0x103030FF, 0x3FE38E39, 0x06320AF1, 0x7E2C0220, 0x062C2CF1, 0x102C2CFF, + 0x3FE38E39, 0x7E2E0221, 0x062E2EF1, 0x7E340280, 0x7E360280, 0x7E380280, 0x103A2CFF, 0xBE800000, + 0x083A3B18, 0x103C2EFF, 0xBE800000, 0x083C3D19, 0x103A3B1D, 0x3E3A3D1E, 0x103A3AFF, 0x444C14E6, + 0x083A3AF2, 0x203A3A80, 0x103A3B1D, 0x3E343AFF, 0x3EB33333, 0x3E363AFF, 0x3E810625, 0x3E383AFF, + 0x3E0F5C29, 0x103A2CF1, 0x083A3B18, 0x103C2EF1, 0x083C3D19, 0x103A3B1D, 0x3E3A3D1E, 0x103A3AFF, + 0x42F6E9E0, 0x083A3AF2, 0x203A3A80, 0x103A3B1D, 0x3E343AFF, 0x3D3851EC, 0x3E363AFF, 0x3DA3D70A, + 0x3E383AFF, 0x3DCCCCCD, 0x103A2CFF, 0xBF4CCCCD, 0x083A3B18, 0x103C2EFF, 0xBF4CCCCD, 0x083C3D19, + 0x103A3B1D, 0x3E3A3D1E, 0x103A3AFF, 0x43C80000, 0x083A3AF2, 0x203A3A80, 0x103A3B1D, 0x3E343AFF, + 0x3DCAC083, 0x3E363AFF, 0x3E3851EC, 0x3E383AFF, 0x3DDD2F1B, 0x103A2CFF, 0xBF8CCCCD, 0x083A3B18, + 0x103C2EFF, 0xBF8CCCCD, 0x083C3D19, 0x103A3B1D, 0x3E3A3D1E, 0x103A3AFF, 0x424C14E6, 0x083A3AF2, + 0x203A3A80, 0x103A3B1D, 0x3E343AFF, 0x3D2C0831, 0x3E363AFF, 0x3D072B02, 0x3E383AFF, 0x3D75C28F, + 0x103A2CFF, 0x3ECCCCCD, 0x083A3B18, 0x103C2EFF, 0x3ECCCCCD, 0x083C3D19, 0x103A3B1D, 0x3E3A3D1E, + 0x103A3AFF, 0x44C80000, 0x083A3AF2, 0x203A3A80, 0x103A3B1D, 0x3E343AFF, 0x3E99999A, 0x3E363AFF, + 0x3E828F5C, 0x3E383AFF, 0x3E28F5C3, 0x103A2CFF, 0x3F333333, 0x083A3B18, 0x103C2EFF, 0x3F333333, + 0x083C3D19, 0x103A3B1D, 0x3E3A3D1E, 0x103A3AFF, 0x438AE38E, 0x083A3AF2, 0x203A3A80, 0x103A3B1D, + 0x3E343AFF, 0x3D75C28F, 0x3E363AFF, 0x3DAC0831, 0x3E383AFF, 0x3DF5C28F, 0x083A2D18, 0x083C2F19, + 0x103E3D1E, 0x103E3EFF, 0x46D9038E, 0xD2200020, 0x40023B1D, 0x3E3E40F6, 0xD34A001F, 0x2000011F, + 0x3E343EFF, 0x3E0CCCCD, 0x3E363EFF, 0x3E400000, 0x3E383EFF, 0x3E800000, 0x103E3B1D, 0x3E3E3D1E, + 0x7E3E671F, 0x063E3EFF, 0xBE99999A, 0x103E3EFF, 0x42055555, 0x103E3F1F, 0x083E3EF2, 0x203E3E80, + 0x103E3F1F, 0x3E343EFF, 0x3D4CCCCD, 0x3E363EFF, 0x3D2E147B, 0x3E383EFF, 0x3D0F5C29, 0x3E103422, + 0x3E123623, 0x3E143824, 0x20101080, 0x1E1010F2, 0x20121280, 0x1E1212F2, 0x20141480, 0x1E1414F2, + 0x7E204F08, 0x102020FF, 0x3ED55555, 0x7E204B10, 0x102020FF, 0x3F870A3D, 0x0A2020FF, 0x3D6147AE, + 0x102A10FF, 0x414EB852, 0x7C0C10FF, 0x3B4D2E1C, 0x00202B10, 0x7E224F09, 0x102222FF, 0x3ED55555, + 0x7E224B11, 0x102222FF, 0x3F870A3D, 0x0A2222FF, 0x3D6147AE, 0x102A12FF, 0x414EB852, 0x7C0C12FF, + 0x3B4D2E1C, 0x00222B11, 0x7E244F0A, 0x102424FF, 0x3ED55555, 0x7E244B12, 0x102424FF, 0x3F870A3D, + 0x0A2424FF, 0x3D6147AE, 0x102A14FF, 0x414EB852, 0x7C0C14FF, 0x3B4D2E1C, 0x00242B12, 0x06202910, + 0x06222911, 0x06242912, 0x7E2602F2, 0xF800180F, 0x13121110, 0xBF810000, 0x5362724F, 0x00726468, + 0x0003D800, 0x00000000, 0xDEADBEEF, 0xCAFE0214, 0x00000000, }; diff --git a/shaders/ps_post_final.s b/shaders/ps_post_final.s index 92a6f2d..aaa30dc 100644 --- a/shaders/ps_post_final.s +++ b/shaders/ps_post_final.s @@ -3,6 +3,7 @@ s_load_dwordx4 s[12:15], s[0:1], 0x8 s_load_dwordx4 s[16:19], s[0:1], 0xc s_load_dwordx8 s[20:27], s[0:1], 0x10 s_load_dwordx4 s[28:31], s[0:1], 0x18 +s_load_dwordx8 s[32:39], s[0:1], 0x1c s_waitcnt lgkmcnt(0) v_mul_f32 v4, s16, v2 v_mul_f32 v5, s17, v3 @@ -22,6 +23,120 @@ v_mac_f32 v10, s18, v14 v_mul_f32 v8, s19, v8 v_mul_f32 v9, s19, v9 v_mul_f32 v10, s19, v10 +v_add_f32 v24, -0.5, v4 +v_mul_f32 v24, 0x3fe38e39, v24 +v_add_f32 v25, -0.5, v5 +v_mov_b32 v22, s32 +v_add_f32 v22, -0.5, v22 +v_mul_f32 v22, 0x3fe38e39, v22 +v_mov_b32 v23, s33 +v_add_f32 v23, -0.5, v23 +v_mov_b32 v26, 0 +v_mov_b32 v27, 0 +v_mov_b32 v28, 0 +v_mul_f32 v29, 0xbe800000, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0xbe800000, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x444c14e6, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3eb33333, v29 +v_mac_f32 v27, 0x3e810625, v29 +v_mac_f32 v28, 0x3e0f5c29, v29 +v_mul_f32 v29, 0xbf000000, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0xbf000000, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x42f6e9e0, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3d3851ec, v29 +v_mac_f32 v27, 0x3da3d70a, v29 +v_mac_f32 v28, 0x3dcccccd, v29 +v_mul_f32 v29, 0xbf4ccccd, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0xbf4ccccd, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x43c80000, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3dcac083, v29 +v_mac_f32 v27, 0x3e3851ec, v29 +v_mac_f32 v28, 0x3ddd2f1b, v29 +v_mul_f32 v29, 0xbf8ccccd, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0xbf8ccccd, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x424c14e6, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3d2c0831, v29 +v_mac_f32 v27, 0x3d072b02, v29 +v_mac_f32 v28, 0x3d75c28f, v29 +v_mul_f32 v29, 0x3ecccccd, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0x3ecccccd, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x44c80000, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3e99999a, v29 +v_mac_f32 v27, 0x3e828f5c, v29 +v_mac_f32 v28, 0x3e28f5c3, v29 +v_mul_f32 v29, 0x3f333333, v22 +v_sub_f32 v29, v24, v29 +v_mul_f32 v30, 0x3f333333, v23 +v_sub_f32 v30, v25, v30 +v_mul_f32 v29, v29, v29 +v_mac_f32 v29, v30, v30 +v_mul_f32 v29, 0x438ae38e, v29 +v_sub_f32 v29, 1.0, v29 +v_max_f32 v29, 0, v29 +v_mul_f32 v29, v29, v29 +v_mac_f32 v26, 0x3d75c28f, v29 +v_mac_f32 v27, 0x3dac0831, v29 +v_mac_f32 v28, 0x3df5c28f, v29 +v_sub_f32 v29, v24, v22 +v_sub_f32 v30, v25, v23 +v_mul_f32 v31, v30, v30 +v_mul_f32 v31, 0x46d9038e, v31 +v_max_f32 v32, v29, -v29 +v_mac_f32 v31, 4.0, v32 +v_exp_f32 v31, -v31 +v_mac_f32 v26, 0x3e0ccccd, v31 +v_mac_f32 v27, 0x3e400000, v31 +v_mac_f32 v28, 0x3e800000, v31 +v_mul_f32 v31, v29, v29 +v_mac_f32 v31, v30, v30 +v_sqrt_f32 v31, v31 +v_add_f32 v31, 0xbe99999a, v31 +v_mul_f32 v31, 0x42055555, v31 +v_mul_f32 v31, v31, v31 +v_sub_f32 v31, 1.0, v31 +v_max_f32 v31, 0, v31 +v_mul_f32 v31, v31, v31 +v_mac_f32 v26, 0x3d4ccccd, v31 +v_mac_f32 v27, 0x3d2e147b, v31 +v_mac_f32 v28, 0x3d0f5c29, v31 +v_mac_f32 v8, s34, v26 +v_mac_f32 v9, s35, v27 +v_mac_f32 v10, s36, v28 v_max_f32 v8, 0, v8 v_min_f32 v8, 1.0, v8 v_max_f32 v9, 0, v9 diff --git a/src/main.c b/src/main.c index 8ac5562..9c9a33e 100644 --- a/src/main.c +++ b/src/main.c @@ -129,13 +129,14 @@ /* Sun disc edge radius in pixels (1080p). The old disc was 59 px tall and 105 px wide (NDC distance on a 16:9 screen); it is now round. */ -#define SUN_DISC_RADIUS_PX 110.0f +#define SUN_DISC_RADIUS_PX 93.5f /* Linear HDR pipeline: the scene renders to RGBA16F, bloom runs at quarter resolution, the composite writes the sRGB display buffer (videoout format A8R8G8B8Srgb). Values are linear light; 1.0 = display white. */ #define SUN_HDR 4.0f /* sun disc colour x this (desc[84]) */ #define MOON_HDR 2.0f /* moon disc colour x this (desc[88]) */ +#define MOON_LIGHT 0.621f /* night light magnitude (moonlight): 0.69 - 10% */ #define BLOOM_THRESHOLD 1.0f /* only what is brighter than white blooms */ #define BLOOM_INTENSITY 0.25f #define EXPOSURE 1.0f @@ -154,20 +155,18 @@ /* Imported models (OBJ / STL / PLY): vs_model + ps_model, model transform on the GPU. */ #define MODEL_FIT_RADIUS \ 0.6928203f /* scaled to the built-in cube's bounding radius (0.4 * sqrt 3) */ -#define MODEL_POM_DEPTH 0.0125f /* relief depth in UV units (= D_UV in tools/gen_model.py) */ +#define MODEL_POM_DEPTH 0.003125f /* relief depth in UV units (= D_UV in tools/gen_model.py) */ #define MODEL_RELIEF 1.0f /* relief self-shadow strength */ #define MODEL_SHADOW_OFFSET 0.02f /* shadow lookup: offset along the normal (world units) */ #define MODEL_SHADOW_BIAS \ (1.5f / 255.0f) /* shadow lookup: depth bias, 1.5 steps of the 8-bit map */ -/* PS4 diagnostic (GPU hang in the first main-loop frame, CP stopped after 0x12): - until this frame a loaded model is drawn by the old PS4-proven path (vs_shader - / ps_shader, static) while the floor already samples the BC textures; from - this frame on vs_model / ps_model. A hang before it blames the floor, at it - the model path. 0 = model path from the first frame. */ -#define MODEL_PATH_FROM_FRAME 120 +#define MODEL_ROUGHNESS 0.45f /* satin finish: GGX roughness (0 mirror .. 1 matte) */ +#define MODEL_F0 0.04f /* Fresnel reflectance at normal incidence (paint / plastic) */ +#define FLARE_STRENGTH 1.0f /* lens flare: 0 off; x sun colour x visibility x edge fade */ +#define FLARE_EDGE 0.12f /* lens flare fades out over this screen fraction at the edges */ /* Printed in the trace header so logs from different builds can be told apart. */ -#define BUILD_TAG "bc-tiled" +#define BUILD_TAG "logo-badge-orig" /* Shadow map: 4096×4096 (4K). Real PS4 games render to 4K shadow maps regularly (and bigger). The 32 MB Vulkan validation error in the user's log was NOT a GCN/PS4 limit — it was specifically shadPS4's @@ -400,6 +399,12 @@ static void* g_hdr = 0; static void* g_bloom_a[BLOOM_LEVELS]; static void* g_bloom_b[BLOOM_LEVELS]; static uint32_t* g_post_tab = 0; +/* Prop box for the lens flare occlusion test: model-space bounds and the world + transform (3x4 rows) of the loaded model, or of the built-in cube (+-0.4). */ +static float g_prop_lo[3] = {-0.4f, -0.4f, -0.4f}; +static float g_prop_hi[3] = {0.4f, 0.4f, 0.4f}; +static float g_prop_m[12] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.4f, 0.0f, 0.0f, 1.0f, 0.0f}; static void* g_ps_post_down_gpu = 0; static void* g_ps_post_blur_gpu = 0; static void* g_ps_post_comp_gpu = 0; @@ -806,6 +811,96 @@ static void build_static_vb(float* vb) { } } +/* Lens flare occlusion: does the ray o + t d (t > 0) hit the floor or the prop? + Floor as generated: y = -0.5 - (x^2 + z^2) / 40000 over +-FLOOR_HALF, so + g(t) = c + b t + a t^2 with a = (dx^2 + dz^2) / 40000, b = dy + (ox dx + oz dz) / + 20000, c = oy + 0.5 + (ox^2 + oz^2) / 40000 (a ~ 1e-5: roots in the stable form + q = -(b + sign(b) sqrt(b^2 - 4ac)) / 2, t = q / a, c / q). Prop: the ray in + model space (A^-1 (o - t), A^-1 d, A = the 3x3 of g_prop_m) against the bounds + (slabs). */ +static int flare_ray_blocked(const float* o, const float* d) { + float a = (d[0] * d[0] + d[2] * d[2]) / 40000.0f; + float b = d[1] + (o[0] * d[0] + o[2] * d[2]) / 20000.0f; + float c = o[1] + 0.5f + (o[0] * o[0] + o[2] * o[2]) / 40000.0f; + float disc = b * b - 4.0f * a * c; + if (disc >= 0.0f) { + float q = -0.5f * (b + (b >= 0.0f ? my_sqrt(disc) : -my_sqrt(disc))); + float r[2] = {a > 0.0f ? q / a : -1.0f, q != 0.0f ? c / q : -1.0f}; + for (int k = 0; k < 2; k++) { + if (r[k] <= 0.0f) + continue; + float x = o[0] + r[k] * d[0], z = o[2] + r[k] * d[2]; + if (x >= -FLOOR_HALF && x <= FLOOR_HALF && z >= -FLOOR_HALF && z <= FLOOR_HALF) + return 1; + } + } + const float* m = g_prop_m; + float c00 = m[5] * m[10] - m[6] * m[9], c01 = m[6] * m[8] - m[4] * m[10]; + float c02 = m[4] * m[9] - m[5] * m[8]; + float det = m[0] * c00 + m[1] * c01 + m[2] * c02; + if (det == 0.0f) + return 0; + float inv[9] = {c00, m[2] * m[9] - m[1] * m[10], m[1] * m[6] - m[2] * m[5], + c01, m[0] * m[10] - m[2] * m[8], m[2] * m[4] - m[0] * m[6], + c02, m[1] * m[8] - m[0] * m[9], m[0] * m[5] - m[1] * m[4]}; + float p[3] = {o[0] - m[3], o[1] - m[7], o[2] - m[11]}, po[3], dm[3]; + for (int k = 0; k < 3; k++) { + po[k] = (inv[k * 3] * p[0] + inv[k * 3 + 1] * p[1] + inv[k * 3 + 2] * p[2]) / det; + dm[k] = (inv[k * 3] * d[0] + inv[k * 3 + 1] * d[1] + inv[k * 3 + 2] * d[2]) / det; + } + float t0 = 0.0f, t1 = 1e30f; + for (int k = 0; k < 3; k++) { + if (dm[k] == 0.0f) { + if (po[k] < g_prop_lo[k] || po[k] > g_prop_hi[k]) + return 0; + continue; + } + float ta = (g_prop_lo[k] - po[k]) / dm[k], tb = (g_prop_hi[k] - po[k]) / dm[k]; + if (ta > tb) { + float tt = ta; + ta = tb; + tb = tt; + } + if (ta > t0) + t0 = ta; + if (tb < t1) + t1 = tb; + if (t0 > t1) + return 0; + } + return 1; +} + +/* Visible fraction of the sun disc: 29 rays from the camera through a 7 x 7 grid + inside the disc (SUN_DISC_RADIUS_PX around NDC (nx, ny)), weighted by ps_dark's + disc profile (1 - d^2 / r^2)^2. Rays from build_mvp's basis: d = f + r nx aspect / + fov + u ny / fov. */ +static float flare_visibility(float yaw, float pitch, const float* cam, float nx, float ny) { + float sy = my_sin(yaw), cy = my_cos(yaw), sp = my_sin(pitch), cp = my_cos(pitch); + const float f[3] = {sy * cp, -sp, -cy * cp}, r[3] = {cy, 0.0f, sy}, + u[3] = {sy * sp, cp, -cy * sp}; + float aspect = (float)DISPLAY_W / (float)DISPLAY_H; + float fov = my_cos(0.3054f) / my_sin(0.3054f); + float rn = SUN_DISC_RADIUS_PX / ((float)DISPLAY_H * 0.5f); + float wsum = 0.0f, vis = 0.0f; + for (int j = -3; j <= 3; j++) + for (int i = -3; i <= 3; i++) { + int q = i * i + j * j; + if (q >= 9) + continue; + float w = 1.0f - (float)q / 9.0f; + w *= w; + float px = nx + (float)i / 3.0f * rn / aspect, py = ny + (float)j / 3.0f * rn; + float d[3]; + for (int k = 0; k < 3; k++) + d[k] = f[k] + r[k] * px * aspect / fov + u[k] * py / fov; + wsum += w; + if (!flare_ray_blocked(cam, d)) + vis += w; + } + return vis / wsum; +} + /* FPS free-fly camera: position + yaw/pitch → view-projection matrix */ static void build_mvp(float *mvp, float yaw, float pitch, float cx, float cy, float cz) { @@ -1203,7 +1298,7 @@ static void post_consts(uint32_t* t, float a, float b, float c, float d) { f[3] = d; } static void build_post_tables(uint32_t* tab) { - my_memset(tab, 0, POST_PASSES * 32 * 4); + my_memset(tab, 0, (POST_PASSES + 1) * 32 * 4); /* + final pass dwords 32..63 (flare) */ uint32_t* t = tab; for (int i = 0; i < BLOOM_LEVELS; i++, t += 32) { float w = g_bloom_w[i], h = g_bloom_h[i]; @@ -1309,7 +1404,7 @@ static void post_pass(struct PM4Builder* b, void* dst, uint32_t pitch, uint32_t #define PS_POST_DOWN_RSRC1 ((2u << 6) | 9u) #define PS_POST_BLUR_RSRC1 ((2u << 6) | 12u) #define PS_POST_COMP_RSRC1 ((4u << 6) | 3u) -#define PS_POST_FINAL_RSRC1 ((4u << 6) | 5u) /* v21, s31 + VCC */ +#define PS_POST_FINAL_RSRC1 ((5u << 6) | 8u) /* v32, s39 + VCC (lens flare) */ /* HDR scene -> 6-level bloom chain -> composite into the sRGB display buffer. Order and tables as build_post_tables. */ @@ -1602,8 +1697,8 @@ static uint32_t build_dcb(struct PM4Builder *b, build_vsharp(cube_v,(char*)vb_base+MVP_OFF,(uint32_t)(vb_total > MVP_OFF ? vb_total - MVP_OFF : VERT_BUF_SIZE - MVP_OFF)); if (g_model.enabled) { /* vs_model: V# + M in s[0:15] (16 user SGPRs); v0-v48, s0-s15 + VCC -> - 52 VGPRs, 24 SGPRs = 0x8C. ps_model: v0-v97, s0-s87 + VCC -> 100 - VGPRs, 96 SGPRs = 0x2D8. Three params: param2 = tangent, handedness. */ + 52 VGPRs, 24 SGPRs = 0x8C. ps_model: v0-v97, s0-s95 + VCC -> 100 + VGPRs, 104 SGPRs = 0x318. Three params: param2 = tangent, handedness. */ uint64_t a = (uint64_t)(uintptr_t)g_model.vs; uint32_t r[4] = {(uint32_t)(a >> 8), (uint32_t)(a >> 40), 0x8Cu, (16u << 1)}; pm4_set_sh_regs(b, SH_VS_PGM_LO, r, 4); @@ -1612,7 +1707,7 @@ static uint32_t build_dcb(struct PM4Builder *b, my_memcpy(ud + 4, g_model.m, 48); pm4_set_sh_regs(b, SH_VS_USER_DATA_0, ud, 16); a = (uint64_t)(uintptr_t)g_model.ps; - uint32_t p[4] = {(uint32_t)(a >> 8), (uint32_t)(a >> 40), 0x2D8u, (2u << 1)}; + uint32_t p[4] = {(uint32_t)(a >> 8), (uint32_t)(a >> 40), 0x318u, (2u << 1)}; pm4_set_sh_regs(b, SH_PS_PGM_LO, p, 4); pm4_set_context_reg(b, CTX_VS_OUTPUT_CONFIG, 2u << 1); /* three params */ pm4_set_context_reg(b, CTX_PS_INPUT_CNTL_0 + 2, 2); @@ -2651,6 +2746,19 @@ int main(void) { mc[5] = 1.0f; mc[6] = MODEL_SHADOW_OFFSET; mc[7] = MODEL_SHADOW_BIAS; + /* Satin finish (ps_model desc[152..157]): a = roughness^2; a^2, k = a / 2, sun + Fresnel F0 + (1 - F0) (1 - V.H)^5, sky Fresnel F0 + (max(1 - r, F0) - F0) + (1 - N.V)^5. */ + float a = MODEL_ROUGHNESS * MODEL_ROUGHNESS; + float g = 1.0f - MODEL_ROUGHNESS; + mc[8] = a * a; + mc[9] = 0.5f * a; + mc[10] = MODEL_F0; + mc[11] = 1.0f - MODEL_F0; + mc[12] = MODEL_F0; + mc[13] = (g > MODEL_F0 ? g : MODEL_F0) - MODEL_F0; + mc[14] = 0.0f; + mc[15] = 0.0f; } /* VB layout: @@ -2736,7 +2844,7 @@ int main(void) { g_bloom_b[i] = gpu_alloc(sz, 0x10000); post_ok = post_ok && g_bloom_a[i] && g_bloom_b[i]; } - g_post_tab = (uint32_t*)gpu_alloc_typed(POST_PASSES * 32 * 4, 0x100, MEM_TYPE_ONION); + g_post_tab = (uint32_t*)gpu_alloc_typed((POST_PASSES + 1) * 32 * 4, 0x100, MEM_TYPE_ONION); if (post_ok && g_post_tab) build_post_tables(g_post_tab); else @@ -2978,6 +3086,12 @@ int main(void) { g_model_cx = (minx + maxx) * 0.5f; g_model_cy = (miny + maxy) * 0.5f; g_model_cz = (minz + maxz) * 0.5f; + g_prop_lo[0] = minx; + g_prop_lo[1] = miny; + g_prop_lo[2] = minz; + g_prop_hi[0] = maxx; + g_prop_hi[1] = maxy; + g_prop_hi[2] = maxz; float dx = maxx - minx, dy = maxy - miny, dz = maxz - minz; float diag = my_sqrt(dx*dx + dy*dy + dz*dz); g_model_radius = diag * 0.5f; @@ -2991,7 +3105,8 @@ int main(void) { g_model_cy = 0.0f; g_model_cz = 0.0f; g_model_radius = 0.8f; - /* g_model.enabled is switched on in the frame loop (MODEL_PATH_FROM_FRAME). */ + g_model.enabled = 1; + trace_msg("model draw path enabled (vs_model / ps_model)\n"); loaded = 1; model_loaded = 1; } @@ -3449,6 +3564,18 @@ int main(void) { g_model.m[row * 4 + 3] = (row == 1) ? cube_world_y : 0.0f; } } + { + /* The prop's transform for the lens flare occlusion test (model: M above; + built-in cube: the same motion at scale 1). */ + float sc = model_loaded ? MODEL_FIT_RADIUS / model_fit_radius : 1.0f; + const float R[3][3] = { + {cy_, 0.0f, sy_}, {sx_ * sy_, cx_, -sx_ * cy_}, {-cx_ * sy_, sx_, cx_ * cy_}}; + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 3; col++) + g_prop_m[row * 4 + col] = R[row][col] * sc; + g_prop_m[row * 4 + 3] = (row == 1) ? cube_world_y : 0.0f; + } + } float *cb = (float*)((char*)vb + CUBE_DATA_OFF); /* Only the built-in cube: with a model loaded, vb + CUBE_DATA_OFF is the model's first 36 vertices, and rewriting them drew the cube inside @@ -3564,12 +3691,12 @@ int main(void) { (sun_y becomes >=0 always after the swap). Sun magnitude ramp scales the Lambert dot product in cube/floor PS: - night → 0.60 (moon, 20% brighter than old 0.50) - horizon (sun_y=0) → 0.60 (matches night for seamless transition) - rising 0 → sin(20°)=0.342 → linear ramp 0.60 → 1.20 - above 20° elevation → 1.20 (peak day, +20% boost over old 1.00) + night → MOON_LIGHT 0.621 (moon) + horizon (sun_y=0) → 0.98 + rising 0 → sun_y 0.15 → linear ramp 0.98 → 1.38 + above sun_y 0.15 → 1.38 (peak day) - Threshold lowered to 20° so the sun stays at full peak brightness + Peak from sun_y 0.15 (8.6°) so the sun stays at full brightness for nearly all of the day. Darkening only kicks in during the final ~1-2 hours before sunset (or first 1-2 after sunrise). */ float orig_sun_y = sun_y; @@ -3579,8 +3706,10 @@ int main(void) { sun_x = -sun_x; sun_y = -sun_y; sun_z = -sun_z; - /* Night: 0.69 (was 0.60, +15% brighter as requested) */ - sun_x *= 0.69f; sun_y *= 0.69f; sun_z *= 0.69f; + /* Night: MOON_LIGHT (0.621 = the previous 0.69 - 10%) */ + sun_x *= MOON_LIGHT; + sun_y *= MOON_LIGHT; + sun_z *= MOON_LIGHT; } else { /* Day/twilight: ramp 0.98 at horizon → 1.38 at sun_y >= sin(8.6°) = 0.15. Boosted 15% from 0.85→1.20 to 0.98→1.38. Dimming only kicks in at @@ -3751,7 +3880,8 @@ int main(void) { instead of vanishing when its centre crosses the horizon. Lighting and shadows stay with the body above the horizon (desc[12], light MVP). Placement as before: sun = direction x the day magnitude ramp, - moon = anti-sun x 0.69, both x 100. ps_dark: f = clamp(1 - d^2 / + moon = anti-sun x 0.69, both x 100; the moon disc has the sun's radius (same + apparent size: 400x smaller, 400x closer). ps_dark: f = clamp(1 - d^2 / radius^2, 0, 1)^2, d in aspect-corrected NDC (x * W/H, y). */ { float *mvp = (float*)((char*)vb + MVP_OFF); @@ -3763,7 +3893,7 @@ int main(void) { mag = 1.38f; const float body[2][4] = { {sun_dx * mag, sun_dy * mag, sun_dz * mag, sun_r * sun_r}, - {-sun_dx * 0.69f, -sun_dy * 0.69f, -sun_dz * 0.69f, sun_r * sun_r * 0.75f}}; + {-sun_dx * 0.69f, -sun_dy * 0.69f, -sun_dz * 0.69f, sun_r * sun_r}}; for (int k = 0; k < 2; k++) { float bx = body[k][0] * 100, by = body[k][1] * 100, bz = body[k][2] * 100; float cx = mvp[0] * bx + mvp[1] * by + mvp[2] * bz + mvp[3]; @@ -3799,6 +3929,38 @@ int main(void) { mc[2] = srgb_to_linear(0.84f) * MOON_HDR; mc[3] = 0.0f; } + /* Lens flare (ps_post_final, final pass table dwords 28..32): sun position + (u, v: pixel / size, v down) and strength = sun colour x FLARE_STRENGTH x + visible fraction of the disc x edge fade. desc[16..17] = sun NDC x aspect, y + (99 behind the camera); desc[84..86] = sun colour x SUN_HDR. */ + if (g_post_tab) { + float* ft = (float*)(g_post_tab + (POST_PASSES - 1) * 32 + 28); + const float* sd = (const float*)(desc + 16); + const float* scl = (const float*)(desc + 84); + float nx = sd[0] * ((float)DISPLAY_H / (float)DISPLAY_W), ny = sd[1]; + float fu = 0.5f + 0.5f * nx, fv = 0.5f - 0.5f * ny, k = 0.0f; + float e = fu < 1.0f - fu ? fu : 1.0f - fu; + if (fv < e) + e = fv; + if (1.0f - fv < e) + e = 1.0f - fv; + if (sd[0] < 90.0f && e > 0.0f) { + float fade = e / FLARE_EDGE; + if (fade > 1.0f) + fade = 1.0f; + const float cam[3] = {cam_x, cam_y, cam_z}; + k = FLARE_STRENGTH * fade * fade * (3.0f - 2.0f * fade) * + flare_visibility(cam_yaw, cam_pitch, cam, nx, ny) / SUN_HDR; + } + ft[0] = fu; + ft[1] = fv; + ft[2] = k * scl[0]; + ft[3] = k * scl[1]; + ft[4] = k * scl[2]; + ft[5] = 0.0f; + ft[6] = 0.0f; + ft[7] = 0.0f; + } /* Build main DCB (samples shadow_depth but doesn't write it). The DCB itself requests a GPU-side depth clear via DB_RENDER_CONTROL.depth_clear_enable=1 @@ -3877,18 +4039,6 @@ int main(void) { skipped it would otherwise never update and the checkpoint would look frozen for the wrong reason. */ g_cp_frame = frame; - /* MODEL_PATH_FROM_FRAME: see its definition (PS4 hang diagnostic). */ - if (model_loaded && !g_model.enabled && frame >= MODEL_PATH_FROM_FRAME) { - g_model.enabled = 1; - char L[80]; - int p = 0; - const char* m = "model draw path enabled (vs_model / ps_model) at f="; - while (*m) - L[p++] = *m++; - p += lg_i64(L + p, (long long)frame); - L[p++] = '\n'; - trace_line(L, (unsigned long)p); - } uint32_t shadow_sz = 0; if (shadow_depth && g_shadow_ready) { diff --git a/tools/README.txt b/tools/README.txt index d48a571..b4580dc 100644 --- a/tools/README.txt +++ b/tools/README.txt @@ -24,3 +24,6 @@ are stored in the engine convention (+u, +v), measured against the height map. The PKG also needs sce_sys/about/right.sprx (from the OpenOrbis samples; not in this project). + +logo_2048.png: the cube prop's logo (badge + wordmark in the logo's font), the +input of gen_model.py for the albedo, the engraving height and the normal map. diff --git a/tools/build_assets.py b/tools/build_assets.py index dac74ea..589ab7d 100644 --- a/tools/build_assets.py +++ b/tools/build_assets.py @@ -9,7 +9,7 @@ Output layout: models/cube/cube.obj gen_model.py - images/cube/albedo.dds normal.dds height.dds (logo: RGBA8, BC5, BC4) + images/cube/albedo.dds normal.dds height.dds (logo 2048: BC1 sRGB, BC5, BC4) images/floor/albedo.dds normal.dds height.dds (BC1 sRGB, BC5, BC4) sound/bgm/bgm.wav make_bgm.py Needs numpy, Pillow, quicktex and ffmpeg.""" @@ -43,7 +43,7 @@ def main(): run(os.path.join(HERE, "gen_model.py"), tmp) shutil.copyfile(os.path.join(tmp, "model.obj"), os.path.join(out, "models/cube/cube.obj")) cube = os.path.join(out, "images/cube") - run(tex, "albedo", os.path.join(tmp, "model.bmp"), os.path.join(cube, "albedo.dds"), "--raw") + run(tex, "albedo", os.path.join(tmp, "model.bmp"), os.path.join(cube, "albedo.dds")) run(tex, "normal", os.path.join(tmp, "model_normal.bmp"), os.path.join(cube, "normal.dds"), "--height", os.path.join(tmp, "model_height.bmp")) run(tex, "height", os.path.join(tmp, "model_height.bmp"), os.path.join(cube, "height.dds")) diff --git a/tools/gen_model.py b/tools/gen_model.py index caf5739..27ad6a2 100644 --- a/tools/gen_model.py +++ b/tools/gen_model.py @@ -1,15 +1,17 @@ #!/usr/bin/env python3 """Generates the ShadCube4 prop into OUT_DIR (default .): model.obj (rounded cube, per-vertex normals, logo UVs on every face), model.bmp (the logo from -src/logo_texture.h), model_height.bmp (engraved logo: 1 - ink coverage, smoothed) -and model_normal.bmp (from the height at relief depth D_UV, which must equal -MODEL_POM_DEPTH in src/main.c). Needs numpy and Pillow. +tools/logo_2048.png: the ShadPS4 badge + "ShadPS4" in URW Gothic Demi, the +logo's font), model_height.bmp (engraved logo: distance-field bevel on +the logo ink) and model_normal.bmp (from the height at relief depth D_UV, which must +equal MODEL_POM_DEPTH in src/main.c). Needs numpy, scipy and Pillow. python3 gen_model.py [OUT_DIR]""" import numpy as np, math, struct, os, re, sys from PIL import Image H, R, S = 0.9, 0.09, 4 # half size, edge radius, bevel segments per side -D_UV = 0.0125 # relief depth in UV units (must equal MODEL_POM_DEPTH in main.c) -MAP = 512 # height / normal map size +D_UV = 0.003125 # relief depth in UV units (must equal MODEL_POM_DEPTH in main.c) +MAP = 2048 # logo, height and normal map size +BEVEL_PX = 10 # engraving wall width at MAP (distance-field bevel) def grid_axis(): inner = H - R @@ -62,40 +64,38 @@ def write_bmp24(path, rgb_top_down): info = struct.pack(' 0.5 + d = ndimage.distance_transform_edt(inside) # px (at 2*MAP) to the ink edge + x = np.clip(d / (2.0 * BEVEL_PX), 0, 1) + h2 = 1.0 - x * x * (3 - 2 * x) + h = h2.reshape(MAP, 2, MAP, 2).mean((1, 3)) dhdu = (np.roll(h, -1, 1) - np.roll(h, 1, 1)) * (MAP / 2.0) - dhdv = -(np.roll(h, -1, 0) - np.roll(h, 1, 0)) * (MAP / 2.0) + dhdv = -(np.roll(h, -1, 0) - np.roll(h, 1, 0)) * (MAP / 2.0) # rows top-down, v up nx, ny, nz = -D_UV * dhdu, -D_UV * dhdv, np.ones_like(h) - l = np.sqrt(nx * nx + ny * ny + nz * nz); nx, ny, nz = nx / l, ny / l, nz / l - hq = np.round(h * 255).astype(np.uint8) - nrm = np.stack([np.round((c * 0.5 + 0.5) * 255).clip(0, 255) for c in (nx, ny, nz)], -1).astype(np.uint8) - return hq, nrm, h + l = np.sqrt(nx * nx + ny * ny + nz * nz) + nrm = np.stack([np.round((c / l * 0.5 + 0.5) * 255).clip(0, 255) for c in (nx, ny, nz)], -1).astype(np.uint8) + return rgb, np.round(h * 255).astype(np.uint8), nrm -def load_logo(path): - txt = open(path).read() - w = int(re.search(r"#define LOGO_WIDTH (\d+)", txt).group(1)) - h = int(re.search(r"#define LOGO_HEIGHT (\d+)", txt).group(1)) - body = txt[txt.index("{") + 1:txt.rindex("}")] - v = np.array([int(x, 16) for x in re.findall(r"0x[0-9a-fA-F]+", body)], np.uint8) - return v.reshape(h, w, 4) # rows top-down, RGBA if __name__ == "__main__": out = sys.argv[1] if len(sys.argv) > 1 else "." - here = os.path.dirname(os.path.abspath(__file__)) - logo = load_logo(os.path.join(here, "..", "src", "logo_texture.h")) + sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) V, VT, VN, F = build() write_obj(os.path.join(out, "model.obj"), V, VT, VN, F) - write_bmp24(os.path.join(out, "model.bmp"), logo[:, :, :3]) - hq, nrm, h = maps(logo) + rgb, hq, nrm = maps() + write_bmp24(os.path.join(out, "model.bmp"), rgb) write_bmp24(os.path.join(out, "model_height.bmp"), np.stack([hq] * 3, -1)) write_bmp24(os.path.join(out, "model_normal.bmp"), nrm) - print("model.obj: %d vertices, %d triangles; maps %dx%d" % (len(V), len(F), MAP, MAP)) + print("model.obj: %d vertices, %d triangles; logo / height / normal %dx%d" % (len(V), len(F), MAP, MAP)) diff --git a/tools/logo_2048.png b/tools/logo_2048.png new file mode 100644 index 0000000..8d3897a Binary files /dev/null and b/tools/logo_2048.png differ