{ "_doc": "Vulkan 렌더 그래프 (src/vkgs/src/render_graph.*). pipelines = 파이프라인 정의, resources = 그래프가 추적하는 리소스, passes = 노드 (kind = 엔진의 실행기 이름, uses = [리소스, 사용 방식]). 엔진은 선언 순서대로 for 문 하나로 순회하며, uses 로 배리어·레이아웃 전환을 자동으로 넣는다 (선언 순서 = 접근 순서). vkgs_viewer --graph out.dot 로 그림.", "pipelines": { "_doc": "graphics: vertex + fragment, topology(triangle_list|triangle_strip|line_list), depth(off|test|test_write|write_only), cull(none|back), line_width(dynamic 이면 vkCmdSetLineWidth). compute: compute.", "gs_preprocess": {"compute": "gs_preprocess.comp"}, "gs_sort": {"compute": "gs_sort.comp"}, "gs_radix_hist": {"compute": "gs_radix_hist.comp"}, "gs_radix_scan": {"compute": "gs_radix_scan.comp"}, "gs_radix_scatter": {"compute": "gs_radix_scatter.comp"}, "gs_splat": {"vertex": "gs_splat.vert", "fragment": "gs_splat.frag", "topology": "triangle_strip", "depth": "test"}, "line": {"vertex": "line.vert", "fragment": "line.frag", "topology": "line_list", "depth": "test", "line_width": "dynamic"}, "occluder": {"vertex": "line.vert", "fragment": "line.frag", "topology": "triangle_list", "depth": "write_only", "line_width": "dynamic"}, "env": {"vertex": "env.vert", "fragment": "env.frag", "topology": "triangle_list", "depth": "off", "target": "background"}, "sky_sim": {"vertex": "env.vert", "fragment": "sky_sim.frag", "topology": "triangle_list", "depth": "off", "target": "background"}, "pbr": {"vertex": "pbr.vert", "fragment": "pbr.frag", "topology": "triangle_list", "depth": "test_write", "cull": "back"}, "gltf_opaque": {"vertex": "pbr_gltf.vert", "fragment": "pbr_gltf.frag", "topology": "triangle_list", "depth": "test_write"}, "gltf_blend": {"vertex": "pbr_gltf.vert", "fragment": "pbr_gltf.frag", "topology": "triangle_list", "depth": "test"}, "shadow": {"vertex": "shadow.vert", "fragment": "shadow.frag", "topology": "triangle_strip", "depth": "test"}, "weather": {"compute": "weather.comp"}, "precip": {"vertex": "precip.vert", "fragment": "precip.frag", "topology": "triangle_strip", "target": "precip"}, "fxaa": {"compute": "fxaa.comp"}, "camera_isp": {"compute": "camera_isp.comp", "_doc": "셰이더 그래프 configs/shader_graphs/camera_isp.json 이 생성"}, "camera_mode": {"compute": "camera_mode.comp"} }, "resources": { "gaussians": {"type": "buffer", "doc": "가우시안 (위치·공분산·SH), 로드 때 한 번"}, "camera": {"type": "buffer", "doc": "카메라 UBO"}, "splats": {"type": "buffer", "doc": "화면공간 스플랫"}, "keys": {"type": "buffer", "doc": "깊이 정렬 키 (보이는 것만 앞에 모은다)"}, "keys_tmp": {"type": "buffer", "doc": "radix 정렬 임시 (keys 와 번갈아)", "create": {"bytes_per": "gaussians_pow2", "stride": 8, "bindless": "ssbo"}}, "sort_hist": {"type": "buffer", "doc": "radix 정렬 (워크그룹, 자릿수) 히스토그램·출력 위치", "create": {"bytes": 524288, "bindless": "ssbo"}}, "draw_args": {"type": "buffer", "doc": "인다이렉트 그리기 인자"}, "draw_readback": {"type": "buffer", "doc": "보이는 스플랫 수 (호스트 읽기)"}, "color": {"type": "image", "format": "rgba16f", "doc": "장면 색 (premultiplied). rgba16f | rgba32f — 16비트는 블렌딩 대역폭이 반"}, "depth_acc": {"type": "image", "format": "rg32f", "doc": "거리 누적 (Σzα, Σα) — 표면 깊이 = R/G, 배경 비율 = 1−G (depth_common.glsl). rg32f | rg16f"}, "depth": {"type": "image", "format": "d32", "doc": "메시 깊이"}, "weather_ubo": {"type": "buffer", "doc": "날씨·조도 매개변수"}, "post": {"type": "image", "format": "rgba16f", "doc": "날씨 후처리 결과 → 화면·PNG·미리보기"}, "background": {"type": "image", "format": "rgba16f", "doc": "배경 하늘 (시뮬레이션 하늘·학습된 하늘·환경맵). 장면은 투명 배경 위에 쌓고 weather 가 합친다", "create": {"size": "screen"}}, "precip": {"type": "image", "format": "rgba16f", "doc": "강수 입자 레이어 (premultiplied 선형) → weather 가 합성", "create": {"size": "screen"}}, "isp_params": {"type": "buffer", "doc": "카메라 ISP 셰이더 그래프 매개변수 (float[])", "create": {"bytes": 1024, "host_visible": true, "bindless": "ssbo"}} }, "targets": { "_doc": "렌더 패스 정의: color = 색 첨부 (그래프가 만든 이미지), 매번 지운다. 파이프라인의 target 과 래스터 패스의 params.target 이 이 이름을 쓴다. scene 은 엔진 기본 (color + depth_acc + depth)", "precip": {"color": ["precip"]}, "background": {"color": ["background"]} }, "passes": [ {"name": "clear_draw_args", "kind": "fill_draw_args", "uses": [["draw_args", "transfer_dst"]], "params": {"buffer": "draw_args", "values": [4, 0, 0, 0]}}, {"name": "preprocess", "kind": "compute", "uses": [["gaussians", "storage_read"], ["camera", "uniform"], ["splats", "storage_write"], ["keys", "storage_write"], ["draw_args", "storage_read_write"]], "params": {"pipeline": "gs_preprocess", "dispatch": "gaussians_pow2"}}, {"name": "sort", "kind": "radix_sort", "_doc": "보이는 것만 GPU radix (8비트 × 4패스, 안정). subgroup ballot 이 없으면 bitonic (기준 구현, 2^n 전체). VKGS_BITONIC=1 로 강제", "uses": [["keys", "storage_read_write"], ["keys_tmp", "storage_read_write"], ["sort_hist", "storage_read_write"], ["draw_args", "storage_read"]], "params": {"hist": "gs_radix_hist", "scan": "gs_radix_scan", "scatter": "gs_radix_scatter", "keys": "keys", "tmp": "keys_tmp", "histogram": "sort_hist", "groups": 512, "key_bits": 32, "fallback": "bitonic_sort", "fallback_pipeline": "gs_sort"}}, {"name": "readback_count", "kind": "copy_buffer", "uses": [["draw_args", "transfer_src"], ["draw_readback", "transfer_dst"]], "params": {"src": "draw_args", "dst": "draw_readback", "bytes": 16, "host_read": true}}, {"name": "background", "kind": "raster", "_doc": "배경 하늘을 따로 — 날씨가 가우시안 부분과 하늘 부분을 따로 보정한 뒤 덮임 α 로 합친다 (시뮬레이션 하늘을 두 번 어둡게 하지 않게)", "uses": [["weather_ubo", "uniform"], ["background", "color_attachment"]], "params": {"target": "background", "draws": ["background"]}}, {"name": "scene", "kind": "raster", "uses": [["splats", "vertex"], ["keys", "vertex"], ["draw_args", "indirect"], ["color", "color_attachment"], ["depth_acc", "color_attachment"], ["depth", "depth_attachment"]], "params": {"draws": ["spheres", "gltf_opaque", "splats", "shadows", "gltf_translucent", "lines"]}}, {"name": "precip", "kind": "raster", "_doc": "월드 공간 비·눈 입자 (precip.vert). 자차 주변 상자에 월드 고정 → 6캠이 같은 빗방울, 시차·주행 기울기. 거리 버퍼로 가려짐", "uses": [["depth_acc", "storage_read"], ["weather_ubo", "uniform"], ["precip", "color_attachment"]], "params": {"target": "precip", "draws": ["precip"]}}, {"name": "weather", "kind": "compute", "uses": [["color", "storage_read"], ["depth_acc", "storage_read"], ["precip", "storage_read"], ["background", "storage_read"], ["weather_ubo", "uniform"], ["post", "storage_write"]], "params": {"pipeline": "weather", "dispatch": "screen", "push_slots": ["precip", "background"]}}, {"name": "fxaa", "kind": "compute", "optional": true, "_doc": "화면 공간 AA (메시·선 가장자리). post → color(다 쓴 장면 색을 빌림) → 다음 패스가 post 로 복사. MSAA 는 스플랫 블렌딩을 샘플 수배로 늘려 쓰지 않는다", "uses": [["post", "storage_read"], ["color", "storage_write"]], "params": {"pipeline": "fxaa", "dispatch": "screen"}}, {"name": "fxaa_resolve", "kind": "copy_image", "follows": "fxaa", "uses": [["color", "transfer_src"], ["post", "transfer_dst"]], "params": {"src": "color", "dst": "post"}}, {"name": "camera_isp", "kind": "compute", "optional": true, "enabled": false, "_doc": "셰이더 그래프(카메라 ISP). 픽셀 단위 노드만이라 post 를 제자리에서 고친다. 켜기: F2 창 또는 sim.json shader_graphs.camera_isp.enabled", "uses": [["post", "storage_read_write"], ["isp_params", "storage_read"]], "params": {"pipeline": "camera_isp", "dispatch": "screen", "push_slots": ["isp_params"]}}, {"name": "camera_mode", "kind": "compute", "_doc": "카메라 모드 (깊이 · 시맨틱 · 흑백, 뷰어 F3). RGB 면 셰이더가 바로 끝난다. 깊이 = depth_acc 를 색으로, 흑백 = 최종 영상의 루마", "uses": [["post", "storage_read_write"], ["depth_acc", "storage_read"], ["camera", "uniform"]], "params": {"pipeline": "camera_mode", "dispatch": "screen"}}, {"name": "to_present", "kind": "none", "uses": [["post", "transfer_src"]], "_doc": "실행할 일은 없고, post 를 화면·PNG·미리보기 복사(transfer)용으로 전환하는 노드"} ] }