Начальный коммит: Vulkan-редактор SimVulcan + исследование KBC-LBM
Состояние на момент заведения репозитория. C++ приложение (src/, shaders/, tests/) — минимальный редактор 3D-моделей на Vulkan 1.3: орбитальная камера, три опорные сетки через начало координат, загрузка .obj с режимами отображения. Весь Vulkan изолирован в src/vk/. Исследование (docs/) — оригинальные статьи по KBC (docs/origins) и Python-решатель D2Q9 KBC-N1 с AMR 2x и SDF+Bouzidi (docs/theory). В решателе перед коммитом исправлены дефекты, найденные сверкой с первоисточниками: относительный порог знаменателя энтропийного стабилизатора (абсолютный вырождал KBC в LBGK на 77-99% узлов), заворот вход/выход в углах домена, диагностика средней плотности по фиктивным узлам тела, зашитый refine=2. Подробности — docs/theory/solver_2x_sdf/README.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Collect all shader sources and feed them to the simv_shaders custom target.
|
||||
file(GLOB_RECURSE SHADER_SOURCES CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/editor/*.vert"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/editor/*.frag"
|
||||
)
|
||||
|
||||
if(SHADER_SOURCES)
|
||||
# INCLUDE root is `shaders/` so that #include "common/foo.glsl" would resolve
|
||||
# to shaders/common/foo.glsl if a shader needs a shared helper.
|
||||
simv_compile_shaders(simv_shaders
|
||||
${SHADER_SOURCES}
|
||||
INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
)
|
||||
else()
|
||||
# Empty placeholder so dependent targets don't break when no shaders exist yet.
|
||||
add_custom_target(simv_shaders ALL COMMAND ${CMAKE_COMMAND} -E true)
|
||||
endif()
|
||||
@@ -0,0 +1,8 @@
|
||||
#version 460
|
||||
|
||||
layout(location = 0) in vec3 vColor;
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(vColor, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#version 460
|
||||
// Reference-grid / axis lines: per-vertex colour, transformed by the MVP.
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
mat4 mvp;
|
||||
} pc;
|
||||
|
||||
layout(location = 0) out vec3 vColor;
|
||||
|
||||
void main() {
|
||||
vColor = inColor;
|
||||
gl_Position = pc.mvp * vec4(inPos, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#version 460
|
||||
// Flat shading: the per-face normal is reconstructed from screen-space
|
||||
// derivatives of the model-space position, so the vertex stream needs no
|
||||
// normals. color.a selects shaded (1) vs constant colour (0, for wireframe).
|
||||
|
||||
layout(location = 0) in vec3 vModelPos;
|
||||
layout(location = 0) out vec4 outColor;
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
mat4 mvp;
|
||||
vec4 color;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
vec3 dx = dFdx(vModelPos);
|
||||
vec3 dy = dFdy(vModelPos);
|
||||
vec3 c = cross(dx, dy);
|
||||
float len = length(c);
|
||||
vec3 n = (len > 1e-8) ? c / len : vec3(0.0, 0.0, 1.0);
|
||||
|
||||
const vec3 L = normalize(vec3(0.4, 0.85, 0.55));
|
||||
float diff = abs(dot(n, L)); // two-sided
|
||||
float shade = clamp(0.25 + 0.8 * diff, 0.0, 1.0);
|
||||
|
||||
vec3 base = pc.color.rgb;
|
||||
vec3 rgb = mix(base, base * shade, pc.color.a);
|
||||
outColor = vec4(rgb, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#version 460
|
||||
// Transforms model vertices by the MVP push constant. The model-space position
|
||||
// is passed through so the fragment shader can derive a flat normal from it.
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
mat4 mvp;
|
||||
vec4 color; // .rgb base colour, .a = lit flag (1 = shaded, 0 = flat)
|
||||
} pc;
|
||||
|
||||
layout(location = 0) out vec3 vModelPos;
|
||||
|
||||
void main() {
|
||||
vModelPos = inPos;
|
||||
gl_Position = pc.mvp * vec4(inPos, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user