Skip to content

Commit 97fe97f

Browse files
committed
testing shadercross and workflows (closes #28)
1 parent 9bf9390 commit 97fe97f

57 files changed

Lines changed: 1442 additions & 35 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
build:
9+
strategy:
10+
matrix:
11+
os:
12+
- ubuntu-latest
13+
- windows-2025
14+
- macos-latest
15+
runs-on: ${{ matrix.os }}
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
submodules: recursive
22+
23+
- name: Dependencies
24+
if: runner.os == 'Linux'
25+
run: |
26+
sudo apt-get update
27+
sudo apt-get install -y \
28+
build-essential \
29+
git \
30+
make \
31+
pkg-config \
32+
cmake \
33+
ninja-build \
34+
gnome-desktop-testing \
35+
libasound2-dev \
36+
libpulse-dev \
37+
libaudio-dev \
38+
libfribidi-dev \
39+
libjack-dev \
40+
libsndio-dev \
41+
libx11-dev \
42+
libxext-dev \
43+
libxrandr-dev \
44+
libxcursor-dev \
45+
libxfixes-dev \
46+
libxi-dev \
47+
libxss-dev \
48+
libxtst-dev \
49+
libxkbcommon-dev \
50+
libdrm-dev \
51+
libgbm-dev \
52+
libgl1-mesa-dev \
53+
libgles2-mesa-dev \
54+
libegl1-mesa-dev \
55+
libdbus-1-dev \
56+
libibus-1.0-dev \
57+
libudev-dev \
58+
libthai-dev
59+
libwayland-dev \
60+
libdecor-0-dev \
61+
liburing-dev \
62+
63+
- name: Configure
64+
run: cmake -S . -B build
65+
66+
- name: Build
67+
run: cmake --build build

CMakeLists.txt

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,56 @@ add_executable(blocks WIN32
2727
src/world.c
2828
)
2929
target_link_libraries(blocks PUBLIC SDL3::SDL3)
30-
if(UNIX)
31-
target_link_libraries(blocks PUBLIC m)
32-
endif()
3330
target_include_directories(blocks PUBLIC lib/sqlite3)
3431
target_include_directories(blocks PUBLIC lib/stb)
3532
set_target_properties(blocks PROPERTIES C_STANDARD 11)
3633

3734
function(shader FILE)
38-
set(SOURCE shaders/${FILE})
39-
set(OUTPUT ${BINARY_DIR}/${FILE})
40-
add_custom_command(
41-
OUTPUT ${OUTPUT}
42-
COMMAND glslc ${SOURCE} -o ${OUTPUT} -I src
43-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
44-
DEPENDS ${SOURCE} shaders/helpers.glsl src/config.h
45-
COMMENT ${SOURCE}
46-
)
47-
string(REPLACE . _ NAME ${FILE})
48-
add_custom_target(${NAME} DEPENDS ${OUTPUT})
49-
add_dependencies(blocks ${NAME})
35+
set(GLSL ${CMAKE_SOURCE_DIR}/shaders/${FILE})
36+
set(SPV ${CMAKE_SOURCE_DIR}/shaders/bin/${FILE}.spv)
37+
set(DXIL ${CMAKE_SOURCE_DIR}/shaders/bin/${FILE}.dxil)
38+
set(MSL ${CMAKE_SOURCE_DIR}/shaders/bin/${FILE}.msl)
39+
set(JSON ${CMAKE_SOURCE_DIR}/shaders/bin/${FILE}.json)
40+
function(compile PROGRAM SOURCE OUTPUT)
41+
add_custom_command(
42+
OUTPUT ${OUTPUT}
43+
COMMAND ${PROGRAM} ${SOURCE} -o ${OUTPUT} -I src
44+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
45+
DEPENDS ${SOURCE} shaders/helpers.glsl src/config.h
46+
COMMENT "${SOURCE} -> ${OUTPUT}"
47+
)
48+
get_filename_component(NAME ${OUTPUT} NAME)
49+
string(REPLACE . _ NAME ${NAME})
50+
set(NAME compile_${NAME})
51+
add_custom_target(${NAME} DEPENDS ${OUTPUT})
52+
add_dependencies(blocks ${NAME})
53+
endfunction()
54+
if (MSVC)
55+
set(SHADERCROSS lib/SDL_shadercross/msvc/shadercross.exe)
56+
compile(glslc ${GLSL} ${SPV})
57+
compile(${SHADERCROSS} ${SPV} ${MSL})
58+
compile(${SHADERCROSS} ${SPV} ${JSON})
59+
endif()
60+
function(package OUTPUT)
61+
get_filename_component(NAME ${OUTPUT} NAME)
62+
set(BINARY ${BINARY_DIR}/${NAME})
63+
add_custom_command(
64+
OUTPUT ${BINARY}
65+
COMMAND ${CMAKE_COMMAND} -E copy ${OUTPUT} ${BINARY}
66+
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
67+
DEPENDS ${OUTPUT}
68+
COMMENT "${OUTPUT} -> ${BINARY}"
69+
)
70+
string(REPLACE . _ NAME ${NAME})
71+
set(NAME package_${NAME})
72+
add_custom_target(${NAME} DEPENDS ${BINARY})
73+
add_dependencies(blocks ${NAME})
74+
endfunction()
75+
if(NOT APPLE)
76+
package(${SPV})
77+
else()
78+
package(${MSL})
79+
endif()
5080
endfunction()
5181
shader(composite.frag)
5282
shader(fullscreen.vert)

lib/SDL_shadercross/msvc/SDL3.dll

5.49 MB
Binary file not shown.
29 KB
Binary file not shown.
17.2 MB
Binary file not shown.

lib/SDL_shadercross/msvc/dxil.dll

1.44 MB
Binary file not shown.
19 KB
Binary file not shown.
1.9 MB
Binary file not shown.

shaders/bin/composite.frag.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "samplers": 6, "storage_textures": 0, "storage_buffers": 0, "uniform_buffers": 3 }

