176 lines
8.0 KiB
Plaintext
176 lines
8.0 KiB
Plaintext
#include <metal_stdlib>
|
|
|
|
using namespace metal;
|
|
|
|
template<typename T, int N, int M>
|
|
inline vec<T, M> operator*(matrix<T, N, M> lhs, packed_vec<T, N> rhs) {
|
|
return lhs * vec<T, N>(rhs);
|
|
}
|
|
|
|
template<typename T, int N, int M>
|
|
inline vec<T, N> operator*(packed_vec<T, M> lhs, matrix<T, N, M> rhs) {
|
|
return vec<T, M>(lhs) * rhs;
|
|
}
|
|
|
|
struct RenderParams {
|
|
/* 0x0000 */ float4x4 modelViewProjectionMatrix;
|
|
/* 0x0040 */ packed_float3 right;
|
|
/* 0x004c */ int8_t tint_pad[4];
|
|
/* 0x0050 */ packed_float3 up;
|
|
/* 0x005c */ int8_t tint_pad_1[4];
|
|
};
|
|
struct VertexInput {
|
|
float3 position;
|
|
float4 color;
|
|
float2 quad_pos;
|
|
};
|
|
struct VertexOutput {
|
|
float4 position;
|
|
float4 color;
|
|
float2 quad_pos;
|
|
};
|
|
struct tint_symbol_2 {
|
|
float3 position [[attribute(0)]];
|
|
float4 color [[attribute(1)]];
|
|
float2 quad_pos [[attribute(2)]];
|
|
};
|
|
struct tint_symbol_3 {
|
|
float4 color [[user(locn0)]];
|
|
float2 quad_pos [[user(locn1)]];
|
|
float4 position [[position]];
|
|
};
|
|
struct tint_symbol_5 {
|
|
float4 color [[user(locn0)]];
|
|
float2 quad_pos [[user(locn1)]];
|
|
};
|
|
struct tint_symbol_6 {
|
|
float4 value [[color(0)]];
|
|
};
|
|
struct SimulationParams {
|
|
/* 0x0000 */ float deltaTime;
|
|
/* 0x0004 */ int8_t tint_pad_2[12];
|
|
/* 0x0010 */ float4 seed;
|
|
};
|
|
struct Particle {
|
|
/* 0x0000 */ packed_float3 position;
|
|
/* 0x000c */ float lifetime;
|
|
/* 0x0010 */ float4 color;
|
|
/* 0x0020 */ packed_float3 velocity;
|
|
/* 0x002c */ int8_t tint_pad_3[4];
|
|
};
|
|
struct Particles {
|
|
/* 0x0000 */ Particle particles[1];
|
|
};
|
|
struct UBO {
|
|
/* 0x0000 */ uint width;
|
|
};
|
|
struct Buffer {
|
|
/* 0x0000 */ float weights[1];
|
|
};
|
|
|
|
float rand(thread float2* const tint_symbol_9) {
|
|
(*(tint_symbol_9))[0] = fract((cos(dot(*(tint_symbol_9), float2(23.140779495f, 232.616897583f))) * 136.816802979f));
|
|
(*(tint_symbol_9))[1] = fract((cos(dot(*(tint_symbol_9), float2(54.478565216f, 345.841522217f))) * 534.764526367f));
|
|
return (*(tint_symbol_9))[1];
|
|
}
|
|
|
|
VertexOutput vs_main_inner(VertexInput in, const constant RenderParams* const tint_symbol_10) {
|
|
float3 quad_pos = (float2x3((*(tint_symbol_10)).right, (*(tint_symbol_10)).up) * in.quad_pos);
|
|
float3 position = (in.position + (quad_pos * 0.01f));
|
|
VertexOutput out = {};
|
|
out.position = ((*(tint_symbol_10)).modelViewProjectionMatrix * float4(position, 1.0f));
|
|
out.color = in.color;
|
|
out.quad_pos = in.quad_pos;
|
|
return out;
|
|
}
|
|
|
|
vertex tint_symbol_3 vs_main(const constant RenderParams* tint_symbol_11 [[buffer(0)]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
|
|
VertexInput const tint_symbol_7 = {.position=tint_symbol_1.position, .color=tint_symbol_1.color, .quad_pos=tint_symbol_1.quad_pos};
|
|
VertexOutput const inner_result = vs_main_inner(tint_symbol_7, tint_symbol_11);
|
|
tint_symbol_3 wrapper_result = {};
|
|
wrapper_result.position = inner_result.position;
|
|
wrapper_result.color = inner_result.color;
|
|
wrapper_result.quad_pos = inner_result.quad_pos;
|
|
return wrapper_result;
|
|
}
|
|
|
|
float4 fs_main_inner(VertexOutput in) {
|
|
float4 color = in.color;
|
|
color[3] = (color[3] * fmax((1.0f - length(in.quad_pos)), 0.0f));
|
|
return color;
|
|
}
|
|
|
|
fragment tint_symbol_6 fs_main(float4 position [[position]], tint_symbol_5 tint_symbol_4 [[stage_in]]) {
|
|
VertexOutput const tint_symbol_8 = {.position=position, .color=tint_symbol_4.color, .quad_pos=tint_symbol_4.quad_pos};
|
|
float4 const inner_result_1 = fs_main_inner(tint_symbol_8);
|
|
tint_symbol_6 wrapper_result_1 = {};
|
|
wrapper_result_1.value = inner_result_1;
|
|
return wrapper_result_1;
|
|
}
|
|
|
|
void simulate_inner(uint3 GlobalInvocationID, thread float2* const tint_symbol_12, const constant SimulationParams* const tint_symbol_13, device Particles* const tint_symbol_14, texture2d<float, access::sample> tint_symbol_15) {
|
|
*(tint_symbol_12) = ((float4((*(tint_symbol_13)).seed).xy + float2(uint3(GlobalInvocationID).xy)) * float4((*(tint_symbol_13)).seed).zw);
|
|
uint const idx = GlobalInvocationID[0];
|
|
Particle particle = (*(tint_symbol_14)).particles[idx];
|
|
particle.velocity[2] = (particle.velocity[2] - ((*(tint_symbol_13)).deltaTime * 0.5f));
|
|
particle.position = (particle.position + ((*(tint_symbol_13)).deltaTime * particle.velocity));
|
|
particle.lifetime = (particle.lifetime - (*(tint_symbol_13)).deltaTime);
|
|
particle.color[3] = smoothstep(0.0f, 0.5f, particle.lifetime);
|
|
if ((particle.lifetime < 0.0f)) {
|
|
int2 coord = int2(0, 0);
|
|
for(int level = as_type<int>((as_type<uint>(int(tint_symbol_15.get_num_mip_levels())) - as_type<uint>(1))); (level > 0); level = as_type<int>((as_type<uint>(level) - as_type<uint>(1)))) {
|
|
float4 const probabilites = tint_symbol_15.read(uint2(coord), level);
|
|
float4 const value = float4(rand(tint_symbol_12));
|
|
bool4 const mask = ((value >= float4(0.0f, float4(probabilites).xyz)) & (value < probabilites));
|
|
coord = as_type<int2>((as_type<uint2>(coord) * as_type<uint>(2)));
|
|
coord[0] = as_type<int>((as_type<uint>(coord[0]) + as_type<uint>(select(0, 1, any(bool4(mask).yw)))));
|
|
coord[1] = as_type<int>((as_type<uint>(coord[1]) + as_type<uint>(select(0, 1, any(bool4(mask).zw)))));
|
|
}
|
|
float2 const uv = (float2(coord) / float2(int2(tint_symbol_15.get_width(), tint_symbol_15.get_height())));
|
|
particle.position = float3((((uv - 0.5f) * 3.0f) * float2(1.0f, -1.0f)), 0.0f);
|
|
particle.color = tint_symbol_15.read(uint2(coord), 0);
|
|
particle.velocity[0] = ((rand(tint_symbol_12) - 0.5f) * 0.100000001f);
|
|
particle.velocity[1] = ((rand(tint_symbol_12) - 0.5f) * 0.100000001f);
|
|
particle.velocity[2] = (rand(tint_symbol_12) * 0.300000012f);
|
|
particle.lifetime = (0.5f + (rand(tint_symbol_12) * 2.0f));
|
|
}
|
|
(*(tint_symbol_14)).particles[idx] = particle;
|
|
}
|
|
|
|
kernel void simulate(const constant SimulationParams* tint_symbol_17 [[buffer(0)]], device Particles* tint_symbol_18 [[buffer(1)]], texture2d<float, access::sample> tint_symbol_19 [[texture(0)]], uint3 GlobalInvocationID [[thread_position_in_grid]]) {
|
|
thread float2 tint_symbol_16 = 0.0f;
|
|
simulate_inner(GlobalInvocationID, &(tint_symbol_16), tint_symbol_17, tint_symbol_18, tint_symbol_19);
|
|
return;
|
|
}
|
|
|
|
void import_level_inner(uint3 coord, const constant UBO* const tint_symbol_20, device Buffer* const tint_symbol_21, texture2d<float, access::sample> tint_symbol_22) {
|
|
uint const offset = (coord[0] + (coord[1] * (*(tint_symbol_20)).width));
|
|
(*(tint_symbol_21)).weights[offset] = tint_symbol_22.read(uint2(int2(uint3(coord).xy)), 0)[3];
|
|
}
|
|
|
|
kernel void import_level(const constant UBO* tint_symbol_23 [[buffer(2)]], device Buffer* tint_symbol_24 [[buffer(3)]], texture2d<float, access::sample> tint_symbol_25 [[texture(1)]], uint3 coord [[thread_position_in_grid]]) {
|
|
import_level_inner(coord, tint_symbol_23, tint_symbol_24, tint_symbol_25);
|
|
return;
|
|
}
|
|
|
|
void export_level_inner(uint3 coord, texture2d<float, access::write> tint_symbol_26, const constant UBO* const tint_symbol_27, const device Buffer* const tint_symbol_28, device Buffer* const tint_symbol_29) {
|
|
if (all((uint3(coord).xy < uint2(int2(tint_symbol_26.get_width(), tint_symbol_26.get_height()))))) {
|
|
uint const dst_offset = (coord[0] + (coord[1] * (*(tint_symbol_27)).width));
|
|
uint const src_offset = ((coord[0] * 2u) + ((coord[1] * 2u) * (*(tint_symbol_27)).width));
|
|
float const a_1 = (*(tint_symbol_28)).weights[(src_offset + 0u)];
|
|
float const b = (*(tint_symbol_28)).weights[(src_offset + 1u)];
|
|
float const c = (*(tint_symbol_28)).weights[((src_offset + 0u) + (*(tint_symbol_27)).width)];
|
|
float const d = (*(tint_symbol_28)).weights[((src_offset + 1u) + (*(tint_symbol_27)).width)];
|
|
float const sum = dot(float4(a_1, b, c, d), float4(1.0f));
|
|
(*(tint_symbol_29)).weights[dst_offset] = (sum / 4.0f);
|
|
float4 const probabilities = (float4(a_1, (a_1 + b), ((a_1 + b) + c), sum) / fmax(sum, 0.0001f));
|
|
tint_symbol_26.write(probabilities, uint2(int2(uint3(coord).xy)));
|
|
}
|
|
}
|
|
|
|
kernel void export_level(texture2d<float, access::write> tint_symbol_30 [[texture(2)]], const constant UBO* tint_symbol_31 [[buffer(2)]], const device Buffer* tint_symbol_32 [[buffer(4)]], device Buffer* tint_symbol_33 [[buffer(3)]], uint3 coord [[thread_position_in_grid]]) {
|
|
export_level_inner(coord, tint_symbol_30, tint_symbol_31, tint_symbol_32, tint_symbol_33);
|
|
return;
|
|
}
|
|
|