Compare commits

...

455 Commits

Author SHA1 Message Date
6e9265e92e checkpoint(new_editor): native d3d12 ui path
Key node 1: move main-window UI presentation onto the D3D12 render loop with native UI renderer, text system, and texture host.

Key node 2: wire frame timing/FPS display, window runtime, swapchain presentation, and native screenshot capture around the new path.

Key node 3: carry editor shell/workspace/viewport/panel interaction updates needed by the new renderer and detached window flow.

Key node 4: pump async resource loads and scene bridge follow-up needed for scene content visibility in new_editor.
2026-04-21 20:49:18 +08:00
a779b04dba Restore new_editor toolbar play button styling 2026-04-21 20:43:17 +08:00
0780e54efa refactor(srp): adopt scriptableobject render asset creation 2026-04-21 20:33:57 +08:00
f3be86a52b refactor(srp): introduce scriptableobject render asset substrate 2026-04-21 20:25:05 +08:00
e527ca4e3a refactor(srp): align urp renderer feature ownership model 2026-04-21 20:17:08 +08:00
0d0919b276 refactor(srp): synchronize urp renderer feature runtime state 2026-04-21 19:59:20 +08:00
ffe4717d8f refactor(srp): tighten renderer feature lifecycle invalidation 2026-04-21 19:43:45 +08:00
97bd990b12 refactor(srp): model shared native backend substrate 2026-04-21 19:31:52 +08:00
f2806b0136 refactor(srp): rename native pipeline backend terminology 2026-04-21 19:19:27 +08:00
8a8b72e273 refactor(srp): rename native scene draw substrate contract 2026-04-21 19:06:38 +08:00
01b5e0abcd refactor(srp): remove managed backend key binding detour 2026-04-21 18:46:43 +08:00
ed738475fe refactor(srp): remove managed standalone pass key seam 2026-04-21 18:36:11 +08:00
0a4c782122 refactor(srp): remove native directional shadow planning policy seam 2026-04-21 18:19:27 +08:00
f75164a4fa refactor(srp): move scene setup ownership into managed renderer 2026-04-21 18:05:33 +08:00
233cf25965 Restore new_editor inspector layout fixes 2026-04-21 18:00:15 +08:00
1e16995757 refactor(srp): move urp shadow execution bridge into managed 2026-04-21 17:41:44 +08:00
578103f970 refactor(srp): align urp renderer slot semantics 2026-04-21 17:08:26 +08:00
4300e45168 refactor(srp): add camera depth prepass planning bridge 2026-04-21 16:56:20 +08:00
1cb23cd178 refactor(srp): move urp shadow and prepass core blocks into renderer 2026-04-21 16:43:56 +08:00
eb5b51ddb1 docs(plan): add new_editor d3d12 ui root refactor plan 2026-04-21 16:37:58 +08:00
1a6aacb636 refactor(srp): enable managed standalone shadow and depth stages 2026-04-21 16:22:26 +08:00
2c49ac58d9 refactor(srp): infer fullscreen stages from renderer pass queue 2026-04-21 15:54:26 +08:00
f2be5627be refactor(srp): move core stage defaults into universal renderer 2026-04-21 15:44:19 +08:00
6a538d0d2e refactor(srp): close renderer-backed backend seam 2026-04-21 14:52:04 +08:00
4883413d48 refactor(srp): narrow renderer-data backend seam 2026-04-21 14:26:45 +08:00
e0c9707aaf refactor(srp): tighten native seam visibility 2026-04-21 14:17:10 +08:00
32d725844f refactor(srp): narrow generic native policy key seams 2026-04-21 14:09:23 +08:00
289b216bc5 refactor(srp): narrow generic pipeline renderer key seam 2026-04-21 14:05:17 +08:00
4010b6159b Reapply "Archive superseded RHI present policy plan"
This reverts commit 64e778da65.
2026-04-21 13:57:08 +08:00
7775b42d31 refactor(srp): remove managed camera-frame policy key bridge 2026-04-21 13:56:52 +08:00
2c9e8dad49 Revert "Update new_editor inspector layout and host rendering"
This reverts commit 5d81a64ef3.
2026-04-21 13:55:30 +08:00
64e778da65 Revert "Archive superseded RHI present policy plan"
This reverts commit 042de39fb1.
2026-04-21 13:55:29 +08:00
2426777cf7 refactor(srp): signal managed camera frame baseline directly 2026-04-21 13:36:09 +08:00
042de39fb1 Archive superseded RHI present policy plan 2026-04-21 13:27:15 +08:00
5d81a64ef3 Update new_editor inspector layout and host rendering 2026-04-21 13:24:03 +08:00
d388c3994b refactor(srp): split managed camera frame plan baseline policy 2026-04-21 13:23:00 +08:00
40bf945cef refactor(srp): clear legacy fullscreen stages before managed planning 2026-04-21 13:12:43 +08:00
2d4ff384fd refactor(srp): remove renderer fullscreen stage heuristics 2026-04-21 13:07:24 +08:00
5bec70dcc5 refactor(srp): move urp final color execution into managed feature 2026-04-21 12:59:52 +08:00
0063acadc9 refactor(srp): move urp final color defaults into managed asset 2026-04-21 12:44:42 +08:00
d3db6b21ea refactor(srp): remove fullscreen stage support heuristic 2026-04-21 12:37:18 +08:00
abc300fe03 refactor(srp): move camera frame plan policy into managed urp 2026-04-21 12:22:37 +08:00
793027df23 Refactor RHI swapchain present policy 2026-04-21 12:19:15 +08:00
8e4576de95 refactor(srp): move render scene setup into managed urp 2026-04-21 03:09:08 +08:00
db08861183 refactor(srp): move directional shadow planning policy into managed urp 2026-04-21 03:01:56 +08:00
1f01f45bee fix(rhi): align swap chain overrides with present policy interface 2026-04-21 03:01:36 +08:00
0e1b96d641 refactor(srp): move directional shadow execution policy into managed urp 2026-04-21 02:49:15 +08:00
e2b2df4c8f refactor(srp): move shadow caster stage selection into managed urp
- add standalone pass asset factories for camera frame stages\n- let managed pipeline assets declare stage pass asset keys\n- make universal renderer data explicitly own the builtin shadow caster stage
2026-04-21 02:38:56 +08:00
bfc4b90ce6 refactor(srp): bridge universal shadow planning settings into managed asset
- expose directional shadow planning settings on camera request context\n- let the managed universal asset override planner defaults\n- recompute native directional shadow requests only when settings change
2026-04-21 02:19:30 +08:00
5747968fc4 refactor(srp): move universal shadow ownership into asset layer
- track missing render graph scriptcore sources and rendering utility headers

- expose camera request directional shadow control to managed universal asset configuration
2026-04-21 02:03:27 +08:00
4d587c5d0b refactor(srp): move builtin scene feature ownership into renderer features 2026-04-21 01:54:02 +08:00
33c88f8234 Add native scrolling to new editor tree views 2026-04-21 01:38:55 +08:00
383d1e9c73 refactor(srp): bind managed native scene renderers per renderer selection 2026-04-21 01:34:13 +08:00
c60f3db80d refactor(srp): make stage capability follow selected renderer 2026-04-21 01:11:03 +08:00
7f1089fb0a perf(new_editor): decouple frame slots from swapchain buffers 2026-04-21 01:03:00 +08:00
9b7b369007 refactor(new_editor): snapshot hosted editor restructuring 2026-04-21 00:57:14 +08:00
e123e584c8 feat(srp): add camera-driven universal renderer selection 2026-04-21 00:53:35 +08:00
a6f7530855 refactor(srp): infer fullscreen stages from renderer pass queues 2026-04-21 00:34:46 +08:00
5700272260 refactor(srp): replace raw scene pass arrays with main-scene settings 2026-04-20 23:49:24 +08:00
36c0614c14 refactor(srp): finalize universal package split and data-drive default scene passes 2026-04-20 23:40:00 +08:00
7fe922d1c9 feat(srp): add render state block scene draw overrides
- add managed RenderStateBlock authoring types and wire them through DrawingSettings
- let RenderObjectsRendererFeature author depth and stencil overrides for scene draws
- apply scene draw render state overrides inside builtin forward pipeline and document the stage plan
2026-04-20 23:21:04 +08:00
16788fec34 feat(srp): add explicit skybox draw primitive
- add ScriptableRenderContext.DrawSkybox as a public main-scene draw primitive
- route default RecordScene and DrawSkyboxPass recording through explicit draw calls
- expose the new DrawSkybox API in the scriptable render context probe
2026-04-20 23:02:49 +08:00
cd6f9aa4cf feat(srp): add shader pass selection for scene draws
- let DrawingSettings carry an optional shaderPassName across managed and native scene draw APIs
- allow RenderObjectsRendererFeature to author explicit ForwardLit or Unlit scene draws
- exercise the new scene draw pass selection seam in the project render pipeline probe
2026-04-20 22:58:08 +08:00
0319680954 feat(srp): add drawing settings override material seam
- add a managed DrawingSettings seam for scene draw authoring
- let builtin forward scene draws use an override material when provided
- wire DrawObjectsPass and RenderObjectsRendererFeature through the new settings
2026-04-20 22:46:19 +08:00
fece3a84ad feat(srp): add render layer filtering to scene draw
- carry MeshRenderer renderLayer through scene extraction into VisibleRenderItem
- extend native and managed FilteringSettings with renderLayerMask support
- let RenderObjectsRendererFeature author layer-filtered object draws
2026-04-20 22:21:29 +08:00
5237da23dd feat(srp): add reusable skybox pass
- extract DrawSkyboxPass from UniversalRenderer into a formal package pass primitive
- keep the default Universal skybox stage wired through the new reusable pass
- reduce direct scene phase recording leakage inside the package layer
2026-04-20 22:14:19 +08:00
db7f427112 feat(srp): add render queue range authoring
- add a core RenderQueueRange helper for managed scene draw filtering
- let FilteringSettings and RenderObjectsRendererFeature consume queue ranges directly
- wire the new authoring path into probes and project-side usage
2026-04-20 22:10:18 +08:00
cee65fcf40 feat(srp): add descriptor-driven object draw authoring
- bridge renderer list descriptors into ScriptableRenderContext scene draw calls
- reuse DrawObjectsPass across Universal and project custom renderers
- add RenderObjectsRendererFeature for package-level object draw extension
2026-04-20 22:05:38 +08:00
3df87e941c feat(srp): formalize scene recording and draw entrypoints 2026-04-20 18:54:04 +08:00
b521616e27 refactor(rendering/srp): unify managed fullscreen raster recording 2026-04-20 18:26:47 +08:00
3e32f82e37 feat(srp): lock project-side pipeline lifecycle contracts
Add project asset probes for renderer invalidation, asset invalidation, and runtime release through the public SRP API surface.

Cover the project/Assets bridge path with lifecycle scripting tests and archive the completed project-side SRP bridge plan.
2026-04-20 15:26:33 +08:00
3bdd45b590 feat(srp): bridge project-defined pipeline assets 2026-04-20 15:07:38 +08:00
3f2c0fc9bd chore(srp): add project pipeline probe asset metadata 2026-04-20 15:04:43 +08:00
a615f78e72 feat(srp): formalize renderer contracts and project feature bridge 2026-04-20 15:03:45 +08:00
10b092d467 refactor(srp): add renderer backend registry seam 2026-04-20 12:47:25 +08:00
59f2249e07 refactor(srp): add asset runtime invalidation seam 2026-04-20 03:06:04 +08:00
d196ec9264 refactor(srp): add renderer data invalidation seam
Introduce ScriptableRendererData dirty/invalidation support so renderer and feature caches can be released and rebuilt within the same managed asset runtime.

Add managed probes and scripting coverage for non-public dirty APIs and for renderer rebuild after invalidation, then archive the completed phase plan.
2026-04-20 02:48:16 +08:00
5e88449e3d refactor(srp): move renderer feature setup into renderer data
Introduce a formal ScriptableRendererData setup seam so renderer feature attachment is owned by renderer data instead of renderer constructors pulling feature caches.

Route lifecycle and reuse probes through the new setup path, lock the non-public setup seam in the API surface probe, and update scripting expectations accordingly.
2026-04-20 02:30:07 +08:00
778913ddcb refactor(srp): make universal renderer execution context-first
Promote ScriptableRenderer renderer-recording context methods to the primary Universal execution seam and route the renderer-driven pipeline through that seam.

Update managed probes and scripting expectations to cover the new non-public renderer recording contract, and archive the completed phase plan.
2026-04-20 02:15:47 +08:00
cd29c8b2bc feat(srp): add renderer-driven pipeline backbone
Introduce renderer-driven and renderer-backed managed pipeline base types in the Universal package.

Move shared renderer-data/default-renderer ownership out of UniversalRenderPipelineAsset, migrate probe assets onto the generic seam, and expose renderer recording/request context types for future SRP expansion.

Update scripting API-surface expectations and validate with build, unit tests, scripting tests, and old editor smoke.
2026-04-20 02:05:17 +08:00
9e6c473186 feat(srp): add managed camera frame planning seam
Expose native camera frame planning controls to managed pipeline assets and renderer features.

Allow managed planning to override fullscreen stage heuristics while keeping CameraFramePlan as the native execution contract.

Add scripting coverage, probe assets, and archive the phase plan after build, test, and editor smoke validation.
2026-04-20 01:48:16 +08:00
58dde75d3d refactor(srp): add managed lifecycle cleanup seams
Invoke managed pipeline disposal and asset runtime cleanup from the native bridge lifecycle. Add Universal renderer and feature cleanup hooks plus regression probes to verify runtime cache teardown semantics.
2026-04-20 01:14:37 +08:00
beaf5809d5 refactor(srp): unify managed pipeline instance ownership
Move shared managed ScriptableRenderPipeline instance ownership into MonoManagedRenderPipelineAssetRuntime.

Make stage recorders borrow the runtime-owned pipeline instead of creating and destroying private handles.

Add a regression test that locks one CreatePipeline call across multiple stage recorders.
2026-04-20 00:44:09 +08:00
cbc0ddbd42 refactor(srp): formalize universal renderer selection and caching 2026-04-20 00:16:32 +08:00
ad32d64269 refactor(srp): move universal backend ownership into renderer data 2026-04-20 00:04:24 +08:00
9c8f2ae84c refactor(srp): let universal assets declare native backend keys 2026-04-19 23:32:41 +08:00
21b790c2f8 refactor(srp): unify mono recorder backend ownership 2026-04-19 23:09:34 +08:00
74e790891c refactor(srp): decouple managed pipeline assets from fixed native backend 2026-04-19 21:46:05 +08:00
20e727e882 refactor(srp): close universal recording composition seam 2026-04-19 17:00:48 +08:00
6c605bbe20 refactor(srp): hide universal recording helpers behind base apis 2026-04-19 16:17:38 +08:00
93f06e84ed Refactor new editor boundaries and test ownership 2026-04-19 15:52:28 +08:00
dc13b56cf3 refactor(srp): collapse universal pipeline wrappers 2026-04-19 15:33:03 +08:00
237a628e2a refactor(srp): rename camera request context surface 2026-04-19 15:20:34 +08:00
8edc68f02b refactor(srp): move recording helpers into universal extensions 2026-04-19 14:42:57 +08:00
f4d4112e2f refactor(srp): move rendering data ownership into universal package 2026-04-19 14:19:57 +08:00
a7cda9375a refactor(srp): move renderer model into universal package 2026-04-19 14:11:25 +08:00
570467a083 refactor(srp): rename first-party renderer package to universal 2026-04-19 14:04:19 +08:00
537d7d99fc refactor(srp): remove managed frame planning hook
- derive fullscreen stage planning from pipeline render-graph support
- trim planning-only APIs from the managed SRP bridge and public surface
- update probes and tests to lock the slimmer SRP API boundary
2026-04-19 13:47:20 +08:00
08e2b38df2 refactor(srp): hide pipeline data behind rendering data 2026-04-19 13:12:26 +08:00
0cea7b80e8 refactor(srp): align renderer api with unity contexts 2026-04-19 13:05:57 +08:00
fe7e6dddf3 refactor(srp): move renderer request helpers out of core 2026-04-19 05:34:43 +08:00
9da85e9ad8 refactor(srp): move rendering data into renderer layer 2026-04-19 05:25:47 +08:00
11a03a4b46 refactor(srp): unify engine managed assembly discovery 2026-04-19 05:17:42 +08:00
5fa209ab5d refactor(srp): split universal managed pipeline assembly 2026-04-19 05:03:56 +08:00
f45b34a03a Refactor new editor state ownership model 2026-04-19 04:36:52 +08:00
48bfde28e3 refactor(rendering): formalize pipeline selection and engine asset discovery 2026-04-19 04:31:48 +08:00
78bcd2e9ca refactor(new_editor): unify panel input and rename primitives 2026-04-19 03:23:16 +08:00
c59cd83c38 refactor(new_editor): tighten app dependency boundaries 2026-04-19 02:48:41 +08:00
7429f22fb1 refactor(rendering): split managed SRP layers and namespaces 2026-04-19 02:38:48 +08:00
612e3ba0b3 refactor(new_editor): internalize legacy viewport gizmo support 2026-04-19 00:36:24 +08:00
0819424e94 feat(reference): add urp nahida sample project 2026-04-19 00:33:03 +08:00
a65d5cfd21 chore(gitignore): ignore local capture and packaging artifacts 2026-04-19 00:31:59 +08:00
6e26ec7103 refactor(mvs): simplify 3dgs d3d12 render path 2026-04-19 00:30:42 +08:00
1405ef6a29 feat(project): refresh sample scenes and Nahida assets 2026-04-19 00:29:32 +08:00
f4fef59b2f feat(rendering): add volumetric performance coverage 2026-04-19 00:27:13 +08:00
d2017b251c feat(audio): formalize runtime effects and wav loading 2026-04-19 00:26:28 +08:00
8164baba0a docs(plan): archive thesis drafts and reference updates 2026-04-19 00:24:25 +08:00
56bfb0e298 chore(gitignore): ignore physx generated directories 2026-04-19 00:22:25 +08:00
b989edca91 feat(rendering): add managed SRP renderer runtime 2026-04-19 00:05:29 +08:00
a57b322bc7 feat(new_editor): wire project, inspector, and viewport runtime 2026-04-19 00:03:25 +08:00
8257403036 feat(editor): persist graphics settings and shadow overrides 2026-04-19 00:01:49 +08:00
9ca7960346 docs(plan): archive editor and SRP milestones 2026-04-18 23:57:55 +08:00
7dfdda2b11 Refine new_editor scene viewport flow 2026-04-18 23:56:17 +08:00
f544b2792b Refactor new editor scene viewport tools 2026-04-18 18:55:19 +08:00
b8e84001fa fix(rendering): preserve managed SRP selection across scene replace 2026-04-18 17:47:11 +08:00
cac6e34fa5 fix(rendering): clear managed SRP selection on runtime stop 2026-04-18 16:52:59 +08:00
30ee70a4d1 feat(rendering): select managed SRP through asset instances 2026-04-18 16:41:53 +08:00
849625e732 feat(rendering): expose managed SRP asset final color defaults 2026-04-18 16:19:54 +08:00
5fd474d08d feat(rendering): add shader-vector fullscreen SRP seam
Generalize the native fullscreen pass and descriptor plumbing so managed SRP can request shader-driven fullscreen stages without being locked to the ColorScale path.

Keep ColorScale as a convenience descriptor mapped to the builtin color-scale shader, and add native fullscreen factory coverage for the new shader-vector path.
2026-04-18 16:08:01 +08:00
2b6d62a127 refactor(rendering): unify managed fullscreen planning stage api
replace post-process and final-output specific planning calls with a single fullscreen stage bridge

align managed planning with the native CameraFrameStage fullscreen seam
2026-04-18 15:12:41 +08:00
eb39f87cdd docs: rewrite MiniEngine Core graphics feature guide 2026-04-18 15:02:48 +08:00
c4adbcd83e refactor(rendering): genericize native fullscreen pass descriptors
replace camera-specific post-process descriptor naming with generic fullscreen pass types