shaders/bin/composite.frag.msl

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#pragma clang diagnostic ignored "-Wmissing-prototypes"
2+
#pragma clang diagnostic ignored "-Wmissing-braces"
3+
4+
#include <metal_stdlib>
5+
#include <simd/simd.h>
6+
7+
using namespace metal;
8+
9+
template<typename T, size_t Num>
10+
struct spvUnsafeArray
11+
{
12+
T elements[Num ? Num : 1];
13+
14+
thread T& operator [] (size_t pos) thread
15+
{
16+
return elements[pos];
17+
}
18+
constexpr const thread T& operator [] (size_t pos) const thread
19+
{
20+
return elements[pos];
21+
}
22+
23+
device T& operator [] (size_t pos) device
24+
{
25+
return elements[pos];
26+
}
27+
constexpr const device T& operator [] (size_t pos) const device
28+
{
29+
return elements[pos];
30+
}
31+
32+
constexpr const constant T& operator [] (size_t pos) const constant
33+
{
34+
return elements[pos];
35+
}
36+
37+
threadgroup T& operator [] (size_t pos) threadgroup
38+
{
39+
return elements[pos];
40+
}
41+
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
42+
{
43+
return elements[pos];
44+
}
45+
};
46+
47+
struct t_shadow_matrix
48+
{
49+
float4x4 u_shadow_matrix;
50+
};
51+
52+
struct t_player_position
53+
{
54+
float3 u_player_position;
55+
};
56+
57+
struct t_shadow_vector
58+
{
59+
float3 u_shadow_vector;
60+
};
61+
62+
constant spvUnsafeArray<float3, 6> _74 = spvUnsafeArray<float3, 6>({ float3(0.0, 0.0, 1.0), float3(0.0, 0.0, -1.0), float3(1.0, 0.0, 0.0), float3(-1.0, 0.0, 0.0), float3(0.0, 1.0, 0.0), float3(0.0, -1.0, 0.0) });
63+
64+
struct main0_out
65+
{
66+
float4 o_color [[color(0)]];
67+
};
68+
69+
struct main0_in
70+
{
71+
float2 i_uv [[user(locn0)]];
72+
};
73+
74+
static inline __attribute__((always_inline))
75+
uint get_direction(uint voxel)
76+
{
77+
return (voxel >> uint(26)) & 7u;
78+
}
79+
80+
static inline __attribute__((always_inline))
81+
float3 get_normal(uint voxel)
82+
{
83+
return _74[get_direction(voxel)];
84+
}
85+
86+
static inline __attribute__((always_inline))
87+
bool get_shadowed(uint voxel)
88+
{
89+
return ((voxel >> uint(30)) & 1u) != 0u;
90+
}
91+
92+
static inline __attribute__((always_inline))
93+
bool get_occluded(uint voxel)
94+
{
95+
return ((voxel >> uint(31)) & 1u) != 0u;
96+
}
97+
98+
static inline __attribute__((always_inline))
99+
float get_fog(float x)
100+
{
101+
return fast::min(powr(x / 250.0, 2.5), 1.0);
102+
}
103+
104+
static inline __attribute__((always_inline))
105+
float3 get_sky(float y)
106+
{
107+
return mix(float3(0.699999988079071044921875, 0.89999997615814208984375, 1.0), float3(0.300000011920928955078125, 0.60000002384185791015625, 0.89999997615814208984375), float3(fast::clamp(y, 0.0, 0.800000011920928955078125)));
108+
}
109+
110+
static inline __attribute__((always_inline))
111+
float4 get_color(texture2d_array<float> atlas, sampler atlasSmplr, texture2d<float> shadowmap, sampler shadowmapSmplr, float3 position, float3 uv, float3 normal, float3 player_position, float3 shadow_position, float3 shadow_vector, bool shadowed, bool occluded, float fog, float ssao, float alpha)
112+
{
113+
float3 shadow_uv;
114+
shadow_uv.x = (shadow_position.x * 0.5) + 0.5;
115+
shadow_uv.y = 1.0 - ((shadow_position.y * 0.5) + 0.5);
116+
shadow_uv.z = shadow_position.z;
117+
float ao = ssao * 0.4000000059604644775390625;
118+
float ambient = 0.20000000298023223876953125;
119+
float directional = 0.0;
120+
float angle = dot(normal, -shadow_vector);
121+
float depth = shadow_uv.z - 0.001000000047497451305389404296875;
122+
bool _145 = !shadowed;
123+
bool _179;
124+
if (!_145)
125+
{
126+
bool _150 = angle > 0.0;
127+
bool _178;
128+
if (_150)
129+
{
130+
bool _157 = all(shadow_uv <= float3(0.0));
131+
bool _165;
132+
if (!_157)
133+
{
134+
_165 = all(shadow_uv >= float3(1.0));
135+
}
136+
else
137+
{
138+
_165 = _157;
139+
}
140+
bool _177;
141+
if (!_165)
142+
{
143+
_177 = depth < shadowmap.sample(shadowmapSmplr, shadow_uv.xy).x;
144+
}
145+
else
146+
{
147+
_177 = _165;
148+
}
149+
_178 = _177;
150+
}
151+
else
152+
{
153+
_178 = _150;
154+
}
155+
_179 = _178;
156+
}
157+
else
158+
{
159+
_179 = _145;
160+
}
161+
if (_179)
162+
{
163+
directional = fast::max(angle, 0.0) * 1.2000000476837158203125;
164+
}
165+
if (!occluded)
166+
{
167+
ao = 0.699999988079071044921875;
168+
}
169+
float4 color = atlas.sample(atlasSmplr, uv.xy, uint(rint(uv.z)));
170+
color.w = fast::clamp(color.w + alpha, 0.0, 1.0);
171+
float light = (ao + ambient) + directional;
172+
float dy = position.y - player_position.y;
173+
float dx = distance(position.xz, player_position.xz);
174+
float pitch = precise::atan2(dy, dx);
175+
float4 sky = float4(get_sky(pitch), 1.0);
176+
float4 composite = float4(color.xyz * light, color.w);
177+
return mix(composite, sky, float4(fog));
178+
}
179+
180+
fragment main0_out main0(main0_in in [[stage_in]], constant t_player_position& _297 [[buffer(0)]], constant t_shadow_vector& _309 [[buffer(1)]], constant t_shadow_matrix& _276 [[buffer(2)]], texture2d_array<float> s_atlas [[texture(0)]], texture2d<float> s_position [[texture(1)]], texture2d<float> s_uv [[texture(2)]], texture2d<uint> s_voxel [[texture(3)]], texture2d<float> s_shadowmap [[texture(4)]], texture2d<float> s_ssao [[texture(5)]], sampler s_atlasSmplr [[sampler(0)]], sampler s_positionSmplr [[sampler(1)]], sampler s_uvSmplr [[sampler(2)]], sampler s_voxelSmplr [[sampler(3)]], sampler s_shadowmapSmplr [[sampler(4)]], sampler s_ssaoSmplr [[sampler(5)]])
181+
{
182+
main0_out out = {};
183+
float3 position = s_position.sample(s_positionSmplr, in.i_uv).xyz;
184+
float3 uv = s_uv.sample(s_uvSmplr, in.i_uv).xyz;
185+
uint voxel = s_voxel.sample(s_voxelSmplr, in.i_uv).x;
186+
if (length(uv) == 0.0)
187+
{
188+
discard_fragment();
189+
}
190+
float4 shadow_position = _276.u_shadow_matrix * float4(position, 1.0);
191+
out.o_color = get_color(s_atlas, s_atlasSmplr, s_shadowmap, s_shadowmapSmplr, position, uv, get_normal(voxel), _297.u_player_position, shadow_position.xyz / float3(shadow_position.w), _309.u_shadow_vector, get_shadowed(voxel), get_occluded(voxel), get_fog(distance(position.xz, _297.u_player_position.xz)), s_ssao.sample(s_ssaoSmplr, in.i_uv).x, 0.0);
192+
return out;
193+
}
194+

0 commit comments

Comments
 (0)