From eb79ff9879f383ff56f7425e5e3106756d809d6c Mon Sep 17 00:00:00 2001 From: legatt Date: Mon, 27 Apr 2026 17:24:51 +0300 Subject: [PATCH] Shaders SPIR-V compilation in SDK --- assets-src/materials/provinces.mat.json | 4 +- .../shaders/provinces-flat/provinces.frag | 10 +++ .../shaders/provinces-flat/provinces.vert | 35 +++++++++ .../provinces-sphere-eq/provinces.frag | 10 +++ .../provinces-sphere-eq/provinces.vert | 67 ++++++++++++++++++ assets/materials/provinces.mat | Bin 14 -> 14 bytes .../{ => provinces-flat}/provinces.frag | Bin .../{ => provinces-flat}/provinces.vert | Bin .../provinces-sphere-eq/provinces.frag | Bin 0 -> 432 bytes .../provinces-sphere-eq/provinces.vert | Bin 0 -> 1892 bytes engine/modules/AssetManager.cppm | 4 +- sdk/modules/io.cppm | 1 - sdk/src/main.cpp | 53 +++++++++++++- 13 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 assets-src/shaders/provinces-flat/provinces.frag create mode 100644 assets-src/shaders/provinces-flat/provinces.vert create mode 100644 assets-src/shaders/provinces-sphere-eq/provinces.frag create mode 100644 assets-src/shaders/provinces-sphere-eq/provinces.vert rename assets/shaders/{ => provinces-flat}/provinces.frag (100%) rename assets/shaders/{ => provinces-flat}/provinces.vert (100%) create mode 100644 assets/shaders/provinces-sphere-eq/provinces.frag create mode 100644 assets/shaders/provinces-sphere-eq/provinces.vert diff --git a/assets-src/materials/provinces.mat.json b/assets-src/materials/provinces.mat.json index 1d969a2..2ee7e4e 100644 --- a/assets-src/materials/provinces.mat.json +++ b/assets-src/materials/provinces.mat.json @@ -1,4 +1,4 @@ { - "vertexShaderAssetID": "assets/shaders/provinces.vert", - "fragmentShaderAssetID": "assets/shaders/provinces.frag" + "vertexShaderAssetID": "assets/shaders/provinces-flat/provinces.vert", + "fragmentShaderAssetID": "assets/shaders/provinces-flat/provinces.frag" } \ No newline at end of file diff --git a/assets-src/shaders/provinces-flat/provinces.frag b/assets-src/shaders/provinces-flat/provinces.frag new file mode 100644 index 0000000..1730b4f --- /dev/null +++ b/assets-src/shaders/provinces-flat/provinces.frag @@ -0,0 +1,10 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} \ No newline at end of file diff --git a/assets-src/shaders/provinces-flat/provinces.vert b/assets-src/shaders/provinces-flat/provinces.vert new file mode 100644 index 0000000..5d8fc93 --- /dev/null +++ b/assets-src/shaders/provinces-flat/provinces.vert @@ -0,0 +1,35 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec2 position; + +layout(binding = 0) uniform Camera { + mat4 viewProjection; +} camera; + +layout(push_constant) uniform Model { + mat4 model; +} model; + +struct Province { + uint regionId; + uint color; +}; +layout(std430, binding = 1) readonly buffer Data { + Province provinces[]; +}; + +layout(location = 0) out vec3 fragColor; + +vec3 unpackColor(uint c) { + return vec3( + c & 0xFFu, + (c >> 8) & 0xFFu, + (c >> 16) & 0xFFu + ) / 255.0; +} + +void main() { + gl_Position = camera.viewProjection * vec4(position, 0.0, 1.0); + fragColor = unpackColor(provinces[gl_InstanceIndex].color); +} \ No newline at end of file diff --git a/assets-src/shaders/provinces-sphere-eq/provinces.frag b/assets-src/shaders/provinces-sphere-eq/provinces.frag new file mode 100644 index 0000000..1730b4f --- /dev/null +++ b/assets-src/shaders/provinces-sphere-eq/provinces.frag @@ -0,0 +1,10 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} \ No newline at end of file diff --git a/assets-src/shaders/provinces-sphere-eq/provinces.vert b/assets-src/shaders/provinces-sphere-eq/provinces.vert new file mode 100644 index 0000000..da7622f --- /dev/null +++ b/assets-src/shaders/provinces-sphere-eq/provinces.vert @@ -0,0 +1,67 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec2 position; + +layout(binding = 0) uniform Camera { + mat4 viewProjection; +} camera; + +layout(push_constant) uniform Model { + mat4 model; +} model; + +struct Province { + uint regionId; + uint color; +}; +layout(std430, binding = 1) readonly buffer Data { + Province provinces[]; +}; + +layout(location = 0) out vec3 fragColor; + +const float PI = 3.141592653589793; + +vec3 unpackColor(uint c) { + return vec3( + c & 0xFFu, + (c >> 8) & 0xFFu, + (c >> 16) & 0xFFu + ) / 255.0; +} + +vec2 toUV(vec2 pos) +{ + vec2 uv = pos / vec2(5632.0, 2048.0); + + uv.y = 1.0 - uv.y; + + return uv; //TODO: Provide map size +} + +vec3 mercatorToSphere(vec2 uv) +{ + float lon = uv.x * 2.0 * PI - PI; + lon += PI; + float lat = PI * 0.5 - uv.y * PI; + + float cosLat = cos(lat); + + return vec3( + cosLat * cos(lon), + sin(lat), + cosLat * sin(lon) + ); +} + +void main() { + vec2 uv = toUV(position); + vec3 spherePos = mercatorToSphere(uv); + gl_Position = camera.viewProjection + * vec4(spherePos, 1.0); + + //gl_Position = camera.viewProjection * vec4(position, 0.0, 1.0); + //fragColor = unpackColor(provinces[gl_InstanceIndex].color); + fragColor = unpackColor(provinces[gl_InstanceIndex].regionId); +} \ No newline at end of file diff --git a/assets/materials/provinces.mat b/assets/materials/provinces.mat index 3561dc74e7689af381be1ce7e22c64adf53f2da1..d3a8a53564659bd40aa2b45d2a69b1e3fae09605 100644 GIT binary patch literal 14 VcmWe&5@7uQX@yj3>m&0x1^^@>1vmfz literal 14 VcmWe&5@7rvR zFPkPGjfjWHq8)kMPCpWyz^j+MTJP4w-_v0@8h@GSL|O*TbfXcEu=w5|e|%_y7U+@F zXF#mD>AwMw+RR<&%uLYl)Y#qofLk3dz$h%dF=6rQ-kMZ?a>C-Z*i^dRvz^4^(xO9_gug7{KpO3yZ;NY S-n{Sbv0$qIExbqp+lGec>2F2DUdq6=jf{Pj!FFm z$Gov`q(+Lpi|=kMzXya+=}UUuL}|bI0kGOUd^pt)XYop3nf=FNt$p>zcr0@EJC3i0 zZ@-hjr(*0GC2oEin`+Dnb=@Q_)ZLSBO1FJ@eOMT#t3Xv9o7QiMWFG8;Vxg8EggE$1K)ZojI&$%Bf>KA35_2 z_%*<9X5QHOku$%Db-(ANZ}A2HPFK%?6n`aV^>i}3ev@y&8u?W79e=fX<^T8mK|E8b z^md}`9e)D3gnejvu5at|-oIh|Js*VioD*OSEW~r~Mb7h&z&Qi=fxP#bi`)Zz=g(ZK zTf(=_rJj2qf+b+@iF<_a{sEBm9^(%Ka~rvjd!GQ$v`_Pif12afPrA?W-D5u0KF3$1 z5#%*qE_dGRxo4f2ccNti3jhfEs zRp9SJ%|m<{W9!s+j&1^Hs2}}B>@DETS#K`&;!NEJ=0Brt{3>$(f0;zjw|pJ> ReadJson(const std::filesystem::path &assetPath) { std::ifstream fin(assetPath); if (!fin.is_open()) { diff --git a/sdk/src/main.cpp b/sdk/src/main.cpp index ffd2f22..735abd2 100644 --- a/sdk/src/main.cpp +++ b/sdk/src/main.cpp @@ -13,6 +13,12 @@ import std; using json = nlohmann::json; using path = std::filesystem::path; +void IfNotExluded(const std::vector &exluded, const path &a, const std::function &callback) { + if (std::ranges::find(exluded, a) == exluded.end()) + callback(); + else LOG(INFO, "SKIP EXCLUDED [%s]", a.c_str()); +} + template void CompileJson(const ee_sdk::JsonCompiler &compiler, const path &relative, const path &src, const path &out) { LOG(INFO, "Start compiling %s...", relative.c_str()); @@ -46,6 +52,32 @@ void CompileMaps(const ee_sdk::MapMeshCompiler &compiler, const path &relative, } } +void CompileSPIRV(const path &compiler, const path &relative, const path &src, const path &out) { + LOG(INFO, "Start compiling %s...", relative.c_str()); + + for (const std::filesystem::directory_entry &asset : std::filesystem::recursive_directory_iterator(src/relative)) { + if (!asset.is_regular_file()) continue; + + const path shader = std::filesystem::relative(asset.path(), src/relative); + std::filesystem::create_directories((out/relative/shader).parent_path()); + + const std::string cmd = std::format("{} \"{}\" -O -o \"{}\"", + compiler.string(), + asset.path().string(), + (out/relative/shader).string() + ); + LOG(INFO, "Run [%hs]", cmd.c_str()); + + if ( + const std::int32_t result = std::system(cmd.c_str()); + result == 0 + ) { + LOG(INFO, "COMPILED SPIR-V SHADER: [%s]", (relative/shader).c_str()); + } + else LOG(CRITICAL, "COMPILATION FAILED: [%s]. Result code: %d", (relative/shader).c_str(), result); + } +} + int main(const int argc, char **argv) { std::uint32_t status = 0; @@ -61,6 +93,8 @@ int main(const int argc, char **argv) { options.add_options() ("src", "Path to your mod source assets", cxxopts::value()) ("o,out", "Path to compiled assets", cxxopts::value()->default_value("out")) + ("e,exclude", "List of excluded asset types", cxxopts::value>()->default_value("")) + ("E,exclude-path", "List of exluded asset paths", cxxopts::value>()->default_value("")) ("h,help", "Print usage"); if ( @@ -73,12 +107,25 @@ int main(const int argc, char **argv) { const path &src = cmd["src"].as(); const path &out = cmd["out"].as(); + const std::vector &excludedTypes = cmd["exclude"].as>(); + const std::vector &excludedPaths = cmd["exclude-path"].as>(); + const ee_sdk::JsonCompiler jsonCompiler(src/"regions.json"); - CompileJson(jsonCompiler, "materials", src, out); - CompileJson(jsonCompiler, "scenarios", src, out); + IfNotExluded(excludedTypes, "materials", [jsonCompiler, src, out] { + CompileJson(jsonCompiler, "materials", src, out); + }); + IfNotExluded(excludedTypes, "scenarios", [jsonCompiler, src, out] { + CompileJson(jsonCompiler, "scenarios", src, out); + }); constexpr ee_sdk::MapMeshCompiler mapMeshCompiler; - CompileMaps(mapMeshCompiler, "map", src, out); + IfNotExluded(excludedTypes, "map", [mapMeshCompiler, src, out] { + CompileMaps(mapMeshCompiler, "map", src, out); + }); + + IfNotExluded(excludedTypes, "shaders", [src, out] { + CompileSPIRV("glslc", "shaders", src, out); + }); } }