2023-09-18 18:11:07 +00:00
|
|
|
// language: metal1.0
|
2021-01-30 05:11:23 +00:00
|
|
|
#include <metal_stdlib>
|
|
|
|
#include <simd/simd.h>
|
|
|
|
|
2022-02-21 21:22:54 +00:00
|
|
|
using metal::uint;
|
|
|
|
|
2021-05-01 02:40:32 +00:00
|
|
|
struct _mslBufferSizes {
|
2022-03-09 08:01:56 +00:00
|
|
|
uint size2;
|
2021-05-01 02:40:32 +00:00
|
|
|
};
|
|
|
|
|
2021-01-30 05:11:23 +00:00
|
|
|
struct Globals {
|
2022-03-09 08:01:56 +00:00
|
|
|
metal::float4x4 view_proj;
|
2021-04-08 15:00:11 +00:00
|
|
|
metal::uint4 num_lights;
|
2021-01-30 05:11:23 +00:00
|
|
|
};
|
2022-03-09 08:01:56 +00:00
|
|
|
struct Entity {
|
|
|
|
metal::float4x4 world;
|
|
|
|
metal::float4 color;
|
|
|
|
};
|
|
|
|
struct VertexOutput {
|
|
|
|
metal::float4 proj_position;
|
|
|
|
metal::float3 world_normal;
|
|
|
|
metal::float4 world_position;
|
|
|
|
};
|
2021-01-30 05:11:23 +00:00
|
|
|
struct Light {
|
2021-04-08 15:00:11 +00:00
|
|
|
metal::float4x4 proj;
|
|
|
|
metal::float4 pos;
|
|
|
|
metal::float4 color;
|
2021-01-30 05:11:23 +00:00
|
|
|
};
|
2024-09-02 12:04:51 +00:00
|
|
|
typedef Light type_8[1];
|
|
|
|
struct type_9 {
|
2022-03-09 08:01:56 +00:00
|
|
|
Light inner[10];
|
2021-01-30 05:11:23 +00:00
|
|
|
};
|
2023-04-05 15:38:03 +00:00
|
|
|
constant metal::float3 c_ambient = metal::float3(0.05, 0.05, 0.05);
|
|
|
|
constant uint c_max_lights = 10u;
|
2021-04-08 15:00:11 +00:00
|
|
|
|
|
|
|
float fetch_shadow(
|
2022-02-21 21:22:54 +00:00
|
|
|
uint light_id,
|
2021-04-08 15:00:11 +00:00
|
|
|
metal::float4 homogeneous_coords,
|
|
|
|
metal::depth2d_array<float, metal::access::sample> t_shadow,
|
2021-05-13 05:26:08 +00:00
|
|
|
metal::sampler sampler_shadow
|
2021-01-30 05:11:23 +00:00
|
|
|
) {
|
2021-04-08 16:29:26 +00:00
|
|
|
if (homogeneous_coords.w <= 0.0) {
|
|
|
|
return 1.0;
|
2021-01-30 05:11:23 +00:00
|
|
|
}
|
2021-06-08 16:09:46 +00:00
|
|
|
metal::float2 flip_correction = metal::float2(0.5, -0.5);
|
2022-03-09 08:01:56 +00:00
|
|
|
float proj_correction = 1.0 / homogeneous_coords.w;
|
|
|
|
metal::float2 light_local = ((homogeneous_coords.xy * flip_correction) * proj_correction) + metal::float2(0.5, 0.5);
|
2023-01-12 17:26:28 +00:00
|
|
|
float _e24 = t_shadow.sample_compare(sampler_shadow, light_local, static_cast<int>(light_id), homogeneous_coords.z * proj_correction);
|
|
|
|
return _e24;
|
2022-03-09 08:01:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct vs_mainInput {
|
2022-03-11 06:17:02 +00:00
|
|
|
metal::int4 position [[attribute(0)]];
|
2022-03-09 08:01:56 +00:00
|
|
|
metal::int4 normal [[attribute(1)]];
|
|
|
|
};
|
|
|
|
struct vs_mainOutput {
|
|
|
|
metal::float4 proj_position [[position]];
|
|
|
|
metal::float3 world_normal [[user(loc0), center_perspective]];
|
|
|
|
metal::float4 world_position [[user(loc1), center_perspective]];
|
|
|
|
};
|
|
|
|
vertex vs_mainOutput vs_main(
|
2022-03-11 06:17:02 +00:00
|
|
|
vs_mainInput varyings [[stage_in]]
|
2022-03-09 08:01:56 +00:00
|
|
|
, constant Globals& u_globals [[user(fake0)]]
|
|
|
|
, constant Entity& u_entity [[user(fake0)]]
|
|
|
|
) {
|
2022-03-11 06:17:02 +00:00
|
|
|
const auto position = varyings.position;
|
|
|
|
const auto normal = varyings.normal;
|
2022-04-29 19:31:06 +00:00
|
|
|
VertexOutput out = {};
|
2022-03-09 08:01:56 +00:00
|
|
|
metal::float4x4 w = u_entity.world;
|
|
|
|
metal::float4x4 _e7 = u_entity.world;
|
2022-03-11 06:17:02 +00:00
|
|
|
metal::float4 world_pos = _e7 * static_cast<metal::float4>(position);
|
2022-04-29 17:48:27 +00:00
|
|
|
out.world_normal = metal::float3x3(w[0].xyz, w[1].xyz, w[2].xyz) * static_cast<metal::float3>(normal.xyz);
|
|
|
|
out.world_position = world_pos;
|
2023-01-12 17:26:28 +00:00
|
|
|
metal::float4x4 _e26 = u_globals.view_proj;
|
|
|
|
out.proj_position = _e26 * world_pos;
|
|
|
|
VertexOutput _e28 = out;
|
|
|
|
const auto _tmp = _e28;
|
2022-03-09 08:01:56 +00:00
|
|
|
return vs_mainOutput { _tmp.proj_position, _tmp.world_normal, _tmp.world_position };
|
2021-01-30 05:11:23 +00:00
|
|
|
}
|
|
|
|
|
2022-03-09 08:01:56 +00:00
|
|
|
|
2021-01-30 05:11:23 +00:00
|
|
|
struct fs_mainInput {
|
2022-03-09 08:01:56 +00:00
|
|
|
metal::float3 world_normal [[user(loc0), center_perspective]];
|
|
|
|
metal::float4 world_position [[user(loc1), center_perspective]];
|
2021-01-30 05:11:23 +00:00
|
|
|
};
|
|
|
|
struct fs_mainOutput {
|
2022-03-11 06:17:02 +00:00
|
|
|
metal::float4 member_1 [[color(0)]];
|
2021-01-30 05:11:23 +00:00
|
|
|
};
|
|
|
|
fragment fs_mainOutput fs_main(
|
2022-03-11 06:17:02 +00:00
|
|
|
fs_mainInput varyings_1 [[stage_in]]
|
2022-03-09 08:01:56 +00:00
|
|
|
, metal::float4 proj_position [[position]]
|
2021-04-20 14:01:32 +00:00
|
|
|
, constant Globals& u_globals [[user(fake0)]]
|
2022-03-09 08:01:56 +00:00
|
|
|
, constant Entity& u_entity [[user(fake0)]]
|
2024-09-02 12:04:51 +00:00
|
|
|
, device type_8 const& s_lights [[user(fake0)]]
|
2021-04-20 14:01:32 +00:00
|
|
|
, metal::depth2d_array<float, metal::access::sample> t_shadow [[user(fake0)]]
|
|
|
|
, metal::sampler sampler_shadow [[user(fake0)]]
|
2022-02-05 03:03:54 +00:00
|
|
|
, constant _mslBufferSizes& _buffer_sizes [[user(fake0)]]
|
2021-01-30 05:11:23 +00:00
|
|
|
) {
|
2022-04-29 17:48:27 +00:00
|
|
|
const VertexOutput in = { proj_position, varyings_1.world_normal, varyings_1.world_position };
|
2023-04-19 13:16:46 +00:00
|
|
|
metal::float3 color = c_ambient;
|
|
|
|
uint i = 0u;
|
2022-04-29 17:48:27 +00:00
|
|
|
metal::float3 normal_1 = metal::normalize(in.world_normal);
|
2021-01-30 05:11:23 +00:00
|
|
|
bool loop_init = true;
|
|
|
|
while(true) {
|
|
|
|
if (!loop_init) {
|
2023-04-05 15:38:03 +00:00
|
|
|
uint _e40 = i;
|
|
|
|
i = _e40 + 1u;
|
2021-01-30 05:11:23 +00:00
|
|
|
}
|
|
|
|
loop_init = false;
|
2023-01-12 17:26:28 +00:00
|
|
|
uint _e7 = i;
|
|
|
|
uint _e11 = u_globals.num_lights.x;
|
|
|
|
if (_e7 < metal::min(_e11, c_max_lights)) {
|
2022-03-09 08:01:56 +00:00
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
2023-01-12 17:26:28 +00:00
|
|
|
{
|
|
|
|
uint _e16 = i;
|
|
|
|
Light light = s_lights[_e16];
|
|
|
|
uint _e19 = i;
|
|
|
|
float _e23 = fetch_shadow(_e19, light.proj * in.world_position, t_shadow, sampler_shadow);
|
|
|
|
metal::float3 light_dir = metal::normalize(light.pos.xyz - in.world_position.xyz);
|
|
|
|
float diffuse = metal::max(0.0, metal::dot(normal_1, light_dir));
|
|
|
|
metal::float3 _e37 = color;
|
|
|
|
color = _e37 + ((_e23 * diffuse) * light.color.xyz);
|
|
|
|
}
|
2022-03-09 08:01:56 +00:00
|
|
|
}
|
2023-01-12 17:26:28 +00:00
|
|
|
metal::float3 _e42 = color;
|
|
|
|
metal::float4 _e47 = u_entity.color;
|
|
|
|
return fs_mainOutput { metal::float4(_e42, 1.0) * _e47 };
|
2022-03-09 08:01:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct fs_main_without_storageInput {
|
|
|
|
metal::float3 world_normal [[user(loc0), center_perspective]];
|
|
|
|
metal::float4 world_position [[user(loc1), center_perspective]];
|
|
|
|
};
|
|
|
|
struct fs_main_without_storageOutput {
|
2022-03-11 06:17:02 +00:00
|
|
|
metal::float4 member_2 [[color(0)]];
|
2022-03-09 08:01:56 +00:00
|
|
|
};
|
|
|
|
fragment fs_main_without_storageOutput fs_main_without_storage(
|
2022-03-11 06:17:02 +00:00
|
|
|
fs_main_without_storageInput varyings_2 [[stage_in]]
|
2022-03-09 08:01:56 +00:00
|
|
|
, metal::float4 proj_position_1 [[position]]
|
|
|
|
, constant Globals& u_globals [[user(fake0)]]
|
|
|
|
, constant Entity& u_entity [[user(fake0)]]
|
2024-09-02 12:04:51 +00:00
|
|
|
, constant type_9& u_lights [[user(fake0)]]
|
2022-03-09 08:01:56 +00:00
|
|
|
, metal::depth2d_array<float, metal::access::sample> t_shadow [[user(fake0)]]
|
|
|
|
, metal::sampler sampler_shadow [[user(fake0)]]
|
|
|
|
) {
|
2022-04-29 17:48:27 +00:00
|
|
|
const VertexOutput in_1 = { proj_position_1, varyings_2.world_normal, varyings_2.world_position };
|
2023-04-19 13:16:46 +00:00
|
|
|
metal::float3 color_1 = c_ambient;
|
|
|
|
uint i_1 = 0u;
|
2022-04-29 17:48:27 +00:00
|
|
|
metal::float3 normal_2 = metal::normalize(in_1.world_normal);
|
2022-03-09 08:01:56 +00:00
|
|
|
bool loop_init_1 = true;
|
|
|
|
while(true) {
|
|
|
|
if (!loop_init_1) {
|
2023-04-05 15:38:03 +00:00
|
|
|
uint _e40 = i_1;
|
|
|
|
i_1 = _e40 + 1u;
|
2022-03-09 08:01:56 +00:00
|
|
|
}
|
|
|
|
loop_init_1 = false;
|
2023-01-12 17:26:28 +00:00
|
|
|
uint _e7 = i_1;
|
|
|
|
uint _e11 = u_globals.num_lights.x;
|
|
|
|
if (_e7 < metal::min(_e11, c_max_lights)) {
|
2022-03-09 08:01:56 +00:00
|
|
|
} else {
|
2021-01-30 05:11:23 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-01-12 17:26:28 +00:00
|
|
|
{
|
|
|
|
uint _e16 = i_1;
|
|
|
|
Light light_1 = u_lights.inner[_e16];
|
|
|
|
uint _e19 = i_1;
|
|
|
|
float _e23 = fetch_shadow(_e19, light_1.proj * in_1.world_position, t_shadow, sampler_shadow);
|
|
|
|
metal::float3 light_dir_1 = metal::normalize(light_1.pos.xyz - in_1.world_position.xyz);
|
|
|
|
float diffuse_1 = metal::max(0.0, metal::dot(normal_2, light_dir_1));
|
|
|
|
metal::float3 _e37 = color_1;
|
|
|
|
color_1 = _e37 + ((_e23 * diffuse_1) * light_1.color.xyz);
|
|
|
|
}
|
2021-01-30 05:11:23 +00:00
|
|
|
}
|
2023-01-12 17:26:28 +00:00
|
|
|
metal::float3 _e42 = color_1;
|
|
|
|
metal::float4 _e47 = u_entity.color;
|
|
|
|
return fs_main_without_storageOutput { metal::float4(_e42, 1.0) * _e47 };
|
2021-01-30 05:11:23 +00:00
|
|
|
}
|