#include #include constexpr constant unsigned c_max_lights = 10u; struct Globals { metal::uint4 num_lights; }; struct Light { metal::float4x4 proj; metal::float4 pos; metal::float4 color; }; typedef Light type3[1]; struct Lights { type3 data; }; constant metal::float3 c_ambient = {0.05, 0.05, 0.05}; float fetch_shadow( metal::uint light_id, metal::float4 homogeneous_coords, metal::depth2d_array t_shadow, metal::sampler sampler_shadow ) { if (homogeneous_coords.w <= 0.0) { return 1.0; } float _e26 = t_shadow.sample_compare(sampler_shadow, ((homogeneous_coords.xy * metal::float2(0.5, -0.5)) / float2(homogeneous_coords.w)) + metal::float2(0.5, 0.5), static_cast(light_id), homogeneous_coords.z / homogeneous_coords.w); return _e26; } struct fs_mainInput { metal::float3 raw_normal [[user(loc0), center_perspective]]; metal::float4 position [[user(loc1), center_perspective]]; }; struct fs_mainOutput { metal::float4 member [[color(0)]]; }; fragment fs_mainOutput fs_main( fs_mainInput varyings [[stage_in]] , constant Globals& u_globals [[user(fake0)]] , constant Lights& s_lights [[user(fake0)]] , metal::depth2d_array t_shadow [[user(fake0)]] , metal::sampler sampler_shadow [[user(fake0)]] ) { const auto raw_normal = varyings.raw_normal; const auto position = varyings.position; metal::float3 color1 = c_ambient; metal::uint i = 0u; bool loop_init = true; while(true) { if (!loop_init) { i = i + 1u; } loop_init = false; if (i >= metal::min(u_globals.num_lights.x, c_max_lights)) { break; } Light _e21 = s_lights.data[i]; float _e25 = fetch_shadow(i, _e21.proj * position, t_shadow, sampler_shadow); color1 = color1 + ((_e25 * metal::max(0.0, metal::dot(metal::normalize(raw_normal), metal::normalize(_e21.pos.xyz - position.xyz)))) * _e21.color.xyz); } return fs_mainOutput { metal::float4(color1, 1.0) }; }