route camera planning and managed SRP runtime through the same fullscreen pass seam
2026-04-18 14:59:55 +08:00
c91e87f2e2 refactor(rendering): queue managed fullscreen pass descriptors 2026-04-18 13:51:09 +08:00
788b1b971e refactor(rendering): rename native scene recorder seam 2026-04-18 13:36:37 +08:00
cf54014de9 refactor(rendering): remove builtin naming from managed srp context 2026-04-18 13:30:45 +08:00
2409f479e9 refactor(rendering): route managed scene recording through native scene renderer factory 2026-04-18 01:24:21 +08:00
1ba73fdf0a refactor(rendering): extract native scene renderer contract for srp 2026-04-18 01:19:02 +08:00
df02a4e741 fix(rendering): refresh managed pipelines on srp environment changes 2026-04-18 01:10:45 +08:00
e388b6fbe3 fix(rendering): rebind managed srp asset runtime after bridge reset 2026-04-18 01:01:30 +08:00
afb2c1579c test(rendering): prove managed forward pipeline scene render path 2026-04-18 00:51:51 +08:00
b48760ca3d Refactor new editor scene runtime ownership 2026-04-18 00:45:14 +08:00
2fe1076218 test(rendering): add managed default pipeline selection probe 2026-04-18 00:22:15 +08:00
a6c78af54c feat(rendering): add managed camera request planning seam 2026-04-18 00:07:13 +08:00
fa9a5ffb00 refactor(rendering): retain managed pipeline asset runtime per native asset 2026-04-17 23:54:04 +08:00
6838b00d97 feat(rendering): add managed fullscreen stage planning seam 2026-04-17 23:39:08 +08:00
4a4e921eb1 new_editor: fix detached multi-tab tab dragging 2026-04-17 23:18:05 +08:00
b9f78c29b8 feat(rendering): add managed fullscreen stage recording seam 2026-04-17 22:58:39 +08:00
ed9b5178f8 docs: archive old plans 2026-04-17 22:43:27 +08:00
a10d1d80b0 docs: clarify new_editor closure status 2026-04-17 22:37:26 +08:00
bf9a906464 new_editor: filter closing windows from interaction 2026-04-17 22:35:16 +08:00
ba8437d919 new_editor: make window sync rollback safe 2026-04-17 22:32:58 +08:00
6f6c8877fa feat(rendering): expose builtin forward scene steps to srp context 2026-04-17 22:26:51 +08:00
69319b4a7b new_editor: filter dead windows from live workspace sets 2026-04-17 22:20:06 +08:00
8f051fd1d1 new_editor: harden cross-window drag validation 2026-04-17 22:16:34 +08:00
066442cee5 new_editor: revalidate same-window workspace mutations 2026-04-17 22:12:01 +08:00
0ef6d2a365 new_editor: tighten detached window transfer invariants 2026-04-17 22:03:56 +08:00
af6e0858be new_editor: close integration build boundary 2026-04-17 21:57:24 +08:00
9026aff881 feat(rendering): add scriptable render context v1 2026-04-17 21:53:52 +08:00
4e2261ad37 docs: fix MiniEngine Core guide encoding 2026-04-17 21:42:06 +08:00
f4fb859972 feat(scripting): add managed SRP runtime bridge 2026-04-17 21:38:22 +08:00
8f847db816 new_editor: tighten window workspace validation 2026-04-17 21:23:47 +08:00
a8b3877f4b docs: add MiniEngine Core beginner guide 2026-04-17 19:53:42 +08:00
e087f1f2b0 docs(rendering): add rendergraph and SRP architecture overview 2026-04-17 19:42:38 +08:00
52af8e3a6f refactor(new_editor): close docking loop and app internals 2026-04-15 23:13:09 +08:00
cd8ce5947c refactor(rendering): move old editor viewport passes out of engine 2026-04-15 22:54:38 +08:00
dde03c5241 refactor(new_editor): continue architecture closeout 2026-04-15 22:47:42 +08:00
a458f2838c refactor(rendering): remove unused object id outline pass 2026-04-15 22:36:38 +08:00
e9da6b290d refactor(rendering): shrink render pass graph compatibility helpers 2026-04-15 22:32:21 +08:00
a8c1337774 refactor(rendering): move scene request shadow planning behind pipeline assets 2026-04-15 22:25:04 +08:00
cf1d6e1c1a refactor(rendering): extract default pipeline resolution from camera renderer 2026-04-15 21:55:35 +08:00
e23d9710e7 refactor(rendering): move directional shadow execution defaults into pipeline 2026-04-15 21:48:41 +08:00
02438762fd refactor(rendering): move host standalone pass defaults into assets 2026-04-15 21:32:50 +08:00
f2eebfc842 refactor(rendering): move scene data policy into render pipelines 2026-04-15 21:28:02 +08:00
215c353ace refactor(rendering): move frame plan defaults behind pipeline assets 2026-04-15 21:22:29 +08:00
02aa9a8ea5 refactor(rendering): auto-initialize scriptable render pipeline host 2026-04-15 21:15:39 +08:00
966106e0c0 refactor(rendering): make camera frame plans own generated sequences 2026-04-15 21:06:30 +08:00
8798e63e32 refactor(rendering): formalize native graph recording helpers 2026-04-15 20:46:00 +08:00
7b9e172dbf test(scripting): cover scriptable render pipeline asset selection 2026-04-15 20:16:50 +08:00
04ecac26d6 feat(scripting): add managed srp base api 2026-04-15 20:14:48 +08:00
cafe3c8076 refactor(rendering): add srp host stage recorder bridge 2026-04-15 20:07:52 +08:00
22a2b982ef refactor(rendering): clean native scene graph naming 2026-04-15 20:00:30 +08:00
5e841ddd1b refactor(rendering): rename stage graph contract files 2026-04-15 19:36:21 +08:00
7671663b12 refactor(rendering): generalize pipeline stage render graph boundary 2026-04-15 19:31:52 +08:00
df8f433fbb refactor(new_editor): streamline internal layout and command routing 2026-04-15 19:30:58 +08:00
9654f4d91a test(editor): verify physics play session runtime closure 2026-04-15 17:51:22 +08:00
308fbd0aac refactor(rendering): drive main scene graph usage through stage policy 2026-04-15 16:49:21 +08:00
bf0b81d034 refactor(rendering): centralize stage graph output policies 2026-04-15 16:42:36 +08:00
c853f67c56 refactor(rendering): remove main scene stage recording special cases 2026-04-15 16:18:35 +08:00
03ee1706ae refactor(rendering): formalize fallback stage policy 2026-04-15 16:09:20 +08:00
e93196c7d0 refactor(rendering): share stage runtime request resolution 2026-04-15 15:55:16 +08:00
5d54799f05 refactor(rendering): unify stage runtime request dispatch 2026-04-15 15:46:27 +08:00
93b5c446cb refactor(rendering): formalize shared stage output surfaces 2026-04-15 15:35:38 +08:00
ce573d4e2d refactor(rendering): unify fullscreen stage color-chain queries 2026-04-15 15:31:05 +08:00
3afe44d2fa refactor(rendering): centralize camera frame stage graph policy 2026-04-15 15:28:15 +08:00
1ad3bfc702 refactor(rendering): centralize fullscreen stage surface resolution 2026-04-15 15:20:59 +08:00
795eaf80df refactor(rendering): formalize camera frame stage contracts 2026-04-15 15:14:06 +08:00
3937badf37 docs: restructure thesis chapters 4 to 6 2026-04-15 14:55:52 +08:00
65cb212020 fix(scripting): stabilize mono wrapper test teardown 2026-04-15 14:27:21 +08:00
982a877714 docs: refine thesis chapters 3 and 7 2026-04-15 14:23:51 +08:00
bda8a35d77 feat(scripting): expose PhysX rigidbody and raycast APIs 2026-04-15 13:58:30 +08:00
914c9361ed refactor(rendering): shorten camera-frame graph file layout 2026-04-15 13:53:44 +08:00
aec7d79d83 fix(new_editor/cursor): stabilize multi-window resize cursors 2026-04-15 13:44:07 +08:00
608f33d4d3 fix(new_editor/docking): darken overlay and use full center preview 2026-04-15 13:37:39 +08:00
51aea47c83 feat(physics): dispatch PhysX simulation events to scene scripts 2026-04-15 13:36:39 +08:00
077786e4c7 docs: update thesis draft chapters 2026-04-15 13:23:32 +08:00
7e21e3887e fix(new_editor/docking): restore cross-window drop preview 2026-04-15 13:22:58 +08:00
07516b8c2c refactor(rendering): formalize camera-frame fallback surface io modes 2026-04-15 13:16:13 +08:00
b97f9a1555 refactor(rendering): formalize compatible raster pass recording helpers 2026-04-15 13:12:07 +08:00
3f0f279000 refactor(rendering): infer raster pass graph io from declared context 2026-04-15 13:07:09 +08:00
2605608685 fix(new_editor/tab-drag): keep floating window under cursor 2026-04-15 13:03:44 +08:00
ea2e44976a refactor(rendering): add override helpers for shared recording contexts 2026-04-15 13:01:04 +08:00
8aee665d32 refactor(rendering): add callback helpers for common graph pass contracts 2026-04-15 12:55:51 +08:00
1d207cf251 feat(physics): add rigidbody velocity control 2026-04-15 12:53:36 +08:00
8645334e38 refactor(rendering): formalize common raster pass graph contracts 2026-04-15 12:52:44 +08:00
c5dcfaedd5 feat(physics): sync runtime physx body state 2026-04-15 12:47:40 +08:00
7cbc992bd8 feat(physics): add physx raycast queries 2026-04-15 12:43:38 +08:00
f90f449745 refactor(rendering): route feature pass recording through shared context 2026-04-15 12:40:31 +08:00
d501e895eb fix(new_editor/window): move detached root tab into title bar 2026-04-15 12:38:45 +08:00
59941626a7 feat(physics): sync scene actors into physx 2026-04-15 12:37:57 +08:00
c0b61df417 refactor(rendering): reuse shared recording context in forward builder 2026-04-15 12:37:37 +08:00
f020bb759e refactor(rendering): derive stage recording contexts from shared defaults 2026-04-15 12:31:16 +08:00
31f40e2cbb feat(physics): wire physx sdk into build 2026-04-15 12:22:15 +08:00
5bf258df6d refactor(rendering): formalize shared render-graph recording context 2026-04-15 12:17:33 +08:00
9c5b19a928 feat(editor): add audio and physics component editor coverage 2026-04-15 12:15:13 +08:00
34aca206ce fix(physics): keep stub backend buildable without physx 2026-04-15 12:09:09 +08:00
92ba032660 refactor(new_editor/fields): split color field rendering 2026-04-15 11:59:12 +08:00
3317e47009 feat(physics): add runtime physics scaffolding 2026-04-15 11:58:27 +08:00
d17ddffdef refactor(new_editor/shell): split shell interaction responsibilities 2026-04-15 11:52:30 +08:00
78548b610c refactor(new_editor/fields): split property grid rendering and interaction 2026-04-15 11:42:56 +08:00
053c5a1242 refactor(rendering): move recorded stage execution into contract 2026-04-15 11:39:06 +08:00
4fa178cfd1 refactor(new_editor/docking): split dock host interaction helpers 2026-04-15 11:23:39 +08:00
1c84520738 refactor(new_editor/docking): split dock host rendering and hit testing 2026-04-15 11:18:48 +08:00
701ddd9e9d refactor(new_editor/workspace): split workspace controller responsibilities 2026-04-15 11:13:16 +08:00
dedf149f59 docs: update thesis draft 2026-04-15 11:11:22 +08:00
feffa36692 refactor(new_editor/workspace): split workspace model responsibilities 2026-04-15 11:08:18 +08:00
936b10590a refactor(rendering): move standalone stage graph inputs into contract 2026-04-15 10:49:16 +08:00
57f61b05eb refactor(new_editor/app): split editor window frame runtime 2026-04-15 10:47:57 +08:00
b5ca544d31 refactor(new_editor/app): unify borderless dwm attribute dispatch 2026-04-15 10:42:58 +08:00
ddfed4c37b refactor(rendering): move stage resource publication into contract 2026-04-15 10:42:10 +08:00
e95bdb3149 refactor(new_editor/app): split viewport render target cleanup 2026-04-15 10:40:37 +08:00
2606d15e26 refactor(new_editor/app): split native renderer draw responsibilities 2026-04-15 10:36:09 +08:00
5e2693a16a refactor(new_editor/app): move entry point and split window synchronization 2026-04-15 10:31:01 +08:00
e42b0dc50b refactor(rendering): move sequence graph pass authoring into contract 2026-04-15 10:30:04 +08:00
1c9f9a835d refactor(new_editor/app): isolate cross-window drop support 2026-04-15 08:56:57 +08:00
31a979f779 refactor(rendering): route camera-stage graph pass recording through contract 2026-04-15 08:51:40 +08:00
302a13bc99 refactor(new_editor/app): split native renderer lifecycle hotspots 2026-04-15 08:49:14 +08:00
6f1a7120d2 refactor(rendering): move stage graph pass context into contract 2026-04-15 08:45:42 +08:00
0e7bf8d16e refactor(new_editor/app): split frame support and texture decoding 2026-04-15 08:45:04 +08:00
9f3ea11dbc refactor(rendering): move fullscreen stage source binding into contract 2026-04-15 08:38:58 +08:00
f049d9d29e refactor(new_editor/app): split window manager and editor context hotspots 2026-04-15 08:37:07 +08:00
ecb7f24794 refactor(rendering): share camera-stage sequence recording loop 2026-04-15 08:25:48 +08:00
9e5954cf0a refactor(new_editor/app): reorganize host structure and add smoke test 2026-04-15 08:24:06 +08:00
3617b4840b refactor(rendering): route camera-stage fallback pass through graph contract 2026-04-15 08:18:36 +08:00
ac5bf9976d refactor(rendering): formalize camera-stage fallback surface contract 2026-04-15 08:14:13 +08:00
c7241338c9 refactor(rendering): route camera-stage recording through shared graph contract 2026-04-15 08:10:06 +08:00
2cda9fd24a Rendering: formalize main-scene graph contract 2026-04-15 07:56:00 +08:00
8b156dd112 docs(new_editor): archive legacy plans and define consolidation roadmap 2026-04-15 07:52:56 +08:00
0c9a67aaca Rendering: formalize render-pass graph contract 2026-04-15 07:39:28 +08:00
c58c28529f Rendering: formalize camera-frame graph builder context 2026-04-15 07:27:09 +08:00
83f55ed5c0 Rendering: formalize render graph recording context 2026-04-15 07:15:48 +08:00
aa727202af Add managed render pipeline selection bridge 2026-04-15 01:57:14 +08:00
ec6965b0dd Add scriptable render pipeline host 2026-04-15 01:33:42 +08:00
82b8bd22cc Introduce native render pipeline host 2026-04-15 01:26:25 +08:00
d0ce2d7883 Centralize render-graph recording context builders 2026-04-15 01:18:15 +08:00
65b3078c7f Extract builtin forward main-scene graph builder 2026-04-15 01:07:59 +08:00
f6fb396a41 Move camera frame plan logic out of public header 2026-04-15 01:00:40 +08:00
f064d6ed68 Extract camera frame fullscreen stage planner 2026-04-15 00:53:51 +08:00
0afcaa0b3b Move render-graph stage policy into internal host 2026-04-15 00:36:11 +08:00
00fa6fffa0 Group camera frame fullscreen color chain intent 2026-04-15 00:32:23 +08:00
ac836ae961 Extract camera frame stage surface resolver 2026-04-15 00:25:19 +08:00
5edc4ed242 Extract camera frame render-graph stage pass runtime 2026-04-15 00:13:35 +08:00
d92afa27da Extract camera frame render-graph stage record context 2026-04-15 00:08:39 +08:00
8232f59276 Extract camera frame render-graph recording session 2026-04-15 00:01:37 +08:00
16f994b5e5 Extract camera frame render-graph stage dispatcher 2026-04-14 23:44:15 +08:00
bc6fb25ff0 Fix XCUI editor app composition source paths 2026-04-14 23:43:44 +08:00
f26b0024f2 Move camera frame render-graph lifecycle into execution module 2026-04-14 23:38:22 +08:00
3e5b7287c7 Split camera frame render-graph stage recording helpers 2026-04-14 23:33:35 +08:00
39c7ef5fdf Extract camera frame render-graph stage state module 2026-04-14 23:15:40 +08:00
abf30ecfd3 Extract camera frame render-graph stage recording module 2026-04-14 23:03:44 +08:00
61ecb7146d Extract camera frame render-graph execution module 2026-04-14 22:50:16 +08:00
599f622ba4 Extract camera frame render-graph surface utilities 2026-04-14 22:39:35 +08:00
3ea8ce81d6 Factor camera frame render-graph stage build state 2026-04-14 22:28:13 +08:00
a67f8597ba Extract camera frame render-graph stage policy helpers 2026-04-14 22:17:12 +08:00
a02ff65651 Extract camera frame render-graph resource contract header 2026-04-14 22:05:28 +08:00
a3efcda550 Unify camera frame graph resource binding helpers 2026-04-14 22:00:03 +08:00
86eb455ab9 Remove explicit feature-pass shadow graph handle 2026-04-14 21:40:02 +08:00
5b0a1743d9 Formalize camera frame render-graph blackboard resources 2026-04-14 21:34:34 +08:00
1e189ff558 Unify builtin forward phase render graph recording 2026-04-14 21:22:56 +08:00
9980aa9be5 Harden render graph pass capture and feature source-color contract 2026-04-14 21:11:04 +08:00
1d171ea61c Split builtin forward pipeline into feature and internal modules 2026-04-14 20:50:31 +08:00
e1734181a0 audio: return thread-safe state snapshots 2026-04-14 20:44:56 +08:00
c710063d92 Graph-manage camera fullscreen stage routing 2026-04-14 19:32:27 +08:00
c4fe643427 audio: remove unused state lock helpers 2026-04-14 19:24:20 +08:00
23bdf9ed48 audio: snapshot mixer state for render thread 2026-04-14 19:22:24 +08:00
78556ea683 audio: narrow render locking to snapshots 2026-04-14 19:15:23 +08:00
5a938935e1 Remove legacy camera sequence execution path 2026-04-14 19:04:55 +08:00
882df1ae5a audio: switch waveout backend to pull rendering 2026-04-14 19:04:18 +08:00
e77dbe40b1 Graph-ify camera pass sequences 2026-04-14 18:56:04 +08:00
4c79554050 Graph-ify camera stage render passes 2026-04-14 17:16:08 +08:00
4fe456c1a2 Add render-graph blackboard for camera frame resources 2026-04-14 16:59:10 +08:00
3e6e997485 Refine detached tab drag host behavior 2026-04-14 16:56:30 +08:00
2a9264cfe4 Graph-ify forward feature injection points 2026-04-14 16:49:06 +08:00
a4c48c1b3f audio: clear mixer routes on destruction 2026-04-14 16:48:39 +08:00
ee03f7035b audio: extract mix render block from update 2026-04-14 16:42:25 +08:00
3e56757910 audio: make system own master gain semantics 2026-04-14 16:39:29 +08:00
a91df8b4cd Split render-graph main scene into forward segments 2026-04-14 16:31:32 +08:00
0060a348f6 audio: clarify waveout device contract 2026-04-14 16:30:02 +08:00
2eaab2481f audio: reuse audio system scratch buffers 2026-04-14 16:25:11 +08:00
c495581878 Add render-graph main-scene pipeline recording 2026-04-14 16:22:58 +08:00
307259091e Implement multi-window detached tab host flow 2026-04-14 16:19:23 +08:00
4b58df9a61 audio: share decoded clip cache across sources 2026-04-14 16:17:17 +08:00
5de4848d70 Graph-manage single-pass fullscreen stages 2026-04-14 15:08:08 +08:00
3f871a4f45 Lay groundwork for detached editor windows 2026-04-14 15:07:52 +08:00
804e5138d7 Graph-manage main scene imported surfaces 2026-04-14 14:58:40 +08:00
af6de86647 Add render graph runtime UAV support 2026-04-14 14:46:13 +08:00
91c62c6b14 Refine new editor shell host and embedded icons 2026-04-14 14:41:45 +08:00
4ee1bcc599 Integrate graph-managed depth surfaces into camera stages 2026-04-14 14:27:30 +08:00
31a8125fc1 Add render graph runtime depth support 2026-04-14 14:05:59 +08:00
87bf83451b Add render graph depth access semantics 2026-04-14 13:56:08 +08:00
9950e0a44f Move fullscreen graph ownership out of pass transitions 2026-04-14 13:48:59 +08:00
8bd375cd24 Add render graph texture transition plans 2026-04-14 04:45:39 +08:00
c0d62dc749 Support graph-owned imported texture transitions 2026-04-14 04:41:58 +08:00
c98b41f6f4 Implement render graph compiler and transient fullscreen execution 2026-04-14 04:37:07 +08:00
72d09a1c49 Fix editor host resize and dock splitter behavior 2026-04-14 03:34:31 +08:00
ba91e0f5dd Fix borderless host resize presentation ordering 2026-04-14 01:42:44 +08:00
9064c2f5f2 Add borderless editor host chrome 2026-04-14 01:14:45 +08:00
5797a75619 Extract frame-plan fullscreen stage builder 2026-04-14 01:01:45 +08:00
e83f911aef Add borderless host migration plan 2026-04-14 00:56:23 +08:00
dd2299c8b0 Clarify frame plan compatibility adapters 2026-04-14 00:54:47 +08:00
b8d29e39f6 Migrate scene renderer callers to frame plans 2026-04-14 00:52:43 +08:00
72914b3865 Keep shadow execution state out of scene planner 2026-04-14 00:43:55 +08:00
e6950fa704 Switch scene viewport flow to frame plans 2026-04-14 00:40:11 +08:00
21b0530f7b Separate request and frame-stage execution contracts 2026-04-14 00:30:15 +08:00
c3d443eb85 Reduce host swap chain latency 2026-04-14 00:25:57 +08:00
d705cc839b Reduce redundant resize repaint passes 2026-04-13 23:38:45 +08:00
0d6b8bf7d8 Formalize directional shadow runtime contracts 2026-04-13 23:11:28 +08:00
4362008b39 Refactor new editor host resize pipeline 2026-04-13 23:09:02 +08:00
712f99e723 Refactor rendering frame execution contracts 2026-04-13 22:16:04 +08:00
48daaa1bd0 Fix Nahida toon binding and test assets 2026-04-13 21:09:40 +08:00
e462f7d6f7 Add 3DGS D3D12 composite debug checkpoint 2026-04-13 20:17:13 +08:00
5b89c2bb76 Separate viewport target and descriptor ownership 2026-04-13 19:57:25 +08:00
f3fc34898a Refactor new editor host orchestration 2026-04-13 19:37:10 +08:00
d2140bf5cc Checkpoint current new editor host iteration 2026-04-13 18:52:30 +08:00
a0d5e84516 Render 3DGS debug splats as quads 2026-04-13 13:38:41 +08:00
8ba05216fb Establish 3DGS D3D12 sorted baseline 2026-04-13 13:16:57 +08:00
0cc3d6da46 Fix new editor window resize presentation 2026-04-13 12:20:25 +08:00
adb6fe4659 rendering: improve main light shadow receiver filtering 2026-04-13 03:14:06 +08:00
95edf0435f rendering: stabilize single-map directional shadow fitting 2026-04-13 03:13:30 +08:00
82c55b3999 docs: rebuild main light shadow repair plan 2026-04-13 02:24:30 +08:00
00875e0c90 rendering: tune main light shadow bias defaults 2026-04-13 02:24:14 +08:00
b7428b0ef1 Stabilize 3DGS D3D12 phase 3 and sort key setup 2026-04-13 02:23:39 +08:00
1d6f2e290d rendering: formalize main light shadow bias settings 2026-04-13 01:40:29 +08:00
2ee74e7761 rendering: formalize main light shadow params 2026-04-13 01:06:09 +08:00
64212a53c7 Add 3DGS D3D12 MVS bootstrap and PLY loader 2026-04-13 00:36:50 +08:00
6f876678f5 editor: prefer bundled mono runtime discovery 2026-04-13 00:27:11 +08:00
2326857a43 build: remove forced MSVC multi-tool disable 2026-04-13 00:24:49 +08:00
0f60f0f657 Carry backing resource in UI texture handles 2026-04-12 23:25:18 +08:00
dd3731ba66 Execute viewport offscreen frames through D3D12 host 2026-04-12 23:21:59 +08:00
941034b387 Wire viewport shell host chain and move host under app 2026-04-12 23:13:00 +08:00
89590242bd docs(editor): sync script assembly builder api docs 2026-04-12 22:50:50 +08:00
a660fc489a Plan new editor viewport render host migration 2026-04-12 22:35:23 +08:00
e86d260d64 Fix Nahida unlit baseline isolation 2026-04-12 12:48:38 +08:00
347d08463b Fix D3D12 descriptor set staging for shader tables 2026-04-12 11:49:12 +08:00
7ee28a7969 Add gaussian splat asset caching groundwork 2026-04-12 11:15:59 +08:00
b7ce8618d2 Advance new editor hosted panels and state flow 2026-04-12 11:12:27 +08:00
7ad4bfbb1c Extract new editor host command session bridge 2026-04-12 01:49:08 +08:00
838f676fa6 Refactor new editor app context and workspace shell 2026-04-12 01:29:00 +08:00
0ff02150c0 Refine editor tree alignment and project panel events 2026-04-11 22:31:14 +08:00
8848cfd958 chore: checkpoint current workspace changes 2026-04-11 22:14:02 +08:00
3e55f8c204 fix(editor_ui): resolve splitter and tab drag gesture conflict 2026-04-11 20:33:53 +08:00
0a015b52ca feat(new_editor): add project panel and polish dock chrome 2026-04-11 20:20:30 +08:00
030230eb1f Add Nahida model import and preview pipeline 2026-04-11 20:16:49 +08:00
8f71f99de4 Fix FBX winding for Nahida preview 2026-04-11 18:45:49 +08:00
443c56ed08 Center tab labels and unify dock cursor resolution 2026-04-11 17:37:13 +08:00
2958dcc491 Refine XCEditor docking and DPI rendering 2026-04-11 17:07:37 +08:00
35d3d6328b Fix gaussian splat integration GT baseline 2026-04-11 17:07:00 +08:00
c03c7379c8 Precompute gaussian splat chunk visibility 2026-04-11 16:32:40 +08:00
0a2bdedc59 Archive outdated Library cache plans 2026-04-11 15:57:29 +08:00
2fb6eca854 Cull invisible gaussian splat chunks in prepare pass 2026-04-11 14:22:51 +08:00
c543ccf79c Preserve chunk metadata in gaussian splat subset test 2026-04-11 14:02:09 +08:00
88a71a5426 Bind gaussian splat chunk metadata in prepare pass 2026-04-11 13:55:39 +08:00
ff4e3f639a Generate gaussian splat chunks during PLY import 2026-04-11 07:13:32 +08:00
92d5cc61cf Define gaussian splat chunk data contract 2026-04-11 07:07:21 +08:00
b3acb5afc2 Derive gaussian splat SH order from resource layout 2026-04-11 06:57:47 +08:00
785377bc9b Add SH shading to gaussian splat renderer 2026-04-11 06:32:38 +08:00
5200fca82f Add GPU sorting for gaussian splat rendering 2026-04-11 06:09:53 +08:00
39632e1a04 Add gaussian splat integration baseline 2026-04-11 05:37:31 +08:00
3622bf3aa2 Fix builtin pass layout metadata lifetime 2026-04-11 03:24:32 +08:00
fac6e588a8 Formalize gaussian splat prepare-order pass 2026-04-11 03:02:30 +08:00
5191bb1149 Add formal compute pipeline creation API 2026-04-11 02:27:33 +08:00
d9bc0f1457 Add gaussian splat compute shader contracts 2026-04-11 01:30:59 +08:00
4080b2e5fe Fix D3D12 NanoVDB volume load stalls 2026-04-11 00:27:23 +08:00
be5dabd820 Support compute-only shader authoring variants 2026-04-11 00:24:55 +08:00
107b320aa7 Add builtin GaussianSplat forward pass baseline 2026-04-10 23:11:11 +08:00
15b42c248f Formalize GaussianSplat transient pass resources 2026-04-10 22:15:05 +08:00
977a4cf2a4 Unify dock leaves around single-tab stacks 2026-04-10 21:50:31 +08:00
b187c8970b Formalize GaussianSplat scene extraction 2026-04-10 21:49:53 +08:00
1119af2e38 Upgrade project asset watcher to native Win32 notifications 2026-04-10 21:36:53 +08:00
2338e306bf Add editor Assets watcher refresh loop 2026-04-10 21:16:17 +08:00
87ad489bfd Tighten new editor shell chrome and add dock convergence plan 2026-04-10 21:05:07 +08:00
503e6408ed Add model and GaussianSplat asset pipelines 2026-04-10 20:55:48 +08:00
8f5c342799 Formalize GaussianSplat render cache 2026-04-10 20:44:24 +08:00
84faa585d5 docs(plan): add incremental API doc task board 2026-04-10 18:49:37 +08:00
ac9388445c docs(plan): sync api task board completion state 2026-04-10 18:45:07 +08:00
3561bf22bb docs(ui): refresh selection model and resources umbrella docs 2026-04-10 18:42:11 +08:00
e6ac43b454 docs(rendering): refine selection and object id pass docs 2026-04-10 18:36:17 +08:00
2f3a28ec3e docs(rendering): reconcile infinite grid docs 2026-04-10 18:35:23 +08:00
737ccd2e0c docs(rendering): expand render pass foundation docs 2026-04-10 18:32:41 +08:00
bdf0b9a16b docs(rendering): sync infinite grid and depth style pass docs 2026-04-10 18:31:05 +08:00
0c52e0f640 docs(rendering): refine outline and volumetric pass docs 2026-04-10 18:28:20 +08:00
bb9a4d5ef4 docs(rendering): document color scale post-process API 2026-04-10 18:25:06 +08:00
a990553ade docs(rendering): sync outline inputs and volumetric prewarm docs 2026-04-10 18:23:40 +08:00
de2fc8be43 docs(rendering): document builtin final color pass API 2026-04-10 18:18:41 +08:00
effca78771 docs(asset): sync model and volume api docs 2026-04-10 18:17:19 +08:00
0602b34652 docs(rendering): sync render surface state and sample docs 2026-04-10 18:08:37 +08:00
85b8b3e583 docs(rhi): sync buffer init and sample quality docs 2026-04-10 17:59:59 +08:00
cba3823ea2 docs(rhi): document buffer init overload and sample quality 2026-04-10 17:51:45 +08:00
89bbad2786 docs(xceditor): deepen foundation api pages 2026-04-10 17:43:30 +08:00
00cf3850d5 docs(api): align render material resolve docs 2026-04-10 17:37:57 +08:00
81d0d92aed docs(plan): refresh API restructuring status 2026-04-10 17:36:25 +08:00
2d8ada03a1 docs(api): sync archive links and task board status 2026-04-10 17:34:19 +08:00
7fc7bb0a22 docs(api): sync archive and command guidance 2026-04-10 17:33:51 +08:00
447977214e docs(api): sync entry guidance for dual api roots 2026-04-10 17:32:04 +08:00
46fac8a215 docs(api): sync active and archived API entry docs 2026-04-10 17:27:29 +08:00
e2e4e08479 docs(api): refresh audit sync snapshot 2026-04-10 17:26:05 +08:00
e69240db49 docs(components): fix extractor links in component api docs 2026-04-10 17:21:52 +08:00
dd467d2468 docs: drop audit report from commit history 2026-04-10 17:19:45 +08:00
71a27d7c9c docs(api): sync rebuilt API audit boards 2026-04-10 17:16:11 +08:00
f401a54806 docs(rendering): tighten planning and viewport docs 2026-04-10 17:14:27 +08:00
f917040e9a docs(api): add gaussian splat pages and fix doc generators 2026-04-10 17:12:55 +08:00
66ae9ec919 docs: add xceditor api tree and new resource docs 2026-04-10 17:10:42 +08:00
6b90c2f6c3 docs(api): sync xceditor roots and model importer 2026-04-10 17:08:37 +08:00
4d8a51aee2 docs(rendering): realign api docs to module structure 2026-04-10 16:55:33 +08:00
8cde4e0649 Add new editor product shell baseline 2026-04-10 16:40:11 +08:00
1f79afba3c refactor: move builtin forward draw submission internal 2026-04-10 03:01:30 +08:00
57331c1c25 refactor: unify builtin forward scene execution 2026-04-10 02:56:36 +08:00
ff6d6d31fe refactor: isolate builtin forward skybox path 2026-04-10 02:46:17 +08:00
152997c409 refactor: extract directional shadow planning internals 2026-04-10 02:30:09 +08:00
54eb2415ff refactor: formalize directional shadow planning settings 2026-04-10 02:14:45 +08:00
f476890116 Normalize editor shell validation codes 2026-04-10 02:05:07 +08:00
f9bfd48479 Fix editor shell asset header contract 2026-04-10 02:04:24 +08:00
131f46682b test: close render object id coverage gaps 2026-04-10 02:03:45 +08:00
899442c64d refactor editor ui host and shell asset layout 2026-04-10 01:59:15 +08:00
b5ba985831 Formalize render object id contract 2026-04-10 01:57:15 +08:00
4debbbea1f Tighten final color contract 2026-04-10 01:21:00 +08:00
4111f841d4 Formalize volume shader include context 2026-04-10 01:05:03 +08:00
34a32b73dd Restore unrelated rendering docs 2026-04-10 00:42:53 +08:00
02a0e626fe Refactor XCUI editor module layout 2026-04-10 00:41:28 +08:00
4b47764f26 docs: tighten xcui backend doc boundaries 2026-04-10 00:15:55 +08:00
225f533c7c docs(api): refresh rebuild status and close recovery wave 2026-04-10 00:10:08 +08:00
9b074e3020 docs(api): record editor stale-page cleanup audit 2026-04-10 00:06:13 +08:00
3ed69aa82f docs(api): align selection outline pass docs 2026-04-10 00:00:41 +08:00
a545951a58 docs: drop retired xcui demo panel page 2026-04-09 23:56:09 +08:00
2bb511087f docs: refresh xcui panel and backend references 2026-04-09 23:54:17 +08:00
4aaac9887e docs: align widgets and editor panel notes with refactor 2026-04-09 23:52:07 +08:00
4276 changed files with 8787818 additions and 27590 deletions

14
.gitignore vendored
View File

@@ -24,3 +24,17 @@ Res/NanoVDB/
!engine/third_party/assimp/bin/*.dll
工作/
.trae/
engine/third_party/physx/compiler/
engine/third_party/physx/documentation/
engine/third_party/physx/tools/
.tmp/
imgui.ini
docs/used/draft_docx_extracted.txt
docs/used/draft_docx_reconverted.md
docs/used/draft_docx_reconverted.txt
docs/used/test_capture.ppm
docs/used/test_capture2.ppm
bu.png
屏幕截图 2026-04-13 030852.png
屏幕截图 2026-04-13 031110.png
毕设版打包/

16
.gitmessage Normal file
View File

@@ -0,0 +1,16 @@
# <type>(<scope>): <summary>
#
# Preferred types:
# fix
# refactor
# feat
# docs
# test
# chore
#
# Examples:
# fix(new_editor/window): correct resize invalidation order
# refactor(new_editor/rendering): split D3D12 host device lifecycle
# feat(new_editor/project): add breadcrumb navigation
#
# Keep the summary short and imperative.

View File

@@ -20,9 +20,11 @@
- [docs/plan/Library启动预热与运行时异步加载混合重构计划_2026-04-04.md](docs/plan/Library启动预热与运行时异步加载混合重构计划_2026-04-04.md)
- [docs/plan/Library启动预热与运行时异步加载混合重构计划_进度更新_2026-04-04.md](docs/plan/Library启动预热与运行时异步加载混合重构计划_进度更新_2026-04-04.md)
- [docs/plan/Editor架构说明.md](docs/plan/Editor架构说明.md)
- [docs/plan/Renderer下一阶段_Unity风格Shader体系正式化计划_2026-04-06.md](docs/plan/Renderer下一阶段_Unity风格Shader体系正式化计划_2026-04-06.md)
- [docs/plan/Unity风格模型导入与Model资产架构重构计划_2026-04-10.md](docs/plan/Unity风格模型导入与Model资产架构重构计划_2026-04-10.md)
- [docs/plan/NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md](docs/plan/NanoVDB体积云加载阻塞与Runtime上传修复计划_2026-04-10.md)
- [docs/plan/3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md](docs/plan/3DGS专用PLY导入器与GaussianSplat资源缓存正式化计划_2026-04-10.md)
- [docs/plan/XCUI_NewEditor主线重建计划_2026-04-07.md](docs/plan/XCUI_NewEditor主线重建计划_2026-04-07.md)
- [docs/plan/XCUI完整架构设计与执行计划.md](docs/plan/XCUI完整架构设计与执行计划.md)
- [docs/plan/XCUI_Phase_Status_2026-04-05.md](docs/plan/XCUI_Phase_Status_2026-04-05.md)
- [docs/plan/C#脚本模块下一阶段计划.md](docs/plan/C%23脚本模块下一阶段计划.md)
- [tests/TEST_SPEC.md](tests/TEST_SPEC.md)
- [tests/UI/TEST_SPEC.md](tests/UI/TEST_SPEC.md)
@@ -30,22 +32,35 @@
已归档但当前仍常用的背景文档:
- [Library资产导入与缓存系统收口计划归档](docs/used/Library资产导入与缓存系统收口计划_完成归档_2026-04-03.md)
- [API 文档第三轮任务池(归档基线)](docs/used/API文档实时同步任务池_2026-04-03.md)
- [XCUI Phase Status 2026-04-05归档](docs/used/XCUI_Phase_Status_2026-04-05.md)
- [Shader与Material系统下一阶段计划归档](docs/used/Shader与Material系统下一阶段计划_完成归档_2026-04-04.md)
- [Unity 风格 Shader 体系正式化计划(归档)](docs/used/Renderer下一阶段_Unity风格Shader体系正式化计划_完成归档_2026-04-07.md)
- [Renderer 当前阶段正式收口(阶段归档)](docs/used/Renderer当前阶段正式收口计划_阶段归档_2026-04-10.md)
- [NanoVDB 后续正式化(阶段归档)](docs/used/NanoVDB稀疏体积渲染后续正式化计划_阶段归档_2026-04-10.md)
- [SceneViewport Overlay / Gizmo 重构计划(归档)](docs/used/SceneViewport_Overlay_Gizmo_Rework_Plan_完成归档_2026-04-04.md)
- [Unity式 SceneView Gizmo 正式化方案(归档)](docs/used/Unity式SceneView_Gizmo系统完整审查与正式化重构方案_完成归档_2026-04-06.md)
- [NanoVDB 第一阶段完成归档](docs/used/NanoVDB稀疏体积渲染正式集成计划_第一阶段完成归档_2026-04-09.md)
如果任务落在 API 文档:
1. 先检查 `docs/plan/`有没有日期更晚的 API 相关计划或归档;当前活跃任务池是 [docs/plan/API文档实时同步任务池_2026-04-03.md](docs/plan/API文档实时同步任务池_2026-04-03.md)。这份任务池目前已经推进到第三轮 `T01-T20` 全部完成,结构审计保持全绿,但开始新一轮前仍要先确认是否又追加了新任务块。
2. 再看 [docs/api-skill.md](docs/api-skill.md)
3. 再看 `docs/api/_meta/rebuild-status.md`
4. 一次只认领一个任务块,先改状态为 `DOING`,只写自己任务块允许的范围。
1. 先检查 `docs/plan/`最新的 API 相关计划或并行任务板。当前工作树里已经存在多份 2026-04-09 的活跃文件,例如:
- [docs/plan/API文档目录重构计划_2026-04-09.md](docs/plan/API文档目录重构计划_2026-04-09.md)
- [docs/plan/API文档目录结构重大重构并行任务板_2026-04-09.md](docs/plan/API文档目录结构重大重构并行任务板_2026-04-09.md)
- [docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md](docs/plan/API文档目录结构第二轮重构计划_2026-04-09.md)
- [docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md](docs/plan/API文档目录结构第二轮并行任务板_2026-04-09.md)
- [docs/plan/API文档目录结构重构并行任务板_2026-04-09_第二轮.md](docs/plan/API文档目录结构重构并行任务板_2026-04-09_第二轮.md)
2. 如果这些活跃文件都不覆盖当前问题,再回看 [docs/used/API文档实时同步任务池_2026-04-03.md](docs/used/API文档实时同步任务池_2026-04-03.md) 作为最近一轮完成基线。
3. 再看 [docs/api-skill.md](docs/api-skill.md)。
4. 再看 `docs/api/main.md``docs/api/_meta/rebuild-status.md`,确认当前问题落在 `XCEngine` 还是 `XCEditor` 根树。
5. 一次只认领一个任务块,先改状态为 `DOING`,只写自己任务块允许的范围。
## 2. 当前工程事实
- 顶层 `CMakeLists.txt` 当前纳入 `engine/``editor/``new_editor/``managed/``mvs/RenderDoc/``tests/`
- `engine/` 构建静态库 `XCEngine``editor/` 构建 `XCEditor`,但输出文件名仍是 `editor/bin/<Config>/XCEngine.exe`
- `new_editor/` 当前构建 `XCUIEditorLib``XCUIEditorHost`;启用 `XCENGINE_BUILD_XCUI_EDITOR_APP` 时会输出 `new_editor/bin/<Config>/XCUIEditor.exe`
- `editor/` 目前继续保留为当前正式编辑器、行为对照和视觉基线来源
- `new_editor/` 当前构建 `XCUIEditorLib``XCUIEditorHost`;启用 `XCENGINE_BUILD_XCUI_EDITOR_APP` 时会输出 `new_editor/bin/<Config>/XCUIEditor.exe`,并被视为未来正式编辑器主线,而不再只是临时 sandbox。
- editor 默认把仓库内的 `project/` 识别为工程根目录,也支持 `--project <path>` 覆盖。
- 当前工程真实使用 `Assets/ + .meta + Library/` 的项目布局;`project/Library/` 是当前 workflow 的一部分,不是可随手忽略的垃圾目录。
- Mono 运行时与 editor 的脚本类发现都从 `<project>/Library/ScriptAssemblies/` 加载程序集。
@@ -81,8 +96,13 @@
- `ObjectId` 渲染与 editor picking
- `BuiltinInfiniteGridPass`
- `BuiltinObjectIdOutlinePass`
- `directional shadow`
- `skybox`
- `CameraRenderRequest::postScenePasses`
- `CameraRenderRequest::overlayPasses`
- `post-process / final color` 当前处于正式化收口阶段,不再是纯预留接口。
- `NanoVDB` 体积渲染已进入当前正式运行链路,但 Vulkan / OpenGL 的 rollout 和多后端能力边界仍在继续收口。
- 当前资源与导入主线正在继续向 `Model` 资产架构与 `3DGS GaussianSplat` 资源链扩展,不要再把 `.obj/.fbx/.ply` 简化理解为“文件直读后立刻渲染”的旧 sample 流程。
- 当前主线不是 render graph而是 shader / material contract、builtin pass contract 和 renderer-owned feature contract。
### 3.3 Editor
@@ -126,13 +146,13 @@
### 3.4 XCUI / New Editor
- `new_editor/`当前 `XCUI` editor sandbox 主线;旧 `editor/` 的整体替换仍处于延后状态,不要把 `XCUI` 计划误读成“已经整体替换现有 editor”
- `new_editor/`未来正式编辑器主线,不再只是 sandbox`editor/` 当前继续保留为正式编辑器、行为对照和视觉基线
- 当前宿主分层是:
- `XCUIEditorLib`
- `XCUIEditorHost`
- `XCUIEditorApp`(可选应用壳)
- 共享 UI core、runtime screen host 与 widget 基础能力主要沉淀在 `engine/include/XCEngine/UI/``engine/src/UI/``new_editor/` 负责 XCUI editor 壳、宿主与 widget sandbox
- XCUI / new_editor 的测试规范以 [tests/UI/TEST_SPEC.md](tests/UI/TEST_SPEC.md) 为准;根目录虽然有 `tests/NewEditor/`,但当前具体测试实现主要放在 `tests/UI/`
- 共享 UI core、runtime screen host 与 widget 基础能力主要沉淀在 `engine/include/XCEngine/UI/``engine/src/UI/``new_editor/` 负责 XCUI editor 壳、宿主与产品装配
- `tests/UI/` 是当前 XCUI `Core / Editor / Runtime` 三层的唯一正式基础层验证入口;`new_editor/` 不承担测试堆场职责
### 3.5 Scripting
@@ -158,7 +178,6 @@
- `tests/Fixtures/`
- `tests/Input/`
- `tests/Memory/`
- `tests/NewEditor/`
- `tests/Rendering/`
- `tests/Resources/`
- `tests/RHI/`
@@ -262,15 +281,21 @@
只要任务涉及 `docs/api/`
1.检查 `docs/plan/` 下有没有更新日期更晚的 API 计划或归档
2. 以最新任务池和 [docs/api-skill.md](docs/api-skill.md) 为执行规范
3. 改完必须重新执行:
1. `docs/plan/API文档目录*.md` 里日期最新的 API 计划 / 并行任务板
2. 再看 [docs/api-skill.md](docs/api-skill.md) `docs/api/_meta/rebuild-status.md`
3. 如果活跃计划没有覆盖当前问题,再回看 [docs/used/API文档实时同步任务池_2026-04-03.md](docs/used/API文档实时同步任务池_2026-04-03.md) 作为最近一轮归档基线。
4. 改完必须重新执行:
```powershell
python -B docs/api/_tools/audit_api_docs.py
```
如果审计没回绿,不算完成。
当前审计口径已经同时覆盖:
- `engine/include/XCEngine/**`
- `new_editor/include/XCEditor/**`
- `editor/src/**`
## 5. 推荐构建与验证入口
@@ -321,9 +346,10 @@ ctest --test-dir build -C Debug --output-on-failure
- 资源导入与工程布局:`engine/include/XCEngine/Core/Asset/``engine/src/Core/Asset/``editor/src/Managers/ProjectManager.cpp``project/Assets/``project/Library/`
- Material / shader / artifact`engine/include/XCEngine/Resources/Material/``engine/src/Resources/Material/``engine/include/XCEngine/Core/Asset/ArtifactFormats.h``tests/Resources/Material/`
- Editor viewport / gizmo / picking`editor/src/Viewport/``editor/src/panels/SceneViewPanel.cpp``tests/Editor/`
- XCUI / new_editor`engine/include/XCEngine/UI/``engine/src/UI/``new_editor/include/XCEditor/``new_editor/src/``tests/UI/`
- Editor actions / project routing`editor/src/Actions/``editor/src/Commands/``editor/src/Core/``editor/src/Managers/``tests/Editor/test_action_routing.cpp`
- 脚本运行时与程序集:`engine/include/XCEngine/Scripting/``engine/src/Scripting/``managed/``project/Assets/Scripts/``tests/Scripting/`
- API 文档:`docs/api/XCEngine/``docs/api/_guides/``docs/api/_tools/audit_api_docs.py``docs/plan/API文档实时同步任务池_2026-04-03.md`
- API 文档:`docs/api/main.md``docs/api/XCEngine/``docs/api/XCEditor/``docs/api/_guides/``docs/api/_tools/audit_api_docs.py``docs/plan/API文档目录*.md``docs/used/API文档实时同步任务池_2026-04-03.md`
## 7. 适合当前仓库的工作方式

View File

@@ -1,15 +1,20 @@
cmake_minimum_required(VERSION 3.15)
if(MSVC)
if(POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
endif()
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
"$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
if(POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
endif()
project(XCEngine)
if(MSVC)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
"$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
add_compile_options("$<$<COMPILE_LANGUAGE:C,CXX>:/MP>")
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(CMAKE_VS_GLOBALS "UseMultiToolTask=true")
endif()
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -37,15 +42,198 @@ enable_testing()
option(XCENGINE_ENABLE_MONO_SCRIPTING "Build the Mono-based C# scripting runtime" ON)
option(XCENGINE_BUILD_XCUI_EDITOR_APP "Build the XCUI editor shell app" ON)
set(
XCENGINE_PHYSX_ROOT_DIR
"${CMAKE_SOURCE_DIR}/engine/third_party/physx"
CACHE PATH
"Path to the bundled PhysX SDK root")
set(XCENGINE_PHYSX_INCLUDE_DIR "${XCENGINE_PHYSX_ROOT_DIR}/include")
set(XCENGINE_ENABLE_PHYSX OFF)
set(XCENGINE_PHYSX_LINK_TARGETS)
set(XCENGINE_PHYSX_RUNTIME_DLL_TARGETS)
if(EXISTS "${XCENGINE_PHYSX_INCLUDE_DIR}/PxPhysicsAPI.h")
file(GLOB XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MD LIST_DIRECTORIES true
"${XCENGINE_PHYSX_ROOT_DIR}/bin/win.x86_64.vc*.md")
file(GLOB XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MT LIST_DIRECTORIES true
"${XCENGINE_PHYSX_ROOT_DIR}/bin/win.x86_64.vc*.mt")
if(XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MD)
list(SORT XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MD COMPARE NATURAL ORDER DESCENDING)
list(GET XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MD 0 XCENGINE_PHYSX_BIN_ROOT_DIR)
elseif(XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MT)
list(SORT XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MT COMPARE NATURAL ORDER DESCENDING)
list(GET XCENGINE_PHYSX_BIN_ROOT_CANDIDATES_MT 0 XCENGINE_PHYSX_BIN_ROOT_DIR)
else()
set(XCENGINE_PHYSX_BIN_ROOT_DIR "")
endif()
set(XCENGINE_PHYSX_BIN_DIR_DEBUG "${XCENGINE_PHYSX_BIN_ROOT_DIR}/debug")
set(XCENGINE_PHYSX_BIN_DIR_RELEASE "${XCENGINE_PHYSX_BIN_ROOT_DIR}/release")
set(XCENGINE_PHYSX_BIN_DIR_PROFILE "${XCENGINE_PHYSX_BIN_ROOT_DIR}/profile")
set(XCENGINE_PHYSX_BIN_DIR_CHECKED "${XCENGINE_PHYSX_BIN_ROOT_DIR}/checked")
if(WIN32 AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXFoundation_64.lib" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXFoundation_64.dll" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXCommon_64.lib" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXCommon_64.dll" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysX_64.lib" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysX_64.dll" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXExtensions_static_64.lib")
set(XCENGINE_ENABLE_PHYSX ON)
message(STATUS "PhysX SDK headers found: ${XCENGINE_PHYSX_INCLUDE_DIR}")
message(STATUS "PhysX SDK binaries found: ${XCENGINE_PHYSX_BIN_DIR_DEBUG}")
function(xcengine_add_physx_imported_shared target base_name)
add_library(${target} SHARED IMPORTED GLOBAL)
set(imported_configs)
foreach(config_name DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
if(config_name STREQUAL "DEBUG")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_DEBUG}")
elseif(config_name STREQUAL "RELEASE")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_RELEASE}")
elseif(config_name STREQUAL "RELWITHDEBINFO")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_PROFILE}")
else()
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_CHECKED}")
endif()
set(import_lib "${config_dir}/${base_name}.lib")
set(runtime_dll "${config_dir}/${base_name}.dll")
if(EXISTS "${import_lib}" AND EXISTS "${runtime_dll}")
list(APPEND imported_configs ${config_name})
set_property(TARGET ${target} PROPERTY "IMPORTED_IMPLIB_${config_name}" "${import_lib}")
set_property(TARGET ${target} PROPERTY "IMPORTED_LOCATION_${config_name}" "${runtime_dll}")
endif()
endforeach()
if(NOT imported_configs)
message(FATAL_ERROR "PhysX target ${target} has no available runtime binaries.")
endif()
set_property(TARGET ${target} PROPERTY IMPORTED_CONFIGURATIONS "${imported_configs}")
endfunction()
function(xcengine_add_physx_imported_static target base_name)
add_library(${target} STATIC IMPORTED GLOBAL)
set(imported_configs)
foreach(config_name DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
if(config_name STREQUAL "DEBUG")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_DEBUG}")
elseif(config_name STREQUAL "RELEASE")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_RELEASE}")
elseif(config_name STREQUAL "RELWITHDEBINFO")
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_PROFILE}")
else()
set(config_dir "${XCENGINE_PHYSX_BIN_DIR_CHECKED}")
endif()
set(static_lib "${config_dir}/${base_name}.lib")
if(EXISTS "${static_lib}")
list(APPEND imported_configs ${config_name})
set_property(TARGET ${target} PROPERTY "IMPORTED_LOCATION_${config_name}" "${static_lib}")
endif()
endforeach()
if(NOT imported_configs)
message(FATAL_ERROR "PhysX target ${target} has no available static libraries.")
endif()
set_property(TARGET ${target} PROPERTY IMPORTED_CONFIGURATIONS "${imported_configs}")
endfunction()
function(xcengine_copy_physx_runtime_dlls target)
foreach(physx_target IN LISTS XCENGINE_PHYSX_RUNTIME_DLL_TARGETS)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:${physx_target}>
$<TARGET_FILE_DIR:${target}>/$<TARGET_FILE_NAME:${physx_target}>
)
endforeach()
endfunction()
xcengine_add_physx_imported_shared(XCPhysXFoundation "PhysXFoundation_64")
xcengine_add_physx_imported_shared(XCPhysXCommon "PhysXCommon_64")
xcengine_add_physx_imported_shared(XCPhysXCore "PhysX_64")
if(EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PVDRuntime_64.lib" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PVDRuntime_64.dll")
xcengine_add_physx_imported_shared(XCPhysXPVDRuntime "PVDRuntime_64")
list(APPEND XCENGINE_PHYSX_RUNTIME_DLL_TARGETS XCPhysXPVDRuntime)
endif()
if(EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXCooking_64.lib" AND
EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXCooking_64.dll")
xcengine_add_physx_imported_shared(XCPhysXCooking "PhysXCooking_64")
list(APPEND XCENGINE_PHYSX_RUNTIME_DLL_TARGETS XCPhysXCooking)
endif()
xcengine_add_physx_imported_static(XCPhysXExtensions "PhysXExtensions_static_64")
if(EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXPvdSDK_static_64.lib")
xcengine_add_physx_imported_static(XCPhysXPvdSDK "PhysXPvdSDK_static_64")
endif()
if(EXISTS "${XCENGINE_PHYSX_BIN_DIR_DEBUG}/PhysXTask_static_64.lib")
xcengine_add_physx_imported_static(XCPhysXTask "PhysXTask_static_64")
endif()
list(APPEND XCENGINE_PHYSX_LINK_TARGETS
XCPhysXCore
XCPhysXCommon
XCPhysXFoundation
XCPhysXExtensions
)
if(TARGET XCPhysXPVDRuntime)
list(APPEND XCENGINE_PHYSX_LINK_TARGETS XCPhysXPVDRuntime)
endif()
if(TARGET XCPhysXCooking)
list(APPEND XCENGINE_PHYSX_LINK_TARGETS XCPhysXCooking)
endif()
if(TARGET XCPhysXPvdSDK)
list(APPEND XCENGINE_PHYSX_LINK_TARGETS XCPhysXPvdSDK)
endif()
if(TARGET XCPhysXTask)
list(APPEND XCENGINE_PHYSX_LINK_TARGETS XCPhysXTask)
endif()
list(APPEND XCENGINE_PHYSX_RUNTIME_DLL_TARGETS
XCPhysXFoundation
XCPhysXCommon
XCPhysXCore
)
else()
message(STATUS "PhysX SDK headers found, but required binaries are missing; native PhysX backend will stay disabled until the SDK is built")
endif()
else()
message(STATUS "PhysX SDK headers not found; PhysicsWorld will build without native PhysX backend")
endif()
set(
XCENGINE_MONO_ROOT_DIR
"${CMAKE_SOURCE_DIR}/参考/Fermion/Fermion/external/mono"
CACHE PATH
"Path to the bundled Mono distribution used by the scripting runtime")
if(EXISTS "${CMAKE_SOURCE_DIR}/engine/third_party/mono/binary/mscorlib.dll")
set(
XCENGINE_MONO_ROOT_DIR
"${CMAKE_SOURCE_DIR}/engine/third_party/mono"
CACHE PATH
"Path to the bundled Mono distribution used by the scripting runtime"
FORCE)
endif()
add_subdirectory(engine)
add_subdirectory(managed)
add_subdirectory(editor)
add_subdirectory(new_editor)
add_subdirectory(managed)
add_subdirectory(mvs/RenderDoc)
add_subdirectory(tests)

View File

@@ -0,0 +1,154 @@
cmake_minimum_required(VERSION 3.20)
project(XC3DGSD3D12MVS LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_program(XC_DXC_EXECUTABLE NAMES dxc)
if(NOT XC_DXC_EXECUTABLE)
message(FATAL_ERROR "dxc is required to build the 3DGS D3D12 MVS sort shaders.")
endif()
get_filename_component(XCENGINE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
set(XCENGINE_BUILD_DIR "${XCENGINE_ROOT}/build")
set(XCENGINE_INCLUDE_DIR "${XCENGINE_ROOT}/engine/include")
set(XCENGINE_LIBRARY_DEBUG "${XCENGINE_BUILD_DIR}/engine/Debug/XCEngine.lib")
if(NOT EXISTS "${XCENGINE_LIBRARY_DEBUG}")
message(FATAL_ERROR "Prebuilt XCEngine library was not found: ${XCENGINE_LIBRARY_DEBUG}")
endif()
add_library(XCEngine STATIC IMPORTED GLOBAL)
set_target_properties(XCEngine PROPERTIES
IMPORTED_CONFIGURATIONS "Debug;Release;RelWithDebInfo;MinSizeRel"
IMPORTED_LOCATION_DEBUG "${XCENGINE_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELEASE "${XCENGINE_LIBRARY_DEBUG}"
IMPORTED_LOCATION_RELWITHDEBINFO "${XCENGINE_LIBRARY_DEBUG}"
IMPORTED_LOCATION_MINSIZEREL "${XCENGINE_LIBRARY_DEBUG}"
)
add_executable(xc_3dgs_d3d12_mvs
WIN32
src/main.cpp
src/App.cpp
src/GaussianPlyLoader.cpp
include/XC3DGSD3D12/App.h
include/XC3DGSD3D12/GaussianPlyLoader.h
shaders/PreparedSplatView.hlsli
shaders/PrepareGaussiansCS.hlsl
shaders/BuildSortKeysCS.hlsl
shaders/SortCommon.hlsl
shaders/DeviceRadixSort.hlsl
shaders/DebugPointsVS.hlsl
shaders/DebugPointsPS.hlsl
)
set_source_files_properties(
shaders/PreparedSplatView.hlsli
shaders/PrepareGaussiansCS.hlsl
shaders/BuildSortKeysCS.hlsl
shaders/SortCommon.hlsl
shaders/DeviceRadixSort.hlsl
shaders/DebugPointsVS.hlsl
shaders/DebugPointsPS.hlsl
PROPERTIES
HEADER_FILE_ONLY TRUE
)
target_include_directories(xc_3dgs_d3d12_mvs PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${XCENGINE_INCLUDE_DIR}
)
target_compile_definitions(xc_3dgs_d3d12_mvs PRIVATE
UNICODE
_UNICODE
NOMINMAX
WIN32_LEAN_AND_MEAN
)
if(MSVC)
target_compile_options(xc_3dgs_d3d12_mvs PRIVATE /utf-8)
endif()
target_link_libraries(xc_3dgs_d3d12_mvs PRIVATE
XCEngine
d3d12
dxgi
dxguid
d3dcompiler
winmm
delayimp
bcrypt
opengl32
)
set_target_properties(xc_3dgs_d3d12_mvs PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>"
)
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/room.ply"
"$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/room.ply"
)
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/shaders"
"$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders"
)
add_custom_command(TARGET xc_3dgs_d3d12_mvs POST_BUILD
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E MainCS
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/BuildSortKeysCS.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/BuildSortKeysCS.hlsl"
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E InitDeviceRadixSort
-D KEY_UINT=1
-D PAYLOAD_UINT=1
-D SORT_PAIRS=1
-D SHOULD_ASCEND=1
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixInit.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E Upsweep
-D KEY_UINT=1
-D PAYLOAD_UINT=1
-D SORT_PAIRS=1
-D SHOULD_ASCEND=1
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixUpsweep.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E BuildGlobalHistogram
-D KEY_UINT=1
-D PAYLOAD_UINT=1
-D SORT_PAIRS=1
-D SHOULD_ASCEND=1
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixGlobalHistogram.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E Scan
-D KEY_UINT=1
-D PAYLOAD_UINT=1
-D SORT_PAIRS=1
-D SHOULD_ASCEND=1
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixScan.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
COMMAND "${XC_DXC_EXECUTABLE}"
-T cs_6_6
-E Downsweep
-D KEY_UINT=1
-D PAYLOAD_UINT=1
-D SORT_PAIRS=1
-D SHOULD_ASCEND=1
-Fo "$<TARGET_FILE_DIR:xc_3dgs_d3d12_mvs>/shaders/RadixDownsweep.dxil"
"${CMAKE_CURRENT_SOURCE_DIR}/shaders/DeviceRadixSort.hlsl"
)

View File

@@ -0,0 +1,153 @@
#pragma once
#include <windows.h>
#include <memory>
#include <string>
#include <vector>
#include <wrl/client.h>
#include "XC3DGSD3D12/GaussianPlyLoader.h"
#include "XCEngine/RHI/RHIEnums.h"
#include "XCEngine/RHI/RHITypes.h"
#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h"
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
#include "XCEngine/RHI/D3D12/D3D12CommandList.h"
#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h"
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
#include "XCEngine/RHI/D3D12/D3D12Device.h"
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
#include "XCEngine/RHI/D3D12/D3D12SwapChain.h"
#include "XCEngine/RHI/D3D12/D3D12Texture.h"
namespace XCEngine {
namespace RHI {
class RHIDescriptorPool;
class RHIDescriptorSet;
class RHIPipelineLayout;
class RHIPipelineState;
} // namespace RHI
} // namespace XCEngine
namespace XC3DGSD3D12 {
struct PreparedSplatView {
float clipPosition[4] = {};
float axis1[2] = {};
float axis2[2] = {};
uint32_t packedColor[2] = {};
};
class App {
public:
App();
~App();
bool Initialize(HINSTANCE instance, int showCommand);
int Run();
void SetFrameLimit(unsigned int frameLimit);
void SetGaussianScenePath(std::wstring scenePath);
void SetSummaryPath(std::wstring summaryPath);
void SetScreenshotPath(std::wstring screenshotPath);
const std::wstring& GetLastErrorMessage() const;
private:
static constexpr int kBackBufferCount = 2;
static constexpr int kDefaultWidth = 1280;
static constexpr int kDefaultHeight = 720;
static LRESULT CALLBACK StaticWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
bool RegisterWindowClass(HINSTANCE instance);
bool CreateMainWindow(HINSTANCE instance, int showCommand);
bool LoadGaussianScene();
bool InitializeRhi();
bool InitializeGaussianGpuResources();
bool InitializePreparePassResources();
bool InitializeSortResources();
bool InitializeDebugDrawResources();
void ShutdownGaussianGpuResources();
void ShutdownPreparePassResources();
void ShutdownSortResources();
void ShutdownDebugDrawResources();
void Shutdown();
bool CaptureSortSnapshot();
bool CapturePass3HistogramDebug();
void RenderFrame(bool captureScreenshot);
HWND m_hwnd = nullptr;
HINSTANCE m_instance = nullptr;
int m_width = kDefaultWidth;
int m_height = kDefaultHeight;
bool m_running = false;
bool m_isInitialized = false;
bool m_hasRenderedAtLeastOneFrame = false;
unsigned int m_frameLimit = 0;
unsigned int m_renderedFrameCount = 0;
std::wstring m_gaussianScenePath = L"room.ply";
std::wstring m_summaryPath;
std::wstring m_screenshotPath = L"phase3_debug_points.ppm";
std::wstring m_sortKeySnapshotPath = L"phase3_sortkeys.txt";
std::wstring m_lastErrorMessage;
GaussianSplatRuntimeData m_gaussianSceneData;
XCEngine::RHI::D3D12Buffer m_gaussianPositionBuffer;
XCEngine::RHI::D3D12Buffer m_gaussianOtherBuffer;
XCEngine::RHI::D3D12Buffer m_gaussianShBuffer;
XCEngine::RHI::D3D12Texture m_gaussianColorTexture;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianPositionView;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianOtherView;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianShView;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_gaussianColorView;
std::vector<Microsoft::WRL::ComPtr<ID3D12Resource>> m_gaussianUploadBuffers;
XCEngine::RHI::D3D12Buffer* m_preparedViewBuffer = nullptr;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_preparedViewSrv;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_preparedViewUav;
XCEngine::RHI::RHIPipelineLayout* m_preparePipelineLayout = nullptr;
XCEngine::RHI::RHIPipelineState* m_preparePipelineState = nullptr;
XCEngine::RHI::RHIDescriptorPool* m_prepareDescriptorPool = nullptr;
XCEngine::RHI::RHIDescriptorSet* m_prepareDescriptorSet = nullptr;
XCEngine::RHI::D3D12Buffer* m_sortKeyBuffer = nullptr;
XCEngine::RHI::D3D12Buffer* m_sortKeyScratchBuffer = nullptr;
XCEngine::RHI::D3D12Buffer* m_orderBuffer = nullptr;
XCEngine::RHI::D3D12Buffer* m_orderScratchBuffer = nullptr;
XCEngine::RHI::D3D12Buffer* m_passHistogramBuffer = nullptr;
XCEngine::RHI::D3D12Buffer* m_globalHistogramBuffer = nullptr;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_sortKeyUav;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_sortKeyScratchUav;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderBufferSrv;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderBufferUav;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_orderScratchUav;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_passHistogramUav;
std::unique_ptr<XCEngine::RHI::D3D12ResourceView> m_globalHistogramUav;
XCEngine::RHI::RHIPipelineLayout* m_buildSortKeyPipelineLayout = nullptr;
XCEngine::RHI::RHIPipelineState* m_buildSortKeyPipelineState = nullptr;
XCEngine::RHI::RHIDescriptorPool* m_buildSortKeyDescriptorPool = nullptr;
XCEngine::RHI::RHIDescriptorSet* m_buildSortKeyDescriptorSet = nullptr;
XCEngine::RHI::RHIPipelineLayout* m_radixSortPipelineLayout = nullptr;
XCEngine::RHI::RHIPipelineState* m_radixSortInitPipelineState = nullptr;
XCEngine::RHI::RHIPipelineState* m_radixSortUpsweepPipelineState = nullptr;
XCEngine::RHI::RHIPipelineState* m_radixSortGlobalHistogramPipelineState = nullptr;
XCEngine::RHI::RHIPipelineState* m_radixSortScanPipelineState = nullptr;
XCEngine::RHI::RHIPipelineState* m_radixSortDownsweepPipelineState = nullptr;
XCEngine::RHI::RHIDescriptorPool* m_radixSortDescriptorPool = nullptr;
XCEngine::RHI::RHIDescriptorSet* m_radixSortDescriptorSetPrimaryToScratch = nullptr;
XCEngine::RHI::RHIDescriptorSet* m_radixSortDescriptorSetScratchToPrimary = nullptr;
XCEngine::RHI::RHIPipelineLayout* m_debugPipelineLayout = nullptr;
XCEngine::RHI::RHIPipelineState* m_debugPipelineState = nullptr;
XCEngine::RHI::RHIDescriptorPool* m_debugDescriptorPool = nullptr;
XCEngine::RHI::RHIDescriptorSet* m_debugDescriptorSet = nullptr;
XCEngine::RHI::D3D12Device m_device;
XCEngine::RHI::D3D12CommandQueue m_commandQueue;
XCEngine::RHI::D3D12SwapChain m_swapChain;
XCEngine::RHI::D3D12CommandAllocator m_commandAllocator;
XCEngine::RHI::D3D12CommandList m_commandList;
XCEngine::RHI::D3D12Texture m_depthStencil;
XCEngine::RHI::D3D12DescriptorHeap m_rtvHeap;
XCEngine::RHI::D3D12DescriptorHeap m_dsvHeap;
XCEngine::RHI::D3D12ResourceView m_rtvs[kBackBufferCount];
XCEngine::RHI::D3D12ResourceView m_dsv;
};
} // namespace XC3DGSD3D12

View File

@@ -0,0 +1,46 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <string>
#include <vector>
namespace XC3DGSD3D12 {
struct Float3 {
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
};
struct GaussianSplatRuntimeData {
static constexpr uint32_t kColorTextureWidth = 2048;
static constexpr uint32_t kPositionStride = sizeof(float) * 3;
static constexpr uint32_t kOtherStride = sizeof(uint32_t) + sizeof(float) * 3;
static constexpr uint32_t kColorStride = sizeof(float) * 4;
static constexpr uint32_t kShCoefficientCount = 15;
static constexpr uint32_t kShStride = sizeof(float) * 3 * 16;
uint32_t splatCount = 0;
uint32_t colorTextureWidth = kColorTextureWidth;
uint32_t colorTextureHeight = 0;
Float3 boundsMin = {};
Float3 boundsMax = {};
std::vector<std::byte> positionData;
std::vector<std::byte> otherData;
std::vector<std::byte> colorData;
std::vector<std::byte> shData;
};
bool LoadGaussianSceneFromPly(
const std::filesystem::path& filePath,
GaussianSplatRuntimeData& outData,
std::string& outErrorMessage);
bool WriteGaussianSceneSummary(
const std::filesystem::path& filePath,
const GaussianSplatRuntimeData& data,
std::string& outErrorMessage);
} // namespace XC3DGSD3D12

View File

@@ -0,0 +1,43 @@
#define GROUP_SIZE 64
cbuffer FrameConstants : register(b0)
{
float4x4 gViewProjection;
float4x4 gView;
float4x4 gProjection;
float4 gCameraWorldPos;
float4 gScreenParams;
float4 gSettings;
};
ByteAddressBuffer gPositions : register(t0);
StructuredBuffer<uint> gOrderBuffer : register(t1);
RWStructuredBuffer<uint> gSortKeys : register(u0);
float3 LoadFloat3(ByteAddressBuffer buffer, uint byteOffset)
{
return asfloat(buffer.Load3(byteOffset));
}
uint FloatToSortableUint(float value)
{
uint bits = asuint(value);
uint mask = (0u - (bits >> 31)) | 0x80000000u;
return bits ^ mask;
}
[numthreads(GROUP_SIZE, 1, 1)]
void MainCS(uint3 dispatchThreadId : SV_DispatchThreadID)
{
uint index = dispatchThreadId.x;
uint splatCount = (uint)gSettings.x;
if (index >= splatCount)
{
return;
}
uint splatIndex = gOrderBuffer[index];
float3 position = LoadFloat3(gPositions, splatIndex * 12);
float3 viewPosition = mul(float4(position, 1.0), gView).xyz;
gSortKeys[index] = FloatToSortableUint(viewPosition.z);
}

View File

@@ -0,0 +1,19 @@
struct PixelInput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 localPosition : TEXCOORD0;
};
float4 MainPS(PixelInput input) : SV_Target0
{
float alpha = exp(-dot(input.localPosition, input.localPosition));
alpha = saturate(alpha * input.color.a);
if (alpha < (1.0 / 255.0))
{
discard;
}
return float4(input.color.rgb * alpha, alpha);
}

View File

@@ -0,0 +1,50 @@
#include "PreparedSplatView.hlsli"
cbuffer FrameConstants : register(b0)
{
float4x4 gViewProjection;
float4x4 gView;
float4x4 gProjection;
float4 gCameraWorldPos;
float4 gScreenParams;
float4 gSettings;
};
StructuredBuffer<PreparedSplatView> gPreparedViews : register(t0);
StructuredBuffer<uint> gOrderBuffer : register(t1);
struct VertexOutput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 localPosition : TEXCOORD0;
};
VertexOutput MainVS(uint vertexId : SV_VertexID, uint instanceId : SV_InstanceID)
{
VertexOutput output = (VertexOutput)0;
uint splatIndex = gOrderBuffer[instanceId];
PreparedSplatView view = gPreparedViews[splatIndex];
float4 color = UnpackPreparedColor(view);
if (view.clipPosition.w <= 0.0)
{
const float nanValue = asfloat(0x7fc00000);
output.position = float4(nanValue, nanValue, nanValue, nanValue);
return output;
}
float2 quadPosition = float2(vertexId & 1, (vertexId >> 1) & 1) * 2.0 - 1.0;
quadPosition *= 2.0;
float2 scaledAxis1 = view.axis1 * gSettings.w;
float2 scaledAxis2 = view.axis2 * gSettings.w;
float2 deltaScreenPosition =
(quadPosition.x * scaledAxis1 + quadPosition.y * scaledAxis2) * 2.0 / gScreenParams.xy;
output.position = view.clipPosition;
output.position.xy += deltaScreenPosition * view.clipPosition.w;
output.color = color;
output.localPosition = quadPosition;
return output;
}

View File

@@ -0,0 +1,477 @@
/******************************************************************************
* DeviceRadixSort
* Device Level 8-bit LSD Radix Sort using reduce then scan
*
* SPDX-License-Identifier: MIT
* Copyright Thomas Smith 5/17/2024
* https://github.com/b0nes164/GPUSorting
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "SortCommon.hlsl"
#define US_DIM 128U //The number of threads in a Upsweep threadblock
#define SCAN_DIM 128U //The number of threads in a Scan threadblock
RWStructuredBuffer<uint> b_globalHist : register(u5); //buffer holding device level offsets for each binning pass
RWStructuredBuffer<uint> b_passHist : register(u4); //buffer used to store reduced sums of partition tiles
groupshared uint g_us[RADIX * 2]; //Shared memory for upsweep
groupshared uint g_scan[SCAN_DIM]; //Shared memory for the scan
//*****************************************************************************
//INIT KERNEL
//*****************************************************************************
//Clear the global histogram, as we will be adding to it atomically
[numthreads(1024, 1, 1)]
void InitDeviceRadixSort(int3 id : SV_DispatchThreadID)
{
b_globalHist[id.x] = 0;
}
//*****************************************************************************
//UPSWEEP KERNEL
//*****************************************************************************
//histogram, 64 threads to a histogram
inline void HistogramDigitCounts(uint gtid, uint gid)
{
const uint histOffset = gtid / 64 * RADIX;
const uint partitionEnd = gid == e_threadBlocks - 1 ?
e_numKeys : (gid + 1) * PART_SIZE;
for (uint i = gtid + gid * PART_SIZE; i < partitionEnd; i += US_DIM)
{
#if defined(KEY_UINT)
InterlockedAdd(g_us[ExtractDigit(b_sort[i]) + histOffset], 1);
#elif defined(KEY_INT)
InterlockedAdd(g_us[ExtractDigit(IntToUint(b_sort[i])) + histOffset], 1);
#elif defined(KEY_FLOAT)
InterlockedAdd(g_us[ExtractDigit(FloatToUint(b_sort[i])) + histOffset], 1);
#endif
}
}
//reduce and pass to tile histogram
inline void ReduceWriteDigitCounts(uint gtid, uint gid)
{
for (uint i = gtid; i < RADIX; i += US_DIM)
{
g_us[i] += g_us[i + RADIX];
b_passHist[i * e_threadBlocks + gid] = g_us[i];
}
}
//Build the per-pass 256-bin exclusive prefix from the reduced pass histogram.
inline void BuildGlobalHistogramExclusive(uint gtid)
{
uint digitIndices[2];
uint digitTotals[2];
uint digitCount = 0;
for (uint i = gtid; i < RADIX; i += US_DIM)
{
uint total = 0u;
const uint baseOffset = i * e_threadBlocks;
for (uint blockIndex = 0; blockIndex < e_threadBlocks; ++blockIndex)
{
total += b_passHist[baseOffset + blockIndex];
}
g_us[i] = total;
digitIndices[digitCount] = i;
digitTotals[digitCount] = total;
++digitCount;
}
GroupMemoryBarrierWithGroupSync();
for (uint offset = 1; offset < RADIX; offset <<= 1)
{
for (uint i = gtid; i < RADIX; i += US_DIM)
{
g_us[i + RADIX] = g_us[i] + (i >= offset ? g_us[i - offset] : 0u);
}
GroupMemoryBarrierWithGroupSync();
for (uint i = gtid; i < RADIX; i += US_DIM)
{
g_us[i] = g_us[i + RADIX];
}
GroupMemoryBarrierWithGroupSync();
}
const uint globalHistOffset = GlobalHistOffset();
for (uint localIndex = 0; localIndex < digitCount; ++localIndex)
{
const uint digitIndex = digitIndices[localIndex];
b_globalHist[digitIndex + globalHistOffset] = g_us[digitIndex] - digitTotals[localIndex];
}
}
[numthreads(US_DIM, 1, 1)]
void Upsweep(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
{
//get the wave size
const uint waveSize = getWaveSize();
//clear shared memory
const uint histsEnd = RADIX * 2;
for (uint i = gtid.x; i < histsEnd; i += US_DIM)
g_us[i] = 0;
GroupMemoryBarrierWithGroupSync();
HistogramDigitCounts(gtid.x, gid.x);
GroupMemoryBarrierWithGroupSync();
ReduceWriteDigitCounts(gtid.x, gid.x);
}
[numthreads(US_DIM, 1, 1)]
void BuildGlobalHistogram(uint3 gtid : SV_GroupThreadID)
{
const uint histsEnd = RADIX * 2;
for (uint i = gtid.x; i < histsEnd; i += US_DIM)
g_us[i] = 0;
GroupMemoryBarrierWithGroupSync();
BuildGlobalHistogramExclusive(gtid.x);
}
//*****************************************************************************
//SCAN KERNEL
//*****************************************************************************
inline void ExclusiveThreadBlockScanFullWGE16(
uint gtid,
uint laneMask,
uint circularLaneShift,
uint partEnd,
uint deviceOffset,
uint waveSize,
inout uint reduction)
{
for (uint i = gtid; i < partEnd; i += SCAN_DIM)
{
g_scan[gtid] = b_passHist[i + deviceOffset];
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
GroupMemoryBarrierWithGroupSync();
if (gtid < SCAN_DIM / waveSize)
{
g_scan[(gtid + 1) * waveSize - 1] +=
WavePrefixSum(g_scan[(gtid + 1) * waveSize - 1]);
}
GroupMemoryBarrierWithGroupSync();
uint t = (WaveGetLaneIndex() != laneMask ? g_scan[gtid] : 0) + reduction;
if (gtid >= waveSize)
t += WaveReadLaneAt(g_scan[gtid - 1], 0);
b_passHist[circularLaneShift + (i & ~laneMask) + deviceOffset] = t;
reduction += g_scan[SCAN_DIM - 1];
GroupMemoryBarrierWithGroupSync();
}
}
inline void ExclusiveThreadBlockScanPartialWGE16(
uint gtid,
uint laneMask,
uint circularLaneShift,
uint partEnd,
uint deviceOffset,
uint waveSize,
uint reduction)
{
uint i = gtid + partEnd;
if (i < e_threadBlocks)
g_scan[gtid] = b_passHist[deviceOffset + i];
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
GroupMemoryBarrierWithGroupSync();
if (gtid < SCAN_DIM / waveSize)
{
g_scan[(gtid + 1) * waveSize - 1] +=
WavePrefixSum(g_scan[(gtid + 1) * waveSize - 1]);
}
GroupMemoryBarrierWithGroupSync();
const uint index = circularLaneShift + (i & ~laneMask);
if (index < e_threadBlocks)
{
uint t = (WaveGetLaneIndex() != laneMask ? g_scan[gtid] : 0) + reduction;
if (gtid >= waveSize)
t += g_scan[(gtid & ~laneMask) - 1];
b_passHist[index + deviceOffset] = t;
}
}
inline void ExclusiveThreadBlockScanWGE16(uint gtid, uint gid, uint waveSize)
{
uint reduction = 0;
const uint laneMask = waveSize - 1;
const uint circularLaneShift = WaveGetLaneIndex() + 1 & laneMask;
const uint partionsEnd = e_threadBlocks / SCAN_DIM * SCAN_DIM;
const uint deviceOffset = gid * e_threadBlocks;
ExclusiveThreadBlockScanFullWGE16(
gtid,
laneMask,
circularLaneShift,
partionsEnd,
deviceOffset,
waveSize,
reduction);
ExclusiveThreadBlockScanPartialWGE16(
gtid,
laneMask,
circularLaneShift,
partionsEnd,
deviceOffset,
waveSize,
reduction);
}
inline void ExclusiveThreadBlockScanFullWLT16(
uint gtid,
uint partitions,
uint deviceOffset,
uint laneLog,
uint circularLaneShift,
uint waveSize,
inout uint reduction)
{
for (uint k = 0; k < partitions; ++k)
{
g_scan[gtid] = b_passHist[gtid + k * SCAN_DIM + deviceOffset];
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
GroupMemoryBarrierWithGroupSync();
if (gtid < waveSize)
{
b_passHist[circularLaneShift + k * SCAN_DIM + deviceOffset] =
(circularLaneShift ? g_scan[gtid] : 0) + reduction;
}
uint offset = laneLog;
uint j = waveSize;
for (; j < (SCAN_DIM >> 1); j <<= laneLog)
{
if (gtid < (SCAN_DIM >> offset))
{
g_scan[((gtid + 1) << offset) - 1] +=
WavePrefixSum(g_scan[((gtid + 1) << offset) - 1]);
}
GroupMemoryBarrierWithGroupSync();
if ((gtid & ((j << laneLog) - 1)) >= j)
{
if (gtid < (j << laneLog))
{
b_passHist[gtid + k * SCAN_DIM + deviceOffset] =
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0) +
((gtid & (j - 1)) ? g_scan[gtid - 1] : 0) + reduction;
}
else
{
if ((gtid + 1) & (j - 1))
{
g_scan[gtid] +=
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0);
}
}
}
offset += laneLog;
}
GroupMemoryBarrierWithGroupSync();
//If SCAN_DIM is not a power of lanecount
for (uint i = gtid + j; i < SCAN_DIM; i += SCAN_DIM)
{
b_passHist[i + k * SCAN_DIM + deviceOffset] =
WaveReadLaneAt(g_scan[((i >> offset) << offset) - 1], 0) +
((i & (j - 1)) ? g_scan[i - 1] : 0) + reduction;
}
reduction += WaveReadLaneAt(g_scan[SCAN_DIM - 1], 0) +
WaveReadLaneAt(g_scan[(((SCAN_DIM - 1) >> offset) << offset) - 1], 0);
GroupMemoryBarrierWithGroupSync();
}
}
inline void ExclusiveThreadBlockScanParitalWLT16(
uint gtid,
uint partitions,
uint deviceOffset,
uint laneLog,
uint circularLaneShift,
uint waveSize,
uint reduction)
{
const uint finalPartSize = e_threadBlocks - partitions * SCAN_DIM;
if (gtid < finalPartSize)
{
g_scan[gtid] = b_passHist[gtid + partitions * SCAN_DIM + deviceOffset];
g_scan[gtid] += WavePrefixSum(g_scan[gtid]);
}
GroupMemoryBarrierWithGroupSync();
if (gtid < waveSize && circularLaneShift < finalPartSize)
{
b_passHist[circularLaneShift + partitions * SCAN_DIM + deviceOffset] =
(circularLaneShift ? g_scan[gtid] : 0) + reduction;
}
uint offset = laneLog;
for (uint j = waveSize; j < finalPartSize; j <<= laneLog)
{
if (gtid < (finalPartSize >> offset))
{
g_scan[((gtid + 1) << offset) - 1] +=
WavePrefixSum(g_scan[((gtid + 1) << offset) - 1]);
}
GroupMemoryBarrierWithGroupSync();
if ((gtid & ((j << laneLog) - 1)) >= j && gtid < finalPartSize)
{
if (gtid < (j << laneLog))
{
b_passHist[gtid + partitions * SCAN_DIM + deviceOffset] =
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0) +
((gtid & (j - 1)) ? g_scan[gtid - 1] : 0) + reduction;
}
else
{
if ((gtid + 1) & (j - 1))
{
g_scan[gtid] +=
WaveReadLaneAt(g_scan[((gtid >> offset) << offset) - 1], 0);
}
}
}
offset += laneLog;
}
}
inline void ExclusiveThreadBlockScanWLT16(uint gtid, uint gid, uint waveSize)
{
uint reduction = 0;
const uint partitions = e_threadBlocks / SCAN_DIM;
const uint deviceOffset = gid * e_threadBlocks;
const uint laneLog = countbits(waveSize - 1);
const uint circularLaneShift = WaveGetLaneIndex() + 1 & waveSize - 1;
ExclusiveThreadBlockScanFullWLT16(
gtid,
partitions,
deviceOffset,
laneLog,
circularLaneShift,
waveSize,
reduction);
ExclusiveThreadBlockScanParitalWLT16(
gtid,
partitions,
deviceOffset,
laneLog,
circularLaneShift,
waveSize,
reduction);
}
//Scan does not need flattening of gids
[numthreads(SCAN_DIM, 1, 1)]
void Scan(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
{
if (gtid.x != 0u)
{
return;
}
const uint deviceOffset = gid.x * e_threadBlocks;
uint runningOffset = 0u;
for (uint blockIndex = 0u; blockIndex < e_threadBlocks; ++blockIndex)
{
const uint index = deviceOffset + blockIndex;
const uint count = b_passHist[index];
b_passHist[index] = runningOffset;
runningOffset += count;
}
}
//*****************************************************************************
//DOWNSWEEP KERNEL
//*****************************************************************************
inline void LoadThreadBlockReductions(uint gtid, uint gid, uint exclusiveHistReduction)
{
if (gtid < RADIX)
{
g_d[gtid + PART_SIZE] = b_globalHist[gtid + GlobalHistOffset()] +
b_passHist[gtid * e_threadBlocks + gid] - exclusiveHistReduction;
}
}
[numthreads(D_DIM, 1, 1)]
void Downsweep(uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
{
if (gtid.x != 0u)
{
return;
}
const uint partitionStart = gid.x * PART_SIZE;
const uint partitionEnd = min(partitionStart + PART_SIZE, e_numKeys);
uint digitOffsets[RADIX];
const uint globalHistOffset = GlobalHistOffset();
for (uint digit = 0u; digit < RADIX; ++digit)
{
digitOffsets[digit] =
b_globalHist[globalHistOffset + digit] +
b_passHist[digit * e_threadBlocks + gid.x];
}
for (uint index = partitionStart; index < partitionEnd; ++index)
{
uint key;
#if defined(KEY_UINT)
key = b_sort[index];
#elif defined(KEY_INT)
key = IntToUint(b_sort[index]);
#elif defined(KEY_FLOAT)
key = FloatToUint(b_sort[index]);
#endif
const uint digit = ExtractDigit(key);
const uint destinationIndex = digitOffsets[digit]++;
#if defined(KEY_UINT)
b_alt[destinationIndex] = key;
#elif defined(KEY_INT)
b_alt[destinationIndex] = UintToInt(key);
#elif defined(KEY_FLOAT)
b_alt[destinationIndex] = UintToFloat(key);
#endif
#if defined(SORT_PAIRS)
#if defined(PAYLOAD_UINT)
b_altPayload[destinationIndex] = b_sortPayload[index];
#elif defined(PAYLOAD_INT)
b_altPayload[destinationIndex] = b_sortPayload[index];
#elif defined(PAYLOAD_FLOAT)
b_altPayload[destinationIndex] = b_sortPayload[index];
#endif
#endif
}
}

View File

@@ -0,0 +1,268 @@
#include "PreparedSplatView.hlsli"
#define GROUP_SIZE 64
cbuffer FrameConstants : register(b0)
{
float4x4 gViewProjection;
float4x4 gView;
float4x4 gProjection;
float4 gCameraWorldPos;
float4 gScreenParams;
float4 gSettings;
};
ByteAddressBuffer gPositions : register(t0);
ByteAddressBuffer gOther : register(t1);
Texture2D<float4> gColor : register(t2);
ByteAddressBuffer gSh : register(t3);
RWStructuredBuffer<PreparedSplatView> gPreparedViews : register(u0);
static const float SH_C1 = 0.4886025;
static const float SH_C2[] = { 1.0925484, -1.0925484, 0.3153916, -1.0925484, 0.5462742 };
static const float SH_C3[] = { -0.5900436, 2.8906114, -0.4570458, 0.3731763, -0.4570458, 1.4453057, -0.5900436 };
static const uint kColorTextureWidth = 2048;
static const uint kOtherStride = 16;
static const uint kShStride = 192;
struct SplatSHData
{
float3 col;
float3 sh[15];
};
float3 LoadFloat3(ByteAddressBuffer buffer, uint byteOffset)
{
return asfloat(buffer.Load3(byteOffset));
}
uint EncodeMorton2D_16x16(uint2 c)
{
uint t = ((c.y & 0xF) << 8) | (c.x & 0xF);
t = (t ^ (t << 2)) & 0x3333;
t = (t ^ (t << 1)) & 0x5555;
return (t | (t >> 7)) & 0xFF;
}
uint2 DecodeMorton2D_16x16(uint t)
{
t = (t & 0xFF) | ((t & 0xFE) << 7);
t &= 0x5555;
t = (t ^ (t >> 1)) & 0x3333;
t = (t ^ (t >> 2)) & 0x0F0F;
return uint2(t & 0xF, t >> 8);
}
uint3 SplatIndexToPixelIndex(uint index)
{
uint2 xy = DecodeMorton2D_16x16(index);
uint tileWidth = kColorTextureWidth / 16;
index >>= 8;
uint3 result;
result.x = (index % tileWidth) * 16 + xy.x;
result.y = (index / tileWidth) * 16 + xy.y;
result.z = 0;
return result;
}
float4 DecodePacked_10_10_10_2(uint encoded)
{
return float4(
(encoded & 1023) / 1023.0,
((encoded >> 10) & 1023) / 1023.0,
((encoded >> 20) & 1023) / 1023.0,
((encoded >> 30) & 3) / 3.0);
}
float4 DecodeRotation(float4 packedRotation)
{
uint droppedIndex = (uint)round(packedRotation.w * 3.0);
float4 rotation;
rotation.xyz = packedRotation.xyz * sqrt(2.0) - (1.0 / sqrt(2.0));
rotation.w = sqrt(1.0 - saturate(dot(rotation.xyz, rotation.xyz)));
if (droppedIndex == 0)
{
rotation = rotation.wxyz;
}
if (droppedIndex == 1)
{
rotation = rotation.xwyz;
}
if (droppedIndex == 2)
{
rotation = rotation.xywz;
}
return rotation;
}
float3x3 CalcMatrixFromRotationScale(float4 rotation, float3 scale)
{
float3x3 scaleMatrix = float3x3(
scale.x, 0, 0,
0, scale.y, 0,
0, 0, scale.z);
float x = rotation.x;
float y = rotation.y;
float z = rotation.z;
float w = rotation.w;
float3x3 rotationMatrix = float3x3(
1 - 2 * (y * y + z * z), 2 * (x * y - w * z), 2 * (x * z + w * y),
2 * (x * y + w * z), 1 - 2 * (x * x + z * z), 2 * (y * z - w * x),
2 * (x * z - w * y), 2 * (y * z + w * x), 1 - 2 * (x * x + y * y));
return mul(transpose(rotationMatrix), scaleMatrix);
}
void CalcCovariance3D(float3x3 rotationScaleMatrix, out float3 sigma0, out float3 sigma1)
{
float3x3 sigma = mul(rotationScaleMatrix, transpose(rotationScaleMatrix));
sigma0 = float3(sigma._m00, sigma._m01, sigma._m02);
sigma1 = float3(sigma._m11, sigma._m12, sigma._m22);
}
float3 CalcCovariance2D(float3 worldPosition, float3 covariance0, float3 covariance1)
{
float3 viewPosition = mul(float4(worldPosition, 1.0), gView).xyz;
float tanFovX = rcp(gProjection._m00);
float tanFovY = rcp(gProjection._m11);
float clampX = 1.3 * tanFovX;
float clampY = 1.3 * tanFovY;
viewPosition.x = clamp(viewPosition.x / viewPosition.z, -clampX, clampX) * viewPosition.z;
viewPosition.y = clamp(viewPosition.y / viewPosition.z, -clampY, clampY) * viewPosition.z;
float focal = gScreenParams.x * gProjection._m00 * 0.5;
float3x3 jacobian = float3x3(
focal / viewPosition.z, 0, -(focal * viewPosition.x) / (viewPosition.z * viewPosition.z),
0, focal / viewPosition.z, -(focal * viewPosition.y) / (viewPosition.z * viewPosition.z),
0, 0, 0);
float3x3 worldToView = transpose((float3x3)gView);
float3x3 transform = mul(jacobian, worldToView);
float3x3 covariance = float3x3(
covariance0.x, covariance0.y, covariance0.z,
covariance0.y, covariance1.x, covariance1.y,
covariance0.z, covariance1.y, covariance1.z);
float3x3 projected = mul(transform, mul(covariance, transpose(transform)));
projected._m00 += 0.3;
projected._m11 += 0.3;
return float3(projected._m00, projected._m01, projected._m11);
}
void DecomposeCovariance(float3 covariance2D, out float2 axis1, out float2 axis2)
{
float diagonal0 = covariance2D.x;
float diagonal1 = covariance2D.z;
float offDiagonal = covariance2D.y;
float mid = 0.5 * (diagonal0 + diagonal1);
float radius = length(float2((diagonal0 - diagonal1) * 0.5, offDiagonal));
float lambda0 = mid + radius;
float lambda1 = max(mid - radius, 0.1);
float2 diagonalVector = normalize(float2(offDiagonal, lambda0 - diagonal0));
diagonalVector.y = -diagonalVector.y;
const float maxSize = 4096.0;
axis1 = min(sqrt(2.0 * lambda0), maxSize) * diagonalVector;
axis2 = min(sqrt(2.0 * lambda1), maxSize) * float2(diagonalVector.y, -diagonalVector.x);
}
SplatSHData LoadSplatSH(uint index)
{
SplatSHData sh;
const uint shBaseOffset = index * kShStride;
sh.col = gColor.Load(int3(SplatIndexToPixelIndex(index).xy, 0)).rgb;
[unroll]
for (uint coefficientIndex = 0; coefficientIndex < 15; ++coefficientIndex)
{
sh.sh[coefficientIndex] = LoadFloat3(gSh, shBaseOffset + coefficientIndex * 12);
}
return sh;
}
float3 ShadeSH(SplatSHData sh, float3 direction, int shOrder)
{
direction *= -1.0;
float x = direction.x;
float y = direction.y;
float z = direction.z;
float3 result = sh.col;
if (shOrder >= 1)
{
result += SH_C1 * (-sh.sh[0] * y + sh.sh[1] * z - sh.sh[2] * x);
if (shOrder >= 2)
{
float xx = x * x;
float yy = y * y;
float zz = z * z;
float xy = x * y;
float yz = y * z;
float xz = x * z;
result +=
(SH_C2[0] * xy) * sh.sh[3] +
(SH_C2[1] * yz) * sh.sh[4] +
(SH_C2[2] * (2 * zz - xx - yy)) * sh.sh[5] +
(SH_C2[3] * xz) * sh.sh[6] +
(SH_C2[4] * (xx - yy)) * sh.sh[7];
if (shOrder >= 3)
{
result +=
(SH_C3[0] * y * (3 * xx - yy)) * sh.sh[8] +
(SH_C3[1] * xy * z) * sh.sh[9] +
(SH_C3[2] * y * (4 * zz - xx - yy)) * sh.sh[10] +
(SH_C3[3] * z * (2 * zz - 3 * xx - 3 * yy)) * sh.sh[11] +
(SH_C3[4] * x * (4 * zz - xx - yy)) * sh.sh[12] +
(SH_C3[5] * z * (xx - yy)) * sh.sh[13] +
(SH_C3[6] * x * (xx - 3 * yy)) * sh.sh[14];
}
}
}
return max(result, 0.0);
}
[numthreads(GROUP_SIZE, 1, 1)]
void MainCS(uint3 dispatchThreadId : SV_DispatchThreadID)
{
uint index = dispatchThreadId.x;
uint splatCount = (uint)gSettings.x;
if (index >= splatCount)
{
return;
}
PreparedSplatView view = (PreparedSplatView)0;
float3 position = LoadFloat3(gPositions, index * 12);
uint packedRotation = gOther.Load(index * kOtherStride);
float4 rotation = DecodeRotation(DecodePacked_10_10_10_2(packedRotation));
float3 scale = LoadFloat3(gOther, index * kOtherStride + 4);
float4 colorOpacity = gColor.Load(int3(SplatIndexToPixelIndex(index).xy, 0));
view.clipPosition = mul(float4(position, 1.0), gViewProjection);
if (view.clipPosition.w > 0.0)
{
float3x3 rotationScale = CalcMatrixFromRotationScale(rotation, scale);
float3 covariance0;
float3 covariance1;
CalcCovariance3D(rotationScale, covariance0, covariance1);
float3 covariance2D = CalcCovariance2D(position, covariance0, covariance1);
DecomposeCovariance(covariance2D, view.axis1, view.axis2);
SplatSHData sh = LoadSplatSH(index);
float3 viewDirection = normalize(gCameraWorldPos.xyz - position);
float3 shadedColor = ShadeSH(sh, viewDirection, (int)gSettings.z);
float opacity = saturate(colorOpacity.a * gSettings.y);
view.packedColor.x = (f32tof16(shadedColor.r) << 16) | f32tof16(shadedColor.g);
view.packedColor.y = (f32tof16(shadedColor.b) << 16) | f32tof16(opacity);
}
gPreparedViews[index] = view;
}

View File

@@ -0,0 +1,22 @@
#ifndef PREPARED_SPLAT_VIEW_HLSLI
#define PREPARED_SPLAT_VIEW_HLSLI
struct PreparedSplatView
{
float4 clipPosition;
float2 axis1;
float2 axis2;
uint2 packedColor;
};
float4 UnpackPreparedColor(PreparedSplatView view)
{
float4 color;
color.r = f16tof32((view.packedColor.x >> 16) & 0xFFFF);
color.g = f16tof32(view.packedColor.x & 0xFFFF);
color.b = f16tof32((view.packedColor.y >> 16) & 0xFFFF);
color.a = f16tof32(view.packedColor.y & 0xFFFF);
return color;
}
#endif

View File

@@ -0,0 +1,959 @@
/******************************************************************************
* SortCommon
* Common functions for GPUSorting
*
* SPDX-License-Identifier: MIT
* Copyright Thomas Smith 5/17/2024
* https://github.com/b0nes164/GPUSorting
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#define KEYS_PER_THREAD 15U
#define D_DIM 256U
#define PART_SIZE 3840U
#define D_TOTAL_SMEM 4096U
#define RADIX 256U //Number of digit bins
#define RADIX_MASK 255U //Mask of digit bins
#define HALF_RADIX 128U //For smaller waves where bit packing is necessary
#define HALF_MASK 127U // ''
#define RADIX_LOG 8U //log2(RADIX)
#define RADIX_PASSES 4U //(Key width) / RADIX_LOG
cbuffer cbGpuSorting : register(b0)
{
uint e_numKeys;
uint e_radixShift;
uint e_threadBlocks;
uint padding;
};
#if defined(KEY_UINT)
RWStructuredBuffer<uint> b_sort : register(u0);
RWStructuredBuffer<uint> b_alt : register(u1);
#elif defined(KEY_INT)
RWStructuredBuffer<int> b_sort : register(u0);
RWStructuredBuffer<int> b_alt : register(u1);
#elif defined(KEY_FLOAT)
RWStructuredBuffer<float> b_sort : register(u0);
RWStructuredBuffer<float> b_alt : register(u1);
#endif
#if defined(PAYLOAD_UINT)
RWStructuredBuffer<uint> b_sortPayload : register(u2);
RWStructuredBuffer<uint> b_altPayload : register(u3);
#elif defined(PAYLOAD_INT)
RWStructuredBuffer<int> b_sortPayload : register(u2);
RWStructuredBuffer<int> b_altPayload : register(u3);
#elif defined(PAYLOAD_FLOAT)
RWStructuredBuffer<float> b_sortPayload : register(u2);
RWStructuredBuffer<float> b_altPayload : register(u3);
#endif
groupshared uint g_d[D_TOTAL_SMEM]; //Shared memory for DigitBinningPass and DownSweep kernels
struct KeyStruct
{
uint k[KEYS_PER_THREAD];
};
struct OffsetStruct
{
#if defined(ENABLE_16_BIT)
uint16_t o[KEYS_PER_THREAD];
#else
uint o[KEYS_PER_THREAD];
#endif
};
struct DigitStruct
{
#if defined(ENABLE_16_BIT)
uint16_t d[KEYS_PER_THREAD];
#else
uint d[KEYS_PER_THREAD];
#endif
};
//*****************************************************************************
//HELPER FUNCTIONS
//*****************************************************************************
//Due to a bug with SPIRV pre 1.6, we cannot use WaveGetLaneCount() to get the currently active wavesize
inline uint getWaveSize()
{
#if defined(VULKAN)
GroupMemoryBarrierWithGroupSync(); //Make absolutely sure the wave is not diverged here
return dot(countbits(WaveActiveBallot(true)), uint4(1, 1, 1, 1));
#else
return WaveGetLaneCount();
#endif
}
inline uint getWaveIndex(uint gtid, uint waveSize)
{
return gtid / waveSize;
}
//Radix Tricks by Michael Herf
//http://stereopsis.com/radix.html
inline uint FloatToUint(float f)
{
uint mask = -((int) (asuint(f) >> 31)) | 0x80000000;
return asuint(f) ^ mask;
}
inline float UintToFloat(uint u)
{
uint mask = ((u >> 31) - 1) | 0x80000000;
return asfloat(u ^ mask);
}
inline uint IntToUint(int i)
{
return asuint(i ^ 0x80000000);
}
inline int UintToInt(uint u)
{
return asint(u ^ 0x80000000);
}
inline uint getWaveCountPass(uint waveSize)
{
return D_DIM / waveSize;
}
inline uint ExtractDigit(uint key)
{
return key >> e_radixShift & RADIX_MASK;
}
inline uint ExtractDigit(uint key, uint shift)
{
return key >> shift & RADIX_MASK;
}
inline uint ExtractPackedIndex(uint key)
{
return key >> (e_radixShift + 1) & HALF_MASK;
}
inline uint ExtractPackedShift(uint key)
{
return (key >> e_radixShift & 1) ? 16 : 0;
}
inline uint ExtractPackedValue(uint packed, uint key)
{
return packed >> ExtractPackedShift(key) & 0xffff;
}
inline uint SubPartSizeWGE16(uint waveSize)
{
return KEYS_PER_THREAD * waveSize;
}
inline uint SharedOffsetWGE16(uint gtid, uint waveSize)
{
return WaveGetLaneIndex() + getWaveIndex(gtid, waveSize) * SubPartSizeWGE16(waveSize);
}
inline uint SubPartSizeWLT16(uint waveSize, uint _serialIterations)
{
return KEYS_PER_THREAD * waveSize * _serialIterations;
}
inline uint SharedOffsetWLT16(uint gtid, uint waveSize, uint _serialIterations)
{
return WaveGetLaneIndex() +
(getWaveIndex(gtid, waveSize) / _serialIterations * SubPartSizeWLT16(waveSize, _serialIterations)) +
(getWaveIndex(gtid, waveSize) % _serialIterations * waveSize);
}
inline uint DeviceOffsetWGE16(uint gtid, uint waveSize, uint partIndex)
{
return SharedOffsetWGE16(gtid, waveSize) + partIndex * PART_SIZE;
}
inline uint DeviceOffsetWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
{
return SharedOffsetWLT16(gtid, waveSize, serialIterations) + partIndex * PART_SIZE;
}
inline uint GlobalHistOffset()
{
return e_radixShift << 5;
}
inline uint WaveHistsSizeWGE16(uint waveSize)
{
return D_DIM / waveSize * RADIX;
}
inline uint WaveHistsSizeWLT16()
{
return D_TOTAL_SMEM;
}
//*****************************************************************************
//FUNCTIONS COMMON TO THE DOWNSWEEP / DIGIT BINNING PASS
//*****************************************************************************
//If the size of a wave is too small, we do not have enough space in
//shared memory to assign a histogram to each wave, so instead,
//some operations are peformed serially.
inline uint SerialIterations(uint waveSize)
{
return (D_DIM / waveSize + 31) >> 5;
}
inline void ClearWaveHists(uint gtid, uint waveSize)
{
const uint histsEnd = waveSize >= 16 ?
WaveHistsSizeWGE16(waveSize) : WaveHistsSizeWLT16();
for (uint i = gtid; i < histsEnd; i += D_DIM)
g_d[i] = 0;
}
inline void LoadKey(inout uint key, uint index)
{
#if defined(KEY_UINT)
key = b_sort[index];
#elif defined(KEY_INT)
key = UintToInt(b_sort[index]);
#elif defined(KEY_FLOAT)
key = FloatToUint(b_sort[index]);
#endif
}
inline void LoadDummyKey(inout uint key)
{
key = 0xffffffff;
}
inline KeyStruct LoadKeysWGE16(uint gtid, uint waveSize, uint partIndex)
{
KeyStruct keys;
[unroll]
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
i < KEYS_PER_THREAD;
++i, t += waveSize)
{
LoadKey(keys.k[i], t);
}
return keys;
}
inline KeyStruct LoadKeysWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
{
KeyStruct keys;
[unroll]
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
i < KEYS_PER_THREAD;
++i, t += waveSize * serialIterations)
{
LoadKey(keys.k[i], t);
}
return keys;
}
inline KeyStruct LoadKeysPartialWGE16(uint gtid, uint waveSize, uint partIndex)
{
KeyStruct keys;
[unroll]
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
i < KEYS_PER_THREAD;
++i, t += waveSize)
{
if (t < e_numKeys)
LoadKey(keys.k[i], t);
else
LoadDummyKey(keys.k[i]);
}
return keys;
}
inline KeyStruct LoadKeysPartialWLT16(uint gtid, uint waveSize, uint partIndex, uint serialIterations)
{
KeyStruct keys;
[unroll]
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
i < KEYS_PER_THREAD;
++i, t += waveSize * serialIterations)
{
if (t < e_numKeys)
LoadKey(keys.k[i], t);
else
LoadDummyKey(keys.k[i]);
}
return keys;
}
inline uint WaveFlagsWGE16(uint waveSize)
{
return (waveSize & 31) ? (1U << waveSize) - 1 : 0xffffffff;
}
inline uint WaveFlagsWLT16(uint waveSize)
{
return (1U << waveSize) - 1;;
}
inline void WarpLevelMultiSplitWGE16(uint key, inout uint4 waveFlags)
{
[unroll]
for (uint k = 0; k < RADIX_LOG; ++k)
{
const uint currentBit = 1U << (k + e_radixShift);
const bool t = (key & currentBit) != 0;
GroupMemoryBarrierWithGroupSync(); //Play on the safe side, throw in a barrier for convergence
const uint4 ballot = WaveActiveBallot(t);
if(t)
waveFlags &= ballot;
else
waveFlags &= (~ballot);
}
}
inline uint2 CountBitsWGE16(uint waveSize, uint ltMask, uint4 waveFlags)
{
uint2 count = uint2(0, 0);
for(uint wavePart = 0; wavePart < waveSize; wavePart += 32)
{
uint t = countbits(waveFlags[wavePart >> 5]);
if (WaveGetLaneIndex() >= wavePart)
{
if (WaveGetLaneIndex() >= wavePart + 32)
count.x += t;
else
count.x += countbits(waveFlags[wavePart >> 5] & ltMask);
}
count.y += t;
}
return count;
}
inline void WarpLevelMultiSplitWLT16(uint key, inout uint waveFlags)
{
[unroll]
for (uint k = 0; k < RADIX_LOG; ++k)
{
const bool t = key >> (k + e_radixShift) & 1;
waveFlags &= (t ? 0 : 0xffffffff) ^ (uint) WaveActiveBallot(t);
}
}
inline OffsetStruct RankKeysWGE16(
uint waveSize,
uint waveOffset,
KeyStruct keys)
{
OffsetStruct offsets;
const uint initialFlags = WaveFlagsWGE16(waveSize);
const uint ltMask = (1U << (WaveGetLaneIndex() & 31)) - 1;
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
{
uint4 waveFlags = initialFlags;
WarpLevelMultiSplitWGE16(keys.k[i], waveFlags);
const uint index = ExtractDigit(keys.k[i]) + waveOffset;
const uint2 bitCount = CountBitsWGE16(waveSize, ltMask, waveFlags);
offsets.o[i] = g_d[index] + bitCount.x;
GroupMemoryBarrierWithGroupSync();
if (bitCount.x == 0)
g_d[index] += bitCount.y;
GroupMemoryBarrierWithGroupSync();
}
return offsets;
}
inline OffsetStruct RankKeysWLT16(uint waveSize, uint waveIndex, KeyStruct keys, uint serialIterations)
{
OffsetStruct offsets;
const uint ltMask = (1U << WaveGetLaneIndex()) - 1;
const uint initialFlags = WaveFlagsWLT16(waveSize);
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
{
uint waveFlags = initialFlags;
WarpLevelMultiSplitWLT16(keys.k[i], waveFlags);
const uint index = ExtractPackedIndex(keys.k[i]) +
(waveIndex / serialIterations * HALF_RADIX);
const uint peerBits = countbits(waveFlags & ltMask);
for (uint k = 0; k < serialIterations; ++k)
{
if (waveIndex % serialIterations == k)
offsets.o[i] = ExtractPackedValue(g_d[index], keys.k[i]) + peerBits;
GroupMemoryBarrierWithGroupSync();
if (waveIndex % serialIterations == k && peerBits == 0)
{
InterlockedAdd(g_d[index],
countbits(waveFlags) << ExtractPackedShift(keys.k[i]));
}
GroupMemoryBarrierWithGroupSync();
}
}
return offsets;
}
inline uint WaveHistInclusiveScanCircularShiftWGE16(uint gtid, uint waveSize)
{
uint histReduction = g_d[gtid];
for (uint i = gtid + RADIX; i < WaveHistsSizeWGE16(waveSize); i += RADIX)
{
histReduction += g_d[i];
g_d[i] = histReduction - g_d[i];
}
return histReduction;
}
inline uint WaveHistInclusiveScanCircularShiftWLT16(uint gtid)
{
uint histReduction = g_d[gtid];
for (uint i = gtid + HALF_RADIX; i < WaveHistsSizeWLT16(); i += HALF_RADIX)
{
histReduction += g_d[i];
g_d[i] = histReduction - g_d[i];
}
return histReduction;
}
inline void WaveHistReductionExclusiveScanWGE16(uint gtid, uint waveSize, uint histReduction)
{
if (gtid < RADIX)
{
const uint laneMask = waveSize - 1;
g_d[((WaveGetLaneIndex() + 1) & laneMask) + (gtid & ~laneMask)] = histReduction;
}
GroupMemoryBarrierWithGroupSync();
if (gtid < RADIX / waveSize)
{
g_d[gtid * waveSize] =
WavePrefixSum(g_d[gtid * waveSize]);
}
GroupMemoryBarrierWithGroupSync();
uint t = WaveReadLaneAt(g_d[gtid], 0);
if (gtid < RADIX && WaveGetLaneIndex())
g_d[gtid] += t;
}
//inclusive/exclusive prefix sum up the histograms,
//use a blelloch scan for in place packed exclusive
inline void WaveHistReductionExclusiveScanWLT16(uint gtid)
{
uint shift = 1;
for (uint j = RADIX >> 2; j > 0; j >>= 1)
{
GroupMemoryBarrierWithGroupSync();
if (gtid < j)
{
g_d[((((gtid << 1) + 2) << shift) - 1) >> 1] +=
g_d[((((gtid << 1) + 1) << shift) - 1) >> 1] & 0xffff0000;
}
shift++;
}
GroupMemoryBarrierWithGroupSync();
if (gtid == 0)
g_d[HALF_RADIX - 1] &= 0xffff;
for (uint j = 1; j < RADIX >> 1; j <<= 1)
{
--shift;
GroupMemoryBarrierWithGroupSync();
if (gtid < j)
{
const uint t = ((((gtid << 1) + 1) << shift) - 1) >> 1;
const uint t2 = ((((gtid << 1) + 2) << shift) - 1) >> 1;
const uint t3 = g_d[t];
g_d[t] = (g_d[t] & 0xffff) | (g_d[t2] & 0xffff0000);
g_d[t2] += t3 & 0xffff0000;
}
}
GroupMemoryBarrierWithGroupSync();
if (gtid < HALF_RADIX)
{
const uint t = g_d[gtid];
g_d[gtid] = (t >> 16) + (t << 16) + (t & 0xffff0000);
}
}
inline void UpdateOffsetsWGE16(
uint gtid,
uint waveSize,
inout OffsetStruct offsets,
KeyStruct keys)
{
if (gtid >= waveSize)
{
const uint t = getWaveIndex(gtid, waveSize) * RADIX;
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
{
const uint t2 = ExtractDigit(keys.k[i]);
offsets.o[i] += g_d[t2 + t] + g_d[t2];
}
}
else
{
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
offsets.o[i] += g_d[ExtractDigit(keys.k[i])];
}
}
inline void UpdateOffsetsWLT16(
uint gtid,
uint waveSize,
uint serialIterations,
inout OffsetStruct offsets,
KeyStruct keys)
{
if (gtid >= waveSize * serialIterations)
{
const uint t = getWaveIndex(gtid, waveSize) / serialIterations * HALF_RADIX;
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
{
const uint t2 = ExtractPackedIndex(keys.k[i]);
offsets.o[i] += ExtractPackedValue(g_d[t2 + t] + g_d[t2], keys.k[i]);
}
}
else
{
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
offsets.o[i] += ExtractPackedValue(g_d[ExtractPackedIndex(keys.k[i])], keys.k[i]);
}
}
inline void ScatterKeysShared(OffsetStruct offsets, KeyStruct keys)
{
[unroll]
for (uint i = 0; i < KEYS_PER_THREAD; ++i)
g_d[offsets.o[i]] = keys.k[i];
}
inline uint DescendingIndex(uint deviceIndex)
{
return e_numKeys - deviceIndex - 1;
}
inline void WriteKey(uint deviceIndex, uint groupSharedIndex)
{
#if defined(KEY_UINT)
b_alt[deviceIndex] = g_d[groupSharedIndex];
#elif defined(KEY_INT)
b_alt[deviceIndex] = UintToInt(g_d[groupSharedIndex]);
#elif defined(KEY_FLOAT)
b_alt[deviceIndex] = UintToFloat(g_d[groupSharedIndex]);
#endif
}
inline void LoadPayload(inout uint payload, uint deviceIndex)
{
#if defined(PAYLOAD_UINT)
payload = b_sortPayload[deviceIndex];
#elif defined(PAYLOAD_INT) || defined(PAYLOAD_FLOAT)
payload = asuint(b_sortPayload[deviceIndex]);
#endif
}
inline void ScatterPayloadsShared(OffsetStruct offsets, KeyStruct payloads)
{
ScatterKeysShared(offsets, payloads);
}
inline void WritePayload(uint deviceIndex, uint groupSharedIndex)
{
#if defined(PAYLOAD_UINT)
b_altPayload[deviceIndex] = g_d[groupSharedIndex];
#elif defined(PAYLOAD_INT)
b_altPayload[deviceIndex] = asint(g_d[groupSharedIndex]);
#elif defined(PAYLOAD_FLOAT)
b_altPayload[deviceIndex] = asfloat(g_d[groupSharedIndex]);
#endif
}
//*****************************************************************************
//SCATTERING: FULL PARTITIONS
//*****************************************************************************
//KEYS ONLY
inline void ScatterKeysOnlyDeviceAscending(uint gtid)
{
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
WriteKey(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i, i);
}
inline void ScatterKeysOnlyDeviceDescending(uint gtid)
{
if (e_radixShift == 24)
{
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
WriteKey(DescendingIndex(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i), i);
}
else
{
ScatterKeysOnlyDeviceAscending(gtid);
}
}
inline void ScatterKeysOnlyDevice(uint gtid)
{
#if defined(SHOULD_ASCEND)
ScatterKeysOnlyDeviceAscending(gtid);
#else
ScatterKeysOnlyDeviceDescending(gtid);
#endif
}
//KEY VALUE PAIRS
inline void ScatterPairsKeyPhaseAscending(
uint gtid,
inout DigitStruct digits)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
digits.d[i] = ExtractDigit(g_d[t]);
WriteKey(g_d[digits.d[i] + PART_SIZE] + t, t);
}
}
inline void ScatterPairsKeyPhaseDescending(
uint gtid,
inout DigitStruct digits)
{
if (e_radixShift == 24)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
digits.d[i] = ExtractDigit(g_d[t]);
WriteKey(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
}
}
else
{
ScatterPairsKeyPhaseAscending(gtid, digits);
}
}
inline void LoadPayloadsWGE16(
uint gtid,
uint waveSize,
uint partIndex,
inout KeyStruct payloads)
{
[unroll]
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
i < KEYS_PER_THREAD;
++i, t += waveSize)
{
LoadPayload(payloads.k[i], t);
}
}
inline void LoadPayloadsWLT16(
uint gtid,
uint waveSize,
uint partIndex,
uint serialIterations,
inout KeyStruct payloads)
{
[unroll]
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
i < KEYS_PER_THREAD;
++i, t += waveSize * serialIterations)
{
LoadPayload(payloads.k[i], t);
}
}
inline void ScatterPayloadsAscending(uint gtid, DigitStruct digits)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
WritePayload(g_d[digits.d[i] + PART_SIZE] + t, t);
}
inline void ScatterPayloadsDescending(uint gtid, DigitStruct digits)
{
if (e_radixShift == 24)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
WritePayload(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
}
else
{
ScatterPayloadsAscending(gtid, digits);
}
}
inline void ScatterPairsDevice(
uint gtid,
uint waveSize,
uint partIndex,
OffsetStruct offsets)
{
DigitStruct digits;
#if defined(SHOULD_ASCEND)
ScatterPairsKeyPhaseAscending(gtid, digits);
#else
ScatterPairsKeyPhaseDescending(gtid, digits);
#endif
GroupMemoryBarrierWithGroupSync();
KeyStruct payloads;
if (waveSize >= 16)
LoadPayloadsWGE16(gtid, waveSize, partIndex, payloads);
else
LoadPayloadsWLT16(gtid, waveSize, partIndex, SerialIterations(waveSize), payloads);
ScatterPayloadsShared(offsets, payloads);
GroupMemoryBarrierWithGroupSync();
#if defined(SHOULD_ASCEND)
ScatterPayloadsAscending(gtid, digits);
#else
ScatterPayloadsDescending(gtid, digits);
#endif
}
inline void ScatterDevice(
uint gtid,
uint waveSize,
uint partIndex,
OffsetStruct offsets)
{
#if defined(SORT_PAIRS)
ScatterPairsDevice(
gtid,
waveSize,
partIndex,
offsets);
#else
ScatterKeysOnlyDevice(gtid);
#endif
}
//*****************************************************************************
//SCATTERING: PARTIAL PARTITIONS
//*****************************************************************************
//KEYS ONLY
inline void ScatterKeysOnlyDevicePartialAscending(uint gtid, uint finalPartSize)
{
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
{
if (i < finalPartSize)
WriteKey(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i, i);
}
}
inline void ScatterKeysOnlyDevicePartialDescending(uint gtid, uint finalPartSize)
{
if (e_radixShift == 24)
{
for (uint i = gtid; i < PART_SIZE; i += D_DIM)
{
if (i < finalPartSize)
WriteKey(DescendingIndex(g_d[ExtractDigit(g_d[i]) + PART_SIZE] + i), i);
}
}
else
{
ScatterKeysOnlyDevicePartialAscending(gtid, finalPartSize);
}
}
inline void ScatterKeysOnlyDevicePartial(uint gtid, uint partIndex)
{
const uint finalPartSize = e_numKeys - partIndex * PART_SIZE;
#if defined(SHOULD_ASCEND)
ScatterKeysOnlyDevicePartialAscending(gtid, finalPartSize);
#else
ScatterKeysOnlyDevicePartialDescending(gtid, finalPartSize);
#endif
}
//KEY VALUE PAIRS
inline void ScatterPairsKeyPhaseAscendingPartial(
uint gtid,
uint finalPartSize,
inout DigitStruct digits)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
if (t < finalPartSize)
{
digits.d[i] = ExtractDigit(g_d[t]);
WriteKey(g_d[digits.d[i] + PART_SIZE] + t, t);
}
}
}
inline void ScatterPairsKeyPhaseDescendingPartial(
uint gtid,
uint finalPartSize,
inout DigitStruct digits)
{
if (e_radixShift == 24)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
if (t < finalPartSize)
{
digits.d[i] = ExtractDigit(g_d[t]);
WriteKey(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
}
}
}
else
{
ScatterPairsKeyPhaseAscendingPartial(gtid, finalPartSize, digits);
}
}
inline void LoadPayloadsPartialWGE16(
uint gtid,
uint waveSize,
uint partIndex,
inout KeyStruct payloads)
{
[unroll]
for (uint i = 0, t = DeviceOffsetWGE16(gtid, waveSize, partIndex);
i < KEYS_PER_THREAD;
++i, t += waveSize)
{
if (t < e_numKeys)
LoadPayload(payloads.k[i], t);
}
}
inline void LoadPayloadsPartialWLT16(
uint gtid,
uint waveSize,
uint partIndex,
uint serialIterations,
inout KeyStruct payloads)
{
[unroll]
for (uint i = 0, t = DeviceOffsetWLT16(gtid, waveSize, partIndex, serialIterations);
i < KEYS_PER_THREAD;
++i, t += waveSize * serialIterations)
{
if (t < e_numKeys)
LoadPayload(payloads.k[i], t);
}
}
inline void ScatterPayloadsAscendingPartial(
uint gtid,
uint finalPartSize,
DigitStruct digits)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
if (t < finalPartSize)
WritePayload(g_d[digits.d[i] + PART_SIZE] + t, t);
}
}
inline void ScatterPayloadsDescendingPartial(
uint gtid,
uint finalPartSize,
DigitStruct digits)
{
if (e_radixShift == 24)
{
[unroll]
for (uint i = 0, t = gtid; i < KEYS_PER_THREAD; ++i, t += D_DIM)
{
if (t < finalPartSize)
WritePayload(DescendingIndex(g_d[digits.d[i] + PART_SIZE] + t), t);
}
}
else
{
ScatterPayloadsAscendingPartial(gtid, finalPartSize, digits);
}
}
inline void ScatterPairsDevicePartial(
uint gtid,
uint waveSize,
uint partIndex,
OffsetStruct offsets)
{
DigitStruct digits;
const uint finalPartSize = e_numKeys - partIndex * PART_SIZE;
#if defined(SHOULD_ASCEND)
ScatterPairsKeyPhaseAscendingPartial(gtid, finalPartSize, digits);
#else
ScatterPairsKeyPhaseDescendingPartial(gtid, finalPartSize, digits);
#endif
GroupMemoryBarrierWithGroupSync();
KeyStruct payloads;
if (waveSize >= 16)
LoadPayloadsPartialWGE16(gtid, waveSize, partIndex, payloads);
else
LoadPayloadsPartialWLT16(gtid, waveSize, partIndex, SerialIterations(waveSize), payloads);
ScatterPayloadsShared(offsets, payloads);
GroupMemoryBarrierWithGroupSync();
#if defined(SHOULD_ASCEND)
ScatterPayloadsAscendingPartial(gtid, finalPartSize, digits);
#else
ScatterPayloadsDescendingPartial(gtid, finalPartSize, digits);
#endif
}
inline void ScatterDevicePartial(
uint gtid,
uint waveSize,
uint partIndex,
OffsetStruct offsets)
{
#if defined(SORT_PAIRS)
ScatterPairsDevicePartial(
gtid,
waveSize,
partIndex,
offsets);
#else
ScatterKeysOnlyDevicePartial(gtid, partIndex);
#endif
}

2065
MVS/3DGS-D3D12/src/App.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,617 @@
#include "XC3DGSD3D12/GaussianPlyLoader.h"
#include <algorithm>
#include <array>
#include <cmath>
#include <cstring>
#include <fstream>
#include <limits>
#include <sstream>
#include <string_view>
#include <unordered_map>
#include <vector>
namespace XC3DGSD3D12 {
namespace {
constexpr float kSHC0 = 0.2820948f;
enum class PlyPropertyType {
None,
Float32,
Float64,
UInt8,
};
struct PlyProperty {
std::string name;
PlyPropertyType type = PlyPropertyType::None;
uint32_t offset = 0;
uint32_t size = 0;
};
struct PlyHeader {
uint32_t vertexCount = 0;
uint32_t vertexStride = 0;
std::vector<PlyProperty> properties;
};
struct Float4 {
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
float w = 0.0f;
};
struct RawGaussianSplat {
Float3 position = {};
Float3 dc0 = {};
std::array<Float3, GaussianSplatRuntimeData::kShCoefficientCount> sh = {};
float opacity = 0.0f;
Float3 scale = {};
Float4 rotation = {};
};
struct GaussianPlyPropertyLayout {
const PlyProperty* position[3] = {};
const PlyProperty* dc0[3] = {};
const PlyProperty* opacity = nullptr;
const PlyProperty* scale[3] = {};
const PlyProperty* rotation[4] = {};
std::array<const PlyProperty*, GaussianSplatRuntimeData::kShCoefficientCount * 3> sh = {};
};
std::string TrimTrailingCarriageReturn(std::string line) {
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
return line;
}
uint32_t PropertyTypeSize(PlyPropertyType type) {
switch (type) {
case PlyPropertyType::Float32:
return 4;
case PlyPropertyType::Float64:
return 8;
case PlyPropertyType::UInt8:
return 1;
default:
return 0;
}
}
bool ParsePropertyType(const std::string& token, PlyPropertyType& outType) {
if (token == "float") {
outType = PlyPropertyType::Float32;
return true;
}
if (token == "double") {
outType = PlyPropertyType::Float64;
return true;
}
if (token == "uchar") {
outType = PlyPropertyType::UInt8;
return true;
}
outType = PlyPropertyType::None;
return false;
}
bool ParsePlyHeader(std::ifstream& input, PlyHeader& outHeader, std::string& outErrorMessage) {
std::string line;
if (!std::getline(input, line)) {
outErrorMessage = "Failed to read PLY magic line.";
return false;
}
if (TrimTrailingCarriageReturn(line) != "ply") {
outErrorMessage = "Input file is not a valid PLY file.";
return false;
}
bool sawFormat = false;
std::string currentElement;
while (std::getline(input, line)) {
line = TrimTrailingCarriageReturn(line);
if (line == "end_header") {
break;
}
if (line.empty()) {
continue;
}
std::istringstream stream(line);
std::string token;
stream >> token;
if (token == "comment") {
continue;
}
if (token == "format") {
std::string formatName;
std::string version;
stream >> formatName >> version;
if (formatName != "binary_little_endian") {
outErrorMessage = "Only binary_little_endian PLY files are supported.";
return false;
}
sawFormat = true;
continue;
}
if (token == "element") {
stream >> currentElement;
if (currentElement == "vertex") {
stream >> outHeader.vertexCount;
}
continue;
}
if (token == "property" && currentElement == "vertex") {
std::string typeToken;
std::string name;
stream >> typeToken >> name;
PlyPropertyType propertyType = PlyPropertyType::None;
if (!ParsePropertyType(typeToken, propertyType)) {
outErrorMessage = "Unsupported PLY vertex property type: " + typeToken;
return false;
}
PlyProperty property;
property.name = name;
property.type = propertyType;
property.offset = outHeader.vertexStride;
property.size = PropertyTypeSize(propertyType);
outHeader.vertexStride += property.size;
outHeader.properties.push_back(property);
}
}
if (!sawFormat) {
outErrorMessage = "PLY header is missing a valid format declaration.";
return false;
}
if (outHeader.vertexCount == 0) {
outErrorMessage = "PLY file does not contain any vertex data.";
return false;
}
if (outHeader.vertexStride == 0 || outHeader.properties.empty()) {
outErrorMessage = "PLY vertex layout is empty.";
return false;
}
return true;
}
bool ReadPropertyAsFloat(
const std::byte* vertexBytes,
const PlyProperty& property,
float& outValue) {
const std::byte* propertyPtr = vertexBytes + property.offset;
switch (property.type) {
case PlyPropertyType::Float32: {
std::memcpy(&outValue, propertyPtr, sizeof(float));
return true;
}
case PlyPropertyType::Float64: {
double value = 0.0;
std::memcpy(&value, propertyPtr, sizeof(double));
outValue = static_cast<float>(value);
return true;
}
case PlyPropertyType::UInt8: {
uint8_t value = 0;
std::memcpy(&value, propertyPtr, sizeof(uint8_t));
outValue = static_cast<float>(value);
return true;
}
default:
return false;
}
}
bool BuildPropertyMap(
const PlyHeader& header,
std::unordered_map<std::string_view, const PlyProperty*>& outMap,
std::string& outErrorMessage) {
outMap.clear();
outMap.reserve(header.properties.size());
for (const PlyProperty& property : header.properties) {
const auto [it, inserted] = outMap.emplace(property.name, &property);
if (!inserted) {
outErrorMessage = "Duplicate PLY vertex property found: " + property.name;
return false;
}
}
return true;
}
bool RequireProperty(
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
std::string_view name,
const PlyProperty*& outProperty,
std::string& outErrorMessage) {
const auto iterator = propertyMap.find(name);
if (iterator == propertyMap.end()) {
outErrorMessage = "Missing required PLY property: " + std::string(name);
return false;
}
outProperty = iterator->second;
return true;
}
bool BuildGaussianPlyPropertyLayout(
const std::unordered_map<std::string_view, const PlyProperty*>& propertyMap,
GaussianPlyPropertyLayout& outLayout,
std::string& outErrorMessage) {
outLayout = {};
if (!RequireProperty(propertyMap, "x", outLayout.position[0], outErrorMessage) ||
!RequireProperty(propertyMap, "y", outLayout.position[1], outErrorMessage) ||
!RequireProperty(propertyMap, "z", outLayout.position[2], outErrorMessage) ||
!RequireProperty(propertyMap, "f_dc_0", outLayout.dc0[0], outErrorMessage) ||
!RequireProperty(propertyMap, "f_dc_1", outLayout.dc0[1], outErrorMessage) ||
!RequireProperty(propertyMap, "f_dc_2", outLayout.dc0[2], outErrorMessage) ||
!RequireProperty(propertyMap, "opacity", outLayout.opacity, outErrorMessage) ||
!RequireProperty(propertyMap, "scale_0", outLayout.scale[0], outErrorMessage) ||
!RequireProperty(propertyMap, "scale_1", outLayout.scale[1], outErrorMessage) ||
!RequireProperty(propertyMap, "scale_2", outLayout.scale[2], outErrorMessage) ||
!RequireProperty(propertyMap, "rot_0", outLayout.rotation[0], outErrorMessage) ||
!RequireProperty(propertyMap, "rot_1", outLayout.rotation[1], outErrorMessage) ||
!RequireProperty(propertyMap, "rot_2", outLayout.rotation[2], outErrorMessage) ||
!RequireProperty(propertyMap, "rot_3", outLayout.rotation[3], outErrorMessage)) {
return false;
}
for (uint32_t index = 0; index < outLayout.sh.size(); ++index) {
const std::string propertyName = "f_rest_" + std::to_string(index);
if (!RequireProperty(propertyMap, propertyName, outLayout.sh[index], outErrorMessage)) {
return false;
}
}
return true;
}
Float3 Min(const Float3& a, const Float3& b) {
return {
std::min(a.x, b.x),
std::min(a.y, b.y),
std::min(a.z, b.z),
};
}
Float3 Max(const Float3& a, const Float3& b) {
return {
std::max(a.x, b.x),
std::max(a.y, b.y),
std::max(a.z, b.z),
};
}
float Dot(const Float4& a, const Float4& b) {
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
Float4 NormalizeSwizzleRotation(const Float4& wxyz) {
const float lengthSquared = Dot(wxyz, wxyz);
if (lengthSquared <= std::numeric_limits<float>::epsilon()) {
return { 0.0f, 0.0f, 0.0f, 1.0f };
}
const float inverseLength = 1.0f / std::sqrt(lengthSquared);
return {
wxyz.y * inverseLength,
wxyz.z * inverseLength,
wxyz.w * inverseLength,
wxyz.x * inverseLength,
};
}
Float4 PackSmallest3Rotation(Float4 rotation) {
const Float4 absoluteRotation = {
std::fabs(rotation.x),
std::fabs(rotation.y),
std::fabs(rotation.z),
std::fabs(rotation.w),
};
int largestIndex = 0;
float largestValue = absoluteRotation.x;
if (absoluteRotation.y > largestValue) {
largestIndex = 1;
largestValue = absoluteRotation.y;
}
if (absoluteRotation.z > largestValue) {
largestIndex = 2;
largestValue = absoluteRotation.z;
}
if (absoluteRotation.w > largestValue) {
largestIndex = 3;
largestValue = absoluteRotation.w;
}
if (largestIndex == 0) {
rotation = { rotation.y, rotation.z, rotation.w, rotation.x };
} else if (largestIndex == 1) {
rotation = { rotation.x, rotation.z, rotation.w, rotation.y };
} else if (largestIndex == 2) {
rotation = { rotation.x, rotation.y, rotation.w, rotation.z };
}
const float sign = rotation.w >= 0.0f ? 1.0f : -1.0f;
const float invSqrt2 = std::sqrt(2.0f) * 0.5f;
const Float3 encoded = {
(rotation.x * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
(rotation.y * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
(rotation.z * sign * std::sqrt(2.0f)) * 0.5f + 0.5f,
};
(void)invSqrt2;
return { encoded.x, encoded.y, encoded.z, static_cast<float>(largestIndex) / 3.0f };
}
uint32_t EncodeQuatToNorm10(const Float4& packedRotation) {
const auto saturate = [](float value) {
return std::clamp(value, 0.0f, 1.0f);
};
const uint32_t x = static_cast<uint32_t>(saturate(packedRotation.x) * 1023.5f);
const uint32_t y = static_cast<uint32_t>(saturate(packedRotation.y) * 1023.5f);
const uint32_t z = static_cast<uint32_t>(saturate(packedRotation.z) * 1023.5f);
const uint32_t w = static_cast<uint32_t>(saturate(packedRotation.w) * 3.5f);
return x | (y << 10) | (z << 20) | (w << 30);
}
Float3 LinearScale(const Float3& logarithmicScale) {
return {
std::fabs(std::exp(logarithmicScale.x)),
std::fabs(std::exp(logarithmicScale.y)),
std::fabs(std::exp(logarithmicScale.z)),
};
}
Float3 SH0ToColor(const Float3& dc0) {
return {
dc0.x * kSHC0 + 0.5f,
dc0.y * kSHC0 + 0.5f,
dc0.z * kSHC0 + 0.5f,
};
}
float Sigmoid(float value) {
return 1.0f / (1.0f + std::exp(-value));
}
std::array<uint32_t, 2> DecodeMorton2D16x16(uint32_t value) {
value = (value & 0xFFu) | ((value & 0xFEu) << 7u);
value &= 0x5555u;
value = (value ^ (value >> 1u)) & 0x3333u;
value = (value ^ (value >> 2u)) & 0x0F0Fu;
return { value & 0xFu, value >> 8u };
}
uint32_t SplatIndexToTextureIndex(uint32_t index) {
const std::array<uint32_t, 2> morton = DecodeMorton2D16x16(index);
const uint32_t widthInBlocks = GaussianSplatRuntimeData::kColorTextureWidth / 16u;
index >>= 8u;
const uint32_t x = (index % widthInBlocks) * 16u + morton[0];
const uint32_t y = (index / widthInBlocks) * 16u + morton[1];
return y * GaussianSplatRuntimeData::kColorTextureWidth + x;
}
template <typename T>
void WriteValue(std::vector<std::byte>& bytes, size_t offset, const T& value) {
std::memcpy(bytes.data() + offset, &value, sizeof(T));
}
void WriteFloat3(std::vector<std::byte>& bytes, size_t offset, const Float3& value) {
WriteValue(bytes, offset + 0, value.x);
WriteValue(bytes, offset + 4, value.y);
WriteValue(bytes, offset + 8, value.z);
}
void WriteFloat4(std::vector<std::byte>& bytes, size_t offset, float x, float y, float z, float w) {
WriteValue(bytes, offset + 0, x);
WriteValue(bytes, offset + 4, y);
WriteValue(bytes, offset + 8, z);
WriteValue(bytes, offset + 12, w);
}
bool ReadGaussianSplat(
const std::byte* vertexBytes,
const GaussianPlyPropertyLayout& propertyLayout,
RawGaussianSplat& outSplat,
std::string& outErrorMessage) {
auto readFloat = [&](const PlyProperty* property, float& outValue) -> bool {
if (property == nullptr) {
outErrorMessage = "Gaussian PLY property layout is incomplete.";
return false;
}
return ReadPropertyAsFloat(vertexBytes, *property, outValue);
};
if (!readFloat(propertyLayout.position[0], outSplat.position.x) ||
!readFloat(propertyLayout.position[1], outSplat.position.y) ||
!readFloat(propertyLayout.position[2], outSplat.position.z) ||
!readFloat(propertyLayout.dc0[0], outSplat.dc0.x) ||
!readFloat(propertyLayout.dc0[1], outSplat.dc0.y) ||
!readFloat(propertyLayout.dc0[2], outSplat.dc0.z) ||
!readFloat(propertyLayout.opacity, outSplat.opacity) ||
!readFloat(propertyLayout.scale[0], outSplat.scale.x) ||
!readFloat(propertyLayout.scale[1], outSplat.scale.y) ||
!readFloat(propertyLayout.scale[2], outSplat.scale.z) ||
!readFloat(propertyLayout.rotation[0], outSplat.rotation.x) ||
!readFloat(propertyLayout.rotation[1], outSplat.rotation.y) ||
!readFloat(propertyLayout.rotation[2], outSplat.rotation.z) ||
!readFloat(propertyLayout.rotation[3], outSplat.rotation.w)) {
if (outErrorMessage.empty()) {
outErrorMessage = "Failed to read required Gaussian splat PLY properties.";
}
return false;
}
std::array<float, GaussianSplatRuntimeData::kShCoefficientCount * 3> shRaw = {};
for (uint32_t index = 0; index < shRaw.size(); ++index) {
if (!readFloat(propertyLayout.sh[index], shRaw[index])) {
if (outErrorMessage.empty()) {
outErrorMessage = "Failed to read SH rest coefficients from PLY.";
}
return false;
}
}
for (uint32_t coefficientIndex = 0; coefficientIndex < GaussianSplatRuntimeData::kShCoefficientCount; ++coefficientIndex) {
outSplat.sh[coefficientIndex] = {
shRaw[coefficientIndex + 0],
shRaw[coefficientIndex + GaussianSplatRuntimeData::kShCoefficientCount],
shRaw[coefficientIndex + GaussianSplatRuntimeData::kShCoefficientCount * 2],
};
}
return true;
}
void LinearizeGaussianSplat(RawGaussianSplat& splat) {
const Float4 normalizedQuaternion = NormalizeSwizzleRotation(splat.rotation);
const Float4 packedQuaternion = PackSmallest3Rotation(normalizedQuaternion);
splat.rotation = packedQuaternion;
splat.scale = LinearScale(splat.scale);
splat.dc0 = SH0ToColor(splat.dc0);
splat.opacity = Sigmoid(splat.opacity);
}
} // namespace
bool LoadGaussianSceneFromPly(
const std::filesystem::path& filePath,
GaussianSplatRuntimeData& outData,
std::string& outErrorMessage) {
outData = {};
outErrorMessage.clear();
std::ifstream input(filePath, std::ios::binary);
if (!input.is_open()) {
outErrorMessage = "Failed to open PLY file: " + filePath.string();
return false;
}
PlyHeader header;
if (!ParsePlyHeader(input, header, outErrorMessage)) {
return false;
}
std::unordered_map<std::string_view, const PlyProperty*> propertyMap;
if (!BuildPropertyMap(header, propertyMap, outErrorMessage)) {
return false;
}
GaussianPlyPropertyLayout propertyLayout;
if (!BuildGaussianPlyPropertyLayout(propertyMap, propertyLayout, outErrorMessage)) {
return false;
}
outData.splatCount = header.vertexCount;
outData.colorTextureWidth = GaussianSplatRuntimeData::kColorTextureWidth;
outData.colorTextureHeight =
std::max<uint32_t>(1u, (header.vertexCount + outData.colorTextureWidth - 1u) / outData.colorTextureWidth);
outData.colorTextureHeight = (outData.colorTextureHeight + 15u) / 16u * 16u;
outData.positionData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kPositionStride);
outData.otherData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kOtherStride);
outData.colorData.resize(
static_cast<size_t>(outData.colorTextureWidth) *
static_cast<size_t>(outData.colorTextureHeight) *
GaussianSplatRuntimeData::kColorStride);
outData.shData.resize(static_cast<size_t>(header.vertexCount) * GaussianSplatRuntimeData::kShStride);
outData.boundsMin = {
std::numeric_limits<float>::infinity(),
std::numeric_limits<float>::infinity(),
std::numeric_limits<float>::infinity(),
};
outData.boundsMax = {
-std::numeric_limits<float>::infinity(),
-std::numeric_limits<float>::infinity(),
-std::numeric_limits<float>::infinity(),
};
std::vector<std::byte> vertexBytes(header.vertexStride);
for (uint32_t splatIndex = 0; splatIndex < header.vertexCount; ++splatIndex) {
input.read(reinterpret_cast<char*>(vertexBytes.data()), static_cast<std::streamsize>(vertexBytes.size()));
if (input.gcount() != static_cast<std::streamsize>(vertexBytes.size())) {
outErrorMessage =
"Unexpected end of file while reading Gaussian splat vertex " + std::to_string(splatIndex) + ".";
return false;
}
RawGaussianSplat splat;
if (!ReadGaussianSplat(vertexBytes.data(), propertyLayout, splat, outErrorMessage)) {
return false;
}
LinearizeGaussianSplat(splat);
outData.boundsMin = Min(outData.boundsMin, splat.position);
outData.boundsMax = Max(outData.boundsMax, splat.position);
const size_t positionOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kPositionStride;
WriteFloat3(outData.positionData, positionOffset, splat.position);
const size_t otherOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kOtherStride;
const uint32_t packedRotation = EncodeQuatToNorm10(splat.rotation);
WriteValue(outData.otherData, otherOffset, packedRotation);
WriteFloat3(outData.otherData, otherOffset + sizeof(uint32_t), splat.scale);
const size_t shOffset = static_cast<size_t>(splatIndex) * GaussianSplatRuntimeData::kShStride;
for (uint32_t coefficientIndex = 0; coefficientIndex < GaussianSplatRuntimeData::kShCoefficientCount; ++coefficientIndex) {
const size_t coefficientOffset = shOffset + static_cast<size_t>(coefficientIndex) * sizeof(float) * 3u;
WriteFloat3(outData.shData, coefficientOffset, splat.sh[coefficientIndex]);
}
const uint32_t textureIndex = SplatIndexToTextureIndex(splatIndex);
const size_t colorOffset = static_cast<size_t>(textureIndex) * GaussianSplatRuntimeData::kColorStride;
WriteFloat4(outData.colorData, colorOffset, splat.dc0.x, splat.dc0.y, splat.dc0.z, splat.opacity);
}
return true;
}
bool WriteGaussianSceneSummary(
const std::filesystem::path& filePath,
const GaussianSplatRuntimeData& data,
std::string& outErrorMessage) {
outErrorMessage.clear();
std::ofstream output(filePath, std::ios::binary | std::ios::trunc);
if (!output.is_open()) {
outErrorMessage = "Failed to open summary output file: " + filePath.string();
return false;
}
output << "splat_count=" << data.splatCount << '\n';
output << "color_texture_width=" << data.colorTextureWidth << '\n';
output << "color_texture_height=" << data.colorTextureHeight << '\n';
output << "bounds_min=" << data.boundsMin.x << "," << data.boundsMin.y << "," << data.boundsMin.z << '\n';
output << "bounds_max=" << data.boundsMax.x << "," << data.boundsMax.y << "," << data.boundsMax.z << '\n';
output << "position_bytes=" << data.positionData.size() << '\n';
output << "other_bytes=" << data.otherData.size() << '\n';
output << "color_bytes=" << data.colorData.size() << '\n';
output << "sh_bytes=" << data.shData.size() << '\n';
return output.good();
}
} // namespace XC3DGSD3D12

View File

@@ -0,0 +1,42 @@
#include <windows.h>
#include <shellapi.h>
#include <string>
#include "XC3DGSD3D12/App.h"
int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int showCommand) {
XC3DGSD3D12::App app;
int argumentCount = 0;
LPWSTR* arguments = CommandLineToArgvW(GetCommandLineW(), &argumentCount);
for (int index = 1; index + 1 < argumentCount; ++index) {
if (std::wstring(arguments[index]) == L"--frame-limit") {
app.SetFrameLimit(static_cast<unsigned int>(_wtoi(arguments[index + 1])));
++index;
} else if (std::wstring(arguments[index]) == L"--scene") {
app.SetGaussianScenePath(arguments[index + 1]);
++index;
} else if (std::wstring(arguments[index]) == L"--summary-file") {
app.SetSummaryPath(arguments[index + 1]);
++index;
} else if (std::wstring(arguments[index]) == L"--screenshot-file") {
app.SetScreenshotPath(arguments[index + 1]);
++index;
}
}
if (arguments != nullptr) {
LocalFree(arguments);
}
if (!app.Initialize(instance, showCommand)) {
const std::wstring message =
app.GetLastErrorMessage().empty()
? L"Failed to initialize XC 3DGS D3D12 MVS."
: app.GetLastErrorMessage();
MessageBoxW(nullptr, message.c_str(), L"Initialization Error", MB_OK | MB_ICONERROR);
return -1;
}
return app.Run();
}

72
MVS/NahidaRender/.gitignore vendored Normal file
View File

@@ -0,0 +1,72 @@
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/
# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/
# Recordings can get excessive in size
/[Rr]ecordings/
# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*
# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*
# Visual Studio cache directory
.vs/
# Gradle cache directory
.gradle/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta
# Unity3D generated file on crash reports
sysinfo.txt
# Builds
*.apk
*.aab
*.unitypackage
*.app
# Crashlytics generated file
crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*

View File

@@ -0,0 +1,6 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Workload.ManagedGame"
]
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 68bbc4cba3b6dbb4b86a7c53808f8638
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8979e00a9c434454885c4bf6711f1589
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9302fe3896889a84782905c6238755b4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 395a4648ad8e29949875f724cef51c19
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 6eb560da14e928447b90b7dcd5c26c80
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ebd426cddc3f2bb45a717a91e44a04a8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: 3ea5c91be5b2cbf41af5e76906541a28
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: e093901fe428bd143b564aa1c3332d7d
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: 364af43ac586d65439fa133e843e2832
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -0,0 +1,140 @@
fileFormatVersion: 2
guid: 5d192aff5bc6121438505d1f9989df41
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,129 @@
fileFormatVersion: 2
guid: d3fd0a1dc342d4b4fab8ef4b8d009052
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects:
- first:
type: UnityEngine:Texture2D
assembly: UnityEngine.CoreModule
name: Ellen_Body_Map1_D
second: {fileID: 2800000, guid: 3532f977100283548867748b15658232, type: 3}
- first:
type: UnityEngine:Texture2D
assembly: UnityEngine.CoreModule
name: Ellen_Body_Map2_D
second: {fileID: 2800000, guid: e382c6705a3468e4ca57a8d16897ab19, type: 3}
- first:
type: UnityEngine:Texture2D
assembly: UnityEngine.CoreModule
name: Ellen_Face_D
second: {fileID: 2800000, guid: 7c3ba8d23a564894984da6d374ca3731, type: 3}
- first:
type: UnityEngine:Texture2D
assembly: UnityEngine.CoreModule
name: Ellen_Weapon_D
second: {fileID: 2800000, guid: 6881926d8786b304a8bf06ae1afa9bef, type: 3}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 3
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 1
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 3
humanoidOversampling: 1
avatarSetup: 1
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1107 &-1397466275883854417
AnimatorStateMachine:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Base Layer
m_ChildStates:
- serializedVersion: 1
m_State: {fileID: 5128555461953376154}
m_Position: {x: 308, y: 155.20001, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 5128555461953376154}
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ellen
serializedVersion: 5
m_AnimatorParameters: []
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
m_StateMachine: {fileID: -1397466275883854417}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
m_DefaultWeight: 0
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: 9100000}
--- !u!1101 &792017938168458971
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 5128555461953376154}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.93775934
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &5128555461953376154
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Take 001
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: 792017938168458971}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: 1827226128182048838, guid: d3fd0a1dc342d4b4fab8ef4b8d009052,
type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1033ab15ae22d2244849dc2d4303382f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0c1a2b98a2475f14788ef684b83f22fb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ellen_Body_Map1_D
m_Shader: {fileID: -6465566751694194690, guid: 44245ab89240f51459a5077d7145c452,
type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BASE_COLOR_MAP:
m_Texture: {fileID: 2800000, guid: 3ea5c91be5b2cbf41af5e76906541a28, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BUMP_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EMISSION_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _METALNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_IOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_ROUGHNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TRANSPARENCY_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _BASE_COLOR_WEIGHT: 1
- _BUMP_MAP_STRENGTH: 0.3
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EMISSION_WEIGHT: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _METALNESS: 0
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueControl: 0
- _QueueOffset: 0
- _REFLECTIONS_IOR: 1.52
- _REFLECTIONS_ROUGHNESS: 0
- _REFLECTIONS_WEIGHT: 1
- _ReceiveShadows: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _TRANSPARENCY: 0
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BASE_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EMISSION_COLOR: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _REFLECTIONS_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &5074316965000976425
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8fb8894d655641346b205dc67b07366a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-6965004337211005254
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ellen_Body_Map2_D
m_Shader: {fileID: -6465566751694194690, guid: 44245ab89240f51459a5077d7145c452,
type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BASE_COLOR_MAP:
m_Texture: {fileID: 2800000, guid: e093901fe428bd143b564aa1c3332d7d, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BUMP_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EMISSION_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _METALNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_IOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_ROUGHNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TRANSPARENCY_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _BASE_COLOR_WEIGHT: 1
- _BUMP_MAP_STRENGTH: 0.3
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EMISSION_WEIGHT: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _METALNESS: 0
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueControl: 0
- _QueueOffset: 0
- _REFLECTIONS_IOR: 1.52
- _REFLECTIONS_ROUGHNESS: 0
- _REFLECTIONS_WEIGHT: 1
- _ReceiveShadows: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _TRANSPARENCY: 0
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BASE_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EMISSION_COLOR: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _REFLECTIONS_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d58ddc93721772c43a133b364f387d12
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-7105605433481396130
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ellen_Face_D
m_Shader: {fileID: -6465566751694194690, guid: 44245ab89240f51459a5077d7145c452,
type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BASE_COLOR_MAP:
m_Texture: {fileID: 2800000, guid: 364af43ac586d65439fa133e843e2832, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BUMP_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EMISSION_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _METALNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_IOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_ROUGHNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TRANSPARENCY_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _BASE_COLOR_WEIGHT: 1
- _BUMP_MAP_STRENGTH: 0.3
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EMISSION_WEIGHT: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _METALNESS: 0
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueControl: 0
- _QueueOffset: 0
- _REFLECTIONS_IOR: 1.52
- _REFLECTIONS_ROUGHNESS: 0
- _REFLECTIONS_WEIGHT: 1
- _ReceiveShadows: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _TRANSPARENCY: 0
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BASE_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EMISSION_COLOR: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _REFLECTIONS_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0aeabd15ad371ad4484e3399a9de63b2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-193573160482100292
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Ellen_Weapon_D
m_Shader: {fileID: -6465566751694194690, guid: 44245ab89240f51459a5077d7145c452,
type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords:
- _EMISSION
m_LightmapFlags: 2
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BASE_COLOR_MAP:
m_Texture: {fileID: 2800000, guid: 5d192aff5bc6121438505d1f9989df41, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BUMP_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EMISSION_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _METALNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_COLOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_IOR_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _REFLECTIONS_ROUGHNESS_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TRANSPARENCY_MAP:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _BASE_COLOR_WEIGHT: 1
- _BUMP_MAP_STRENGTH: 0.3
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EMISSION_WEIGHT: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _METALNESS: 0
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueControl: 0
- _QueueOffset: 0
- _REFLECTIONS_IOR: 1.52
- _REFLECTIONS_ROUGHNESS: 0
- _REFLECTIONS_WEIGHT: 1
- _ReceiveShadows: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _TRANSPARENCY: 0
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BASE_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EMISSION_COLOR: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _REFLECTIONS_COLOR: {r: 1, g: 1, b: 1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2f23de5ccc06a124195001de1ffc4c2c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,187 @@
Shader "Genshin"
{
Properties
{
[Header(General)]
[MainTexture]_BaseMap("Base Map", 2D) = "white" {}
[MainColor] _BaseColor("Base Color", Color) = (1,1,1,1)
[ToggleUI] _IsDay("Is Day", Float) = 1
[Toggle(_DOUBLE_SIDED)] _DoubleSided("Double Sided", Float) = 0
[Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 2
[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend", Float) = 1
[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend", Float) = 0
[Header(Shadow)]
_LightMap("Light Map", 2D) = "white" {}
_LightDirectionMultiplier("Light Direction Multiplier", Vector) = (1,1,1,0)
_ShadowOffset("Shadow Offset", Float) = 0
_ShadowSmoothness("Shadow Smoothness", Float) = 0
[HDR] _ShadowColor("Shadow Color", Color) = (1,1,1,1)
_ShadowRamp("Shadow Ramp", 2D) = "white" {}
[ToggleUI] _UseCustomMaterialType("Use Custom Material Type", Float) = 0
_CustomMaterialType("Custom Material Type", Float) = 1
[Header(Emission)]
[Toggle(_EMISSION)] _UseEmission("Use Emission", Float) = 0
_EmissionIntensity("Emission Intensity", Float) = 1
[Header(Normal)]
[Toggle(_NORMAL_MAP)] _UseNormalMap("Use Normal Map", Float) = 0
[Normal] _NormalMap("Normal Map", 2D) = "bump" {}
[Header(Face)]
[Toggle(_IS_FACE)] _IsFace("Is Face", Float) = 0
_FaceDirection("Face Direction", Vector) = (0,0,1,0)
_FaceShadowOffset("Face Shadow Offset", Float) = 0
_FaceBlushColor("Face Blush Color", Color) = (1,1,1,1)
_FaceBlushStrength("Face Blush Strength", Float) = 1
_FaceLightMap("Face Light Map", 2D) = "white" {}
_FaceShadow("Face Shadow", 2D) = "white" {}
[Header(Specular)]
[Toggle(_SPECULAR)] _UseSpecular("Use Specular", Float) = 0
_SpecularSmoothness("Specular Smoothness", Float) = 1
_NonmetallicIntensity("Nonmetallic Intensity", Float) = 1
_MetallicIntensity("Metallic Intensity", Float) = 1
_MetalMap("Metal Map", 2D) = "white" {}
[Header(Rim Light)]
[Toggle(_RIM)] _UseRim("Use Rim", Float) = 0
_RimOffset("Rim Offset", Float) = 1
_RimThreshold("Rim Threshold", Float) = 1
_RimIntensity("Rim Intensity", Float) = 1
[Header(Outline)]
[ToggleUI] _UseSmoothNormal("Use Smooth Normal", Float) = 0
_OutlineWidth("Outline Width", Float) = 1
_OutlineWidthParams("Outline Width Params", Vector) = (0,1,0,1)
_OutlineZOffset("Outline Z Offset", Float) = 0
_ScreenOffset("Screen Offset", Vector) = (0,0,0,0)
_OutlineColor("Outline Color", Color) = (0,0,0,1)
_OutlineColor2("Outline Color 2", Color) = (0,0,0,1)
_OutlineColor3("Outline Color 3", Color) = (0,0,0,1)
_OutlineColor4("Outline Color 4", Color) = (0,0,0,1)
_OutlineColor5("Outline Color 5", Color) = (0,0,0,1)
}
Subshader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
"UniversalMaterialType" = "Lit"
"IgnoreProjector" = "True"
}
Pass
{
Name "Forward"
Tags {"LightMode" = "UniversalForward"}
Cull[_Cull]
ZWrite On
Blend[_SrcBlend][_DstBlend]
HLSLPROGRAM
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
#pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
#pragma multi_compile_fragment _ _LIGHT_LAYERS
#pragma multi_compile_fragment _ _LIGHT_COOKIES
#pragma multi_compile _ _FORWARD_PLUS
#pragma multi_compile_fragment _ _WRITE_RENDERING_LAYERS
// Unity defined keywords
#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
#pragma multi_compile _ SHADOWS_SHADOWMASK
#pragma multi_compile _ DIRLIGHTMAP_COMBINED
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ DYNAMICLIGHTMAP_ON
#pragma multi_compile_fragment _ LOD_FADE_CROSSFADE
#pragma multi_compile_fog
#pragma multi_compile_fragment _ DEBUG_DISPLAY
#pragma shader_feature_local_fragment _DOUBLE_SIDED
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _NORMAL_MAP
#pragma shader_feature_local_fragment _IS_FACE
#pragma shader_feature_local_fragment _SPECULAR
#pragma shader_feature_local_fragment _RIM
#pragma vertex ForwardPassVertex
#pragma fragment ForwardPassFragment
#include "GenshinInput.hlsl"
#include "GenshinForwardPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags{"LightMode" = "ShadowCaster"}
ZWrite On
ZTest LEqual
ColorMask 0
Cull[_Cull]
HLSLPROGRAM
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask R
Cull[_Cull]
HLSLPROGRAM
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
Pass
{
Name "Outline"
Tags {"LightMode" = "SRPDefaultUnlit"}
Cull Front
HLSLPROGRAM
#pragma vertex OutlinePassVertex
#pragma fragment OutlinePassFragment
#include "GenshinInput.hlsl"
#include "GenshinOutlinePass.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 43a94ff316d044749abc5a8bce3d6902
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,183 @@
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float2 backUV : TEXCOORD1;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float2 backUV : TEXCOORD1;
float3 positionWS : TEXCOORD2;
half3 tangentWS : TEXCOORD3;
half3 bitangentWS : TEXCOORD4;
half3 normalWS : TEXCOORD5;
float4 positionNDC : TEXCOORD6;
half4 color : COLOR;
float4 positionCS : SV_POSITION;
};
half GetShadow(Varyings input, half3 lightDirection, half aoFactor)
{
half NDotL = dot(input.normalWS, lightDirection);
half halfLambert = 0.5 * NDotL + 0.5;
half shadow = saturate(2.0 * halfLambert * aoFactor);
return lerp(shadow, 1.0, step(0.9, aoFactor));
}
half GetFaceShadow(Varyings input, half3 lightDirection)
{
half3 F = SafeNormalize(half3(_FaceDirection.x, 0.0, _FaceDirection.z));
half3 L = SafeNormalize(half3(lightDirection.x, 0.0, lightDirection.z));
half FDotL = dot(F, L);
half FCrossL = cross(F, L).y;
half2 shadowUV = input.uv;
shadowUV.x = lerp(shadowUV.x, 1.0 - shadowUV.x, step(0.0, FCrossL));
half faceShadowMap = SAMPLE_TEXTURE2D(_FaceLightMap, sampler_FaceLightMap, shadowUV).r;
half faceShadow = step(-0.5 * FDotL + 0.5 + _FaceShadowOffset, faceShadowMap);
half faceMask = SAMPLE_TEXTURE2D(_FaceShadow, sampler_FaceShadow, input.uv).a;
half maskedFaceShadow = lerp(faceShadow, 1.0, faceMask);
return maskedFaceShadow;
}
half3 GetShadowColor(half shadow, half material, half day)
{
int index = 4;
index = lerp(index, 1, step(0.2, material));
index = lerp(index, 2, step(0.4, material));
index = lerp(index, 0, step(0.6, material));
index = lerp(index, 3, step(0.8, material));
half rangeMin = 0.5 + _ShadowOffset - _ShadowSmoothness;
half rangeMax = 0.5 + _ShadowOffset;
half2 rampUV = half2(smoothstep(rangeMin, rangeMax, shadow), index / 10.0 + 0.5 * day + 0.05);
half3 shadowRamp = SAMPLE_TEXTURE2D(_ShadowRamp, sampler_ShadowRamp, rampUV);
half3 shadowColor = shadowRamp * lerp(_ShadowColor, 1.0, smoothstep(0.9, 1.0, rampUV.x));
shadowColor = lerp(shadowColor, 1.0, step(rangeMax, shadow));
return shadowColor;
}
half3 GetSpecular(Varyings input, half3 lightDirection, half3 albedo, half3 lightMap)
{
half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
half3 H = SafeNormalize(lightDirection + V);
half NDotH = dot(input.normalWS, H);
half blinnPhong = pow(saturate(NDotH), _SpecularSmoothness);
half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);
half2 matcapUV = 0.5 * normalVS.xy + 0.5;
half3 metalMap = SAMPLE_TEXTURE2D(_MetalMap, sampler_MetalMap, matcapUV);
half3 nonMetallic = step(1.1, lightMap.b + blinnPhong) * lightMap.r * _NonmetallicIntensity;
half3 metallic = blinnPhong * lightMap.b * albedo * metalMap * _MetallicIntensity;
half3 specular = lerp(nonMetallic, metallic, step(0.9, lightMap.r));
return specular;
}
half GetRim(Varyings input)
{
half3 normalVS = TransformWorldToViewNormal(input.normalWS, true);
float2 uv = input.positionNDC.xy / input.positionNDC.w;
float2 offset = float2(_RimOffset * normalVS.x / _ScreenParams.x, 0.0);
float depth = LinearEyeDepth(SampleSceneDepth(uv), _ZBufferParams);
float offsetDepth = LinearEyeDepth(SampleSceneDepth(uv + offset), _ZBufferParams);
half rim = smoothstep(0.0, _RimThreshold, offsetDepth - depth) * _RimIntensity;
half3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
half NDotV = dot(input.normalWS, V);
half fresnel = pow(saturate(1.0 - NDotV), 5.0);
return rim * fresnel;
}
Varyings ForwardPassVertex(Attributes input)
{
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
Varyings output = (Varyings)0;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.backUV = TRANSFORM_TEX(input.backUV, _BaseMap);
output.positionWS = vertexInput.positionWS;
output.tangentWS = normalInput.tangentWS;
output.bitangentWS = normalInput.bitangentWS;
output.normalWS = normalInput.normalWS;
output.positionNDC = vertexInput.positionNDC;
output.color = input.color;
output.positionCS = vertexInput.positionCS;
output.positionCS.xy += _ScreenOffset.xy * output.positionCS.w;
return output;
}
half4 ForwardPassFragment(Varyings input, FRONT_FACE_TYPE facing : FRONT_FACE_SEMANTIC) : SV_TARGET
{
#if _DOUBLE_SIDED
input.uv = lerp(input.uv, input.backUV, IS_FRONT_VFACE(facing, 0.0, 1.0));
#endif
half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
half3 albedo = baseMap.rgb * _BaseColor.rgb;
half alpha = baseMap.a;
#if _IS_FACE
albedo = lerp(albedo, _FaceBlushColor.rgb, _FaceBlushStrength * alpha);
#endif
#if _NORMAL_MAP
half3x3 tangentToWorld = half3x3(input.tangentWS, input.bitangentWS, input.normalWS);
half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.uv);
half3 normalTS = UnpackNormal(normalMap);
half3 normalWS = TransformTangentToWorld(normalTS, tangentToWorld, true);
input.normalWS = normalWS;
#endif
Light mainLight = GetMainLight();
half3 lightDirection = SafeNormalize(mainLight.direction * _LightDirectionMultiplier);
half4 lightMap = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.uv);
half material = lerp(lightMap.a, _CustomMaterialType, _UseCustomMaterialType);
#if _IS_FACE
half shadow = GetFaceShadow(input, lightDirection);
#else
half aoFactor = lightMap.g * input.color.r;
half shadow = GetShadow(input, lightDirection, aoFactor);
#endif
half3 shadowColor = GetShadowColor(shadow, material, _IsDay);
half3 specular = 0.0;
#if _SPECULAR
specular = GetSpecular(input, lightDirection, albedo, lightMap.rgb);
#endif
half3 emission = 0.0;
#if _EMISSION
emission = albedo * _EmissionIntensity * alpha;
#endif
half3 rim = 0.0;
#if _RIM
rim = albedo * GetRim(input);
#endif
half3 finalColor = albedo * shadowColor + specular + emission + rim;
half finalAlpha = 1.0;
return half4(finalColor, finalAlpha);
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2aea4fee83e5bb145874b2f3bd9bbbbe
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
half _IsDay;
half _Cull;
half _SrcBlend;
half _DstBlend;
half4 _LightDirectionMultiplier;
half _ShadowOffset;
half _ShadowSmoothness;
half4 _ShadowColor;
half _UseCustomMaterialType;
half _CustomMaterialType;
half _EmissionIntensity;
half4 _FaceDirection;
half _FaceShadowOffset;
half4 _FaceBlushColor;
half _FaceBlushStrength;
half _SpecularSmoothness;
half _NonmetallicIntensity;
half _MetallicIntensity;
half _RimOffset;
half _RimThreshold;
half _RimIntensity;
half _UseSmoothNormal;
half _OutlineWidth;
half4 _OutlineWidthParams;
half _OutlineZOffset;
half4 _ScreenOffset;
half4 _OutlineColor;
half4 _OutlineColor2;
half4 _OutlineColor3;
half4 _OutlineColor4;
half4 _OutlineColor5;
CBUFFER_END
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
TEXTURE2D(_LightMap); SAMPLER(sampler_LightMap);
TEXTURE2D(_ShadowRamp); SAMPLER(sampler_ShadowRamp);
TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
TEXTURE2D(_FaceLightMap); SAMPLER(sampler_FaceLightMap);
TEXTURE2D(_FaceShadow); SAMPLER(sampler_FaceShadow);
TEXTURE2D(_MetalMap); SAMPLER(sampler_MetalMap);

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7cc59e5485498594da26921b972bff29
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float4 tangentOS : TANGENT;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float3 smoothNormal : TEXCOORD7;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
};
float GetOutlineWidth(float positionVS_Z)
{
float fovFactor = 2.414 / UNITY_MATRIX_P[1].y;
float z = abs(positionVS_Z * fovFactor);
float4 params = _OutlineWidthParams;
float k = saturate((z - params.x) / (params.y - params.x));
float width = lerp(params.z, params.w, k);
return 0.01 * _OutlineWidth * width;
}
float4 GetOutlinePosition(VertexPositionInputs vertexInput, VertexNormalInputs normalInput, half4 vertexColor)
{
float z = vertexInput.positionVS.z;
float width = GetOutlineWidth(z) * vertexColor.a;
half3 normalVS = TransformWorldToViewNormal(normalInput.normalWS);
normalVS = SafeNormalize(half3(normalVS.xy, 0.0));
float3 positionVS = vertexInput.positionVS;
positionVS += 0.01 * _OutlineZOffset * SafeNormalize(positionVS);
positionVS += width * normalVS;
float4 positionCS = TransformWViewToHClip(positionVS);
positionCS.xy += _ScreenOffset.zw * positionCS.w;
return positionCS;
}
Varyings OutlinePassVertex(Attributes input)
{
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
half3x3 tangentToWorld = half3x3(normalInput.tangentWS, normalInput.bitangentWS, normalInput.normalWS);
half3 normalTS = 2.0 * (input.smoothNormal - 0.5);
half3 normalWS = TransformTangentToWorld(normalTS, tangentToWorld, true);
normalInput.normalWS = lerp(normalInput.normalWS, normalWS, _UseSmoothNormal);
float4 positionCS = GetOutlinePosition(vertexInput, normalInput, input.color);
Varyings output = (Varyings)0;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.positionCS = positionCS;
return output;
}
half4 OutlinePassFragment(Varyings input) : SV_TARGET
{
half4 lightMap = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.uv);
half material = lightMap.a;
half4 color = _OutlineColor5;
color = lerp(color, _OutlineColor4, step(0.2, material));
color = lerp(color, _OutlineColor3, step(0.4, material));
color = lerp(color, _OutlineColor2, step(0.6, material));
color = lerp(color, _OutlineColor, step(0.8, material));
return color;
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 813f7698d2376604ca6a0be4a32948e8
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,190 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Base
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceLightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceShadow:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetalMap:
m_Texture: {fileID: 2800000, guid: d7d1337cec6422b4f9db7325b520d61f, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _CustomMaterialType: 1
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DoubleSided: 0
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EmissionIntensity: 0.2
- _EnvironmentReflections: 1
- _FaceBlushStrength: 0
- _FaceShadowOffset: 0
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _IsDay: 1
- _IsFace: 0
- _Metallic: 0
- _MetallicIntensity: 8
- _NonmetallicIntensity: 0.3
- _OcclusionStrength: 1
- _OutlineWidth: 1.6
- _OutlineZOffset: 0.1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _RimIntensity: 0.5
- _RimOffset: 5
- _RimThreshold: 0.5
- _ShadowOffset: 0.1
- _ShadowSmoothness: 0.4
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SpecularSmoothness: 5
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _UseCustomMaterialType: 0
- _UseEmission: 0
- _UseNormalMap: 0
- _UseRim: 0
- _UseSmoothNormal: 0
- _UseSpecular: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _FaceBlushColor: {r: 1, g: 0.72156864, b: 0.69803923, a: 1}
- _FaceDirection: {r: 0, g: 0, b: 1, a: 0}
- _LightDirectionMultiplier: {r: 1, g: 0.5, b: 1, a: 0}
- _OutlineColor: {r: 0.5176471, g: 0.35686275, b: 0.34117648, a: 1}
- _OutlineColor2: {r: 0.3529412, g: 0.3529412, b: 0.3529412, a: 1}
- _OutlineColor3: {r: 0.47058824, g: 0.47058824, b: 0.5647059, a: 1}
- _OutlineColor4: {r: 0.5176471, g: 0.35686275, b: 0.34117648, a: 1}
- _OutlineColor5: {r: 0.35, g: 0.35, b: 0.35, a: 1}
- _OutlineWidthParams: {r: 0, g: 6, b: 0.1, a: 0.6}
- _ScreenOffset: {r: 0, g: 0, b: 0, a: 0}
- _ShadowColor: {r: 1.1, g: 1.1, b: 1.1, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 30ad25ccfe2f70b4e8544dc4c3a455fa
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Body
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _EMISSION
- _NORMAL_MAP
- _RIM
- _SPECULAR
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 57a770f4365fbb14c84e40cfa596739c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 2800000, guid: 16957b0cd55aa5543a2de2ec31fb4c85, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: bf09bf6ec9e03bf40a0ec73e7a3f4c5b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 1b40895a669bdab449fecf3c904f1a40, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _DoubleSided: 0
- _IsDay: 1
- _OutlineWidth: 1.6
- _UseEmission: 1
- _UseNormalMap: 1
- _UseRim: 1
- _UseSmoothNormal: 1
- _UseSpecular: 1
m_Colors: []
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d079260ac5e43bf498e2b925db67ca2d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Brow
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _IS_FACE
- _RIM
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: e44c095e8f6db98499384bf085687aa5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceLightMap:
m_Texture: {fileID: 2800000, guid: d933369d3fe294a4da5485a61032669e, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceShadow:
m_Texture: {fileID: 2800000, guid: d4fe3d81f5078b240a29ad0d13d5ebcc, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 1b40895a669bdab449fecf3c904f1a40, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _IsFace: 1
- _OutlineWidth: 0
- _UseCustomMaterialType: 1
- _UseRim: 1
m_Colors:
- _BaseColor: {r: 0.9764706, g: 0.80103135, b: 0.76164705, a: 1}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bc3ba53397bde5a40bc70af4d711403c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Dress1
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DOUBLE_SIDED
- _EMISSION
- _NORMAL_MAP
- _RIM
- _SPECULAR
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 57a770f4365fbb14c84e40cfa596739c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 2800000, guid: 16957b0cd55aa5543a2de2ec31fb4c85, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: bf09bf6ec9e03bf40a0ec73e7a3f4c5b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 1b40895a669bdab449fecf3c904f1a40, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 0
- _DoubleSided: 1
- _OutlineZOffset: 0.5
- _UseEmission: 1
- _UseNormalMap: 1
- _UseRim: 1
- _UseSmoothNormal: 1
- _UseSpecular: 1
m_Colors: []
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1aa7d64a95b4c4a47a42956733646dfb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Dress2
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _DOUBLE_SIDED
- _EMISSION
- _NORMAL_MAP
- _RIM
- _SPECULAR
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: f771c421ae0f7e84891ad26baa73e626, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 2800000, guid: 7c407627b6cc5474d87601dddeddf75b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: b3dd0683c060c8b4d8e23df5776b9d56, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 59a761e1753da09429a2c063c23def23, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _Cull: 0
- _DoubleSided: 1
- _OutlineZOffset: 0.5
- _UseEmission: 1
- _UseNormalMap: 1
- _UseRim: 1
- _UseSpecular: 1
m_Colors: []
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5ec9821a77e85744ea957a936e163194
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Face
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _IS_FACE
- _RIM
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: e44c095e8f6db98499384bf085687aa5, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceLightMap:
m_Texture: {fileID: 2800000, guid: d933369d3fe294a4da5485a61032669e, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _FaceShadow:
m_Texture: {fileID: 2800000, guid: d4fe3d81f5078b240a29ad0d13d5ebcc, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 1b40895a669bdab449fecf3c904f1a40, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _FaceBlushStrength: 0.3
- _IsFace: 1
- _OutlineZOffset: 0.5
- _UseCustomMaterialType: 1
- _UseRim: 1
m_Colors:
- _OutlineWidthParams: {r: 0, g: 6, b: 0.1, a: 0.6}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aed51a8e6b3fcff48b4a0c036be81a0d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-3290751858395990286
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 7
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Nahida_Hair
m_Shader: {fileID: 4800000, guid: 43a94ff316d044749abc5a8bce3d6902, type: 3}
m_Parent: {fileID: 2100000, guid: 30ad25ccfe2f70b4e8544dc4c3a455fa, type: 2}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _EMISSION
- _NORMAL_MAP
- _RIM
- _SPECULAR
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: f771c421ae0f7e84891ad26baa73e626, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LightMap:
m_Texture: {fileID: 2800000, guid: 7c407627b6cc5474d87601dddeddf75b, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 2800000, guid: b3dd0683c060c8b4d8e23df5776b9d56, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ShadowRamp:
m_Texture: {fileID: 2800000, guid: 59a761e1753da09429a2c063c23def23, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _UseEmission: 1
- _UseNormalMap: 1
- _UseRim: 1
- _UseSmoothNormal: 1
- _UseSpecular: 1
m_Colors:
- _OutlineColor: {r: 0.2784314, g: 0.18039216, b: 0.14901961, a: 1}
- _OutlineWidthParams: {r: 0, g: 6, b: 0.1, a: 0.6}
m_BuildTextureStacks: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e014b380f94128542b5dfb89a7e6457c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,262 @@
Shader "URPGenshinPostProcess"
{
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#pragma multi_compile_local_fragment _ _BLOOM_COLOR _BLOOM_BRIGHTNESS
#pragma multi_compile_local_fragment _ _TONEMAPPING
float2 _BlitTexture_TexelSize;
half _BloomThreshold;
half _BloomIntensity;
half4 _BloomWeights;
half4 _BloomColor;
half _BlurRadius;
half _Exposure;
half _Contrast;
half _Saturation;
TEXTURE2D(_BloomTextureA);
TEXTURE2D(_BloomTextureB);
TEXTURE2D(_BloomTextureC);
TEXTURE2D(_BloomTextureD);
const static int kernelSize = 9;
const static float kernelOffsets[9] = {
-4.0,
-3.0,
-2.0,
-1.0,
0.0,
1.0,
2.0,
3.0,
4.0,
};
const static float kernel[9] = {
0.01621622,
0.05405405,
0.12162162,
0.19459459,
0.22702703,
0.19459459,
0.12162162,
0.05405405,
0.01621622
};
half4 Prefilter(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
#if _BLOOM_BRIGHTNESS
half brightness = max(max(color.r, color.g), color.b);
color.rgb *= saturate(brightness - _BloomThreshold);
#else
color.rgb = max(color.rgb - _BloomThreshold, 0.0);
#endif
return color;
}
half4 GaussianBlur(float2 uv, float2 direction)
{
float2 offset = _BlurRadius * _BlitTexture_TexelSize * direction;
half4 color = 0.0;
UNITY_UNROLL
for (int i = 0; i < kernelSize; i++)
{
float2 sampleUV = uv + kernelOffsets[i] * offset;
color += kernel[i] * SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, sampleUV);
}
return color;
}
half4 HorizontalBlur1x(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
return GaussianBlur(uv, float2(1.0, 0.0));
}
half4 HorizontalBlur2x(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
return GaussianBlur(uv, float2(2.0, 0.0));
}
half4 VerticalBlur1x(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
return GaussianBlur(uv, float2(0.0, 1.0));
}
half4 VerticalBlur2x(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
return GaussianBlur(uv, float2(0.0, 2.0));
}
half4 Upsample(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
half4 color = 0.0;
half4 weights = _BloomWeights;
color += SAMPLE_TEXTURE2D_X(_BloomTextureA, sampler_LinearClamp, uv) * weights.x;
color += SAMPLE_TEXTURE2D_X(_BloomTextureB, sampler_LinearClamp, uv) * weights.y;
color += SAMPLE_TEXTURE2D_X(_BloomTextureC, sampler_LinearClamp, uv) * weights.z;
color += SAMPLE_TEXTURE2D_X(_BloomTextureD, sampler_LinearClamp, uv) * weights.w;
return color;
}
half3 Tonemap(half3 color)
{
half3 c0 = (1.36 * color + 0.047) * color;
half3 c1 = (0.93 * color + 0.56) * color + 0.14;
return saturate(c0 / c1);
}
half4 ColorGrading(Varyings input) : SV_TARGET
{
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
half4 baseMap = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
half3 color = baseMap.rgb;
half alpha = baseMap.a;
#if _BLOOM_COLOR || _BLOOM_BRIGHTNESS
// Bloom
half3 bloom = SAMPLE_TEXTURE2D_X(_BloomTextureA, sampler_LinearClamp, uv).rgb;
bloom *= _BloomIntensity * _BloomColor.rgb;
color += bloom;
#endif
// Exposure
color *= _Exposure;
#if _TONEMAPPING
// Tonemapping
color = Tonemap(color);
#endif
// Contrast
half3 colorLog = LinearToLogC(color);
colorLog = lerp(ACEScc_MIDGRAY, colorLog, _Contrast);
color = LogCToLinear(colorLog);
// Saturation
half luma = dot(color, half3(0.2126, 0.7152, 0.0722));
color = lerp(luma, color, _Saturation);
return float4(color, alpha);
}
ENDHLSL
Subshader
{
Tags { "RenderPipeline" = "UniversalPipeline" }
ZWrite Off ZTest Always Blend Off Cull Off
Pass
{
Name "Blit"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragBilinear
ENDHLSL
}
Pass
{
Name "BloomPrefilter"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Prefilter
ENDHLSL
}
Pass
{
Name "BloomHorizontalBlur1x"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment HorizontalBlur1x
ENDHLSL
}
Pass
{
Name "BloomHorizontalBlur2x"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment HorizontalBlur2x
ENDHLSL
}
Pass
{
Name "BloomVerticalBlur1x"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment VerticalBlur1x
ENDHLSL
}
Pass
{
Name "BloomVerticalBlur2x"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment VerticalBlur2x
ENDHLSL
}
Pass
{
Name "BloomUpsample"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Upsample
ENDHLSL
}
Pass
{
Name "ColorGrading"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment ColorGrading
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b0d6c4974782c8942a7269d3635777ce
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 703981ff6984b434f96bb2a1bea9cddf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 99c9720ab356a0642a771bea13969a05
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cec25f6e216db8448aae1aeb2acd8257
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System.Collections.Generic;
using UnityEngine;
namespace Nahida
{
public class MaterialUpdater : MonoBehaviour
{
[SerializeField]
private GameObject m_HeadBone;
[SerializeField]
private Vector3 m_HeadDirection = Vector3.up;
[SerializeField]
private List<SkinnedMeshRenderer> m_FaceRenderers;
private void Update()
{
if (m_FaceRenderers == null || m_HeadBone == null)
{
return;
}
Vector3 direction = m_HeadBone.transform.rotation * m_HeadDirection;
foreach (var renderer in m_FaceRenderers)
{
foreach (var material in renderer.materials)
{
material.SetVector("_FaceDirection", direction);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 711d20640ba9a76428eb565b58d22d72
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: af8894628809a3745b95419580b8e8a0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
namespace Nahida.Rendering
{
public enum BloomMode
{
None,
Color,
Brightness
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eca541d34b6a4d84d8286343d86edfee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Nahida.Rendering
{
[Serializable]
[VolumeComponentMenuForRenderPipeline("Custom/Bloom", typeof(UniversalRenderPipeline))]
public class BloomVolume : VolumeComponent, IPostProcessComponent
{
public VolumeParameter<BloomMode> mode = new VolumeParameter<BloomMode>();
public MinFloatParameter threshold = new MinFloatParameter(0.7f, 0f);
public MinFloatParameter intensity = new MinFloatParameter(1.5f, 0f);
public Vector4Parameter weights = new Vector4Parameter(0.25f * Vector4.one);
public ColorParameter color = new ColorParameter(Color.white);
public MinFloatParameter blurRadius = new MinFloatParameter(2f, 0f);
public ClampedFloatParameter downSampleScale = new ClampedFloatParameter(0.5f, 0.1f, 1f);
public bool IsActive()
{
return mode.value != BloomMode.None;
}
public bool IsTileCompatible()
{
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76dafa8030f42e648a782b9ab29b6ccb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Nahida.Rendering
{
[Serializable]
[VolumeComponentMenuForRenderPipeline("Custom/ColorGrading", typeof(UniversalRenderPipeline))]
public class ColorGradingVolume : VolumeComponent, IPostProcessComponent
{
public BoolParameter useTonemapping = new BoolParameter(false);
public MinFloatParameter exposure = new MinFloatParameter(1f, 0f);
public ClampedFloatParameter contrast = new ClampedFloatParameter(0f, -100f, 100f);
public ClampedFloatParameter saturation = new ClampedFloatParameter(0f, -100f, 100f);
public bool IsActive()
{
return useTonemapping.value || exposure.value != 1f || contrast.value != 0f || saturation.value != 0f;
}
public bool IsTileCompatible()
{
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b065805f0c20d0946afc33f94ae2f89d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace Nahida.Rendering
{
public class PostProcessFeature : ScriptableRendererFeature
{
[SerializeField]
private RenderPassEvent m_RenderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
[SerializeField]
private Shader m_Shader;
private PostProcessPass _postProcessPass;
public const int BloomIterations = 4;
public override void Create()
{
if (m_Shader == null)
m_Shader = Shader.Find("URPGenshinPostProcess");
_postProcessPass = new PostProcessPass(m_RenderPassEvent, m_Shader, BloomIterations);
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(_postProcessPass);
}
protected override void Dispose(bool disposing)
{
_postProcessPass?.Dispose();
_postProcessPass = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a75e1afdd7c0c4644bf9681fa79463d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,165 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Nahida.Rendering
{
public class PostProcessPass : ScriptableRenderPass
{
private Material _material;
private RTHandle[] _bloomBufferA;
private RTHandle[] _bloomBufferB;
private bool _useBloom;
private int _iterations;
private float _downSampleScale;
public PostProcessPass(RenderPassEvent renderPassEvent, Shader shader, int iterations)
{
_material = CoreUtils.CreateEngineMaterial(shader);
_iterations = iterations;
_bloomBufferA = new RTHandle[_iterations];
_bloomBufferB = new RTHandle[_iterations];
base.profilingSampler = new ProfilingSampler(nameof(PostProcessPass));
base.renderPassEvent = renderPassEvent;
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cameraType = renderingData.cameraData.cameraType;
if (cameraType == CameraType.Preview || cameraType == CameraType.Reflection)
{
return;
}
var stack = VolumeManager.instance.stack;
var bloomVolume = stack.GetComponent<BloomVolume>();
var colorGradingVolume = stack.GetComponent<ColorGradingVolume>();
if (!bloomVolume.IsActive() && !colorGradingVolume.IsActive())
{
return;
}
_useBloom = bloomVolume.IsActive();
_downSampleScale = bloomVolume.downSampleScale.value;
SetupBuffer(ref renderingData);
SetupMaterial(bloomVolume, colorGradingVolume, ref renderingData);
var command = CommandBufferPool.Get();
Render(command, ref renderingData);
context.ExecuteCommandBuffer(command);
CommandBufferPool.Release(command);
}
private void SetupBuffer(ref RenderingData renderingData)
{
var cameraDescriptor = renderingData.cameraData.cameraTargetDescriptor;
var descriptor = new RenderTextureDescriptor(cameraDescriptor.width, cameraDescriptor.height, cameraDescriptor.graphicsFormat, 0, 0);
if (_useBloom)
{
descriptor.width = (int)Math.Round(descriptor.width * _downSampleScale);
descriptor.height = (int)Math.Round(descriptor.height * _downSampleScale);
for (int i = 0; i < _iterations; i++)
{
RenderingUtils.ReAllocateIfNeeded(ref _bloomBufferA[i], descriptor, FilterMode.Bilinear, name: $"_BloomBufferA_{i}");
RenderingUtils.ReAllocateIfNeeded(ref _bloomBufferB[i], descriptor, FilterMode.Bilinear, name: $"_BloomBufferB_{i}");
descriptor.width = Math.Max(descriptor.width / 2, 1);
descriptor.height = Math.Max(descriptor.height / 2, 1);
}
}
}
private void SetupMaterial(BloomVolume bloomVolume, ColorGradingVolume colorGradingVolume, ref RenderingData renderingData)
{
float screenFactor = renderingData.cameraData.cameraTargetDescriptor.height / 1080f;
CoreUtils.SetKeyword(_material, "_BLOOM_COLOR", bloomVolume.mode.value == BloomMode.Color);
CoreUtils.SetKeyword(_material, "_BLOOM_BRIGHTNESS", bloomVolume.mode.value == BloomMode.Brightness);
CoreUtils.SetKeyword(_material, "_TONEMAPPING", colorGradingVolume.useTonemapping.value);
_material.SetFloat("_Exposure", colorGradingVolume.exposure.value);
_material.SetFloat("_Contrast", 1f + colorGradingVolume.contrast.value / 100f);
_material.SetFloat("_Saturation", 1f + colorGradingVolume.saturation.value / 100f);
if (_useBloom)
{
_material.SetFloat("_BloomThreshold", bloomVolume.threshold.value);
_material.SetFloat("_BloomIntensity", bloomVolume.intensity.value);
_material.SetVector("_BloomWeights", bloomVolume.weights.value);
_material.SetColor("_BloomColor", bloomVolume.color.value);
_material.SetFloat("_BlurRadius", bloomVolume.blurRadius.value * _downSampleScale * screenFactor);
}
}
private void Render(CommandBuffer commandBuffer, ref RenderingData renderingData)
{
var source = renderingData.cameraData.renderer.cameraColorTargetHandle;
using (new ProfilingScope(commandBuffer, profilingSampler))
{
if (_useBloom)
{
RTHandle[] bufferA = _bloomBufferA, bufferB = _bloomBufferB;
Blit(commandBuffer, source, bufferA[0], Pass.BloomPrefilter);
Blit(commandBuffer, bufferA[0], bufferB[0], Pass.BloomHorizontalBlur1x);
Blit(commandBuffer, bufferB[0], bufferA[0], Pass.BloomVerticalBlur1x);
for (int i = 1; i < _iterations; i++)
{
Blit(commandBuffer, bufferA[i - 1], bufferB[i], Pass.BloomHorizontalBlur2x);
Blit(commandBuffer, bufferB[i], bufferA[i], Pass.BloomVerticalBlur1x);
}
commandBuffer.SetGlobalTexture("_BloomTextureA", bufferA[0]);
commandBuffer.SetGlobalTexture("_BloomTextureB", bufferA[1]);
commandBuffer.SetGlobalTexture("_BloomTextureC", bufferA[2]);
commandBuffer.SetGlobalTexture("_BloomTextureD", bufferA[3]);
Blit(commandBuffer, bufferB[0], bufferB[0], Pass.BloomUpsample);
commandBuffer.SetGlobalTexture("_BloomTextureA", bufferB[0]);
}
base.Blit(commandBuffer, ref renderingData, _material, (int)Pass.ColorGrading);
}
}
private void Blit(CommandBuffer commandBuffer, RTHandle source, RTHandle destination, Pass pass)
{
const RenderBufferLoadAction Load = RenderBufferLoadAction.DontCare;
const RenderBufferStoreAction Save = RenderBufferStoreAction.Store;
Blitter.BlitCameraTexture(commandBuffer, source, destination, Load, Save, _material, (int)pass);
}
public void Dispose()
{
for (int i = 0; i < _iterations; i++)
{
_bloomBufferA[i]?.Release();
_bloomBufferB[i]?.Release();
}
CoreUtils.Destroy(_material);
}
public enum Pass
{
Blit,
BloomPrefilter,
BloomHorizontalBlur1x,
BloomHorizontalBlur2x,
BloomVerticalBlur1x,
BloomVerticalBlur2x,
BloomUpsample,
ColorGrading
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c02e00032f3ae5741802c9c3f8f159ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using UnityEngine;
namespace Nahida
{
public class TransformRotator : MonoBehaviour
{
[SerializeField]
private float m_Cycle;
[SerializeField]
private Vector3 m_Axis;
private Quaternion _rotation;
private float _startTime;
private void OnEnable()
{
_rotation = transform.rotation;
_startTime = Time.time;
}
private void Update()
{
float angle = 360f * (Time.time - _startTime) / m_Cycle;
transform.rotation = Quaternion.AngleAxis(angle, m_Axis) * _rotation;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e3dba08e0aa80041b5851de7eb4b984
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8a91b80380d2e7645a41490ca179f3ff
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: da51638b519fbd14fbac4de01b43551b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ca60285cf76f6c148aad8e69a749aaec
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d1934e58fa8b8cf4c97000eb611939a2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Some files were not shown because too many files have changed in this diff Show More