├── .gitignore
├── .vscode
├── settings.json
└── tasks.json
├── 404.html
├── Blender
└── Blender.md
├── CG
└── CG.md
├── DX12
├── Basic.md
├── CoordinateSystem.md
├── D3D12.md
├── DX12.md
├── Descriptor.md
├── Fundation.md
├── HLSL.ResourceBinding.md
├── MiniEngine.Mesh.md
├── MiniEngine.Model.md
├── MiniEngine.PipelineState.md
├── MiniEngine.TextureMananger.md
├── MiniEngine.md
├── RenderLoop.md
├── ResourceBarriers.md
├── WorkSubmitting.md
├── reference.md
├── rootSignature.DefineInHLSL.md
└── rootSignature.md
├── GDC
├── GDC.md
├── UIEngineering.md
└── Witcher3_OptimizingContentPipelinesForOpenWorldGames.md
├── Gemfile
├── UE
├── 0611_0615.md
├── Animation.ParallelUpdate.md
├── Animation.md
├── BuildWorld.HLOD.md
├── BuildWorld.PCG.md
├── BuildWorld.RuntimeStreaming.md
├── BuildWorld.WorldPartition.md
├── BuildWorld.md
├── CitySample.md
├── CustomMesh_Factory.md
├── Debug.md
├── Foliage.md
├── GC.md
├── GDC2023Nanite.md
├── GPUScene.md
├── HISMClusterAlg.md
├── Landscape.md
├── Lecture.LumenBake.md
├── Lumen.md
├── Lyra.AssetMananger.md
├── Lyra.GameModes.md
├── Lyra.UI.ExperienceSelection.md
├── Lyra.UI.md
├── Lyra.md
├── MVVM.md
├── Nanite.md
├── Pro.md
├── RenderMesh.md
├── ShaderDev.md
├── UE.md
├── UE5_IndirectDraw.md
├── UnrealFest2024.md
├── VirtualTexture.md
├── image.png
├── optimization.md
└── ue5_opt.md
├── _config.yml
├── _posts
└── 2024-09-07-welcome-to-jekyll.markdown
├── about.markdown
├── assets
├── DX12
│ ├── PSOHash.png
│ ├── me_common_cbv.png
│ ├── me_initModelInstance.png
│ ├── me_root_parameter_setting.png
│ ├── me_skin_matrices.png
│ └── render_loop_fence.png
├── MiniEngine.Model
│ └── SamplerParm.png
├── MiniEngine
│ ├── DescriptorHandleInc.png
│ ├── DescriptorOffset.png
│ ├── MaterialTextureDescriptor.png
│ └── SamplerDescriptor.png
├── UE
│ ├── CS_HoudiniGraph.png
│ ├── CellCoordsCaculate.png
│ ├── City_Stats.png
│ ├── CreateRuntimeCell.png
│ ├── FourUDIMTex.png
│ ├── GS_PrimitiveIdVertexBufferPool.png
│ ├── GridSize_LevelNum.png
│ ├── HISM_InnerNodeMergejpg.jpg
│ ├── HISM_InstanceData.png
│ ├── HISM_InstanceReorderTable.png
│ ├── HISM_LeafNodeSplit.jpg
│ ├── HISM_StateUpdate.png
│ ├── HLOD_ApproxActorsResult.png
│ ├── HLOD_ApproxResult.png
│ ├── HLOD_BatchPolicy.png
│ ├── HLOD_BuilderBuild.png
│ ├── HLOD_CustomHLODBuilderClass.png
│ ├── HLOD_DetermineLOD.png
│ ├── HLOD_ForceLod.png
│ ├── HLOD_Interface_ApproxActors.png
│ ├── HLOD_MergeMesh.png
│ ├── HLOD_SimplifiedMesh_Material.png
│ ├── HLOD_TestSimplifiedMesh.png
│ ├── HLOD_VirtualBuild.png
│ ├── IntersectingCellNum.png
│ ├── LS_MatID.png
│ ├── LU_PerformanceOverview.png
│ ├── NonAlignedGridLevels.png
│ ├── OpenWorld_Stat.png
│ ├── RM_DeletePrimitive.png
│ ├── RM_InterfaceCreateProxy.png
│ ├── RM_StaticPass.png
│ ├── RM_addprimitivecommand.png
│ ├── RM_create_sceneproxy.png
│ ├── RM_scene_addPrimitive.png
│ ├── SM_expand_interface.png
│ ├── SS_Actor_GetWorld.png
│ ├── SS_BuildPlayerSource.png
│ ├── SS_CellActivate.png
│ ├── SS_CellShowOrHidden.jpg
│ ├── SS_CellSortCompare.png
│ ├── SS_GetOuterWorldPartition.png
│ ├── SS_GetPerformanceCell.png
│ ├── SS_GetWorldPartition.png
│ ├── SS_HLODActorGrid.jpg
│ ├── SS_HLODActorRegister.png
│ ├── SS_HLODActorRegistered.png
│ ├── SS_HLODBuilderRequiresWarmup.png
│ ├── SS_OnCellHidden.png
│ ├── SS_PartitionHLODData.png
│ ├── SS_PlayMainWorld.png
│ ├── SS_PlayerGetSource.png
│ ├── SS_ProccessBlockLoading.png
│ ├── SS_RealActorGetWorld.png
│ ├── SS_ServerWaitClientVisi.png
│ ├── SS_SkipOnSlowLoading.png
│ ├── SS_SphereAABBIntersection.png
│ ├── SS_StreamingCellDataLayer.png
│ ├── SS_ToUnloadCell.png
│ ├── SS_WorldPartitionInit.png
│ ├── StreamingData.png
│ ├── UDIM_Texture.png
│ ├── VF_ActuallParamBind.png
│ ├── VF_AnimationCollectionCfg.png
│ ├── VF_BeginInitResource.png
│ ├── VF_BindPosition.png
│ ├── VF_BindUniformBuffer.png
│ ├── VF_BindUniformBufferData.png
│ ├── VF_CalcBoneMatrixNew.png
│ ├── VF_ComplieResult.png
│ ├── VF_CreateConstantbuffer.png
│ ├── VF_DecalreUniformBuffer.png
│ ├── VF_DeclareVFType.png
│ ├── VF_DiffVSLightMapHQ.png
│ ├── VF_FillVertexPerLod.png
│ ├── VF_GPUSkinVFPermutations.png
│ ├── VF_GameThreadUpdateData.png
│ ├── VF_GetBoneMatrix.png
│ ├── VF_GetEleBindings.png
│ ├── VF_GetInstanceDataFull.png
│ ├── VF_GetVFIntermediates.png
│ ├── VF_GlobalParamUsf.png
│ ├── VF_HLSLFactoryInput.png
│ ├── VF_ImplShaderParam.png
│ ├── VF_ImplUniformForVF.png
│ ├── VF_ImplementVFType.png
│ ├── VF_IncludeGlobalShaderParameter.png
│ ├── VF_IndexBuffer.jpg
│ ├── VF_InitMeshResource.png
│ ├── VF_InputElement.png
│ ├── VF_InterpolantVSToPSResult.png
│ ├── VF_LightMapIndex.png
│ ├── VF_LocalVFParam.png
│ ├── VF_LocalVertexFactoryG.jpg
│ ├── VF_MaxBoneInfluence.png
│ ├── VF_MeshVertexBuffer.png
│ ├── VF_MeshvertexBuffer.jpg
│ ├── VF_ParameterBindInfo.png
│ ├── VF_PostLoadInitResource.png
│ ├── VF_RefenecePositionData.png
│ ├── VF_ResultVS.png
│ ├── VF_SerializeRenderData.png
│ ├── VF_SerializeSourceModel.png
│ ├── VF_ShaderParamMemebrDecl.png
│ ├── VF_SkelotBuffer.png
│ ├── VF_SkelotCalcBoneMatrix.png
│ ├── VF_SkelotUpdateDataThread.jpg
│ ├── VF_SkelotVertexFactoryResource.jpg
│ ├── VF_SkelotVertexParameter.png
│ ├── VF_SkinWeight.png
│ ├── VF_SkinWorldPosition.png
│ ├── VF_StaticMeshVertexBuffers.png
│ ├── VF_VFDefineMa.png
│ ├── VF_VFInitRenderThread.png
│ ├── VF_VFInitResource.png
│ ├── VF_VFMemberProperty.png
│ ├── VF_VFMeshData.jpg
│ ├── VF_VFShaderParam.png
│ ├── VF_VertexBondIndicesWeight.png
│ ├── WP_SetContainerInstanceCollection.png
│ └── evn_tex.png
└── images
│ ├── 2023-04-23-17-36-21.png
│ ├── 2023-04-23-17-45-19.png
│ ├── 2023-04-23-17-47-32.png
│ ├── 2023-04-23-17-50-22.png
│ ├── ActorDescContainer.jpg
│ ├── AddCBV.png
│ ├── AlphaBrush.png
│ ├── Anim_AddExtention.png
│ ├── Anim_AnimSubsystem.png
│ ├── Anim_BuildProperties.png
│ ├── Anim_Crouch.png
│ ├── Anim_ForEachSubsystem.png
│ ├── Anim_MultThread.png
│ ├── Anim_RecreateSparseClassData.png
│ ├── Anim_SparseClass.png
│ ├── Animation_ParallelTask.png
│ ├── Animation_PropertyAccess.png
│ ├── Animation_PropertyAccessSubsystem.png
│ ├── AxisAnalysis.png
│ ├── BindDescriptorHeap.png
│ ├── BindingDescriptorTable.png
│ ├── Buffer.png
│ ├── BundleToAFrame.png
│ ├── CONSTANTS.png
│ ├── Crask.png
│ ├── CreateTextureResource.png
│ ├── Descriptor.png
│ ├── DescriptorTable.png
│ ├── Direct3D12.png
│ ├── DisplaySystem.png
│ ├── EditInSequence.png
│ ├── ExperienceSelection.png
│ ├── Family.png
│ ├── FullBodyCache.png
│ ├── InitializeCommonState.png
│ ├── MVVM_Relation.png
│ ├── MapResource.png
│ ├── ModelVariations.png
│ ├── Montage_FullUpper.png
│ ├── Montage_Notify.png
│ ├── OffsetLookup.png
│ ├── OnConstantBind.png
│ ├── ResourceDimension.png
│ ├── RootParameter.png
│ ├── RootSignatureDesc.png
│ ├── RootSignature_MoreComplex.png
│ ├── StartInsights.png
│ ├── StreamingShaderResourceViews.png
│ ├── TextureManager.png
│ ├── TreeAnimLookup.png
│ ├── UpdateAnimation.png
│ ├── UpperBodyCache.png
│ ├── WP_ActorDescViewMap.jpg
│ ├── WP_BeginGenerate.jpg
│ ├── WP_GenPersistenDesc.png
│ ├── WP_GenerateActorsContainer.jpg
│ ├── WP_RuntimePartition.jpg
│ ├── WorldPartition_CellName.png
│ ├── WorldPartition_LHGridLevel.png
│ └── controlrig_ik.png
├── graphicNotes
├── Lyra_GameSetting.pptx
└── Lyra_Item.pptx
├── index.markdown
├── other
├── 7zip_.md
├── Other
│ └── specifyCode.png
├── automic.md
└── git.md
├── readme.md
└── script
└── move_file.ps1
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .dendron.*
3 | build
4 | seeds
5 | .next
6 | pods/service-connections
7 |
8 | # C++
9 | *.exe
10 | *.ilk
11 | *.obj
12 | *.pdb
13 |
14 | _site
15 | .sass-cache
16 | .jekyll-cache
17 | .jekyll-metadata
18 | vendor
19 | Gemfile.lock
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "xutility": "cpp",
4 | "iterator": "cpp",
5 | "vector": "cpp",
6 | "algorithm": "cpp",
7 | "atomic": "cpp",
8 | "bit": "cpp",
9 | "cctype": "cpp",
10 | "clocale": "cpp",
11 | "cmath": "cpp",
12 | "compare": "cpp",
13 | "concepts": "cpp",
14 | "cstddef": "cpp",
15 | "cstdint": "cpp",
16 | "cstdio": "cpp",
17 | "cstdlib": "cpp",
18 | "cstring": "cpp",
19 | "ctime": "cpp",
20 | "cwchar": "cpp",
21 | "exception": "cpp",
22 | "fstream": "cpp",
23 | "initializer_list": "cpp",
24 | "ios": "cpp",
25 | "iosfwd": "cpp",
26 | "iostream": "cpp",
27 | "istream": "cpp",
28 | "limits": "cpp",
29 | "memory": "cpp",
30 | "new": "cpp",
31 | "ostream": "cpp",
32 | "ranges": "cpp",
33 | "span": "cpp",
34 | "stdexcept": "cpp",
35 | "streambuf": "cpp",
36 | "system_error": "cpp",
37 | "tuple": "cpp",
38 | "type_traits": "cpp",
39 | "typeinfo": "cpp",
40 | "utility": "cpp",
41 | "xfacet": "cpp",
42 | "xiosbase": "cpp",
43 | "xlocale": "cpp",
44 | "xlocinfo": "cpp",
45 | "xlocnum": "cpp",
46 | "xmemory": "cpp",
47 | "xstddef": "cpp",
48 | "xstring": "cpp",
49 | "xtr1common": "cpp"
50 | },
51 | "pasteImage.path": "${projectRoot}/assets/${currentFileNameWithoutExt}",
52 | "MarkdownPaste.path": "${workspaceRoot}/assets/${relativeFileDirname}/",
53 | "MarkdownPaste.nameBase": "${selectedText|image}",
54 | "latex-workshop.latex.recipes": [
55 | {
56 | "name": "xelatex",
57 | "tools": [
58 | "xelatex"
59 | ]
60 | }
61 | ],
62 | "latex-workshop.latex.tools": [
63 | {
64 | "name": "xelatex",
65 | "command": "xelatex",
66 | "args": [
67 | "-synctex=1",
68 | "-interaction=nonstopmode",
69 | "-file-line-error",
70 | "%DOC%"
71 | ]
72 | }
73 | ]
74 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": [
3 | {
4 | "type": "cppbuild",
5 | "label": "C/C++: cl.exe build active file",
6 | "command": "cl.exe",
7 | "args": [
8 | "/Zi",
9 | "/std:c++latest",
10 | "/EHsc",
11 | "/nologo",
12 | "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
13 | "${file}"
14 | ],
15 | "options": {
16 | "cwd": "${fileDirname}"
17 | },
18 | "problemMatcher": [
19 | "$msCompile"
20 | ],
21 | "group": {
22 | "kind": "build",
23 | "isDefault": true
24 | },
25 | "detail": "Task generated by Debugger."
26 | }
27 | ],
28 | "version": "2.0.0"
29 | }
--------------------------------------------------------------------------------
/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /404.html
3 | layout: default
4 | ---
5 |
6 |
19 |
20 |
21 |
404
22 |
23 |
Page not found :(
24 |
The requested page could not be found.
25 |
26 |
--------------------------------------------------------------------------------
/Blender/Blender.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: qboqar9fpgks44ajllzaarl
3 | title: Blender
4 | desc: ''
5 | updated: 1683341462530
6 | created: 1683333234256
7 | ---
8 |
9 | > Base Bledner version: 3.5
10 |
11 | # Code Development
12 |
13 | * https://github.com/blender/blender.git
14 |
15 | * 构建步骤:https://wiki.blender.org/wiki/Building_Blender/Windows
16 |
17 | * Debug python: https://wiki.blender.org/wiki/Tools/Debugging/Python_Visual_Studio
18 |
19 | > make 2022 full nobuild pydebug
20 |
21 | * FQA: https://wiki.blender.org/wiki/Reference/FAQ#Source_Code_FAQ
22 |
23 | * Python API Doc : https://docs.blender.org/api/current/bpy.context.html
24 |
25 | * Book: Core Blender Development - Understanding the Essential
26 | Source Code
27 |
28 | * Code and Design Document: https://wiki.blender.org/wiki/Source
29 |
30 | * 源码结构:https://wiki.blender.org/wiki/Source/File_Structure
31 |
32 | ## Addon
33 |
34 | 源码中没有插件,要自己下载。
35 |
36 | * https://wiki.blender.org/wiki/Process/Addons
37 | * https://docs.blender.org/manual/en/latest/advanced/scripting/addon_tutorial.html
38 |
39 | ### Reload Addon
40 | 开发时在Blender中重新加载插件: Command -> ReloadScript、
41 |
42 | https://projects.blender.org/blender/blender-addons/issues/66924
43 |
44 | ### Development
45 | 导出UE中PivotPainter2使用的纹理资源工具:
46 |
47 | ```https://github.com/Floating-light/blender_addon.git```
48 |
49 | 可当作Blender插件开发的简单参考。源码中有许多Python脚本的示例`scripts\templates_py`,还有参考许多源码实现的功能和插件。
50 |
51 | 可以用VSCode开发,装插件Blender Development, 补全提示由https://github.com/nutti/fake-bpy-module
52 |
53 |
54 | > TODO: 也许可以直接用Blender源码,加上编译选项pydebug,可以同时调试C 和 Python,Python的补全提示也可以用上面的fake-bpy-module,可以直接用pip装在对应版本的Python即可。
55 |
56 | # Blender
57 |
58 | * 对于UE, 要设置UnitScale = 0.01, 在ScenePropertyies -> Units -> UnitScale,然后在File-> Defaults -> SaveStartupFIle,可以让这个设置永久生效
59 |
60 | * Edit -> Preferences -> Interface -> Display ->(勾上 Developer Extras和PythonTooltips)
61 |
62 | -> Editors -> StatusBar -> Show Scene Statistics
63 | 在Blender编辑器中,tooltips包含了对应的PythonAPI,例如 `bpy.ops.mesh.primitive_ico_sphere_add()`,其对应的C导出的函数为:`MESH_OT_primitive_ico_sphere_add`,可以直接搜索源码,看到实现。
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/CG/CG.md:
--------------------------------------------------------------------------------
1 | computational_geometry_algorithms_and_app
2 |
3 | 计算几何相关资源
4 |
5 | * https://www.xuetangx.com/course/THU08091000327/19318293
6 | * https://dsa.cs.tsinghua.edu.cn/~deng/cg/index.htm
7 | * https://www.cgal.org/index.html
8 | * https://doc.cgal.org/Manual/3.5/doc_html/cgal_manual/Arrangement_on_surface_2/Chapter_main.html#arr_sec:overlay
9 | * https://doc.cgal.org/Manual/3.5/doc_html/cgal_manual/Boolean_set_operations_2/Chapter_main.html
10 | * cgal\Boolean_set_operations_2\examples\Boolean_set_operations_2\do_intersect.cpp
11 | * Paper: Advanced Programming Techniques Applied to Cgal’s Arrangement Package
12 | * https://ruixu.me/
13 | * 平面圆并集:
14 | * https://www.ime.usp.br/~cris/aulas/14_2_331/projetos/ImaiIM85.pdf
15 | * https://en.wikipedia.org/wiki/Power_diagram
--------------------------------------------------------------------------------
/DX12/Basic.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: vlsuz7v50xf4mp2sui4xofo
3 | title: Basic
4 | desc: ''
5 | updated: 1668238684604
6 | created: 1667017115678
7 | ---
8 |
9 | # Com接口
10 |
11 | > https://learn.microsoft.com/en-us/windows/win32/com/com-technical-overview
12 |
13 | COM(Component object model)本质上定义了一种标准。这种标准是和语言、平台无关的,许多编程语言都可以创建和使用COM对象。类似于C++标准和不同的编译器实现的关系。
14 |
15 | COM对编程语言唯一的要求是:`可以创建指针结构,并通过指针调用函数`。C++天然支持这一点,所以它本身的语言特性(指针,继承,多态)使得实现和使用COM对象十分简单和自然。
16 |
17 | 所有COM接口都派生自IUnknow:
18 | ```c++
19 | IUnknown
20 | {
21 | public:
22 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(
23 | /* [in] */ REFIID riid,
24 | /* [annotation][iid_is][out] */
25 | _COM_Outptr_ void **ppvObject) = 0;
26 |
27 | virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;
28 | virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
29 | }
30 | ```
31 | 它主要提供多态和生命周期的管理。
32 |
33 | 其中,成员函数`QueryInterface`提供了多态性。由于COM中每个接口都有唯一的ID(GUID,在定义的时候就确定了),所以传入一个接口ID就可以知道当前对象是否支持这个接口,如果可以就返回它的指针。因为这里只用一个GUID标识一个接口,就可以在旧版本的对象上查询新的没支持的接口。
34 |
35 | COM 对象的生命周期由引用计数控制。`AddRef`增加计数,`Release`减少计数,当计数减少到0时,`Release`就会释放这个实例。通常不显式地自己调用这两个函数,而是使用类似于智能指针的`ComPtr`,自动管理其生命周期,也可以自己实现这样的引用计数器。COM对象在创建时,会调用一次`AddRef`,我们拿到COM对象后如果不需要了,就要显式调用一次`Release`。
36 | > https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-d3d12createdevice
37 |
38 | DXGI,DirectX都是用COM实现的。
39 |
40 | # DXGI(DirectX Graphics Infrastructure)
41 |
42 | > https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/d3d10-graphics-programming-guide-dxgi
43 |
44 | 主要处理更低层级的任务,枚举Graphics adapters、Display modes、显示渲染的图像到显示器。这些是独立于DirectX的。
45 |
46 | IDXGIFactory用于创建DXGI相关的对象。而它本身可以通过一个全局函数直接创建:
47 | ```c++
48 | ComPtr factory;
49 | CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory));
50 | ```
51 | Factory可以在不同地地方多次创建。
52 |
53 | ## Adapter
54 |
55 | Adapter是对渲染硬件(显卡)和软件(Direct3D软光栅化器)的抽象。一台主机通常有多个Adapter,独立显卡、集成显卡、软光栅化器。
56 |
57 | 可以通过枚举出所有Adapter,然后查询它是否支持我们需要的Direct3D API版本:
58 | ```c++
59 | ComPtr adapter;
60 | for (UINT adapterIndex = 0; SUCCEEDED(pFactory->EnumAdapters1(adapterIndex, &adapter)); ++adapterIndex)
61 | {
62 | DXGI_ADAPTER_DESC1 desc;
63 | adapter->GetDesc1(&desc);
64 |
65 | if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
66 | {
67 | // Don't select the Basic Render Driver adapter.
68 | continue;
69 | }
70 |
71 | // Check to see whether the adapter supports Direct3D 12, but don't create the
72 | // actual device yet.
73 | if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
74 | {
75 | break;
76 | }
77 | }
78 | ```
79 | 新版本的Factory支持设定GPU preference枚举Adapter:
80 | ```c++
81 | ComPtr adapter;
82 | ComPtr factory6;
83 | if (SUCCEEDED(pFactory->QueryInterface(IID_PPV_ARGS(&factory6))))
84 | {
85 | for (
86 | UINT adapterIndex = 0;
87 | SUCCEEDED(factory6->EnumAdapterByGpuPreference(
88 | adapterIndex,
89 | DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
90 | IID_PPV_ARGS(&adapter)));
91 | ++adapterIndex)
92 | {
93 | DXGI_ADAPTER_DESC1 desc;
94 | adapter->GetDesc1(&desc);
95 |
96 | if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
97 | {
98 | // Don't select the Basic Render Driver adapter.
99 | continue;
100 | }
101 |
102 | // Check to see whether the adapter supports Direct3D 12, but don't create the
103 | // actual device yet.
104 | if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
105 | {
106 | break;
107 | }
108 | }
109 | }
110 | ```
111 | ## Presentation
112 | 图形应用会渲染出一帧图像,要求DXGI将它显示到显示设备上。通常至少会有两个Buffer,一个给DXGI显示(front buffer),另一个渲染用于渲染下一帧(back buffer)。创建和管理这两个Buffer的是SwapChain。一些应用取决于渲染一帧所花的时间或期望帧率肯能需要更多的Buffer。
113 |
114 | 
115 |
116 | Swap chain中的这些Buffer会被创建在显存中,然后通过DAC,把front buffer显示到最终的显示设备上。
117 |
118 | 
119 |
120 | Swap chain在创建时必须与一个Window和Device(D3D12是CommandQueue)绑定,Device是Direct3D对Adapter的抽象,需要通过Adapter创建。当Device改变时,Swap chain也必须重新创建。Swap chain的Buffer以指定大小和格式创建,也可以随时修改。渲染时,从Swap chain取出Buffer,创建RenderTarget,即可通过Direct3D向其中渲染图像。
121 |
122 | 如果调用了`IDXGIFactory::MakeWindowAssociation`,用户可以通过Alt+Enter在全屏和窗口模式之间切换。
123 |
124 | 有关SwapChain的更多信息:
125 |
126 | * https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-flip-model?redirectedfrom=MSDN
127 | * https://www.intel.com/content/www/us/en/developer/articles/code-sample/sample-application-for-direct3d-12-flip-model-swap-chains.html
128 |
129 | ### ResizeBuffer
130 | ### HandleWindowResizing
131 |
132 |
133 | # DirectX12
134 |
135 | > https://learn.microsoft.com/en-us/windows/win32/direct3d12/interface-hierarchy
136 | 
137 |
138 | DirectX提供的功能完全是基于COM实现的。
139 |
140 |
--------------------------------------------------------------------------------
/DX12/CoordinateSystem.md:
--------------------------------------------------------------------------------
1 | # 左手系 or 右手系
2 | 本质是坐标轴的定义和方向的约定。影响图形变换,例如旋转矩阵的构建。
3 |
4 | 左手系
5 | * X 轴:右
6 | * Y 轴:上
7 | * Z 轴:朝屏幕里(远离观察者)
8 | 左手叉乘。
9 |
10 | 右手系
11 | * X 轴:右
12 | * Y 轴:上
13 | * Z 轴:朝屏幕外(朝向观察者)
14 | 右手叉乘。
15 |
16 | 绕某个轴的旋转,实际旋转方向左手系和右手系是相反的。
17 |
18 | 例如绕Z轴旋转30度:
19 | * 左手系:逆时针30度
20 | $$
21 | R_z(\theta)=
22 | \begin{pmatrix}
23 | \cos(\theta) & \sin(\theta) & 0 & 0 \\
24 | -\sin(\theta) & \cos(\theta) & 0 & 0 \\
25 | 0 & 0 & 1 & 0 \\
26 | 0 & 0 & 0 & 1
27 | \end{pmatrix}
28 | $$
29 |
30 | * 右手系:顺时针30度
31 | $$
32 | R_z(\theta)=
33 | \begin{pmatrix}
34 | \cos(\theta) & -\sin(\theta) & 0 & 0 \\
35 | \sin(\theta) & \cos(\theta) & 0 & 0 \\
36 | 0 & 0 & 1 & 0 \\
37 | 0 & 0 & 0 & 1
38 | \end{pmatrix}
39 | $$
40 |
41 | 在一个Application中,只需要确定使用哪一种坐标系,不要混用即可。
42 |
43 | # View Transform
44 | ```
45 | The only difference you will ever see from using a right-handed vs a left-handed coordinate system is the math behind how you construct your projection and camera matrices.
46 | ```
47 | ## 为什么看向-Z(右手坐标系)
48 | > 左手坐标系下看向+Z
49 |
50 | 1. 简化投影Projection变换
51 | 2. View坐标系一致,
52 | * +X方向是屏幕右侧
53 | * +Y是屏幕上方
54 | * -Z是屏幕里面
55 | 3. 在右手坐标系中,观察方向通常是从世界空间的原点看向负Z方向。
56 | 4. 在左手坐标系中,观察方向通常是从世界空间的原点看向正Z方向。
57 | 5. 简化几何变换
58 | 固定观察方向使得几何变换(如物体变换、视口变换等)更直观和统一。在图形管线中,从模型坐标系到视图坐标系再到屏幕坐标系的变换可以更系统化地处理。
59 |
60 | # row major 与 column major
61 | https://stackoverflow.com/questions/16578765/hlsl-mul-variables-clarification
62 |
63 | https://stackoverflow.com/questions/27390049/graphics-row-vs-column-major-transformations
64 |
65 | https://seanmiddleditch.github.io/matrices-handedness-pre-and-post-multiplication-row-vs-column-major-and-notations/
66 |
67 | 定义的是矩阵在内存中的存储方式。假设有一个矩阵从数学上看是这样的:
68 | ```
69 | [ a b c d ]
70 | [ e f g h ]
71 | [ i j k l ]
72 | [ m n o p ]
73 | ```
74 |
75 | 如果以Row major存储,在内存中应该是这样的:
76 | ```
77 | a b c d e f g h i j k l m n o p
78 | ```
79 |
80 | 如果以Column major存储,在内存中应该是这样的:
81 | ```
82 | a e i m b f j n c g k o d h l p
83 | ```
84 |
85 | HLSL读取输入的Matrix:
86 |
87 | https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-per-component-math#matrix-ordering
88 |
89 | DirectX has historically used row-major matrices, row vectors, pre-multiplication, and left-handed coordinates.
90 |
91 | DirectXMath矩阵约定:
92 |
93 | https://learn.microsoft.com/zh-cn/windows/win32/dxmath/pg-xnamath-getting-started
94 |
95 | DirectXMath中对Matrix有以下约定:
96 | * row-major
97 | * row vector
98 | * pre-multiplication
99 | * 这就要求matrix必须是Post-Multiplication情况下矩阵的转置
100 |
101 | HLSL中读取传给CBV中的矩阵:
102 |
103 | * 默认以column_major读取,读到constant registers后,`matrix order`不影响任何后续在Shader代码中的使用。
104 |
105 | * row-major or column-major不影响Shader代码中构建的Matrix,总是row-major。
--------------------------------------------------------------------------------
/DX12/D3D12.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: otmzefuwcx3rt3twfca5n0f
3 | title: D3D12
4 | desc: ''
5 | updated: 1667997319956
6 | created: 1667868747835
7 | ---
8 |
9 | > https://learn.microsoft.com/en-us/windows/win32/direct3d12/interface-hierarchy
10 |
11 | 
12 |
13 | # ID3D12Device
14 |
15 | 代表虚拟的Adapter,用于创建各种D3D对象:
16 |
17 | * Command allocators
18 | * Command lists
19 | * command queues
20 | * Fences
21 | * Resources
22 | * Pipeline state objects
23 | * Heaps
24 | * Root signatures
25 | * Samplers
26 | * Many resource views
27 |
28 | 创建ID3D12Device:
29 | ```c++
30 | HRESULT WINAPI D3D12CreateDevice(
31 | _In_opt_ IUnknown* pAdapter,
32 | D3D_FEATURE_LEVEL MinimumFeatureLevel,
33 | _In_ REFIID riid, // Expected: ID3D12Device
34 | _COM_Outptr_opt_ void** ppDevice );
35 | ```
36 | * pAdapter是DXGI的对象,从DXGIFactory创建。
37 | * MinimumFeatureLevel 要求Device满足的最小[FeatureLevel](https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_feature_level),这将决定支持不同的ShaderModel。
38 | * riid和ppDevice是COM接口的常规操作。ppDevice如果为空,返回结果将表明这个Adapter是否支持这个FeatureLevel。
39 | ```c++
40 | // Check to see whether the adapter supports Direct3D 12, but don't create the
41 | // actual device yet.
42 | if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
43 | {
44 | break;
45 | }
46 | ```
47 |
48 | # ID3D12CommandQueue
49 |
50 | * 提交CommandLists
51 | * 同步CommandList的执行
52 | * instrumenting the command queue
53 | * 更新Resource tile mappings
54 |
55 | 创建:
56 | ```c++
57 | // Describe and create the command queue.
58 | D3D12_COMMAND_QUEUE_DESC queueDesc = {};
59 | queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; // 可以Disable GPU timeout
60 | queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;// 可执行的CommandList类型
61 |
62 | ComPtr m_commandQueue;
63 | m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue));
64 | ```
65 | D3D12中还可用于创建DXGI的SwapChain。
66 |
67 | 提交CommandLists:
68 | ```c++
69 | // Execute the command list.
70 | ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
71 | m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
72 | ```
73 | 提交后并不一定会立即执行,稍后才会把命令给GPU执行。而且这一过程较慢,应该尽量记录更多的Command的,减少提交次数。
74 |
75 | 还可以通过Fence同步GPU的执行:
76 | ```c++
77 | void D3D12HelloTriangle::WaitForPreviousFrame()
78 | {
79 | // WAITING FOR THE FRAME TO COMPLETE BEFORE CONTINUING IS NOT BEST PRACTICE.
80 | // This is code implemented as such for simplicity. The D3D12HelloFrameBuffering
81 | // sample illustrates how to use fences for efficient resource usage and to
82 | // maximize GPU utilization.
83 |
84 | // Signal and increment the fence value.
85 | const UINT64 fence = m_fenceValue;
86 | ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), fence));
87 | m_fenceValue++;
88 |
89 | // Wait until the previous frame is finished.
90 | if (m_fence->GetCompletedValue() < fence)
91 | {
92 | ThrowIfFailed(m_fence->SetEventOnCompletion(fence, m_fenceEvent));
93 | WaitForSingleObject(m_fenceEvent, INFINITE);
94 | }
95 |
96 | m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
97 | }
98 | ```
99 | 这里m_fenceValue总是保存的下一个可用的信号值。`ID3D12CommandQueue::Signal`会保证前面提交的Commandlist都执行完之后才会发出这个信号。随后绑定一个事件到这个Fence,并等待它。
100 |
101 | # ID3D12CommandAllocator
102 |
103 | * 创建Allocator的LIST_TYPE必须和CommandList的类型相同
104 | * 一个Allocator最多和一个正在记录Command的List关联
105 | * 但是一个Allocator可以用于创建任意数量的GraphicsCommandList对象
106 | * ID3D12CommandAllocator::Reset回收内存,可用于新的CommandList,但底层Size不变
107 | * 执行Reset之前App必须保证GPU不在执行和这个Allocator关联的任何CommandList。
108 | * 非线程安全
109 |
110 | # Bundles
111 |
112 | CommandList和Bundles都可以记录Drawing和State-Changing calls,稍后给GPU执行。
113 |
114 | [Bundle Feature](https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles):
115 | * 通过添加二级CommandList利用GPU硬件中存在的功能
116 | * Bundle的目的是使App可以把少量的Commands组合在一起执行
117 | * Bundle在创建时,Driver会执行尽可能多的预处理使得稍后的执行性能消耗更少。
118 | * Bundle被设计成可以被多次复用(通常CommandList只执行一次,但只要App保证前一次执行已经完成了,也可以再次执行)。
119 |
120 | 通常,一些D3D的API调用组成Bundles,API calls和Bundles组成CommandLists,CommandLists组成一帧。下图中Commandlist1和Commandlist2复用了Bundle1。
121 |
122 | 
123 |
124 | ## Creating command list
125 |
126 | 有两个方法可以创建CommandList:
127 |
128 | * ID3D12Device::CreateCommandList
129 | * ID3D12Device4::CreateCommandList1
130 | `ID3D12Device4::CreateCommandList1`可以创建一个已经Close的CommandList,而且也避免了传入Allocator和PSO。
131 |
132 | 用`ID3D12Device::CreateCommandList`创建时可以传入PSO,但这不是必须的。通常一个App会在初始化时创建大量PSO,然后用`ID3D12GraphicsCommandList::SetPipelineState`改变当前绑定的PSO。See:[ManagingGraphicsPipelineState](https://learn.microsoft.com/en-us/windows/win32/direct3d12/managing-graphics-pipeline-state-in-direct3d-12).
133 |
134 | ## Recording command lists
135 | > https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#recording-command-lists
136 |
137 | `CreateCommandList`创建的Commandlist立即处于recording状态。`CreateCommandList1`创建的处于Closed状态,再次使用时要先调用Reset,这里和Allocator不同,CommandList只要提交了就可以Reset(即使有可能还在执行),然后Allocator就可以用于下一个Commandlist。
138 |
139 | * 通常Commandlist提交后马上就Reset (Close)??? ,然后Allocator就可以用于下一个Commandlist。
140 | * 同一时间一个Allocator只能由一个Commandlist记录Command。
141 | * 处于记录状态, 调用ID3D12GraphicsCommandList的方法记录Command。
142 | * 调用Close,使Commandlist不在RecordingState。
143 | * Allocator的池化策略大概是numCommandLists*MaxFramelatency.
144 | * CommandList执行完`ID3D12CommandQueue::ExecuteCommandLists`后就可以重置,就能直接放回池里。
145 | * `ID3D12GraphicsCommandList`不会持有任何传给它的对象的引用,App需要保证不能提交执行引用了已经销毁的Resource的CommandList,必须等GPU执行完了才能销毁Resource。
146 |
147 | ## Bundle restrictions
148 | Bundle Commandlist有一些额外的限制,[一些API不能调用](https://learn.microsoft.com/en-us/windows/win32/direct3d12/recording-command-lists-and-bundles#bundle-restrictions)。这使得ExecuteBundle的开销很低。
149 | * Bundle引用的所有PSO必须有同样的render target formats, depth buffer format, 和sample descriptions。
--------------------------------------------------------------------------------
/DX12/DX12.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: hod3etj3pnf1zm55mxbiwme
3 | title: DX12
4 | desc: ''
5 | updated: 1667017335672
6 | created: 1667017115700
7 | ---
8 |
9 | Note for DirectX12, for source code :
10 |
11 | - [DirectX-Graphics-Samples](https://github.com/microsoft/DirectX-Graphics-Samples)
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/DX12/Descriptor.md:
--------------------------------------------------------------------------------
1 | Descriptor,也称作View,用于描述ID3D12Resource。
2 |
3 | # Descriptor
4 |
5 | 是一块相对比较小的数据,用于充分描述一个GPU对象。
6 |
7 | Descriptor的Size和硬件有关,可以调用`ID3D12Device::GetDescriptorHandleIncrementSize.`获取对应Descriptor的size。
8 |
9 | Driver不会持有Descriptor的引用,由App保证Descriptor的类型和信息是正确的。
10 |
11 | Descriptor[不需要被释放](https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptors-overview#descriptor-data)。
12 |
13 | Descriptor,也称作View,各种Buffer的View,Texture的View,Sampler的View等,都被保存在DescritptorHeap中。
14 |
15 | 为了引用DescriptorHeap中的Descriptor,可以从Heap中创建DescriptorHandle。每个DescritporHeap中的元素都有两种Handle,CPUDescriptorHandle和GPUDescriptorHandle。它们都引用对应的Descriptor,是同一个Descriptor的两种引用方式。
16 |
17 | CPUDescriptorHandle(D3D12_CPU_DESCRIPTOR_HANDLE):
18 | * 用于在CPU端对Descriptor进行管理和操作,更新,Copy。
19 | * 在CPU端通过这个Handle设置DescriptorHeadp中的View。
20 | ```c++
21 | CreateShaderResourceView()
22 | CreateUnorderedAccessView()
23 | CreateRenderTargetView()
24 | CreateDepthStencilView()
25 | CreateConstantBufferView()
26 | CopyDescriptorsSimple()
27 |
28 | OMSetRenderTargets()
29 | ClearDepthStencilView()
30 | ClearRenderTargetView()
31 | ```
32 | GPUDescriptorHandle(D3D12_GPU_DESCRIPTOR_HANDLE):
33 | * 用于在GPU端对Descriptor进行访问和使用。
34 | * 用于GPU端绑定DescriptorTable以进行实际的渲染操作。
35 | * GPU通过它访问Descriptor引用的底层资源
36 | * 通常在执行渲染阶段使用。
37 |
38 | ```c++
39 | SetGraphicsRootDescriptorTable()
40 | SetComputeRootDescriptorTable()
41 | ```
42 |
43 | ```c++
44 | CPU和GPU Handle都需要:
45 | CopyDescriptors()
46 | ClearUnorderedAccessViewUint()
47 | ClearUnorderedAccessViewFloat()
48 | ```
49 |
50 | 为什么有两种Handle,不统一使用一种?
51 |
52 | > 效率和吞吐量: GPU 的指令吞吐量和并行处理能力非常强,但它的上下文切换以及与 CPU 直接交互的开销非常大。这意味着频繁在 GPU 上执行资源管理操作会极大地降低系统性能。相反,CPU 端做这些操作会更有效率。
53 |
54 | > 异步执行: GPU 和 CPU 可以并行工作,但它们之间的通信需要通过命令队列进行,这是一个异步过程。如果让 GPU 也负责资源管理,会导致频繁的同步操作,从而影响异步执行的效率。
55 |
56 | > 统一使用一个 Handle 意味着描述符的创建和绑定都依赖一个共享的句柄空间。这会导致频繁的同步问题,影响指令流的高效性。
57 |
58 | CPUDescriptorHandle 和 GPUDescriptorHandle 可以看作是同一描述符堆在不同执行端(CPU 和 GPU)上的引用。这意味着它们可能指向的实际上是存储在同一描述符堆中的相同描述符,但是根据使用上下文不同,引用方式有所区分。为了让 GPU 以高效的方式去处理和访问资源,这些描述符堆通常驻留在 GPU 内存中或是在 GPU 可访问的区域内。
59 |
60 | 在CPU端初始化Descriptor,更新,复制等操作时,其实是在CPU端高效完成的。然后,需要有某种机制(如命令队列和堆栈)将这些更新"提交"给 GPU。这实际上是通过指令流和同步机制来实现的。在 CPU 创建好描述符之后,通常要通过命令队列将这些描述符提交给 GPU。GPU 在执行这些命令队列时,将会通过 GPUDescriptorHandle 访问这些描述符。这个过程保证了在 GPU 使用资源之前,这些资源已经在 CPU 端正确地初始化和更新。
61 |
62 | 在GPU使用DescriptorHeap中的Descriptor期间,必须确保该DescriptorHeap不会被CPU修改。通常通过CommandList的同步机制保证。
63 |
64 | # D3D12_GPU_VIRTUAL_ADDRESS
65 | ID3D12Resource有个方法`GetGPUVirtualAddress`可以直接得到一个资源的GPU地址。这个地址可以用于直接绑定到CommandList:
66 | ```c++
67 | virtual void SetGraphicsRootShaderResourceView(
68 | _In_ UINT RootParameterIndex,
69 | _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0;
70 | virtual void SetGraphicsRootUnorderedAccessView(
71 | _In_ UINT RootParameterIndex,
72 | _In_ D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) = 0;
73 | ```
74 | 直接用GPU地址绑定,提供了最低的使用开销。适合频繁更新的小资源,如`ConstantBuffer`,`StructuredBuffer`。
75 |
76 | 用DescriptorTable,尽管引入了一些额外的间接层,但其优势在于高度的灵活性和通用性。使得复杂的着色器资源管理变得更加容易,View的管理更加规范化。
--------------------------------------------------------------------------------
/DX12/Fundation.md:
--------------------------------------------------------------------------------
1 | ## Createing a basic Direct3D 12 component
2 |
3 | 1. Vertex Data and Input layout description
4 | 在CPU端将单个顶点的数据存储在一块连续内存空间(通常是一个结构体),然后需要向GPU描述其内容组成(InputLayoutDescrition).
5 | ```c++
6 | typedef struct D3D12_INPUT_LAYOUT_DESC
7 | {
8 | const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs;
9 | UINT NumElements;
10 | }D3D12_INPUT_LAYOUT_DESC;
11 | ```
12 | 其中, 结构体中有多少个数据成员,D3D12_INPUT_LAYOUT_DESC中就有多少个`D3D12_INPUT_ELEMENT_DESC`,即结构体中每一个成员都对应一个`D3D12_INPUT_ELEMENT_DESC`。
13 | ```c++
14 | typedef struct D3D12_INPUT_ELEMENT_DESC
15 | {
16 | LPCSTR SemanticName; // VertexShader中输入参数的名字
17 | UINT SemanticIndex; // 每一个名字默认为数组,这即为它的索引,
18 | DXGI_FORMAT Format; // GPU解释这个元素的格式,DXGI_FORMAT_R32G32B32_FLOAT
19 | UINT InputSlot; // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-input-assembler-stage-getting-started
20 | UINT AlignedByteOffset; // 在绑定到特定Inputslot的顶点数据c++Struct中,当前表示的元素的首地址偏移量
21 | D3D12_INPUT_CLASSIFICATION InputSlotClass;// D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA(另一个用于实现Instanceing)
22 | UINT InstanceDataStepRate; // 0, 用于实现instancing
23 | } D3D12_INPUT_ELEMENT_DESC;
24 | ```
25 | 
26 | `D3D12_INPUT_ELEMENT_DESC`将顶点数据结构体中的一个元素映射到顶点着色器中的一个输入参数。SemanticName和SemanticIndex描述了一个VertexShader中的参数,SemanticName是这个参数名,SemanticIndex是索引,即认为有多个同样SemanticName的参数,在VertexShader输入参数中直接在相应SemanticName后加上索引即可,为0可以不加。
27 |
28 | 这通常和PS,VS shader 一起设置在`D3D12_GRAPHICS_PIPELINE_STATE_DESC`中。
29 |
30 | 2. ID3D12Resource
31 | D2D12中,所有的资源均用ID3D12Resource对象表示。包括VertexBuffer和纹理。
32 |
33 | 创建时构建一个D3DX12_RESOURCE_DESC描述要创建的资源,其中D3DX12_RESOURCE_DESC::D3D12_RESOURCE_DIMENSION用于区分Buffer和Texture,调用`ID3D12Device`的方法(ID3D12Device::CreateCommittedResource)创建ID2D12Resource。
34 |
35 | CD3DX12_RESOURCE_DESC有一些方法只需要简单的几个必要的参数即可创建D3DX12_RESOURCE_DESC,可以简化Desc的创建过程。
36 |
37 | 这些资源通常位于不同类型的堆中(物理内存池)。
38 | https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_heap_type
39 | ```c++
40 | D3D12_HEAP_TYPE_DEFAULT : GPU访问快,读写, 但是CPU无法访问。大多数堆和资源都在这儿,通常通过Upload堆中的资源初始化
41 | D3D12_HEAP_TYPE_UPLOAD :优化的CPU访问,但GPU访问效率不高。通常用于 CPU-write-once, GPU-read-once data。
42 | D3D12_HEAP_TYPE_READBACK : 用于CPU从GPU读回数据。GPU-write-once, CPU-readable data.
43 | D3D12_HEAP_TYPE_CUSTOM
44 | ```
45 | 通常,一些静态的物体每一帧都不会发生改变,应该被保存在DefaultHeap中,但DefaultHeap又不可被GPU读取,所以还要先把数据传到UploadHeap,由它把资源上传至GPU,再复制到DeafultHeap中。
46 |
47 | 这一过程需要调用一系列D3D的函数:
48 |
49 | 1. 创建这两种Buffer(UploadHeap,DefaultHeap),其中这两种Buffer的状态:
50 | * DefaultBuffer D3D12_RESOURCE_STATE_COPY_DEST,因为稍后要把buffer Copy到这儿来
51 | * UploadBuffer D3D12_RESOURCE_STATE_GENERIC_READ, 稍后从中读取Buffer copy到DefaultBuffer中
52 | 2. 将真正的Buffer数据用D3D12_SUBRESOURCE_DATA表示
53 | 3. 借助d3dx12.h中的UpdateSubresources<1>方法, 先调用ID3D12Device::GetCopyableFootprints获取Dest的Footprints
54 | * 调用UpdateSubresources()
55 | * 将Buffer数据读到中间UploadHeap的Resource中(ID3D12Resource::Map())
56 | * 然后调用ID3D12GraphicsCommandList::CopyBufferRegion或ID3D12GraphicsCommandList::CopyTextureRegion将UploadHeap中的Resource复制到DefaultHeap中的Resource
57 | 4. 把DefaultBuffer中的Resource的状态转换为我们期望的用途(D3D12_RESOURCE_STATE_INDEX_BUFFER)
58 | * 创建Barrier, CD3DX12_RESOURCE_BARRIER::Transition()
59 | * ID3D12GraphicsCommandList::ResourceBarrier()
60 | 5. 完成上述操作后,必须在得知复制命令已经完成之后(Fence)才能释放uploadBuffer.
61 | * Descriptor heap
62 | An array of descriptors. Where each descriptor fully describes an object to the GPU.
63 |
64 | * Command allocator
65 | A command allocator manages the underlying storage for command lists and bundles.
66 |
67 | * Root signature
68 | Defines what resources are bound to the graphics pipeline .
69 |
70 | * Pipeline state object
71 | A pipeline state object maintains the state of all currently set shaders as well as certain fixed function state objects(such as the input assembler, tesselator, rasterizer and output merger)
72 |
73 | * Fence
74 | A fence is used to synchronize the CPU (see Multi-engine synchronization)
75 |
76 |
--------------------------------------------------------------------------------
/DX12/HLSL.ResourceBinding.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 7pe1f9prec6xe55krkd107r
3 | title: ResourceBinding
4 | desc: ''
5 | updated: 1669986055386
6 | created: 1669771627659
7 | ---
8 |
9 | # Resource type and arrays
10 |
11 | Shader Model 5.1资源绑定语法中使用`register`关键字传达资源绑定信息给HLSL编译器。例如:
12 |
13 | ```H
14 | Texture2D tex1[4] : register(t3)
15 | ```
16 |
17 | 这个语句声明了一个4个Texture的Array,分别被绑定到slots t3,t4,t5和t6。即从绑定的第一个t3往后顺延。
18 |
19 | HLSL中的Direct3D12资源绑定到逻辑寄存器空间(rigster sapce)内的虚拟寄存器:
20 |
21 | * t —— Shader resource view(SRV)
22 | * s —— Samplers
23 | * u —— unordered access views(UAV)
24 | * b —— Constant buffer views(CBV)
25 |
26 | 引用这个Shader的RootSignature必须与声明的Register slots兼容。例如:
27 |
28 | ```H
29 | DescriptorTable( CBV(b1), SRV(t0,numDescriptors=99), CBV(b2) )
30 | ```
31 |
32 | 这个DescriptorTable所在的RootSignature就和Texture slot3 ~ 6的使用兼容,这个DescriptorTable用到了t0~t99,包含了t3~t6。
33 |
34 | Resource 声明可以是Scalar,1D array,或者multidimendional array:
35 |
36 | ```c++
37 | Texture2D tex1 : register(t3, space0)
38 | Texture2D tex2[4] : register(t10)
39 | Texture2D tex3[7][5][3] : register(t20, space1)
40 | ```
41 |
42 | SM5.1有着与SM5.0一样的资源类型和元素类型。SM5.1的资源声明更灵活,仅会被Runtime下的硬件所限制。关键字space指定了被声明的变量绑定到哪一个寄存器空间。如果缺失space关键字,将会使用默认寄存器空间索引0,上面tex2声明的Resource就绑定在space0中。register(t3,0)永远不会和register(t3, sapce1)冲突,也不会与任何其它寄存器空间内的t3冲突。
43 |
44 | Array resource可以没有size,声明时指定第一个维度为空或者0:
45 |
46 | ```H
47 | Texture2D tex1[] : register(t0)
48 | ```
49 |
50 | 匹配的descriptor table可以是:
51 |
52 | ```H
53 | DescriptorTable( CBV(b1), UAV(u0, numDescriptors = 4), SRV(t0, numDescriptors=unbounded) )
54 | ```
55 |
56 | HLSL中的固定size数组与decriptor table中的numDescriptor设置的固定数字相匹配,HLSL中的无界数组与desscriptor中unbounded声明匹配。
57 |
58 | 多维数组也可以是无界的,在虚拟寄存器空间,多维数组会被展平:
59 |
60 | ```c++
61 | Texture2D tex2[3000][10] : register(t0, space0); // t0-t29999 in space0
62 | Texture2D tex3[0][5][3] : register(t5, space1)
63 | ```
64 |
65 | 同一逻辑寄存器空间下的资源范围不可以重叠,声明的不同资源类型(t,s,u,b)的寄存器范围不会重叠,这些都包括unbounded range。上面的tex2和tex3声明在不同的寄存器空间,所以不会重叠。
66 |
67 | 访问数组资源直接用索引即可:
68 |
69 | ```H
70 | Texture2D tex1[400] : register(t3);
71 | sampler samp[7] : register(s0);
72 | tex1[myMaterialID].Sample(samp[samplerID], texCoords);
73 | ```
74 | 对索引(myMaterialID,samplerID)有一个重要的默认限制,在一个[wave](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/hlsl-shader-model-6-0-features-for-direct3d-12#terminology)中索引不能改变。即使根据实例更改索引也算作变化。
75 |
76 | 如果需要改变索引,需要在index上指明*NonUniformResourceIndex*限定符:
77 | ```c++
78 | tex1[NonUniformResourceIndex(myMaterialID)].Sample(samp[NonUniformResourceIndex(samplerID)], texCoords);
79 | ```
80 | 某些硬件上,使用此限定符生成额外的代码强制跨线程执行的正确性,但性能成本很小。如果没有指明这个限定符却更改了索引,执行结果将是undefined。
81 |
82 | # Descriptor arrays and texture arrays
83 |
84 | 从DirectX 10开始支持`Texture arrays`。Texture arrays只要一个descriptor,所有元素必须有一样的format,width,height和mip count。数组必须在一个连续的虚拟地址空间。下面的代码展示了如何从shader中访问texture array:
85 | ```c++
86 | Texture2DArray myTex2DArray : register(t0); // t0
87 | float3 myCoord(1.0f,1.4f,2.2f); // 2.2f is array index (rounded to int)
88 | color = myTex2DArray.Sample(mySampler, myCoord);
89 | ```
90 | 在texture array中,索引可以自由改变,不需要任何限定符。
91 |
92 | 等价的descriptor array:
93 | ```c++
94 | Texture2D myArrayOfTex2D[] : register(t0); // t0+
95 | float2 myCoord(1.0f, 1.4f);
96 | color = myArrayOfTex2D[2].Sample(mySampler,myCoord); // 2 is index
97 | ```
98 | 这里的索引不再是浮点数。Descriptor array在维度上提供了更多的灵活性。类型(Texture2D)不能改变,但是format,width,height和mip数都可以改变。
99 |
100 | texture array 的 descriptor array也是合法的:
101 |
102 | ```c++
103 | Texture2DArray myArrayOfTex2DArrays[2] : register(t0);
104 | ```
105 |
106 | 如果一个结构体中包含descriptor,则不可以声明这个结构体的数组,下面的代码是不被支持的:
107 |
108 | ```c++
109 | struct myStruct {
110 | Texture2D a;
111 | Texture2D b;
112 | ConstantBuffer c;
113 | };
114 | myStruct foo[10000] : register(....);
115 | ```
116 | 这样定义的内存布局是abcabcabc..., 由于HLSL的限制这是不被支持的。
117 |
118 | # Resource Aliasing
119 |
120 | 在HLSL shader中指定的reource range是逻辑range。通过RootSignature机制可以把它们绑定到heap range。通常一个logical range对应的heap range不应该与其它heap range重叠。但RootSignature的机制可以支持alias,heap range可以重叠, 一个descriptor可以映射到多个logical range。例如,上面的tex2和tex3可以映射到同一个heap range,最终的效果就是在HLSL程序中支持texture别名。如果需要这种别名,要使用D3D10_SHADER_RESOURCES_MAY_ALIAS选项编译shader,在Effect-Compiler Tool(FXC)工具设置/res_may_alias选项。在假定资源可能是alias时,这个选项会生成正确的代码阻止一些load/store优化。
121 |
122 | # Divergence and derivatives
123 |
124 | SM5.1对资源索引没有限制,`tex2[idx].Sample(...)`中,索引idx可以是字面常量,cbuffer constant,或者插值的结果。虽然编程模型提供了如此大的灵活性,还是有一些问题需要注意:
125 |
126 | * 如果索引跨四边形发生变化,则硬件计算的衍生数据(LOD)可能是不确定的。这种情况下,HLSL编译器会尽可能地发出警告,但不会停止编译。
127 |
128 | * 如果资源索引有差异,相较于索引不变的情况下,性能会下降,因为硬件需要针对多个资源执行操作。必须在HLSL代码中用*NonUniformResourceIndex*标记可能出现差异的资源索引。否则结果是不确定的。
129 |
130 | # UAVs in pixel shaders
131 |
132 | SM5.1 对pixel shader中的UAV range没有施加限制,与SM5.0一样。
133 |
134 | # Constant Buffers
135 |
136 | SM5.1中constant buffers的语法有了改变,开发者现在可以索引constant buffers,SM5.1引入了ConstantBuffer"template"构造:
137 | ```c++
138 | struct Foo
139 | {
140 | float4 a;
141 | int2 b;
142 | };
143 | ConstantBuffer myCB1[2][3] : register(b2, space1);
144 | ConstantBuffer myCB2 : register(b0, space1);
145 | ```
146 | 上面的代码声明了类型为*Foo*的constant buffer变量*myCB1*,size为6,还有一个标量constant buffer变量myCB2。然后可以直接索引这些变量:
147 | ```c++
148 | myCB1[i][j].a.xyzw
149 | myCB2.b.yy
150 | ```
151 | 字段a和b不会成为全局变量,而是必须被看作字段。为了向后兼容,SM5.1支持老的cbuffer的标量形式。下面的语句会使'a'和'b'称为全局的,只读变量,但是不可以索引:
152 | ```c++
153 | cbuffer : register(b1)
154 | {
155 | float4 a;
156 | int2 b;
157 | };
158 | ```
159 | 当前,shader编译器仅对user-defined结构体支持ConstantBuffer template。
160 |
161 | 为了兼容,HLSL编译器会为声明在space0的range自动分配resource register。如果声明资源时没有指明space,默认使用space0。编译器会启发式地找到第一个合适的register。这种分配可以通过反射API获取,它经过扩展添加了space字段,BindPoint字段表明资源寄存器范围的下限。
162 |
163 | # Bytecode changes in SM5.1
164 |
165 | SM5.1更改了资源寄存器声明和引用的指令。声明一个寄存器变量的语法,和组织共享内存寄存器一样:
166 |
167 | ```c++
168 | Texture2D tex0 : register(t5, space0);
169 | Texture2D tex1[][5][3] : register(t10, space0);
170 | Texture2D tex2[8] : register(t0, space1);
171 | SamplerState samp0 : register(s5, space0);
172 |
173 | float4 main(float4 coord : COORD) : SV_TARGET
174 | {
175 | float4 r = coord;
176 | r += tex0.Sample(samp0, r.xy);
177 | r += tex2[r.x].Sample(samp0, r.xy);
178 | r += tex1[r.x][r.y][r.z].Sample(samp0, r.xy);
179 | return r;
180 | }
181 | ```
182 | 这会被展开成:
183 | ```c++
184 | // Resource Bindings:
185 | //
186 | // Name Type Format Dim ID HLSL Bind Count
187 | // ------------------------------ ---------- ------- ----------- ----- --------- ---------
188 | // samp0 sampler NA NA S0 a5 1
189 | // tex0 texture float4 2d T0 t5 1
190 | // tex1[0][5][3] texture float4 2d T1 t10 unbounded
191 | // tex2[8] texture float4 2d T2 t0.space1 8
192 | //
193 | //
194 | //
195 | // Input signature:
196 | //
197 | // Name Index Mask Register SysValue Format Used
198 | // -------------------- ----- ------ -------- -------- ------- ------
199 | // COORD 0 xyzw 0 NONE float xyzw
200 | //
201 | //
202 | // Output signature:
203 | //
204 | // Name Index Mask Register SysValue Format Used
205 | // -------------------- ----- ------ -------- -------- ------- ------
206 | // SV_TARGET 0 xyzw 0 TARGET float xyzw
207 | //
208 | ps_5_1
209 | dcl_globalFlags refactoringAllowed
210 | dcl_sampler s0[5:5], mode_default, space=0
211 | dcl_resource_texture2d (float,float,float,float) t0[5:5], space=0
212 | dcl_resource_texture2d (float,float,float,float) t1[10:*], space=0
213 | dcl_resource_texture2d (float,float,float,float) t2[0:7], space=1
214 | dcl_input_ps linear v0.xyzw
215 | dcl_output o0.xyzw
216 | dcl_temps 2
217 | sample r0.xyzw, v0.xyxx, t0[0].xyzw, s0[5]
218 | add r0.xyzw, r0.xyzw, v0.xyzw
219 | ftou r1.x, r0.x
220 | sample r1.xyzw, r0.xyxx, t2[r1.x + 0].xyzw, s0[5]
221 | add r0.xyzw, r0.xyzw, r1.xyzw
222 | ftou r1.xyz, r0.zyxz
223 | imul null, r1.yz, r1.zzyz, l(0, 15, 3, 0)
224 | iadd r1.y, r1.z, r1.y
225 | iadd r1.x, r1.x, r1.y
226 | sample r1.xyzw, r0.xyxx, t1[r1.x + 10].xyzw, s0[5]
227 | add o0.xyzw, r0.xyzw, r1.xyzw
228 | ret
229 | // Approximately 12 instruction slots are used.
230 | ```
231 | 在Shader bytecode中,每一个shader resource range都有一个ID。例如,在shader bytecode中,tex1(t10)texture array称为了'T1'。给每个resource range一个唯一ID可以实现:
232 | * 在一个指令中明确标识一个被索引的resource range()。
233 | * 在声明中附加一些属性,元素类型,stride size,raster operation mode。
234 |
235 | 注意,Range的ID与HLSL的下界声明无关。
236 |
237 | 反射资源绑定的顺序和shader声明指令的顺序是一致的,这样可以帮助识别对应的HLSL变量和bytecode ID。
238 |
239 | SM5.1中的每一个声明指令都使用三个操作数:Range ID, lower和upper bounds。还需要一个额外的token指定register space。一些其它的token也会用于描述额外的range属性,cbuffer或结构体buffer声明指令会有cbuffer或者structure的size。详细的编码细节可以在d3d12TokenizedProgramFormat.h and D3D10ShaderBinary::CShaderCodeParser中找到。
240 |
241 | Example:
242 | ```c++
243 | Texture2D foo[5] : register(t2);
244 | Buffer bar : register(t7);
245 | RWBuffer dataLog : register(u1);
246 |
247 | Sampler samp : register(s0);
248 |
249 | struct Data
250 | {
251 | UINT index;
252 | float4 color;
253 | };
254 | ConstantBuffer myData : register(b0);
255 |
256 | Texture2D terrain[] : register(t8); // Unbounded array
257 | Texture2D misc[] : register(t0,space1); // Another unbounded array
258 | // space1 avoids overlap with above t#
259 |
260 | struct MoreData
261 | {
262 | float4x4 xform;
263 | };
264 | ConstantBuffer myMoreData : register(b1);
265 |
266 | struct Stuff
267 | {
268 | float2 factor;
269 | UINT drawID;
270 | };
271 | ConstantBuffer myStuff[][3][8] : register(b2, space3)
272 | ```
273 |
--------------------------------------------------------------------------------
/DX12/MiniEngine.Mesh.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 94w8v5q4lcpux5c3drc5m81
3 | title: Mesh
4 | desc: ''
5 | updated: 1670719528005
6 | created: 1670719528005
7 | ---
8 |
--------------------------------------------------------------------------------
/DX12/MiniEngine.Model.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 0mgnzscvpzf7jjo1ta03whf
3 | title: Model
4 | desc: ''
5 | updated: 1716596663492
6 | created: 1670806808115
7 | ---
8 | `Model`工程实现了加载gltf文件,并转成自己的mini格式的Model数据文件。还提供了Mesh渲染的基本渲染管线配置。
9 |
10 | # 模型加载与转换
11 | 对于一个加载进来的gltf文件,需要首先转换成自己定义的,方便渲染的格式,并直接以这个格式序列化到磁盘上,作为自定义的模型文件格式。这样可以做到加载自己定义的模型文件就直接可以开始渲染,不用再对模型数据做额外的处理。
12 |
13 | 首先定义文件头结构`FileHeader`,包括格式,版本等基本文件信息,以及基本的模型信息:node数量,Mesh数量,材质数量,各个Buffer的数据大小,方便读取后续的数据。
14 | ```c++
15 | struct FileHeader
16 | {
17 | char id[4]; // "MINI"
18 | uint32_t version; // CURRENT_MINI_FILE_VERSION
19 | uint32_t numNodes;
20 | uint32_t numMeshes;
21 | uint32_t numMaterials;
22 | uint32_t meshDataSize;
23 | uint32_t numTextures;
24 | uint32_t stringTableSize;
25 | uint32_t geometrySize;
26 | uint32_t keyFrameDataSize; // Animation data
27 | uint32_t numAnimationCurves;
28 | uint32_t numAnimations;
29 | uint32_t numJoints; // All joints for all skins
30 | float boundingSphere[4];
31 | float minPos[3];
32 | float maxPos[3];
33 | };
34 | ```
35 | 实际的`ModelData`结构体:
36 | ```c++
37 | struct ModelData
38 | {
39 | BoundingSphere m_BoundingSphere;
40 | AxisAlignedBox m_BoundingBox;
41 | std::vector m_GeometryData;
42 | std::vector m_AnimationKeyFrameData;
43 | std::vector m_AnimationCurves;
44 | std::vector m_Animations;
45 | std::vector m_JointIndices;
46 | std::vector m_JointIBMs;
47 | std::vector m_MaterialTextures; // 对应材质的textures , 一个TextureData里面多个texture, 对应texture的值是下面"m_TextureNames"的index,没有就是 0xFFFF
48 | // addressModes 是采样器的flag, 用一个uint32记下了所有对应texture的采样参数
49 | std::vector m_MaterialConstants; // 材质constants参数, baseColorFactor ...
50 | std::vector m_Meshes;
51 | std::vector m_SceneGraph;
52 | std::vector m_TextureNames; // texture 的相对path(文件名)
53 | std::vector m_TextureOptions; // 每个texture对应的纹理选项:TexConversionFlags, 没有就是0xFF
54 | };
55 | ```
56 | 在加载原始`gltf`文件后,从`gltf`文件构建`ModelData`。
57 | ## 构建材质
58 | 提取Texture,在Model文件中,纹理通常由相对于模型文件的路径表示,通常直接就是文件名,所以直接把`glTF::Asset`中的images路径按顺序复制给`m_TextureNames`。
59 |
60 | 一个Model通常有多个材质。`m_MaterialConstants`与`m_MaterialTextures`一一对应,`m_MaterialConstants`中存储的是每个材质的`Constants`参数:
61 | ```c++
62 | struct MaterialConstantData
63 | {
64 | float baseColorFactor[4]; // default=[1,1,1,1]
65 | float emissiveFactor[3]; // default=[0,0,0]
66 | float normalTextureScale; // default=1
67 | float metallicFactor; // default=1
68 | float roughnessFactor; // default=1
69 | uint32_t flags;
70 | };
71 | ```
72 | 表示这个材质的baseColor系数,emissive系数,metallic,roughness等参数。`m_MaterialTextures`中的元素表示的是一个材质所包含的纹理:
73 | ```c++
74 | enum { kBaseColor, kMetallicRoughness, kOcclusion, kEmissive, kNormal, kNumTextures };
75 | // Used at load time to construct descriptor tables
76 | struct MaterialTextureData
77 | {
78 | uint16_t stringIdx[kNumTextures];
79 | uint32_t addressModes;
80 | };
81 | ```
82 | 渲染管线预先定义好了支持的纹理枚举,`stringIdx`中,以纹理枚举为Index,表示对应纹理在`m_TextureNames`中的索引位置,没有就是0xFFFF,即uint16_t的最大值。`addressModes`是采样器的flag, 用一个uint32记下了所有对应texture的采样参数,按这里原来的写法,每个纹理用了四位记下两个参数,一共五张,32位绰绰有余。
83 |
84 |
85 |
86 | `m_TextureOptions`保存每个Texture的属性,与`m_TextureNames`一一对应,这是每个纹理独立于材质的属性信息:
87 | ```c++
88 | enum TexConversionFlags
89 | {
90 | kSRGB = 1, // Texture contains sRGB colors
91 | kPreserveAlpha = 2, // Keep four channels
92 | kNormalMap = 4, // Texture contains normals
93 | kBumpToNormal = 8, // Generate a normal map from a bump map
94 | kDefaultBC = 16, // Apply standard block compression (BC1-5)
95 | kQualityBC = 32, // Apply quality block compression (BC6H/7)
96 | kFlipVertical = 64,
97 | };
98 | ```
99 | 最后,根据`m_TextureOptions`对所有纹理进行格式转换,压缩等操作,
100 |
101 | ## Mesh
102 | 与Mesh相关的数据结构有两个,Mesh:
103 | ```c++
104 | struct Mesh
105 | {
106 | float bounds[4]; // A bounding sphere
107 | uint32_t vbOffset; // BufferLocation - Buffer.GpuVirtualAddress
108 | uint32_t vbSize; // SizeInBytes
109 | uint32_t vbDepthOffset; // BufferLocation - Buffer.GpuVirtualAddress
110 | uint32_t vbDepthSize; // SizeInBytes
111 | uint32_t ibOffset; // BufferLocation - Buffer.GpuVirtualAddress
112 | uint32_t ibSize; // SizeInBytes
113 | uint8_t vbStride; // StrideInBytes
114 | uint8_t ibFormat; // DXGI_FORMAT
115 | uint16_t meshCBV; // Index of mesh constant buffer, of GraphNode m_SceneGraph
116 | uint16_t materialCBV; // Index of material constant buffer
117 | uint16_t srvTable; // Offset into SRV descriptor heap for textures
118 | uint16_t samplerTable; // Offset into sampler descriptor heap for samplers
119 | uint16_t psoFlags; // Flags needed to request a PSO
120 | uint16_t pso; // Index of pipeline state object
121 | uint16_t numJoints; // Number of skeleton joints when skinning
122 | uint16_t startJoint; // Flat offset to first joint index
123 | uint16_t numDraws; // Number of draw groups
124 |
125 | struct Draw
126 | {
127 | uint32_t primCount; // Number of indices = 3 * number of triangles
128 | uint32_t startIndex; // Offset to first index in index buffer
129 | uint32_t baseVertex; // Offset to first vertex in vertex buffer
130 | };
131 | Draw draw[1]; // Actually 1 or more draws
132 | };
133 | ```
134 | 有一个数组`m_Meshes`,保存所有Mesh。每个Mesh主要保存vertex,index buffer在`m_GeometryData`的起始位置和大小,还有材质信息,以及Runtime下渲染的一些Buffer信息。
135 |
136 | 一个Model的所有Vertex,index buffer都放在一个大的byte数组`m_GeometryData`中。
137 |
138 | `GraphNode`数组`m_SceneGraph`代表场景中所有可渲染的实体,包含LocalTransform,Mesh只有几何数据。
139 |
140 | Mesh对所有它用到的数据都是通过Index间接引用。meshCBV就是表示Transform等基本CBV信息的Node的引用。
141 | ```c++
142 | struct GraphNode // 96 bytes
143 | {
144 | Math::Matrix4 xform;// all Local space
145 | Math::Quaternion rotation;
146 | Math::XMFLOAT3 scale;
147 |
148 | uint32_t matrixIdx : 28; // 当前Node在m_SceneGraph的Index
149 | uint32_t hasSibling : 1; // 是否有右兄弟节点
150 | uint32_t hasChildren : 1;
151 | uint32_t staleMatrix : 1;
152 | uint32_t skeletonRoot : 1;
153 | };
154 | ```
155 | 在构建时,遍历源模型文件的`Scene`,构建`m_SceneGraph`,同时遇到Mesh就构建Mesh。
156 |
157 | 从源模型文件构建Mesh的indices时需要注意:
158 | * Primitive可能不是三角面,此时可能无法处理
159 | * 源Primitive可能没有indices,Primitive中的顶点按顺序作为三角面绘制,此时要手动生成indices
160 | * 源indices的类型不一定是int32,我们可以根据源indices的最大值,确定我们indices是int32的,还是int16的,可以节省内存(是否有必要)。
161 | * 可以先对顶点数据进行优化,对indices进行重排,vertex cache optimization. 最大化"post-transform vertex cache reuse"。这种优化通常与硬件的CacheSize相关,CacheSize不匹配会导致负优化。
162 | ```
163 | OptimizeFaces()
164 | https://github.com/microsoft/DirectXMesh/wiki/OptimizeFaces
165 | ```
166 |
167 | 读取Mesh顶点数据时,通过原始文件的数据信息,有什么顶点数据就读什么顶点数据,并且用psoFlags表明有什么顶点数据,是否开启AlphaBlend等所以与Pso相关的设置,后面就用这个确定使用或创建什么样的PSO。`OptimizeMesh()`
168 |
169 |
170 |
171 |
172 | ## Header m_Header
173 | 保存这个Model的一些基本信息:
174 | * mesh数量
175 | * material数量
176 | * 顶点数据Size
177 | * 索引数据Size
178 | * BoundingBox
179 | 且这个结构体与数据Header的布局一致,可以直接读到这个结构的内存块中。
180 |
181 | 然后按照这些Header的数据读取后续的大块数据,通常顶点,索引数据都是放在一起的,算出它们的SIze后可以可以直接读到一个大的Buffer中(UploadBuffer),然后通过地址偏移引用它们。
182 |
183 | 然后加载所有纹理,根据材质的设置,这里所有材质都是6张纹理,所有这些纹理SRV保存在一块连续heap中,没有的用默认texture代替。这里表明,所有材质都是预先设置好的。
184 |
185 | ## indices buffer optimize
186 | 对indices进行重排,vertex cache optimization. 最大化"post-transform vertex cache reuse"。这种优化通常与硬件的CacheSize相关,CacheSize不匹配会导致负优化。
187 |
188 | `OptimizeFaces()`
189 |
190 | https://github.com/microsoft/DirectXMesh/wiki/OptimizeFaces
191 |
192 | # 自定义模型文件格式
193 | 总体目标:
194 | * 最大化运行时效率
195 | * 加载即可使用,模型顶点、索引Buffer最好是可直接上传到GPU的格式,MaterialConstant也是,可直接上传到CBV。
196 | * 这样避免了需要在CPU开辟额外的内存存放Buffer
197 | * 数据紧密排列,数据块各个部分的Size在Header记好,读取的时候,逻辑上保证和写的时候一样,最小化文件数据。
198 | * 这样容易出错,需要更稳定的序列化系统?
199 | * 加载的时候直接各种GPU Buffer构建好
200 |
201 | 保存模型时:
202 | * 各种顶点数据的优化要先做好
203 | * 包括材质,纹理信息,都一并保存
204 |
205 |
206 | # FQA
207 |
208 | ## 16位(2byte) IndexBuffer必须4byte对齐
209 | D3D12 ERROR: ID3D12CommandList::DrawIndexedInstanced: Vertex buffer GPU address for input slot 0 is not aligned. The GPU address (0x00000000109D65BA) % the stride alignment (4) must be compatible with the alignment requirements of each component in the input layout. I.e, the final computed memory address for each component must be aligned according to its format requirements. [ EXECUTION ERROR #1348: COMMAND_LIST_DRAW_ELEMENT_OFFSET_UNALIGNED]
--------------------------------------------------------------------------------
/DX12/MiniEngine.PipelineState.md:
--------------------------------------------------------------------------------
1 | # Input element layout
2 | D3D12_INPUT_ELEMENT_DESC 是 Direct3D 12 中描述输入布局元素的结构,它用于定义顶点输入的格式和方式。每个 D3D12_INPUT_ELEMENT_DESC 结构体描述一个输入元素(如顶点的位置、法线、纹理坐标等)。它的定义如下:
3 | ```c++
4 | typedef struct D3D12_INPUT_ELEMENT_DESC {
5 | LPCSTR SemanticName;
6 | UINT SemanticIndex;
7 | DXGI_FORMAT Format;
8 | UINT InputSlot;
9 | UINT AlignedByteOffset;
10 | D3D12_INPUT_CLASSIFICATION InputSlotClass;
11 | UINT InstanceDataStepRate;
12 | } D3D12_INPUT_ELEMENT_DESC;
13 | ```
14 | 下面是各个属性的解释:
15 |
16 | 1. SemanticName:
17 | 类型: LPCSTR
18 | 说明: 指定输入元素的语义名称(如 "POSITION", "NORMAL", "TEXCOORD" 等)。语义名称用于将顶点着色器的输入与输入布局中的元素匹配。
19 |
20 | 2. SemanticIndex:
21 | 类型: UINT
22 | 说明: 语义的索引,允许区分具有相同语义名称的多个元素。例如,可以有多个纹理坐标("TEXCOORD0", "TEXCOORD1" 等)。
23 |
24 | 3. Format:
25 | 类型: DXGI_FORMAT
26 | 说明: 指定输入元素的数据格式。常见的格式包括 DXGI_FORMAT_R32G32_FLOAT(2D 浮点向量),DXGI_FORMAT_R32G32B32A32_FLOAT(4D 浮点向量)等。
27 |
28 | 4. InputSlot:
29 | 类型: UINT
30 | 说明: 指定输入槽的索引,该索引是绑定顶点缓冲区的标识符。例如,具有多个顶点缓冲区时可以通过不同的槽号来区分。
31 |
32 | 5. AlignedByteOffset:
33 | 类型: UINT
34 | 说明: 输入元素在每个顶点的内存布局中的偏移量,以字节为单位。
35 | D3D12_APPEND_ALIGNED_ELEMENT 的特殊值可以用于自动计算偏移量。
36 |
37 | 6. InputSlotClass:
38 | 类型: D3D12_INPUT_CLASSIFICATION
39 | 说明: 指定输入元素的分类类型,取值为:
40 | D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA: 每个顶点都有一个对应的数据(常用于顶点属性如位置、法线等)。
41 | D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA: 每个实例都有一个对应的数据(常用于实例化渲染)。
42 |
43 | 7. InstanceDataStepRate:
44 | 类型: UINT
45 | 说明: 当 InputSlotClass 为 D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA 时,指定实例数据的步长率。即每几个实例使用相同的数据。例如,当 InstanceDataStepRate 为 1 时,每个实例的数据都是不一样的;如果为 2,则每两个实例使用相同的数据。
46 |
47 | ## 示例
48 | 假设有一个简单的顶点格式,包含位置和纹理坐标,输入布局的描述可能如下:
49 | ```c++
50 | D3D12_INPUT_ELEMENT_DESC inputElementDescs[] =
51 | {
52 | { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
53 | { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
54 | };
55 | ```
56 | 这里的 POSITION 在第 0 个输入槽(vertex buffer slot 0)中的偏移量为 0,格式为 3D 浮点向量;TEXCOORD 在同一槽中,其偏移量是自动计算的(紧跟在 POSITION 属性之后),格式为 2D 浮点向量。
57 |
58 | 通过正确配置 D3D12_INPUT_ELEMENT_DESC 结构体,您能够告知 D3D12 如何从顶点缓冲区读取数据并传递给顶点着色器。
59 |
60 | # Blend desc
61 | 在 Direct3D 12(D3D12)中,D3D12_BLEND_DESC 结构体用于描述混合状态(Blend State)。混合状态控制渲染时如何将新绘制的像素颜色与帧缓冲区中已有像素的颜色进行组合。这对于实现透明效果和其它复杂的渲染效果非常重要。
62 |
63 | D3D12_BLEND_DESC 结构体定义如下:
64 | ```c++
65 | typedef struct D3D12_BLEND_DESC {
66 | BOOL AlphaToCoverageEnable;
67 | BOOL IndependentBlendEnable;
68 | D3D12_RENDER_TARGET_BLEND_DESC RenderTarget[8];
69 | } D3D12_BLEND_DESC;
70 | ```
71 | 1. BOOL AlphaToCoverageEnable:
72 |
73 | 说明: 指定是否启用 Alpha-to-Coverage。Alpha-to-Coverage 是一种多重采样抗锯齿(MSAA)技术,用于在不透明表面和半透明表面之间进行更细粒度的反锯齿效果。当 TRUE 时启用 Alpha-to-Coverage;当 FALSE 时禁用。
74 |
75 | 2. BOOL IndependentBlendEnable:
76 |
77 | 说明: 指定是否启用独立混合。独立混合允许对每个渲染目标分别设置混合选项。当 TRUE 时,可以为每个渲染目标设置不同的混合配置;当 FALSE 时,所有渲染目标使用 RenderTarget[0] 的混合配置。
78 |
79 | 3. D3D12_RENDER_TARGET_BLEND_DESC[8] RenderTarget:
80 |
81 | 说明: 包含最多 8 个 D3D12_RENDER_TARGET_BLEND_DESC 结构体,每个结构体描述一个渲染目标的混合状态。
82 | 其定义如下:
83 | ```c++
84 | typedef struct D3D12_RENDER_TARGET_BLEND_DESC {
85 | BOOL BlendEnable;
86 | BOOL LogicOpEnable;
87 | D3D12_BLEND SrcBlend;
88 | D3D12_BLEND DestBlend;
89 | D3D12_BLEND_OP BlendOp;
90 | D3D12_BLEND SrcBlendAlpha;
91 | D3D12_BLEND DestBlendAlpha;
92 | D3D12_BLEND_OP BlendOpAlpha;
93 | D3D12_LOGIC_OP LogicOp;
94 | UINT8 RenderTargetWriteMask;
95 | } D3D12_RENDER_TARGET_BLEND_DESC;
96 | ```
97 | 以下是各个属性的详细解释:
98 |
99 | 1. BOOL BlendEnable:
100 | 说明: 指定是否启用混合。当 TRUE 时启用混合;当 FALSE 时禁用。
101 |
102 | 2. BOOL LogicOpEnable:
103 | 说明: 指定是否启用逻辑操作。当 TRUE 时启用逻辑操作,使用 LogicOp 属性;当 FALSE 时禁用。使用`LogicOp`定义的操作,直接对两个RGBA的各个分量进行操作。不再使用后面定义的复杂D3D12_BLEND。
104 |
105 | 3. D3D12_LOGIC_OP LogicOp:
106 | 说明: 指定逻辑操作,用于在逻辑操作模式下组合源和目标颜色。例如 D3D12_LOGIC_OP_CLEAR、D3D12_LOGIC_OP_SET 等(仅在 LogicOpEnable 为 TRUE 时适用)。
107 |
108 | 4. UINT8 RenderTargetWriteMask:
109 | 说明: 指定渲染目标的写入掩码,确定哪些颜色通道(Red、Green、Blue、Alpha)能够被写入。可以是 D3D12_COLOR_WRITE_ENABLE_RED、D3D12_COLOR_WRITE_ENABLE_GREEN、D3D12_COLOR_WRITE_ENABLE_BLUE、D3D12_COLOR_WRITE_ENABLE_ALPHA 的组合。
110 |
111 | `SrcBlend`,`DestBlend`,`BlendOp`定义了新绘制的颜色如何与RenderTarget中已有的颜色混合。`SrcBlend`定义新绘制的颜色的系数计算方式,`DestBlend`定义的是RenderTarget中已有的颜色的系数计算方式,`BlendOp`定义了把这两个颜色分别乘以各自的系数后,如何组合起来,计算公式如下:
112 | ```c++
113 | SourceColor=(Rs,Gs,Bs)
114 | DestColor=(Rd,Gd,Bd)
115 | BlendOp = +
116 | ResultColor = SrcBlendFactor * SourceColor + DestBlendFactor * DestColor
117 |
118 | 如果
119 | SrcBlend=D3D12_BLEND_SRC_ALPHA
120 | DestBlend=D3D12_BLEND_INV_SRC_ALPHA
121 | ResultColor = (As) * SourceColor + (1-As) * DestColor
122 |
123 | BlendOp还有以下选择:
124 | D3D12_BLEND_OP_SUBTRACT 从Src的值减去Dest的值
125 | D3D12_BLEND_OP_REV_SUBTRACT 从Dest的值减去Src的值
126 | ```
127 | `SrcBlendAlpha`,`DestBlendAlpha`,`BlendOpAlpha`也是一样的,不过仅针对如何混合最终的Alpha值。
128 | size_t AlignUpWithMask( size_t value, size_t mask )
129 | {
130 | return (((size_t)value + mask) & ~mask);
131 | }
--------------------------------------------------------------------------------
/DX12/MiniEngine.TextureMananger.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: w1744cxqw4qx6l1njhujeew
3 | title: TextureMananger
4 | desc: ''
5 | updated: 1668688851151
6 | created: 1668597462467
7 | ---
8 |
9 | 
10 |
11 | ## GpuResource
12 |
13 | *GpuResource*表示各种GPUResource,对应于D3D12的*ID3D12Resource*,可以表示各种Buffer。这一层直接持有了一个*ComPtr<ID3D12Resource>*。
14 |
15 | ## Texture
16 |
17 | *Texture*则表示一个TextureResource,提供基础的创建方法,Texture的基本信息,宽,高,depth。还有它对应的SRV。
18 |
19 | ## ManangedTexture
20 |
21 | 这一层支持以引用计数的方式被管理,可以在没有被引用时自动销毁。这个对象不直接暴露给Client,而是用一个包装好的Reference。
22 |
23 | ```c++
24 | class ManagedTexture : public Texture
25 | {
26 | friend class TextureRef;
27 |
28 | public:
29 | ManagedTexture( const wstring& FileName );
30 |
31 | // 支持多线程访问时,有可能需要等待别的线程创建好
32 | void WaitForLoad(void) const;
33 | void CreateFromMemory(ByteArray memory, eDefaultTexture fallback, bool sRGB);
34 |
35 | private:
36 |
37 | bool IsValid(void) const { return m_IsValid; }
38 | void Unload(); // 引用计数为0后调用
39 |
40 | // 相对路径,唯一标识这个Texture
41 | std::wstring m_MapKey; // For deleting from the map later
42 | bool m_IsValid;
43 | bool m_IsLoading;
44 | size_t m_ReferenceCount;
45 | };
46 | ```
47 |
48 | ## TextureRef
49 |
50 | 相当于是*ManagedTexture*的Handle,构造函数和析构函数会修改*ManagedTexture*的引用计数,计数为0时,将会调用*ManagedTexture::Unload()*,进而调用*TextureManager::DestroyTexture()*,从Manage的列表中移除,从而释放这个Texture。这里似乎*DESCRIPTOR_HANDLE*并没有从全局Allocator回收利用,而是直接不管了?
51 |
52 | ```C++
53 | class TextureRef
54 | {
55 | public:
56 |
57 | TextureRef( const TextureRef& ref );
58 | TextureRef( ManagedTexture* tex = nullptr );
59 | ~TextureRef();
60 |
61 | void operator= (std::nullptr_t);
62 | void operator= (TextureRef& rhs);
63 |
64 | // Check that this points to a valid texture (which loaded successfully)
65 | bool IsValid() const;
66 |
67 | // Gets the SRV descriptor handle. If the reference is invalid,
68 | // returns a valid descriptor handle (specified by the fallback)
69 | D3D12_CPU_DESCRIPTOR_HANDLE GetSRV() const;
70 |
71 | // Get the texture pointer. Client is responsible to not dereference
72 | // null pointers.
73 | const Texture* Get( void ) const;
74 |
75 | const Texture* operator->( void ) const;
76 |
77 | private:
78 | ManagedTexture* m_ref;
79 | };
80 | ```
81 |
82 | ## TextureMananger
83 |
84 | 所有ManangedTexture的管理器。TextureManager将所有Texture集中在一起,管理它们的创建和销毁。通过一个路径先从已创建的列表中查找是否已经创建,没有则加载文件,并创建Texture,这里会创建DeafultHeap上的Texture资源,通过UploadHeap把数据传上去,并等待命令执行完毕。
85 |
86 | 释放资源时,直接通过路径找到这个MangedTexture,直接释放即可。
87 |
88 | ```c++
89 | namespace TextureManager
90 | {
91 | wstring s_RootPath = L"";
92 | map> s_TextureCache;
93 |
94 | void Initialize( const wstring& TextureLibRoot )
95 | {
96 | s_RootPath = TextureLibRoot;
97 | }
98 |
99 | void Shutdown( void )
100 | {
101 | s_TextureCache.clear();
102 | }
103 |
104 | mutex s_Mutex;
105 |
106 | ManagedTexture* FindOrLoadTexture( const wstring& fileName, eDefaultTexture fallback, bool forceSRGB )
107 | {
108 | ManagedTexture* tex = nullptr;
109 |
110 | {
111 | lock_guard Guard(s_Mutex);
112 |
113 | wstring key = fileName;
114 | if (forceSRGB)
115 | key += L"_sRGB";
116 |
117 | // Search for an existing managed texture
118 | auto iter = s_TextureCache.find(key);
119 | if (iter != s_TextureCache.end())
120 | {
121 | // If a texture was already created make sure it has finished loading before
122 | // returning a point to it.
123 | tex = iter->second.get();
124 | tex->WaitForLoad();
125 | return tex;
126 | }
127 | else
128 | {
129 | // If it's not found, create a new managed texture and start loading it
130 | tex = new ManagedTexture(key);
131 | s_TextureCache[key].reset(tex);
132 | }
133 | }
134 |
135 | Utility::ByteArray ba = Utility::ReadFileSync( s_RootPath + fileName );
136 | tex->CreateFromMemory(ba, fallback, forceSRGB);
137 |
138 | // This was the first time it was requested, so indicate that the caller must read the file
139 | return tex;
140 | }
141 |
142 | void DestroyTexture(const wstring& key)
143 | {
144 | lock_guard Guard(s_Mutex);
145 |
146 | auto iter = s_TextureCache.find(key);
147 | if (iter != s_TextureCache.end())
148 | s_TextureCache.erase(iter);
149 | }
150 |
151 | } // namespace TextureManager
152 | ```
--------------------------------------------------------------------------------
/DX12/RenderLoop.md:
--------------------------------------------------------------------------------
1 | # IDXGISwapChain::Present
2 |
3 | * 将BackBuffer和FrontBuffer进行交换,自动选择合适的
4 | * IDXGISwapChain3::GetCurrentBackBufferIndex得到应该渲染到的BackBuffer
5 | * 如果开了VSync,则会等待垂直同步信号,确保渲染的帧在显示器刷新周期的开始时被呈现。
6 | * 禁用VSync:当调用Present(0, 0)时,Present函数会尽可能立即交换缓冲区,并把绘制的帧提交到显示器上。
7 | * 调用Present之前,只需确保所有渲染命令都已经提交并开始执行,但并不一定要求它们全部完成。
8 | * Present会确保之前的渲染命令都执行完才呈现结果。会启动图形管线中的一些同步机制。
9 |
10 |
11 | # 三缓冲区渲染循环
12 |
13 | 1. 同步
14 | * Wait同步sm_Fence
15 | * 插入同步sm_Fence
16 | 2. 记录渲染命令
17 | * CommandList提交执行即可,不必同步
18 | 3. Present
19 | * 向g_CurrentBuffer渲染本帧最终的结果
20 | * s_SwapChain1->Present(PresentInterval, 0) // 等待显示器刷新次数
21 | * 更新g_CurrentBuffer = (g_CurrentBuffer + 1) % SWAP_CHAIN_BUFFER_COUNT
22 |
23 | 
24 |
25 | * 在录制第n帧时,显示器正显示着第n-2帧。
26 | * 在录制第n帧时,GPU在计算第n-1帧的渲染命令。
27 | * 录制完第n帧所有渲染命令后,调用Present,将显示第n-1帧的内容。
28 | * 然后等待【录制完第n-1帧】时插入的Fence,确保第n-1帧的所有命令执行完毕。
29 | * 插入新的第n帧渲染命令的同步Fence。
30 | * 最后开始下一帧(n+1)的命令录制。
31 |
32 | # FQA
33 | D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: A command list, which writes to a swapchain back buffer, may only be executed on the command queue associated with that buffer.
34 | Swap Chain: 0x0000015F95F38330:'Unnamed Object' -
35 | Swap Chain Buffer: 0x0000015F95F98070:'Unnamed ID3D12Resource Object' -
36 | Swap Chain Buffer's Command Queue: 0x0000015F95D732D0:'Unnamed ID3D12CommandQueue Object' -
37 | Attempted Execution Command Queue: 0x0000015F946C6210:'CommandListManager::m_CommandQueue' [ STATE_SETTING ERROR #907: EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE]
38 | D3D12: Removing Device.
39 |
40 |
41 | D3D12 ERROR: ID3D12CommandList::DrawInstanced: The render target format in slot 0 does not match that specified by the current pipeline state. (pipeline state = R8G8B8A8_UNORM, render target format = R10G10B10A2_UNORM, RTV ID3D12Resource* = 0x000001DBB9365C20:'Unnamed ID3D12Resource Object') [ EXECUTION ERROR #613: RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE]
--------------------------------------------------------------------------------
/DX12/ResourceBarriers.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 6mz2sb5hgt9si424e7hnmhf
3 | title: ResourceBarriers
4 | desc: ''
5 | updated: 1671763060642
6 | created: 1671759902831
7 | ---
8 |
9 | # 目的
10 |
11 | * 减少CPU的总体利用率
12 | * enable driver multi-threading
13 | * enable driver pre-processing
14 |
15 | example:
16 | texture的状态,是作为SRV访问还是RTV?
17 |
18 | D3D11中由Drivers在背后管理资源的状态。从CPU的角度来看,这是很expensive,在多线程的设计情况下会非常复杂。Direct3D12中由App用`ID3D12GraphicsCommandList::ResourceBarrier`管理资源的状态转换。
19 |
20 | # Using the ResourceBarrier API to manage per-resource state
21 | ResourceBarrier通知Driver,同步对一个资源内存的访问。用ResourceBarrierDescription描述一个资源的的状态要怎么转变。
22 |
23 | 有三种ResourceBarrier,对应`D3D12_RESOURCE_BARRIER`中的union。
24 |
25 | * TransitionBarrier Resource的usage状态的转变。用D3D12_RESOURCE_TRANSITION_BARRIER表明资源转换前后的状态。系统会验证同一个commandList中的转换是连续的。使用flag `D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES`表明这个Resource中所有子资源都需要转换。
26 |
27 | * Aliasing barrier 两个资源映射到同一Heap,而且还有重叠部分,AliasingBarrier可以过渡当前哪一个Resource处于使用状态。`TiledReousrce`, `VolumeTiledResource`。
28 |
29 | * Unordered access view(UAV)barrier 表示所有对这个Resource的读写访问在下次读写之前都必须完成。相同的操作之间不用插入UAVBarrier, 两个Draw都只会读这个Resource,或者只会写Resource。
30 |
31 | * https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-resource-barriers-to-synchronize-resource-states-in-direct3d-12
32 |
33 | # 细节
34 | 假设一个D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,从D3D12_RESOURCE_STATE_COPY_DEST转换到D3D12_RESOURCE_STATE_GENERIC_READ:
35 |
36 | 1. 完成所有待处理的写入操作(D3D12_RESOURCE_STATE_COPY_DEST):
37 | * GPU 确保所有当前排队的对资源的写入操作已完成。这包括所有将要写入 COPY_DEST 状态资源的数据,都必须完成。这一步保证了在进入下一个状态之前,数据的一致性和完整性。
38 | 2. 保证数据可见性:
39 | * 对于 COPY_DEST 状态的资源,确保数据写入完成后可供接下来的读取操作使用。这可能涉及对缓存的冲刷或同步,以确保数据对于后续操作完全可见。
40 | 3. 状态标记更新:
41 | * 将资源的内部状态标记从 D3D12_RESOURCE_STATE_COPY_DEST 更新为 D3D12_RESOURCE_STATE_GENERIC_READ。这在内部数据结构中进行更新,以确保对资源后续访问的正确性。
42 | 4. 确保读取操作(StateAfter)的同步:
43 | * 确保在 D3D12_RESOURCE_STATE_GENERIC_READ 状态下,可以安全地读取数据。这个状态下可能包含多个部分类型,比如着色器资源视图(SRV)、常量缓冲视图(CBV)等。
44 | 5. 继续执行后续命令
45 | * 在资源屏障完成后,GPU 将继续处理命令列表中的后续命令。在这一点上,资源已经处于 D3D12_RESOURCE_STATE_GENERIC_READ 状态,并且可以安全地进行读取操作。
46 |
47 | # BEGIN_ONLY 和 END_ONLY
48 | [Split Barriers](https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-resource-barriers-to-synchronize-resource-states-in-direct3d-12#split-barriers)
49 |
50 | [使用SplitBarriers](https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-resource-barriers-to-synchronize-resource-states-in-direct3d-12#example-of-split-barriers)
51 |
52 | 还有两种特殊的转换方式`D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY`和 `D3D12_RESOURCE_BARRIER_FLAG_END_ONLY`。分别只关系资源的StateBefore和StateAfter相关的操作。
53 |
54 | * D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY
55 | * 保证StateBefore状态下的操作全部完成,且这些操作造成的影响对后续的操作都是可见的。
56 | * 不保证资源一定处于StateAfter
57 | * 此后对资源进行操作可能存在不可预见的行为
58 | * 需要逻辑上保证后续操作只有假定资源状态是StateAfter的操作。
59 | * D3D12_RESOURCE_BARRIER_FLAG_END_ONLY
60 | * 会在假设资源的StateBefore相关的操作都已经转换完成。
61 | * 确保资源最后处于StateAfter的状态
62 |
63 | 这两个标记将一个完整的资源转换过程分成两部分,在进行完`BEGIN_ONLY`后,就可以进行一些复杂的计算任务,这些任务必须确保只对资源进行StateAfter状态下的操作,因为状态转换并没有完全完成。
64 | * 最后再进行`END_ONLY`的转换,确保把资源转换成目标状态(StateAfter)。
65 | * 也可以从StateBefore转换到新的StateAfter。
--------------------------------------------------------------------------------
/DX12/WorkSubmitting.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: y227cvhqe3mkhe69n4j8wy6
3 | title: WorkSubmitting
4 | desc: ''
5 | updated: 1668171641477
6 | created: 1668169030699
7 | ---
8 |
9 | # Work Submission in Direct3D12
10 |
11 | 为了更好地支持RenderingWork地复用和多线程的灵活性,需要D3D App提交渲染任务的方式有根本性地改变。与之前的方式有三方面不同:
12 |
13 | 1. 淘汰*ImmediateContext*,支持了多线程。
14 | > 立即上下文是应用程序主线程向 GPU 发送命令的上下文,立即上下文提交的命令直接提交 GPU 的命令队列中,在创建设备的同时创建它。
15 |
16 | 每个CommandList的API看起来像Direct3D11d的渲染方法,也和immediate contexts一样,不是线程安全的。但是可以创建多个Commandlist,同时记录命令。
17 |
18 | 2. App决定如何把渲染调用组织成GPU的工作项。这使得支持重用渲染命令。
19 |
20 | 利用如今的硬件特性,增加了Bundles:
21 |
22 | * First level commandlist -- *direct command lists*
23 | * Second level commandlist -- *bundles*
24 |
25 | *Bundles*的目的是为了把少量的API命令Goup起来,可以在*DirectCommandList*中重复执行。创建Bundle时,Driver会执行尽可能多的预处理,使后面执行时更高效。可以在多个Commandlist中执行,也可以在同一个Commandlist中执行多次。
26 |
27 | [[Bundle也有许多限制|DX12.D3D12#bundle-restrictions]]。
28 |
29 | 3. App显式控制什么时候把Work提交给GPU。
30 |
31 |
32 |
33 | ### Reference
34 |
35 | [图形程序接口简介](https://zhuanlan.zhihu.com/p/452013032)
--------------------------------------------------------------------------------
/DX12/reference.md:
--------------------------------------------------------------------------------
1 |
2 | # DirectX 全家桶
3 | * https://github.com/microsoft/DirectXTK12.git
4 | * https://github.com/microsoft/DirectXTex.git
5 | * https://github.com/microsoft/DirectXMesh.git
6 | * https://github.com/microsoft/DirectXMath.git
--------------------------------------------------------------------------------
/DX12/rootSignature.DefineInHLSL.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: lgq4zrk3klheefzxfkk57zq
3 | title: DefineInHLSL
4 | desc: ''
5 | updated: 1669771515541
6 | created: 1669722484328
7 | ---
8 |
9 | # 反序列化RootSignature
10 |
11 | 如果已经有了序列化的RootSIgnature或者编译好的包含RootSignature的Shader,可以调用*D3D12CreateVersionedRootSignatureDeserializer*,获得一个*ID3D12VersionedRootSignatureDeserializer*接口,再调用*ID3D12VersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion*可以得到反序列化的D3D12_ROOT_SIGNATURE_DESC1。
12 |
13 | # An example HLSL Root Signature
14 |
15 | Root Signature可以在HLSL中以字符串的形式指定,以逗号分隔,描述了RootSignature中的各个组件。
16 |
17 | https://learn.microsoft.com/en-us/windows/win32/direct3d12/specifying-root-signatures-in-hlsl
--------------------------------------------------------------------------------
/DX12/rootSignature.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: i9pbjvbh3hxrmnmfshnc1ab
3 | title: rootSignature
4 | desc: ''
5 | updated: 1669339498998
6 | created: 1668429269162
7 | ---
8 |
9 | *RootSignature*可以绑定一些每一帧都会发生变化的少量数据,并针对这一点进行了优化。
10 |
11 | *RootSignature*是一种由App定义的资源绑定转换,Shader需要用它定位要访问的资源,RootSignature可以存储:
12 |
13 | [GraphicsPipeline](https://learn.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-flow-of-control#resources-and-the-graphics-pipeline)
14 |
15 | * 指向`descriptor heap`的`descriptor tables`的索引,在那里定义了这个`descriptor table`的`layout`。Descriptor。
16 | * 直接绑定一些用户定义的常量,而不用通过*descriptors*和*descriptor tables*。
17 | * 根签名中直接包含非常少量的*descriptor*,例如每次绘制都会更改的常量缓冲区视图 (CBV),从而使应用程序无需将这些描述符放入描述符堆中。
18 |
19 | *Root signature*需要用一组*ROOT_PARAMETER*,描述了Shader的要绑定的全局参数:
20 |
21 | 
22 |
23 | Parameter可以指定三种类型的参数:
24 |
25 | 
26 |
27 | ## D3D12_ROOT_DESCRIPTOR_TABLE
28 |
29 | 表示了在同一个DescriptorHeap上的一组连续范围内的Descriptor。因为CBV,SRV,UAV可以放到同一个descritpor heap上,所以一个descriptor table可以同时容纳这三种Range。而SAMPLER只能在SAMPLER的heap上,所以只能单独用一个Descriptor table表示。
30 |
31 | 
32 |
33 | 向图形管线设置DescriptorTable,必须先绑定Heaps,然后再设置这些Heap所对应的Ddescriptor table的索引,即它所在ROOT_PARAMETER的索引。
34 |
35 | 这里每种类型的Heap最多只能同时存在一个,即同时最多绑定两个Heap,一个CBV_SRV_UAV,一个SAMPLER。
36 |
37 | 
38 |
39 | 调用*SetGraphicsRootDescriptorTable*后,从BaseDescriptor开始的,由RootParameterIndex指向的DescriptorTable描述的这么多Descriptor将会被用于这个RootParameter。
40 |
41 | 改变descriptor heap在一些硬件上可能导致pipeline flush, 所以建议每种类型的heap只存在一个,这样一帧就只用设置一次, 而不是频繁修改它。可以先将descriptor存在一些和shader无关的地方,然后再拷贝到这两个Heap中。
42 |
43 | ## D3D12_ROOT_CONSTANTS
44 |
45 | 它只指定了一些常量:
46 |
47 | 
48 |
49 | 直接用Commandlist的API`SetGraphicsRoot32BitConstant()`就可以绑定。
50 |
51 | ## D3D12_ROOT_DESCRIPTOR
52 |
53 | 这可以直接绑定一个Descriptor,而无需通过DescriptorTable:
54 |
55 | 
56 |
57 | 用Commandlist的方法直接绑定:
58 |
59 | ```c++
60 | SetGraphicsRootConstantBufferView()
61 | SetGraphicsRootShaderResourceView()
62 | SetGraphicsRootUnorderedAccessView()
63 | ```
64 |
65 | 
66 |
67 | # Root Signatures Overview
68 |
69 | * 可以在HLSL代码中定义RootSignaturesDesc,然后通过*D3D12CreateRootSignatureDeserializer*创建一个反序列化接口,最终可以得到RootRignaturesDesc。
70 |
71 | * RS中每个参数类型都消耗固定空间:
72 | * Descriptor table: 1 DWORD
73 | * Root Constant: 1 DWORD
74 | * Root descriptor: 2 DWORDs
75 | 总共不能超过64DWORD。
76 |
77 | ## Root Constants
78 |
79 | Root Constants是一堆32-bit的数据的合集。在HLSL中以constant buffer的形式出现。真正的ConstantBuffer是以4×32bit为基本单位的数据集合。
80 |
81 | 每个RootConstant Set当作一个32-bit数组,shader对这种数据是只读的,可以动态索引,越界访问会产生未定义行为。在HLSL中,可以为Constants提供数据结构定义以赋予它类型。例如,如果RootSignature定义了一组4个RootConstant,HLSL可以这样解释这四个数据:
82 | ```c++
83 | struct DrawConstants
84 | {
85 | uint foo;
86 | float2 bar;
87 | int moo;
88 | };
89 | ConstantBuffer myDrawConstants : register(b1, space0);
90 | ```
91 | 因为RootSignature空间不支持动态索引,所以在HLSL中,不能把映射到RootConstant的数据定义为数组,即定义一个*float myArray[2];*是非法的,即映射到RootConstants的ConstantBuffer它自己不能是一个数组。
92 |
93 | Constants可以部分设置。
94 |
95 | 当设置Constants时需要注意shader所期望的ConstantBuffer layout,constants可能会被padded到vec4的边界。可以在HLSL中通过检查反射信息验证layout。
96 |
97 | * SetGraphicsRoot32BitConstant
98 | * SetGraphicsRoot32BitConstants
99 | * SetComputeRoot32BitConstant
100 | * SetComputeRoot32BitConstants
101 |
102 | ## Root descriptor
103 | Pros:
104 | * 方便,直接绑定Descriptor,不用遍历Heap
105 | Convs:
106 | * 占用RootSignature空间,2DWORD.
107 |
108 | 通常可以把每次绘制都变化的ConstantBufferView放这儿,这样不用每次都Allocate descriptor heap space,也不用把Descriptor table指向新的位置。直接把descriptor保存在RootSignature中,App就只需要关心把什么View直接绑定到Pipeline即可,而不用维护一个CPU的descriptor heap。
109 |
110 | 可以直接放到RootSignature的Descritpor:
111 | * Constant buffer view.
112 | * Shader resource views,unordered access views,不能有格式转换。
113 | * 可以和RootSingnature绑定的:
114 | * StructuredBuffer\
115 | * RWStructuredBuffer\
116 | * ByteAddressBuffer
117 | * RWByteAddreddBuffer
118 | * 不能绑定的:
119 | * Buffer\
120 | * Buffer\
121 | * Raytracing acceleration structures的SRVs。
122 |
123 |
124 | ## Example
125 | 一个RootConstant参数,消耗1个DWORD:
126 |
127 | 
128 |
129 | API slot 是由root signature中参数的顺序决定的。
130 |
131 | 增加一个Root constant buffer view(2 DWORD):
132 |
133 | 
134 |
135 | 绑定Descritpor table:
136 |
137 | 
138 |
139 | 一个float4 Root constant占用4个DWORDS大小,而且可以仅设置其中几个DWORDS:
140 | ```c++
141 | pCmdList->SetComputeRoot32BitConstants(0,2,myFloat2Array,1); // 2 constants starting at offset 1 (middle 2 values in float4)
142 | ```
143 | 这里仅设置了中间两个数据。
144 |
145 | 更复杂的RootSignature:
146 |
147 | 
148 |
149 | * Slot3,slot6的descriptor table包含了unbounded size 数组。
150 | * DirectX-Graphics-Samples\Samples\Desktop\D3D12DynamicIndexing\src
151 | * hardware tier 2+
152 |
153 | * Slot9中的UAV u4和UAV u5以同样的offset声明,这表明u4和u5都绑定到同一个descriptor。
154 |
155 | ### Streaming Shader Resource Views
156 |
157 | 
158 |
159 | 这张图说明了一种应用场景,所有SRV都放在一个大数组中,在Shader中,通过传入的CBV等常量读取需要Texture。
--------------------------------------------------------------------------------
/GDC/GDC.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 6ohkyz32ig1q2cuwvf2xq9i
3 | title: GDC
4 | desc: ''
5 | updated: 1682242308045
6 | created: 1682242308045
7 | ---
8 |
--------------------------------------------------------------------------------
/GDC/UIEngineering.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: v4hwklnxc6gzuhfip5dk1g2
3 | title: UIEngineering
4 | desc: ''
5 | updated: 1682243437328
6 | created: 1682242327212
7 | ---
8 |
9 | # UI Engineering Patterns from 'Marvel's Midnight Suns'
10 |
11 | https://www.gdcvault.com/play/1028880/UI-Engineering-Patterns-from-Marvel
12 |
13 | * FrontEnd 存在于游戏核心循环之外的UI
14 | * Control User可以与之交互的Visual
15 | * Screen UI system的Base
16 |
17 | ## 如何获取数据
18 | 通过一个GlobalDatabase类,使用Identifiers获取指定数据:
19 | 
20 |
21 | ## The Challenge
22 | * Scale of UI Development
23 | * 150 screens, 90% of them in the frontend
24 |
25 | 需要一个可扩展的架构
26 |
27 | ## UICS - User Interface Component System
28 |
29 | A UI Component is something that provides functionality to a UI screen.
30 |
31 | 
32 |
33 | Example:Inventory Screen
34 | 
35 |
36 | Editor View:
37 | 
38 |
39 |
40 | https://www.gdcvault.com/play/1029143/-God-of-War-Ragnarok
41 |
--------------------------------------------------------------------------------
/GDC/Witcher3_OptimizingContentPipelinesForOpenWorldGames.md:
--------------------------------------------------------------------------------
1 | https://zhuanlan.zhihu.com/p/36282368
2 |
3 | ppt: https://www.gdcvault.com/play/1021880/Content-Optimization-Pipeline-for-an
4 |
5 | 50W个Entities
6 |
7 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | # Hello! This is where you manage which Jekyll version is used to run.
3 | # When you want to use a different version, change it below, save the
4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
5 | #
6 | # bundle exec jekyll serve
7 | #
8 | # This will help ensure the proper Jekyll version is running.
9 | # Happy Jekylling!
10 | # gem "jekyll", "~> 4.3.3"
11 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
12 | gem "minima", "~> 2.5"
13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
14 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
15 | gem "github-pages", "~> 232",group: :jekyll_plugins
16 | # If you have any plugins, put them here!
17 | group :jekyll_plugins do
18 | gem "jekyll-feed", "~> 0.12"
19 | end
20 |
21 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
22 | # and associated library.
23 | platforms :mingw, :x64_mingw, :mswin, :jruby do
24 | gem "tzinfo", ">= 1", "< 3"
25 | gem "tzinfo-data"
26 | end
27 |
28 | # Performance-booster for watching directories on Windows
29 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
30 |
31 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
32 | # do not have a Java counterpart.
33 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
34 |
--------------------------------------------------------------------------------
/UE/0611_0615.md:
--------------------------------------------------------------------------------
1 | 目前看来,海量的Nanite实例导致场景渲染压力剧增。尝试从实际渲染实例数量,和相关Render系统设置上入手降低消耗。
2 | # HLOD
3 | 1. 测试HLODActor
4 | * HLOD可以用HierarchicalLoadVolume生成
5 | * https://dev.epicgames.com/documentation/zh-cn/unreal-engine/hierarchical-level-of-detail-in-unreal-engine
6 | * 可以用Mesh上最低LOD生成合并的Mesh
7 | * `Nanite Mesh不可用`,https://forums.unrealengine.com/t/can-you-use-hlods-with-nanite/763257
8 | * G:\UnrealEngine5\Engine\Source\Runtime\Renderer\Private\SceneVisibility.cpp 3343
9 | 2. 距离剔除对NaniteMesh无效
10 | * CullDistanceVolume 和 DesiredMaxDrawDistance都不行
11 |
12 | 目前看来,只有HISM的距离剔除是GameThread端的,可以对Nanite生效。
13 |
14 | # Shadow
15 | * DynamicShadowDistance ,light
16 | * 距离场阴影替代超出可移动光源动态阴影距离的非Nanite几何体
17 | * DirectLight Dynamic Shadow Distance Movable Light
18 | * DirectionalLight - DynamicShadowDistance 控制非Nanite对象计算ShadowCast的距离,越小性能越好
19 | * 无论距离如何,Nanite几何体始终渲染到虚拟阴影贴图,因为这是性能最高的选项,可提供最高质量。
20 | * r.Shadow.Virtual.UseFarShadowCulling 0 非nanite也始终渲染Shadow。
21 | * SMRT
22 | * 局部光源的 源半径(Source Radius) 或定向光源的 源角度(Source Angle) 控制。越大阴影边缘越柔和
23 | * r.Shadow.Virtual.SMRT.RayCountLocal 和 r.Shadow.Virtual.SMRT.RayCountDirectional
24 | * 越大,柔和阴影区域噪点越少,0,纯硬阴影,上面的设置将不起作用
25 | * r.Shadow.Virtual.SMRT.SamplesPerRayLocal 和 r.Shadow.Virtual.SMRT.SamplesPerRayDirectional
26 | * 每条光线采样数,越大越柔和,0纯硬阴影
27 | * r.Shadow.Virtual.SMRT.MaxRayAngleFromLight 和 r.Shadow.Virtual.SMRT.RayLengthScaleDirectional
28 | * 0.03f 1.5f
29 | * 越大半影越宽
30 | * 非Scalibility
31 | ```
32 | [ShadowQuality@0]
33 | r.Shadow.Virtual.SMRT.RayCountDirectional=0
34 | r.Shadow.Virtual.SMRT.SamplesPerRayDirectional=2
35 | r.Shadow.Virtual.SMRT.RayCountLocal=0
36 | r.Shadow.Virtual.SMRT.SamplesPerRayLocal=2
37 | [ShadowQuality@1]
38 | r.Shadow.Virtual.SMRT.RayCountDirectional=4
39 | r.Shadow.Virtual.SMRT.SamplesPerRayDirectional=2
40 | r.Shadow.Virtual.SMRT.RayCountLocal=4
41 | r.Shadow.Virtual.SMRT.SamplesPerRayLocal=2
42 | [ShadowQuality@2]
43 | r.Shadow.Virtual.SMRT.RayCountDirectional=8
44 | r.Shadow.Virtual.SMRT.SamplesPerRayDirectional=4
45 | r.Shadow.Virtual.SMRT.RayCountLocal=8
46 | r.Shadow.Virtual.SMRT.SamplesPerRayLocal=4
47 | [ShadowQuality@3]
48 | r.Shadow.Virtual.SMRT.RayCountDirectional=8
49 | r.Shadow.Virtual.SMRT.SamplesPerRayDirectional=4
50 | r.Shadow.Virtual.SMRT.RayCountLocal=8
51 | r.Shadow.Virtual.SMRT.SamplesPerRayLocal=4
52 | [ShadowQuality@Cine]
53 | r.Shadow.Virtual.SMRT.RayCountDirectional=16
54 | r.Shadow.Virtual.SMRT.SamplesPerRayDirectional=8
55 | r.Shadow.Virtual.SMRT.RayCountLocal=16
56 | r.Shadow.Virtual.SMRT.SamplesPerRayLocal=8
57 | ```
58 | * ShadowMap 分辨率
59 | * -1.0 表示分辨率加倍
60 | * 1.0 表示分辨率减半, etc. 以此类推。
61 | ```
62 | [ShadowQuality@0]
63 | r.Shadow.Virtual.ResolutionLodBiasDirectional=0.0
64 | r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving=0.0
65 | r.Shadow.Virtual.ResolutionLodBiasLocal=1.0
66 | r.Shadow.Virtual.ResolutionLodBiasLocalMoving=2.0
67 | [ShadowQuality@1]
68 | r.Shadow.Virtual.ResolutionLodBiasDirectional=0.0
69 | r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving=0.0
70 | r.Shadow.Virtual.ResolutionLodBiasLocal=1.0
71 | r.Shadow.Virtual.ResolutionLodBiasLocalMoving=2.0
72 | [ShadowQuality@2]
73 | r.Shadow.Virtual.ResolutionLodBiasDirectional=-0.5
74 | r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving=-0.5
75 | r.Shadow.Virtual.ResolutionLodBiasLocal=0.0
76 | r.Shadow.Virtual.ResolutionLodBiasLocalMoving=1.0
77 | [ShadowQuality@3]
78 | r.Shadow.Virtual.ResolutionLodBiasDirectional=-1.5
79 | r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving=-1.5
80 | r.Shadow.Virtual.ResolutionLodBiasLocal=0.0
81 | r.Shadow.Virtual.ResolutionLodBiasLocalMoving=1.0
82 | [ShadowQuality@Cine]
83 | r.Shadow.Virtual.ResolutionLodBiasDirectional=-1.5
84 | r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving=-1.5
85 | r.Shadow.Virtual.ResolutionLodBiasLocal=0.0
86 | r.Shadow.Virtual.ResolutionLodBiasLocalMoving=0.0
87 | ```
88 | * Coarse Pages(粗页)
89 | * 体积雾和正向渲染半透明度 可能需要在任意位置上对ShadowMap采样。
90 | * 会使用 粗页(Coarse Pages) 这类标记来确保整个域中至少有低分辨率阴影数据可用于取样。
91 | * r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0 尝试禁止非Nanite对象渲染到粗页。
92 | * r.Shadow.Virtual.MarkCoarsePagesLocal 0 关闭局部光源粗页
93 | * r.Shadow.Virtual.MarkCoarsePagesDirectional 关闭定向光源粗页
94 | * 或者可以使用 r.Shadow.Virtual.FirstCoarseLevel 和 r.Shadow.Virtual.LastCoarseLevel 修改标记粗页的裁剪图级别范围。
95 |
96 |
97 | 将带有虚拟阴影贴图的当前光源列表输出到控制台:
98 | ```
99 | r.Shadow.Virtual.Visualize.DumpLightNames
100 | ```
101 |
102 | ## 非Nanite
103 | * r.Shadow.RadiusThreshold 增加这个,越多物体将不会渲染到ShadowMap
104 | * 在有大量植被的场景中,强烈建议使用 r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0 禁用粗页中的非Nanite对象。或者,如果不需要,请考虑完全禁用粗页。
105 |
106 | DirectionalLight:
107 | * 距离场阴影替代超出 动态阴影距离可移动光源(Dynamic Shadow Distance Movable Light) 距离范围的非Nanite几何体,该距离通过光源的级联阴影贴图(Cascaded Shadow Maps)分段设置。
108 | * 在某些情况下,创建移除WPO/PDO的材质LOD可能不切实际,但这些转换的最终效果在远处不明显。使用 r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange 设置距离(以厘米为单位),超过该距离时,将忽略这些材质的缓存失效.
109 |
110 | ## GPU Profiling and Optimization
111 | ### Shadow Depths
112 |
113 | * rendering geometry into shadow maps.
114 | * `RenderVirtualShadowMaps(Nanite)` 渲染NaniteGeometry到VSM,All Directional Lights are rendered in a single Nanite pass, and all local lights are done in a second pass.
115 | * `RenderVirtualShadowMaps(Non-Nanite) `rendering of non-Nanite geometry。Each visible light has a separate pass with individual draw calls for various objects and instances, the same as conventional shadow maps rendering.
116 | * `Atlas and Cubemap`传统Shadowmap,所有不支持VSM的集合体,这应该很少,r.Shadow.Virtual.ForceOnlyVirtualShadowMaps 1强行关掉
117 |
118 | Cost:
119 | * how many shadow pages need to be rendered.
120 | * how much geometry needs to be rendered into them.
121 | * Non-Nanite geometry is much more expensive to render into VSMs
122 |
123 | #### Understanding the Number of Pages Being Drawn
124 | * r.ShaderPrintEnable 1
125 | * r.Shadow.Virtual.ShowStats 1 (or 2 to show only the page statistics)
126 |
127 | 优化:
128 | * reducing screen resolution
129 | * shadow resolution (using the console variables for resolution LOD bias)
130 | * light extents
131 | * the number of shadow casting lights
132 |
133 | Poor performance:
134 | * high number of pages being used
135 | * lots of dunamic invalidation happening
136 |
137 | #### Improving Non-Nanite Performance
138 | * 尽量开Nanite,不论三角面数量
139 | * Nanite Geometry可以遮挡剔除non-Nanite Geometry。
140 | * Non-nanite object必须有充分的LOD hiearchies。
141 | * CPU Culling,r.Shadow.RadiusThreshold
142 | * Directional lights,远距离的阴影用Distance Field Shadows
143 | * Disabling non-Nanite geometry in Coarse Pages can increase performance
144 |
145 | ### Shadow Projection (under Lights).
146 | ```
147 | Lights | DirectLighting | UnbatchedLights
148 | ```
149 | * Shadow Map Ray Tracing
150 | * The most expensive pass is usually the main SMRT loop in `VirtualShadowMapProjection`.
151 | * one VSM projection pass per associated light.
152 | * performance `doesn't depend on the number of pages or caching`.
153 |
154 | 性能影响:
155 | * Average lights per pixel
156 | * 越多的Light照射到Screen上,rendering就越expensive。只照射Screen上一点点pixel的light 更cheaper,但还是有一些固定cost per lights。
157 | * 应该尽量避免几个大的lights影响到Scrren上大片区域
158 | * Rays per pixel
159 | * 阴影softness影响性能,-- > Ray count
160 | * 调整ray 和sample counts前,先考虑降低Local lights -> SourceRadius,Directional Lights -> Source Angle
161 | * Samples per ray
162 |
163 |
--------------------------------------------------------------------------------
/UE/Animation.ParallelUpdate.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 0l0dv0z8mxr1karqb5y7gvf
3 | title: UE5 多线程动画更新与Property Access system
4 | desc: ''
5 | updated: 1714123107166
6 | created: 1713086140565
7 | ---
8 |
9 | # 1. MultiThreadedAnimationUpdate
10 |
11 | 通常,为了计算出最终的Pose,我们需要许多Gameplay数据驱动动画蓝图的计算,一个常用的办法是在动画蓝图的EventGraph中,重写"BlueprintUpdateAnimation", 在其中将需要用于驱动动画状态机计算的数据保存在动画蓝图UAnimInstance自己的属性中,其C++版本是"NativeUpdateAnimation()"。它们在主线程中,由USkeletalMeshComponent::TickComponent调用UAnimInstance::UpdateAnimation触发更新:
12 |
13 | 
14 |
15 | ```
16 | UAnimInstance::UpdateAnimation
17 | // acquire the proxy as we need to update
18 | FAnimInstanceProxy& Proxy = GetProxyOnGameThread();
19 | USkeletalMeshComponent::HandleExistingParallelEvaluationTask // 会等到并行的Task完成
20 | ... ...
21 | NativeUpdateAnimation(DeltaSeconds);
22 | BlueprintUpdateAnimation(DeltaSeconds);
23 | ```
24 |
25 | 在`UAnimInstance::UpdateAnimation`最前面会调用`GetProxyOnGameThread()`,这个里面会处理正在异步更新AnimGraph的Task,等到它完成:
26 |
27 | 
28 |
29 | 如果我们开启了"bAllowMultiThreadedAnimationUpdate", AnimGraph中的节点都会在WorkerThread中执行,而这些Node通常都会访问UAnimation中的属性。所以这里必须等到所有异步的Task完成,这样就确保了我们随后在`NativeUpdateAnimation`和`BlueprintUpdateAnimation`中更新UAnimInstance的属性是线程安全的。
30 |
31 | # 2. Thread Safe Update Animation
32 | 前面提到,我们其实还是需要在主线程更新AnimGraph中需要用到的数据。但是,一些情况下,将会有大量的数据需要更新,且可能需要经过复杂的计算才能得到AnimGraph需要的数据,这一步就可能成为性能瓶颈。所以,我们需要将这一步也并行化。
33 |
34 | 在Work线程执行的`FAnimInstanceProxy::UpdateAnimation()`中,会调用UAnimInstance中的`NativeThreadSafeUpdateAnimation()`和`BlueprintThreadSafeUpdateAnimation()`这两个方法,它们与前面提到的在主线程中更新动画数据的方法相对应,这是它们的Work线程版本:
35 |
36 | ```
37 | FAnimInstanceProxy::UpdateAnimation()
38 | FAnimInstanceProxy::UpdateAnimation_WithRoot
39 | GetAnimInstanceObject()->NativeThreadSafeUpdateAnimation()
40 | GetAnimInstanceObject()->BlueprintThreadSafeUpdateAnimation()
41 | ```
42 |
43 | 我们可以将复杂的计算逻辑放在这两个方法中,把更新动画需要的数据计算也并行化。为了保证线程安全,这两个ThreadSafe的方法中要访问和写的变量都必须是线程安全的,要确保在异步执行`FAnimInstanceProxy::UpdateAnimation()`时,GameThread不会修改这些变量。
44 |
45 | 所以,这里需要用到的所有GameThread的数据,例如Character,PlayerControler等其它对象的属性,需要在前面的GameThread版本的`UpdateAnimation`中保存下来,以供后面异步更新时使用。
46 |
47 | 在蓝图中,UE利用反射系统,实现了自动捕获在蓝图重载的`BlueprintThreadSafeUpdateAnimation()`函数中使用到的GameThread数据,只需要在访问别的数据时,使用`PropertyAccess`节点:
48 |
49 | 
50 |
51 | 所有在UAnimInstance的Context中能访问的函数和变量都能出现在这里,其中,函数必须有返回值,且必须是Pure函数。如果是蓝图定义的函数,返回值的名字必须是`ReturnValue`。
52 |
53 | 任何在这里通过PropertyAccess访问的属性或者方法,都会在GameThread中UpdateAnimation时将这些数据缓存到UAnimInstance中,随后在多线程执行BlueprintThreadSafeUpdateAnimation时,PropertyAccess Node会直接访问这些缓存的值,而不是实际指向的函数或变量,以保证线程安全。
54 |
55 | 
56 |
57 | # 3. AnimBlueprintExtension and FAnimSubsystem
58 | 这个`FAnimSubsystem_PropertyAccess`是如何Work的?
59 |
60 | 在创建每个AnimGraphNode时,会尝试向UAnimBlueprint注册各个Extension:
61 |
62 | 
63 |
64 | 其中就包含了`UAnimBlueprintExtension_PropertyAccess`。在创建UAnimBlueprint时,必定会创建一个`UAnimGraphNode_Root`节点,所以能保证这些Extension被添加。
65 |
66 | 随后在编译蓝图时,`FAnimBlueprintCompilerContext::ProcessExtensions()`会遍历所有Extensions,从`UAnimBlueprintExtension_PropertyAccess`中得到对应的`FAnimSubsystem`的类型,并创建对应FStructProperty*,并且将其放在另一个属性`NewAnimBlueprintConstants`中,这相当于向`NewAnimBlueprintConstants`这个Struct中动态添加了一个属性。
67 |
68 | 而`NewAnimBlueprintConstants`则是在编译蓝图时,为当前GeneretedClass创建的`SparseClassDataStruct`:
69 |
70 | 
71 |
72 | 这个结构里面对应的数据是每个UClass一份,而不是每个Instance一份,在UClass中可以看到:
73 |
74 | 
75 |
76 | 因此,所有Extension对应的FAnimSubsystem都会存在于GenerateClass的SparseClassData中。
77 |
78 | 在UAnimBlueprintGeneratedClass的PostLoad中,会调用`UAnimBlueprintGeneratedClass::BuildConstantProperties()`,从`SparseClassDataStruct`将所有`FAnimSubsystem`保存下来,以方便后续通过GenerateClass上的`ForEachSubsystem`快速访问所有Subsystem。
79 |
80 | 
81 |
82 | 在`ForEachSubsystem`中,就可以通过FProperty的`ContainerPtrToValuePtr`获取到对应的结构体实例:
83 |
84 | 
85 |
86 | `FAnimSubsystem`定义了以下几个虚函数,分别在对应的线程和UpdateAnimation前后调用:
87 |
88 | 
89 |
90 | # 4. FAnimSubsystem_PropertyAccess
91 |
92 | 对于这里的`FAnimSubsystem_PropertyAccess`,他实现了在这几个不同的时间点进行属性缓存,而需要缓存的属性由`FPropertyAccessLibrary`在编译蓝图时记录下来,每一个不同的时机都记录了对应的需要缓存的属性,只有用到的属性会被缓存。
93 |
94 | 因为`FAnimSubsystem_PropertyAccess`是存在于UClass上的,所以缓存的属性不可能在由他自己保存,通过分析可以发现,`FPropertyAccessLibrary`只是记录了每个时机点需要Copy的属性,从哪一个属性Copy到哪一个属性,通过FProperty表示,还有相关的属性和函数的Path。`FPropertyAccessLibrary`上并没有实际保存赋值的属性的地方。
95 |
96 | 在`BlueprintThreadSafeUpdateAnimation()`中使用的`PropertyAccess`节点,实际对应于代码中的`UK2Node_PropertyAccess`,他实现了接口`IClassVariableCreator`,这个接口只有一个方法`CreateClassVariablesFromBlueprint()`,这会在编译蓝图前,重新生成`UAnimBlueprintGeneratedClass`时,遍历所有的Node,调用这个接口方法:
97 |
98 | ```c++
99 | UK2Node_PropertyAccess::CreateClassVariablesFromBlueprint(InCreationContext)
100 | InCreationContext.CreateUniqueVariable(this, ResolvedPinType)
101 | FProperty* NewProperty = FKismetCompilerUtilities::CreatePropertyOnScope(NewClass, VarName, VarType, NewClass, CPF_None, Schema, MessageLog);
102 | ```
103 |
104 | `UK2Node_PropertyAccess`这里会给GenerateClass创建一个和它引用的属性一样类型的变量,即是给当前GenerateClass添加了一个属性,这个属性专用于缓存引用属性的值。
105 |
106 | 随后编译到这个节点时,获取到`UAnimBlueprintExtension_PropertyAccess`,调用它的`AddCopy`方法,指定Source属性Path,即这个节点引用的属性,和目标属性Path,即在`CreateClassVariablesFromBlueprint()`中创建的属性。
107 |
108 | ```c++
109 | UK2Node_PropertyAccess::ExpandNode()
110 | UAnimBlueprintExtension_PropertyAccess* PropertyAccessExtension = UAnimBlueprintExtension::FindExtension(AnimBlueprint);
111 | // ... ...
112 | FPropertyAccessHandle Handle = PropertyAccessExtension->AddCopy(Path, DestPropertyPath, ContextId, this);
113 | PropertyAccessLibraryCompiler->AddCopy(InSourcePath, InDestPath, InContextId, InObject);
114 | // 将Copy信息保存在QueuedCopies中
115 | ```
116 |
117 | 搜集完所有Copy信息后,调用`UAnimBlueprintExtension_PropertyAccess::HandleFinishCompilingClass()`,
118 | ```c++
119 | UAnimBlueprintExtension_PropertyAccess::HandleFinishCompilingClass()
120 | FPropertyAccessLibraryCompiler::FinishCompilation()
121 | // 这里会将所以记录到QueuedCopies的信息填充到`FPropertyAccessLibrary`中,而它是被`FAnimSubsystem_PropertyAccess`持有的。
122 | ::FPropertyAccessEditorSystem::CompileCopy(Class, OnDetermineBatchId, *Library, Copy);
123 | ```
124 | 所有PropertyAccess用到的属性都会有一条对应的Copy记录,表示应该从哪个Source属性Copy到Dst属性(由Node在GenerateClass上创建的)。在主线程更新动画时,就先调用`FAnimSubsystem_PropertyAccess`的更新方法,将所有属性Copy到UAnimInstance实例上。随后在Work线程真正访问这些属性时,就是访问的这些Copy目标属性。
125 |
126 | # 5. Workflow
127 | 至此,整个PropertyAccess的Copy和同步流程就明了了:
128 |
129 | 
130 |
131 | 这是蓝图使用`BlueprintThreadSafeUpdateAnimation()`和`PropertyAccessNode`的全部过程。
132 |
133 | 如果在c++中使用多线程的变量更新,需要重写对应的Native版本的方法:`NativeUpdateAnimation()`和`NativeThreadSafeUpdateAnimation()`。 在`NativeUpdateAnimation()`中,访问各种GameObject,将后续需要用到的属性保存在UAnimInstance中,这里最好只进行简单的变量赋值,不进行任何逻辑运算。在`NativeThreadSafeUpdateAnimation()`中,利用前面保存的变量值,进行复杂的逻辑计算,得到AnimGraph需要用到的数据。随后在AnimGraph中利用`NativeThreadSafeUpdateAnimation()`中得到的数据,计算Pose。
--------------------------------------------------------------------------------
/UE/Animation.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 2i18atlgt276hh2qe693yzc
3 | title: Animation
4 | desc: ''
5 | updated: 1712329674929
6 | created: 1712281493515
7 | ---
8 |
9 | # 1. 状态机和动画别名
10 |
11 | 在Animation Graphics中,有个Output Pose节点, 输出最终的姿态.
12 |
13 | locomotion 通常指角色或物体在空间中的移动. 走、跑。表示动画的基础步态周期,这些周期可以被循环使用模拟持续行走或跑动,这是进行后续角色动画处理的基本输出。所以状态机中通常有一个Locomotion状态机输出一个缓存Pose, 表示当前帧根据基本移动状态得到的基础Pose,在后续的计算中反复使用。
14 |
15 | 这里通常是Idle --> Walk/Run, 后者可由Speed在一维混合空间插值得出。
16 |
17 |
18 |
19 | # 2. 重定向人体模型资产
20 | 将旧骨骼的动画Sequence重定向到新的骨骼,生成新的AnimSequence。
21 | AnimSequence界面中,有Skeleton Tree可以显示额外的重定向选项,以修正部分骨骼。
22 |
23 | # 3. 使用导入的动画
24 |
25 | 在Animation Graphics的状态机中,任何一个节点都需要一个输出Pose,直接将AnimSequence拖到State Graphic中即可生成一个Sequence节点,并连接到输出Pose,表示这个State的输出。
26 |
27 | 使用从不同的骨骼重定向过来的AnimSequence,有可能导致IK失效,因为旧的的AnimSequence认为IK骨骼的位置与当前骨骼的不同。IK通常在最终的Output Pose前计算,Control Rig。
28 |
29 | 如果新旧动画计算IK的脚部骨骼的位置不同,则会导致不正确的结果。所以在Control Rig计算前,要想办法让用于计算ik的骨骼ik_foot_l,ik_foot_r的位置,是当前骨骼上正确的位置,这个正确的位置,通常就是当前骨骼的foot_l,foot_r的位置:
30 | 
31 |
32 | # 4. 混合空间和分析工具
33 |
34 | 1D BlendSpace,一维的一个变量,混合少量的动画(3个),根据速度混合持枪站立和持枪跑和持枪冲刺。中间如果有多个过渡AnimSequence,混合就会越平滑。
35 |
36 | 滑步,写一个调试按键,SetGlobalTimeDilation(0.2), 放慢时间,观察滑步。
37 |
38 | 混合空间分析,自动确定Axis的最大值:
39 | 
40 | 随后在CharacterMovement中也设置同样的最大值即可解决滑步问题。
41 |
42 | 此时动画仍然会有个地方有突变的问题,这是冲刺动画的起始帧和结束帧的姿势不同导致的,在正常速度播放下看不出来。
43 |
44 | # 5. 剪切和替换动画
45 |
46 | 现有的动画状态机中,跳被分为了三个动画,跳跃,下落,着陆。但是初学者包中的动画确实一个完整的跳跃动画。所以需要利用UE5中的工具(Edit in Sequence)将它分成这三个动画。
47 |
48 | * Manny_jump_start 冲站立姿势到空中准备下落
49 | * Manny_jump_loop 占位,暂时截一帧, Rate Scale 设为0,这个只有一帧,不应该动
50 | * Manny_jump_land 24 - 最后一帧
51 |
52 | 由于新创建的land动画不是叠加动画,而是一个完整的动画,如果和之前一样叠加上Locomotion的输出,就会膨胀到非常大,所以这里直接去掉Locomotion的叠加。
53 |
54 | # 6. 角色蹲伏功能-逻辑与动画
55 |
56 | 输入控制,胶囊体大小变化,charactermovement的设置。
57 |
58 | 动画部分:用一个bool值确定角色是否处于蹲下状态,而且需要从Character对象中更新这个值到AnimInstance中。角色可以从任何移动状态和Land状态过渡到蹲下状态(创建StateAlias),处于蹲下时,可以蹲着不动,也可以蹲着移动,这里就有两种动画,所以Crouch可以是一个子状态机。子状态机有两个状态,由速度决定是静止还是移动。
59 | 
60 |
61 | 7. 使用插槽给角色添加武器
62 |
63 | 两者都可以做到:
64 | Sokets
65 | * 一个骨骼可以有任意多个Sockets
66 | * 不能在Runtime修改它的位置,但是可以修改它Attach的骨骼的位置
67 | Virtual Bones
68 | * 一个Bone只能有一个虚拟骨骼。
69 | * 它可以在动画蓝图中使用,作为IK Target,或者注视Target,还可以修改位置。
70 |
71 | 我们用Sokets,直接在对应骨骼hand_r上创建。
72 |
73 | 武器也是一个Actor(子Actor),也有SkeletalMesh。将它Attach到Character的Mesh下,就可以选择ParentSokets
74 |
75 | 随后,在角色SkeletonMesh中,可以在WeaponSoket上选择一个预览的SkeltonMesh枪,然后选择预览动画为Idle。条则WeaponSoket的位置,以确保枪的姿态正确。
76 |
77 | # 10. 切换不同的武器附着点
78 |
79 | 武器可以背在背上,在背上也创建一个Socket,调整这个Soket的位置,使枪放上去看起来刚刚好。
80 |
81 | 调用武器的AttachActorToComponent,设定对应的Soket名字,以把武器Attach到对应的地方。
82 |
83 | # 11. 使用Montage过渡武器切换
84 |
85 | 持拿武器和解除武器状态下的idle和walk/run状态的动画应该是不同的,至少手应该是持拿或放松的状态。这可以在Locomation StateMachine中,通过判断是否处于收起武器状态,选择使用装备武器状态下的idel / walk/run动画,或者解除武器下的idle / walk/run动画。
86 |
87 | 从对应的收枪Animation创建Montage。在播放Montage时,有时希望只要一个Animation上的部分动作,比如上半身或全身。
88 |
89 | 在奔跑时,我们希望只要上半身的收枪动画,下半身要继续奔跑。
90 | 静止时,希望要全身的收枪动画。
91 |
92 | 但是播一个Montage时,又不想太复杂,还需要考虑是否静止,所以,一个Montage可以准备两种播放模式,即不同的Slot,可以有FullBodySlot,也有UpperBodySlot,为这两个Slot都准备好动画,由动画蓝图根据当前是否奔跑决定用哪一个slot的Montage。
93 |
94 | 在Montage中创建FullBody和UpperBody Group,设置对应的动画,这里都是一样的:
95 | 
96 |
97 | 在动画蓝图中,可以使用Slot节点,引用对应的Montage模式,Slot节点输入由状态机计算好的Pose,在对应Slot有Montage时,用Montage覆盖,没有则用输入的Source。
98 |
99 | 不同的Slot,定义了该取用动画的哪一部分。
100 |
101 | FullBody则很好处理,直接使用MainStateCache输入到对应Slot即可:
102 | 
103 |
104 | UpperBody则在读取了对应UpperBodySlot的Montage输入后,还需要将上半身混合到正常的MainStateCache:
105 | 
106 |
107 | 最后根据速度,使用BlendPosesByBool。
108 |
109 | 为了在恰当的时机改变枪Attach的位置,我们需要为Montage创建Notify事件,在动画蓝图中,得到事件的通知,然后调用相应的Character的逻辑处理Attach位置的交换。
110 |
111 | 
112 |
113 | 这里两个Montage几乎是一样的,只有Notiy的时机和事件名字不同。利用不同的Montage很好地区分了两个不同地行为,代码不用关注过多的细节。
114 |
115 | # 14. 编辑动画
116 | 上面的收枪中,最终Montage收枪的位置与我们实际希望的位置不一样。
117 |
118 | 首先调整后背Socket的位置和旋转,使其处于理想位置。
119 |
120 | 用Edit In Sequence,编辑动画,使其把枪放在背上时,与背上的枪的最终位置一致。
121 |
122 | 
123 |
--------------------------------------------------------------------------------
/UE/BuildWorld.PCG.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: gs2lw6moigop9x95jaiiul5
3 | title: PCG
4 | desc: ''
5 | updated: 1715128518889
6 | created: 1714790934310
7 | ---
8 |
9 | Reference:
10 | * [UnrealCircle]UE PCG方向的探索尝试 https://www.bilibili.com/video/BV1dg411c7om
11 |
12 | * Procedural World Generation of Far Cry 5 | GDC 2018
13 | * https://zhuanlan.zhihu.com/p/482742580
14 | * Procedural city generation in python - L-System
15 | * Tutorial: Complex roads in Houdini
16 | * Houdini 官网,UE Youtube
17 | * Houdini PDG
18 | * Unreal inside: https://www.youtube.com/watch?v=6JUfisUhm68&t=3908s
19 | * GDC2023:https://www.youtube.com/watch?v=aoCGLW53fZg&t=507s
20 | * bilibili office: https://space.bilibili.com/138827797/search/video?keyword=Procedural
21 |
22 | # Procedural Content Generation Framework
23 |
24 |
25 | ## UPCGComponent
--------------------------------------------------------------------------------
/UE/BuildWorld.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: g059qwzhhj669c9escltjt5
3 | title: BuildWorld
4 | desc: ''
5 | updated: 1715216374318
6 | created: 1715128562734
7 | ---
8 | 使用UE5的游戏:
9 |
10 | https://www.ign.com/games/feature/unreal-engine-5
--------------------------------------------------------------------------------
/UE/CitySample.md:
--------------------------------------------------------------------------------
1 | https://www.bilibili.com/video/BV1TP4y1T7Pj :
2 | * 00 建筑拆分,HLOD
3 | * 建筑外的小道具,在生成建筑时,生成对应的道具锚点,然后按分类,随机放置道具
4 | * 27:24 基础模型,材质,纹理制作 Look Dev
5 | * 建筑材质
6 | * 砖块纹理,UDIM
7 | * 
8 | * Trim Sheet approach Texture
9 | * 在一个Texture上做好一系列高度复用的元素
10 | * 不同的模型设计好UV采样到一个Texture
11 | * 用PerInstanceRandom 随机选择UDIM
12 | * 
13 | * Env mask , pack
14 | * 
15 | * 42:16 路 M_Freeway_Asphalt
16 | * 路面积水,贴花,解决Tile重复,维诺图噪声
17 | * MF_TextureCellBombing
18 | * Z-Rotation Aligned world space texture projection,可以绕z旋转的WorldAlignedUV
19 |
20 |
21 | https://www.bilibili.com/video/BV1W5411D7HT
22 | * 程序化生成,Houdini - Introduction
23 | * 6:00, 用样条线控制high level形状
24 | * City processor, Road section
25 | * 基本图元
26 | * 17:27 the city ground
27 | 
28 |
29 | * 25:04 Building generate
30 | * Shape grammar
31 | * module placement
32 | * WFC Wave function collapse
33 |
34 | * 45:01 Crowd & Traffic System
35 |
36 |
37 |
--------------------------------------------------------------------------------
/UE/Debug.md:
--------------------------------------------------------------------------------
1 |
2 | # Debug GPU
3 | ## RenderDoc
4 |
5 | ## NSight Graphics
6 | 可以编辑器下截帧,会自动关掉DLSS FG。容易卡死。截一次就得重启。
7 | [Documenttaion](https://docs.nvidia.com/nsight-graphics/UserGuide/index.html)
8 |
9 | ## Pix
--------------------------------------------------------------------------------
/UE/Foliage.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 37s5hfuk2dpjc0ibrx5xobo
3 | title: Foliage
4 | desc: ''
5 | updated: 1680854587627
6 | created: 1680838069263
7 | ---
8 |
9 | # Procedural Foliage LandscapeLayer filtter
10 |
11 | LandscapeLayerCheck()
12 |
13 | ## 密度处理
14 |
15 | G:\UnrealEngine5\Engine\Source\Runtime\Foliage\Private\ProceduralFoliageTile.cpp Line: 487
16 |
17 | 先按固定的算法给出较为密集的散点,再以设置的密度概率过滤掉一些点。
18 |
19 | - 获取一系列的散点
20 | - G:\UnrealEngine5\Engine\Source\Runtime\Foliage\Private\ProceduralFoliageSpawner.cpp Line: 111
21 | - 按Tile拼接,并按密度曲线过滤 UProceduralFoliageComponent::GenerateProceduralContent() EditorOnly
22 | - UProceduralFoliageTile::ExtractDesiredInstances() Line 487 --> FDesiredFoliageInstance : StartTrace, EndTrace
23 | - 得到随机区域全量的随机散点的Trace信息
24 | - FEdModeFoliage::AddInstances() EditorOnly
25 | - 构建Map `UFoliageType -> TArray`
26 | - `FEdModeFoliage::AddInstancesImp(UFoliageType, TArray)`
27 | - FEdModeFoliage::CalculatePotentialInstances_ThreadSafe()
28 | - 对每一个随机出来的点,进一步执行过滤条件
29 | - AInstancedFoliageActor::FoliageTrace() 应该放在什么COmponent上,确定放的具体位置,可以放的Mesh类型的过滤
30 | - 得到`TArray`
31 | - 找到IFA添加对应的FoliageType : AInstancedFoliageActor::AddFoliageType()
32 | - 得到`TArray`,
33 |
34 | - FoliageEdMode.cpp `SpawnFoliageInstance(UFoliageType, TArray)`
35 | - 从IFA找到FFoliageInfo IFA->AddFoliageType(Settings, &Info);
36 | - 添加实例: Info->AddInstances(FoliageSettings, PlacedLevelInstances.Value); // 仅在Editor 下保存Instance
37 | - FFoliageInfo::AddInstancesImpl
38 | - Implementation的实现为FFoliageStaticMesh
39 |
40 |
41 |
42 | # Procedural grass
43 | 参考《对马岛之魂》程序化草地,支持风场,交互,效果好性能也好.
44 | * [虚幻引擎5 对马岛之魂 GPU Compute Shader](https://www.bilibili.com/video/BV19v421v7zY)
45 | * https://zhuanlan.zhihu.com/p/671157323
46 | * https://www.youtube.com/watch?v=Ibe1JBF5i5Y&t=530s
47 | * https://zhuanlan.zhihu.com/p/647997882
48 | * [Procedural Grass](https://outerra.blogspot.com/search/label/grass)
49 | * [GDC-Procedural Grass in 'Ghost of Tsushima'](https://gdcvault.com/play/1027033/Advanced-Graphics-Summit-Procedural-Grass)
50 |
--------------------------------------------------------------------------------
/UE/GC.md:
--------------------------------------------------------------------------------
1 | 标记清除算法。
2 |
3 | 由`UWorld::Tick()`每帧调用`UEngine::ConditionalCollectGarbage()`,尝试GC,这里主要处理:
4 | * 限制主流程一帧只能走一次
5 | * 处理非Shipping下的控制台变量:
6 | * gc.StressTestGC
7 | * gc.ForceCollectGarbageEveryFrame
8 | * 根据World的状态确定流程:
9 | *
10 | *
11 | *
12 | * 处理gc.CollectGarbageEveryFrame N 每N帧执行一次GC
13 | * 处理gc.ContinuousIncrementalGC
14 |
15 | 对于每个对象,如何找到并记录成员的类型和地址?
16 | 首先回顾一下UE的反射系统。一个UObject类对应一个UClass,UClass中保存有这个UObject派生类型的所有反射信息。
17 |
18 | `GetPrivateStaticClassBody()`创建UClass。
19 |
20 |
21 |
22 | 是否要记录所有成员的信息?
23 |
24 |
25 |
26 | reference:
27 |
28 | * https://zhuanlan.zhihu.com/p/219588301
29 | * https://zhuanlan.zhihu.com/p/67055774
30 | * https://zhuanlan.zhihu.com/p/402398260
--------------------------------------------------------------------------------
/UE/GDC2023Nanite.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: bnq07qttl824zwts7ghsk2f
3 | title: GDC2023Nanite
4 | desc: ''
5 | updated: 1683461403688
6 | created: 1683421979323
7 | ---
8 | TODO: Displacement with Nanite
9 |
10 | # High-detail geometry with Nanite
11 | 通常的工作流程:
12 | * 构建high-detail的模型
13 | * 导入引擎,并用自动生成的LODs作为Fallback
14 |
15 | 在Fortnite中,
16 | * 需要频繁地发布大量内容
17 | * 高度可自定义的建筑系统
18 | * 因此,手动给每一种high-detail models的变体建模是不现实的
19 |
20 | 
21 |
22 | 所以只能用Displacement。
23 | ## Displacement with Nanite
24 | 在Fortnite中,要求:
25 | * Crack-free meshes
26 | * Seamless modular tiling meshes
27 | * 与Fortnite中的建筑系统一起使用(这应该是一个特殊需求)
28 | * Scalability
29 | * 容易更新旧资产
30 | * 低内存占用率
31 | * 对美术的工作流的影响也要尽可能地低
32 |
33 | 1. World position offset shader
34 | * Pros:
35 | * 完全动态
36 | * 即时更新
37 | * Cons:
38 | * 在NaniteMesh上用WPO,性能消耗非常大
39 | * 所有Mesh默认都需要很高地曲面细分
40 |
41 | 2.在DCC中使用Displacement直接建模
42 | * Pros:
43 | * Artist对最终效果可以完全掌控
44 | * Cons:
45 | * Artists将会有巨大工作量
46 | * 一旦导入Engine,将难以修改,不灵活
47 | * 迭代慢
48 | 所以这两种方式都不合适。
49 |
50 | **Solution:让Artist仅创建Low-poly Mesh和Displacement map,在UE中程序化生成对应的Nanite Mesh!**
51 |
52 | ## 解决常见的Displacement问题
53 |
54 | * Split vertices displacement
55 |
56 | 会在Mesh上造成Crack:
57 |
58 | 
59 |
60 | * Average normal displacement
61 | * Mesh会出现畸变
62 | * UV展开困难
63 | * 破坏modular seamless tiling meshes
64 |
65 | 使用Direct and indirect displacement解决这些问题。
66 | * Displacement prototype in Houdini
67 | * 使用Mask确定顶点是Direct还是indirect displacement
68 | * Indirect displaced vertices将查找它到其它Direct vert的距离,并由此确定使用对应Direct displaced顶点的Displacement vector.
69 | * 证明了这一方法的正确性,但工作流不友好。
70 |
71 | Unreal Engine geometry script prototype
72 |
73 | * 也可以达到相同的效果,但工作流上仍然不是很理想。
74 |
75 | ## Move all to c++ code
76 |
77 | * Fortnite在可破坏建筑块上使用了Texture data-driven system
78 | * This blends up to four material layers in a single material element
79 | * Displacement texture 和相关设置就添加到这个TextureData中
80 | * Artist仅需要制作Displacement maps和简单的low-poly meshes
81 | * 然后在编辑器内根据这些Displacement maps程序化生成所有high detail meshes。
82 |
83 | ### Optimizations
84 |
85 | * 仅生成最少的需要的Unique的Meshes
86 | * Adaptive tesselation
87 | * 代码处理high detail nanite mesh的创建
88 | * Nanite mesh存储在DDC中
89 |
90 | # Trees and foliage
91 | Video : https://www.youtube.com/watch?v=05FCjQR--Sc&list=PLZlv_N0_O1gYUMkyGerbUGedE7y-XQSJR&index=2
92 | ## 测试结果
93 | * OpaqueMaterial比masked alpha test materials快得多
94 | * WPO能用,但开销非常很大
95 | * 每棵树的顶点数量 < 36W
96 | * 虽然树干和树叶都是opaque,如果进一步将它拆分成两个材质,比使用更高开销的单个材质整体渲染更快。
97 | * Nanite本身的渲染有overdraw问题
98 | * Shadow proxies可以帮助节省性能,但在非常远的距离上,没有太好的效果,因为此时ProxyMesh和真实渲染的Mesh有着差不多的三角形数量。
99 | * 所有这些细节的处理需要专门设计的程序化建模工具
100 | ## Tree
101 | ### Each vertex count
102 | * 单个树叶有大概8 - 10 个Verts
103 | * 在树冠内部被外面单个树叶遮挡的区域,使用有30 - 38 个顶点的树叶簇,以更少的顶点,使看起来更密。
104 | * 大概3W片树叶, 整体 ~ 36W面
105 |
106 | ### WPO animation shader需要更高效:
107 | * PivotPainter消耗过高。
108 | * 要保持Shader中的计算量最小,不能有复杂的计算
109 | * 将Animation bake到lookup texture(4张)中。
110 | * U - Animation timeline, V - mapping of each branch
111 | * Texture1 - Neutral pose of the tree
112 | * Texture2 - Wind orientation-> 基于风向修改Animation
113 | * Texture3 - Position offset
114 | * Texture4 - Rotation offset
115 | * 用Houdini script完成
116 | 
117 |
118 | ### Result
119 | * High-detailed animated trees
120 | * 由于那四个Texture要使用非流送的HDR纹理,所以内存上的开销比较大
121 |
122 | Future improvements
123 |
124 | * 单个树叶的移动还需要做得更好一点
125 | * Physicals field reactions
126 | * 动画过于刚性(rigid), 还需要做得更柔和一点
127 |
128 | Fallback mesh需要单独制作,用单独的材质,引擎提供方法可以把一个自定义的fallback meshes导入,并组成单个资产,并添加Nanite Override Material。
129 |
130 | > 在平台不支持Nanite或高级LOD时需要使用fallback mesh
131 |
132 | ### Single Material
133 |
134 | 如果,所有NaniteTree都用一个材质渲染(No Material Instance)(用UDIMs[^1]和array textures),理论上讲会更快。
135 |
136 | 但事实并非如此,因为Shader更复杂,导致开销剧增。
137 |
138 | ### Pipeline Blueprint
139 |
140 | * 自动合并Nanite 和 它的fallback mesh
141 | * 自动把来自另一资产的Collision合并到Nanite资产
142 | * 自动bake impostor(fallback mesh ?)
143 |
144 | ## Grass and small pants
145 |
146 | * Vertices < 1200(直径约150cm的一簇草) per cluster
147 | * 需要Distance culling
148 | * 因为VertexShader开销很大,WPO需要按距离Disabled
149 | * 这意味着,不能用Vert position offset shader在远处淡化草地。可以移到Pixel shader做
150 | * blade modeled 比 cards with masked material好
151 | * 降低Nanite overdraw 甚至比树还重要
152 |
153 | WPO animation仍然需要优化:
154 |
155 | 使用一张lookup texture用作offset,看起来不及真正的Rotaion(PivotPainter),但开销非常低。
156 |
157 | 
158 |
159 | Wind speed noise texture
160 |
161 | * RG channel:风向 noise
162 | * B:intensity noise
163 | * Wind speed 存在mipmap1
164 |
165 | TODO :
166 | # Converting old assets to nanite meshes
167 |
168 | [^1]: [UDIMs](https://garagefarm.net/blog/setting-up-udims-in-blender-step-by-step#:~:text=What%20are%20UDIMS,grid%20we're%20used%20to)
--------------------------------------------------------------------------------
/UE/GPUScene.md:
--------------------------------------------------------------------------------
1 | refernece: https://zhuanlan.zhihu.com/p/614758211
2 |
3 |
4 | 每个Primitive的数据,LocalToRelativeWorld,CustomPrimitiveData等数据,Shader中对应结构体:FPrimitiveSceneData。
5 |
6 | FPrimitiveUniformShaderParameters
7 |
8 | FPrimitiveSceneProxy::CreateUniformBuffer()
9 | FPrimitiveSceneProxy::UpdateUniformBuffer()
10 |
11 | FInstanceSceneShaderData , Shader中FInstanceSceneData。
12 |
13 |
14 | # Shader
15 | BasePassVS中:
16 | 通过它获取`FInstanceSceneData`和`FPrimitiveSceneData`,
17 |
18 | 用的是`(FVertexFactoryInput)Input .InstanceIdOffset, Input .DrawInstanceId`,
19 |
20 | uint InstanceIdOffset : ATTRIBUTE13 ; uint DrawInstanceId : SV_InstanceID;
21 |
22 | FSceneDataIntermediates GetSceneDataIntermediates(uint InstanceIdOffset, uint DrawInstanceId)
23 |
24 | 被存到FVertexFactoryIntermediates.Common中。
25 |
26 | 开始绑定:FMeshPassProcessor::BuildMeshDrawCommands() 顶点数据,各种View。
27 |
28 | 在VS里,用GetPrimitiveData从PrimitiveIndex获取FPrimitiveSceneData。
29 | 对应到Shader中,G:\workspace\UnrealEngine\Engine\Shaders\Private\SceneData.ush Line351
30 |
31 | ```c++
32 | float4 LoadPrimitivePrimitiveSceneDataElement(uint PrimitiveIndex, uint ItemIndex)
33 | {
34 | uint TargetIdx = PrimitiveIndex + ItemIndex;
35 |
36 | #if SHADER_USES_PRIMITIVE_UBO
37 | return 0; // FIXME LoadPrimitivePrimitiveSceneDataElement for UBO case
38 | #elif USE_GLOBAL_GPU_SCENE_DATA
39 | checkStructuredBufferAccessSlow(GPUScenePrimitiveSceneData, TargetIdx);
40 | return GPUScenePrimitiveSceneData[TargetIdx];
41 | #elif USE_GLOBAL_GPU_SCENE_DATA_RW
42 | checkStructuredBufferAccessSlow(GPUScenePrimitiveSceneDataRW, TargetIdx);
43 | return GPUScenePrimitiveSceneDataRW[TargetIdx];
44 | #else
45 | checkStructuredBufferAccessSlow(Scene.GPUScene.GPUScenePrimitiveSceneData, TargetIdx);
46 | return Scene.GPUScene.GPUScenePrimitiveSceneData[TargetIdx];
47 | #endif
48 | }
49 | ```
50 | Mesh的顶点数据中的PrimitiveId,即Shader中的InstanceIdOffset,在Draw的时候动态绑定,与其它数据在构建顶点工厂时就绑定不一样:
51 | 
52 | ```
53 | DrawDynamicMeshPassPrivate()
54 | SortAndMergeDynamicPassMeshDrawCommands中构建Primitiveindex
55 | TranslatePrimitiveId处理索引,最高位。
56 | SubmitMeshDrawCommandsRange
57 | FMeshDrawCommand::SubmitDraw(
58 | FMeshDrawCommand::SubmitDrawBegin
59 | RHICmdList.SetStreamSource(Stream.StreamIndex, SceneArgs.PrimitiveIdsBuffer, SceneArgs.PrimitiveIdOffset);
60 | FMeshDrawCommand::SubmitDrawEnd 提交绘制
61 | ```
62 |
63 | # Static Mesh 渲染流程:
64 | Primitive通过ENQUEUE_RENDER_COMMAND发送渲染线程命令,FScene::PrimitiveSceneInfo_RenderThread(),添加到FScene的成员变量AddedPrimitiveSceneInfos中,在下一次渲染开始的FScene::Update()中处理。
65 | ```c++
66 | FScene::Update()
67 | //对新加的Primitive
68 | FPrimitiveSceneInfo::AddStaticMeshes()
69 | Proxy->DrawStaticElements(&BatchingSPDI)
70 | dithered LOD
71 | FPrimitiveSceneInfo::CacheMeshDrawCommands(this, SceneInfosWithStaticDrawListUpdate);
72 | * 用一个DrawContext FCachedPassMeshDrawListContextImmediate DrawListContext(*Scene);
73 | * 对每个FPrimitiveSceneInfo,的每个StaticMeshes,搜集起来处理
74 | * 对每个Pass - EMeshPass::Num,创建CreateMeshPassProcessor
75 | * 对每个MeshBatch调用Processor->AddMeshBatch()
76 | * 最终每个StaticMeshes,创建与EMeshPass::Num相同数量的Command,在StaticMeshCommandInfos。
77 | * 最终是存在了FScene的成员变量上FCachedPassMeshDrawList CachedDrawLists[EMeshPass::Num];
78 | ```
79 | [只有在绘制状态不每帧都改变,且可以在AddToScene内设置所有着色器绑定时,才能缓存的绘制命令。](https://dev.epicgames.com/documentation/zh-cn/unreal-engine/mesh-drawing-pipeline-in-unreal-engine?application_version=5.3#%E7%BC%93%E5%AD%98%E7%9A%84%E7%BD%91%E6%A0%BC%E4%BD%93%E7%BB%98%E5%88%B6%E5%91%BD%E4%BB%A4)
80 |
81 |
82 | # DynamicMesh渲染流程
83 |
84 | // 先处理剔除,对所有通过剔除的Mesh进行
85 | // 对所有GatherDynamicMesh进行操作
86 | FVisibilityTaskData::SetupMeshPasses()//拿到所有可见的DynamicMesh
87 | FSceneRenderer::SetupMeshPass()//对每一个Pass创建Processor
88 | // InstanceCullingContext,DynamicMeshElements
89 | // 对每个Pass进行处理,EMeshPass::Num
90 | FParallelMeshDrawCommandPass::DispatchPassSetup(Processor)
91 | FMeshDrawCommandPassSetupTask::AnyThreadTask()
92 | GenerateDynamicMeshDrawCommands() // 构建FDynamicPassMeshDrawListContext
93 | PassMeshProcessor->SetDrawListContext(&DynamicPassMeshDrawListContext);
94 | PassMeshProcessor->AddMeshBatch(*MeshAndRelevance.Mesh, BatchElementMask, MeshAndRelevance.PrimitiveSceneProxy);
95 | FBasePassMeshProcessor::TryAddMeshBatch()
96 | FBasePassMeshProcessor::Process(
97 | FMeshPassProcessor::BuildMeshDrawCommands
98 | 往DrawListContext添加FMeshDrawCommand, FMeshCommandOneFrameArray& DrawList;
99 |
100 |
101 | FViewInfo::(FParallelMeshDrawCommandPass)ParallelMeshDrawCommandPasses所有Pass对应的FMeshDrawCommandPassSetupTask,包含所有FMeshDrawCommand。
102 |
103 | FDeferredShadingSceneRenderer::RenderBasePassInternal()
104 | //对所有View
105 | FParallelMeshDrawCommandPass::DispatchDraw()
106 | FDrawVisibleMeshCommandsAnyThreadTask
107 | FInstanceCullingContext::SubmitDrawCommands()
108 | FMeshDrawCommand::SubmitDraw()
109 | FMeshDrawCommand::SubmitDrawEnd()
110 | Nanite::DrawBasePass()//然后Nanite
111 |
112 | # reference
113 | * https://zhuanlan.zhihu.com/p/657669302
114 | * https://zhuanlan.zhihu.com/p/651173532
115 | * 渲染管线原理机制源码剖析 https://zhuanlan.zhihu.com/p/641367884
--------------------------------------------------------------------------------
/UE/HISMClusterAlg.md:
--------------------------------------------------------------------------------
1 |
2 | # 划分Leaf节点
3 |
4 | UHierarchicalInstancedStaticMeshComponent::FClusterBuilder::BuildTreeAndBuffer()
5 | BuildTree();
6 |
7 | InternalNodeBranchingFactor = CVarFoliageSplitFactor.GetValueOnAnyThread();(16)
8 | 划分节点时,小于这个数就可以合并成一个父Cluster。
9 |
10 | MaxInstancesPerLeaf初始化为LOD0顶点数/`foliage.MinVertsToSplitNode=8192`,`FMath::Clamp(VertsToSplit / LOD0Verts, 1, 1024);`。
11 | 也就是说希望叶节点总的实例数量*顶点数=8192.
12 |
13 | 还要保证叶节点数量尽量不要小于可合并节点数`InternalNodeBranchingFactor`。
14 | ```c++
15 | if (Num / MaxInstancesPerLeaf < InternalNodeBranchingFactor) // if there are less than InternalNodeBranchingFactor leaf nodes
16 | {
17 | MaxInstancesPerLeaf = FMath::Clamp(Num / InternalNodeBranchingFactor, 1, 1024); // then make sure we have at least InternalNodeBranchingFactor leaves
18 | }
19 | ```
20 |
21 | * 先确定最大划分单位(划分到元素数量<=BranchingFactor就可以成为一个Cluster)
22 | * BranchingFactor = MaxInstancesPerLeaf
23 | * SortIndex里是(0~NumInstance-1)的Index。
24 | * SortPoints是对应Instance的Location
25 | * Split(Range(StartIndex,EndIndex))
26 | * 如果范围内元素数量<=BranchingFactor
27 | * 向Clusters添加这个Range的起点Index和范围内的元素数量
28 | * 获取范围内的点组成的Bound
29 | * 找到这个Bound的最长轴Axis
30 | * 对这个范围内的Instance按Axis的坐标从小到大排序。
31 | * 更新这个Range内Index顺序,按对应Instance的Axis坐标从小到大排列。
32 | * 将这个Range分为两部分
33 | * 如果Range中有偶数个元素,均分。奇数个元素,中间元素离谁近就分给谁。
34 | * Split(Start, EndLeft);
35 | * Split(StartRight, End);
36 | * 完事儿之后SortIndex中是一组组连续的在某个Axis方向上最近的InstanceIndex
37 | * 由Clusters指示哪些Range是一个Clusters。
38 |
39 | 从Cluster构造`TArray Nodes;`数组,并把`SortIndex`Copy一份到`TArray SortedInstances;`。`Nodes`的顺序是按引用的`FirstInstance`从小到大排列的。
40 |
41 | 
42 |
43 | # 合并Leaf节点
44 |
45 | 与上面叶节点的划分采用一样的算法:
46 | * BranchingFactor 初始化为 InternalNodeBranchingFactor(16)
47 | * SortIndex:0~NumRoot-1 -> Result->Nodes
48 | * SortPoints:对应FClusterNode Bound的中心点
49 | 划分结果:
50 | * Clusters.Start -> Index to SortIndex Array,
51 | * Clusters.Num ElementNum begin with Start
52 | Clusters中就是对上一级节点合并后的Cluster结果。因为要把叶节点重新按Bound中心位置排序,以保证当前Cluster对`SortedInstances`的引用仍然是连续的,所以这里还要重排SortedIstances中的顺序以保证这件事。
53 |
54 | 一直循环处理每一级,直到只剩一个Root节点,且顶层节点按顺序排在最前面。(中间的过程巨TM复杂)
55 |
56 | 
57 |
58 | # InstanceReorderTable
59 |
60 | 
61 |
62 | InstanceReorderTable记下了Transform对应在SortedInstances中的Index。
63 |
64 | # Build Buffer
65 | UHierarchicalInstancedStaticMeshComponent::FClusterBuilder::BuildTreeAndBuffer()
66 | BuildTree();
67 | BuildInstanceBuffer();
68 |
69 | 绘制的顺序是按SortedInstances中排的顺序。For循环Transform,用`InstanceReorderTable[i]`得到`Transform[i]`是第几个绘制的。一个一个设置所有instance的数据初始化Buffer,最终Buffer中的Transform就是按照SortedInstances的Index排列的。
70 |
71 | FStaticMeshInstanceData:
72 |
73 | 
74 |
75 | # ApplyBuildTree
76 |
77 | 触发更新
78 | MarkRenderInstancesDirty();
79 | UWorld::MarkActorComponentForNeededEndOfFrameUpdate()
80 |
81 | GameThread帧末尾
82 | UWorld::SendAllEndOfFrameUpdates()
83 | UActorComponent::DoDeferredRenderUpdates_Concurrent()
84 |
85 |
86 | 
87 |
88 | 添加,删除,移动 Instance 都会导致整个ClusterTree重新构建,然后重新创建渲染状态。
89 |
90 |
--------------------------------------------------------------------------------
/UE/Landscape.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 3imty7e5rg467oyfqg2xchi
3 | title: Landscape
4 | desc: ''
5 | updated: 1680245781669
6 | created: 1680245517243
7 | ---
8 | ## AlphaBrush
9 | 可以将一个高度图作为笔刷,直接将结果叠加在当前Landscape上。
10 |
11 | Doc:
12 | https://docs.unrealengine.com/5.1/zh-CN/landscape-brushes-in-unreal-engine/
13 |
14 | 
15 |
16 | # Splat map
17 |
18 | https://www.bilibili.com/video/BV1MC4y1Y7ft
19 |
20 | 每层材质都要占用一个8bit WeightMap通道,PS中采样每层材质的纹理,乘以Weight并相加。
21 |
22 | 8层材质,2个RGBA8 WeightMap,每像素采样18次=8*Albedo + 8*Normal+2*WeightMap。
23 |
24 | 2张RGBA占用空间也较大。
25 |
26 | 端游比手游材质层数翻倍。
27 |
28 | 大世界需要有32层及以上的材质层数。
29 |
30 | ULandscape中,按每个地块使用到的材质层情况划分材质变体,减少不必要的Layer采样,增加DrawCall,不够灵活?
31 |
32 | **需要的是整个大世界整体支持更多的材质,而不是局部。**
33 |
34 | Ghost Recon Wildlands Terrain Tools and Technology -- GDC2017
35 | * https://www.gdcvault.com/play/1024708/-Ghost-Recon-Wildlands-Terrain
36 | * https://zhuanlan.zhihu.com/p/34223867
37 | * https://zhuanlan.zhihu.com/p/364242852
38 |
39 | Far Cry 5 :
40 | * https://zhuanlan.zhihu.com/p/364546293
41 | * https://zhuanlan.zhihu.com/p/589351932
42 | * https://www.cnblogs.com/TracePlus/p/9202567.html
43 |
44 | 
45 |
46 | MatID Texture中,每个纹素代表实际1m的方块范围,其中有四个MatID,索引向TextureArray,这四个材质怎么混合 ? 还是说只采样一个?
47 |
48 | 再采样周围四个MatID根据距离把这四种材质混合,使MatID边界过渡自然。
49 |
50 | Blend everything depending on the normal axis ?
51 |
52 |
53 | Reference:
54 | * https://zhuanlan.zhihu.com/p/668278748
55 | * https://blog.csdn.net/qq_29523119/article/details/134173248
56 |
57 |
58 | # UE5 Landscape
59 |
60 | ULandscapeSubsystem : public UTickableWorldSubsystem,ALandscape
61 | ULandscapeComponent,FLandscapeComponentSceneProxy
62 |
63 |
64 | * Section是LOD计算、剔除的基本单位。
65 | * HeightMap一样的情况下,也就是整体地形大小一样的情况下,
66 | * 一个Component4个Section,可以减少4倍的Component数量,对CPU性能友好
67 | * 增大Section大小,可以减少Component数量,提升CPU性能
68 | * 但GPU性能下降,因为一个Section会渲染过多的顶点。
69 |
70 | 总体来说:
71 | * Seciton越小,剔除、LOD优化更多,但CPU开销高
72 | * Section越大,组件就少,CPU消耗降低,但GPU开销增加
73 |
74 | 以Section为单位考虑,一个Section对应一张HeightMap,HeightMap中一个纹素对应Section中一个顶点,所以,
75 | * 如果一个Section 64个顶点,对应一个64*64纹理,可以表示63个Quads,即63米。
76 | * 4*4Component,每个Component一个Seciton的情况下
77 | * Quads为63*4 252个
78 | * 分辨率(有效顶点数量)为 252+1
79 | * 如果一个Component有两个Section,4*4个Component
80 | * 每个Component有126个Quads,127个Verts
81 | * 整体有126*4=504个Quads
82 | * 分辨率(有效顶点数量)为504+1
83 |
84 | 考虑总体分辨率时,总是和Section数和Quads数入手,分辨率总是Quads数+1,HeightMap分辨率总是Quads数+1.
85 |
86 | ## ULandscapeComponent
87 | ```
88 | int32 SectionBaseX; // Quad为单位,属于这个Component的开始的Quad。
89 | int32 SectionBaseY;
90 | int32 ComponentSizeQuads;
91 | int32 SubsectionSizeQuads;
92 | int32 NumSubsections;
93 | TObjectPtr HeightmapTexture;
94 | TArray> WeightmapTextures;
95 | TArray WeightmapLayerAllocations;
96 |
97 | TMap, int8> MaterialPerLOD;
98 | int32 LODBias;
99 | TArray LODIndexToMaterialIndex;
100 | ```
101 |
102 | ```
103 | Component 1. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_0
104 | SectionBaseXY[0,0], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
105 | Component 2. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_1
106 | SectionBaseXY[126,0], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
107 | Component 3. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_2
108 | SectionBaseXY[252,0], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
109 | Component 4. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_3
110 | SectionBaseXY[0,126], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
111 | Component 5. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_4
112 | SectionBaseXY[126,126], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
113 | Component 6. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_5
114 | SectionBaseXY[252,126], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
115 | Component 7. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_6
116 | SectionBaseXY[0,252], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
117 | Component 8. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_7
118 | SectionBaseXY[126,252], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
119 | Component 9. /Game/Map/MyTestLevel.MyTestLevel:PersistentLevel.Landscape_1.LandscapeComponent_8
120 | SectionBaseXY[252,252], ComponentSizeQuads: 126, SubsectionSizeQuads: 63, NumSubsections: 2
121 | ```
--------------------------------------------------------------------------------
/UE/Lecture.LumenBake.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: z48wc0kzcdubvcr2njw3nz8
3 | title: LumenBake
4 | desc: ''
5 | updated: 1670117031175
6 | created: 1670114132682
7 | ---
8 |
9 | * https://www.bilibili.com/video/BV1wP411u79Z/?spm_id_from=444.41.list.card_archive.click&vd_source=b9fb6109477c7f517e916955290f758b
10 |
11 | # Lumen静态烘培
12 |
13 | ## Dynamic GI system
14 |
15 | Scene presentation:
16 | * Surfel
17 | * Voxel
18 | * Triangles
19 | * Other acceleration structures
20 | * Lumen scene with mesh card
21 |
22 | > Siggraph 2021: Global illumination based on surfels
23 |
24 | > GTC2014: voxel based gi on gpu
25 |
26 | # 新材质系统Strata-UE5.1
27 |
28 |
--------------------------------------------------------------------------------
/UE/Lumen.md:
--------------------------------------------------------------------------------
1 | Renference:
2 | * [最强分析 |一文理解Lumen及全局光照的实现机制](https://zhuanlan.zhihu.com/p/643337359)
3 | * [UE5 Lumen 源码解析(一)原理篇](https://zhuanlan.zhihu.com/p/499713106)
4 | # GI
5 | * [Realistic Image synthesis using photon mapping](https://graphics.stanford.edu/~henrik/papers/book/)
6 | * [A Practical Guide to Global Illumination using Photon Maps - Siggraph 2000 course](https://graphics.stanford.edu/courses/cs348b-00/course8.pdf)
7 | # SDF
8 | * https://iquilezles.org/articles/distfunctions/
9 | * [Raytracing and Raycasting with Signed Distance Functions](https://ben.land/post/2022/08/15/raycasting-raytracing-sdf/)
10 | * [Signed Distance Fields Using Single-Pass GPU Scan Conversion of Tetrahedra](https://developer.nvidia.com/gpugems/gpugems3/part-v-physics-simulation/chapter-34-signed-distance-fields-using-single-pass-gpu)
11 | * [UE5 Mesh Distance Field](https://dev.epicgames.com/documentation/en-us/unreal-engine/mesh-distance-fields-in-unreal-engine?application_version=5.0)
12 | * [SDF - Rendering](https://kosmonautblog.wordpress.com/2017/05/01/signed-distance-field-rendering-journey-pt-1/)
13 | * [Siggraph2015 course](https://advances.realtimerendering.com/s2015/index.html)
14 | * [Epic - Dynamic Occlusion with Signed Distance Fields](https://advances.realtimerendering.com/s2015/DynamicOcclusionWithSignedDistanceFields.pdf)
15 | * 有关UE的SDF AO的一些细节
16 |
17 | ## UE5 Mesh SDF
18 | 把空间体素化(Volume texture),每个点存的是它到最近的表面的距离,点在Mesh外则为正值,在Mesh内则为负值。
19 | * Sphere tracing,从一个点出发,知道了离自己最近的Surface的距离(以当前点为中心,距离为半径的球范围内都没有别的Surface),可以直接向前进这么多距离,快速求交。
20 | * Distance Field Ambient Occlusion
21 | * [Using distance field for lighting](https://iquilezles.org/articles/raymarchingdf/)
22 |
23 | # BRDF
24 | * [基于物理渲染的基础知识(辐射度量学,BRDF和渲染方程)](https://zhuanlan.zhihu.com/p/145410416)
25 | * [PBRT4_Radiometry](https://pbr-book.org/4ed/Radiometry,_Spectra,_and_Color/Surface_Reflection)
26 | * [BRDF PataBlog](https://www.patapom.com/blog/BRDF/BRDF%20Definition/)
27 | * [Importance sampling - what](https://patapom.com/blog/Math/ImportanceSampling/)
28 | * [Importance sampling - PDF to Actual Sampling](https://www.tobias-franke.eu/log/2014/03/30/notes_on_importance_sampling.html)
29 | * [DDGI Probe - 预计算](https://zhuanlan.zhihu.com/p/404520592)
30 | * [RTXGI - DDGI](https://developer.nvidia.cn/rtx/ray-tracing/rtxgi)
31 |
32 |
33 | # 基础信息
34 | * Radiant energy 辐射出来的电磁能量,$Q[J=Joule]$
35 | * Radiant flux 单位时间辐射的Radiant energy,辐射功率,可衡量光线亮度。$\Phi=\frac{dQ}{dt}$
36 | * Radiant intensity 点光源,单位立体角 的辐射功率。$I(\omega)=\frac{d\Phi}{d\omega}$
37 | * Irradiance 对于一个Surface点X,单位area接收到的辐射功率。$E(X)=\frac{d\Phi(X)}{dA}$
38 | * Radiance 对于一个Surface点p,单位area,单位立体角$\omega$,接收到的辐射功率。
39 | $$
40 | L(p,\omega)=\frac{\mathrm{d}^2\Phi(p,\omega)}{\mathrm{d}\omega \mathrm{d}Acos\theta}
41 | $$
42 |
43 | * Additive Color Mixing 增加亮度,多光源混合
44 | * Multiplicative Color Mixing 减少亮度,模拟光在物体表面的吸收与反射
45 |
46 | $$
47 | L_o(p,\omega_o)=L_e(p,\omega_o)+\int_{\Omega^+} L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)(n.\omega_i)\mathrm{d}\omega_i
48 | $$
--------------------------------------------------------------------------------
/UE/Lyra.AssetMananger.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: m0982l7s6k4habx1sxccmdr
3 | title: AssetMananger
4 | desc: ''
5 | updated: 1680828146214
6 | created: 1680601476785
7 | ---
8 |
9 | > Version: UE5.1.1
10 |
11 | 通常,我们会派生`UPrimaryDataAsset`定义一些`DataAsset`,里面会引用一些其它对象。一般有两种引用方式,即直接引用或者软引用:
12 | ```c++
13 | UTexture2D* Texture; // 直接引用
14 | TSoftObjectPtr ActorClass; // 软引用
15 | ```
16 | 直接引用的对象会在加载这个DataAsset时直接加载进来:
17 | ```c++
18 | ULyraAssetManager& AssetManager = ULyraAssetManager::Get();
19 | FSoftObjectPath AssetPath = AssetManager.GetPrimaryAssetPath(ExperienceId); // FPrimaryAssetId ExperienceId
20 | TSubclassOf AssetClass = Cast(AssetPath.TryLoad());
21 | check(AssetClass);
22 | const ULyraExperienceDefinition* Experience = GetDefault(AssetClass);
23 | ```
24 | 包括嵌套任何深度的直接引用,这和通常的UObject加载逻辑一样。对于软引用,这种情况下是不会加载的。
25 |
26 | 软引用的加载需要用UAssetManager的方法和Bundle,通常是通过方法`UAssetManager::LoadPrimaryAssets`加载,而软引用的属性上必须指明所属的Bundle,加载时指定要加载的Bundles,这样匹配的软引用的资源就会被加载上来:
27 | ```c++
28 | // Define
29 | UPROPERTY(meta=(AssetBundles = "TestBundle"))
30 | TSoftObjectPtr ActorClass; // 软引用
31 |
32 | // Load
33 | TSet BundleAssetList = {}; // Asset id to load
34 | TArray BundlesToLoad = { FName(TEXT("TestBundle")) };
35 |
36 | AssetManager.LoadPrimaryAssets(BundleAssetList, RawAssetList);
37 | ```
38 | 这样,`FPrimaryAssetId`所表示的DataAsset的所有软引用的属性,只要指明了Bundle为"TestBundle"的都会被加载出来。没有指明Bundle的软引用,默认实现下是不会加载的。不指明要加载的Bundle,也是任何软引用都不会加载。软引用属性中嵌套的软引用不会被加载。
39 |
40 | 其实现就是在保存一DataAsset时,会扫描当前DataAsset的所有属性中的元数据,并添加到AssetBundleData`(记录了BundleName -> TArray 的Array)`中:
41 | ```c++
42 | void UPrimaryDataAsset::UpdateAssetBundleData()
43 | {
44 | // By default parse the metadata
45 | if (UAssetManager::IsValid())
46 | {
47 | AssetBundleData.Reset();
48 | UAssetManager::Get().InitializeAssetBundlesFromMetadata(this, AssetBundleData);
49 | // 扫描所有属性,直接引用的UObject也会递归地扫描它。
50 | }
51 | }
52 | ```
53 | Cook时AssetRegistry会把Bundle保存下来,打包出来的Game就可以直接通过AssetManager使用。`LoadPrimaryAssets()`就会查找PrimaryAsset对应的Bundles缓存,找到其对应的所有软引用资产并加载。
54 | ```c++
55 | FAssetBundleEntry UAssetManager::GetAssetBundleEntry(const FPrimaryAssetId& BundleScope, FName BundleName) const
56 | {
57 | if (const TSharedPtr* FoundMap = CachedAssetBundles.Find(BundleScope))
58 | {
59 | for (FAssetBundleEntry& Entry : (**FoundMap).Bundles)
60 | {
61 | if (Entry.BundleName == BundleName)
62 | {
63 | return Entry;
64 | }
65 | }
66 | }
67 |
68 | return FAssetBundleEntry();
69 | }
70 | ```
71 | 一些情况下,我们希望通过其它的设置决定某个软引用属于什么Bundle。Lyra中,通过重载`UPrimaryDataAsset::UpdateAssetBundleData()`,向其中添加自定义的逻辑设置一些属性的Bundle。例如,`UGameFeatureAction_AddComponents`处理Client和Server Bundle:
72 | ```c++
73 | // 引用了GameFeatureAction的DataAsset中需要实现:
74 | #if WITH_EDITORONLY_DATA
75 | void ULyraExperienceDefinition::UpdateAssetBundleData()
76 | {
77 | Super::UpdateAssetBundleData();
78 |
79 | for (UGameFeatureAction* Action : Actions)
80 | {
81 | if (Action)
82 | {
83 | Action->AddAdditionalAssetBundleData(AssetBundleData);
84 | }
85 | }
86 | }
87 | #endif // WITH_EDITORONLY_DATA
88 |
89 | // 具体的Action中实现自定义逻辑添加BundleAsset
90 | #if WITH_EDITORONLY_DATA
91 | void UGameFeatureAction_AddComponents::AddAdditionalAssetBundleData(FAssetBundleData& AssetBundleData)
92 | {
93 | if (UAssetManager::IsValid())
94 | {
95 | for (const FGameFeatureComponentEntry& Entry : ComponentList)
96 | {
97 | if (Entry.bClientComponent)
98 | {
99 | AssetBundleData.AddBundleAsset(UGameFeaturesSubsystemSettings::LoadStateClient, Entry.ComponentClass.ToSoftObjectPath().GetAssetPath());
100 | }
101 | if (Entry.bServerComponent)
102 | {
103 | AssetBundleData.AddBundleAsset(UGameFeaturesSubsystemSettings::LoadStateServer, Entry.ComponentClass.ToSoftObjectPath().GetAssetPath());
104 | }
105 | }
106 | }
107 | }
108 | #endif
109 | ```
110 |
111 |
--------------------------------------------------------------------------------
/UE/Lyra.GameModes.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 32yjtl1nooo27rdlxg0uk98
3 | title: GameModes
4 | desc: ''
5 | updated: 1680832945846
6 | created: 1680482435878
7 | ---
8 |
9 | Lyra中不同的游戏模式由一个`ULyraExperienceDefinition`定义。里面定义了一种游戏模式所需的初始化数据,包括:
10 | - 需要开启的`GameFetaure`
11 | - 默认的`PawnData`
12 | - 需要执行的`GemaFeatureAction`
13 | - 其它需要执行的`ActionSet(ULyraExperienceActionSet)`
14 | 可以看出,除了PawnData,其它设置虽有不同,但本质都是执行GameFeatureAction,只是组织方式不同,方便不同程度的配置复用。
15 |
16 | ## 初始化
17 | 在Server上,GameMode在InitGame时执行了寻找要使用的ExperienceId的方法`ALyraGameMode::HandleMatchAssignmentIfNotExpectingOne()`, 这里会被延迟到下一帧执行,估计是为了确保GameMode系统完全初始化。通常,为了方便开发,需要为Experience的选择提供足够的灵活性,这里按优先级确定Experience:
18 | - Matchmaking assignment (if present)
19 | - 玩家的正常游戏流程,会在给GameMode指定的OptionsString中设置Experience。
20 | - OptionsString 是OpenLevel时写在URL里的,可以用UGameplayStatics::HasOption()等方法解析。
21 | - 格式类似于:/ShooterMaps/Maps/L_Expanse?listen?Experience=B_ShooterGame_Elimination
22 | - [[UE.Lyra.UI.ExperienceSelection]]
23 | - Developer Settings (PIE only)
24 | - Command Line override 指定'Experience='
25 | - World Settings
26 | - Default experience 写死的一个Experience
27 |
28 | 因为要支持多人游戏,所以配置的初始化最终应该在GameState上执行,且所有端都应该执行。所以定义了一个`ULyraExperienceManagerComponent`负责初始化`Experience`。
29 |
30 | GameMode确定Experience后,找到GameState上的`ULyraExperienceManagerComponent`:
31 | ```c++
32 | // 这里用FindComponent,而不是直接访问方法或成员变量,使得耦合更低,只依赖于AActor中的方法
33 | ULyraExperienceManagerComponent* ExperienceComponent = GameState->FindComponentByClass();
34 | check(ExperienceComponent);
35 | ExperienceComponent->ServerSetCurrentExperience(ExperienceId);
36 | ```
37 | 开始执行真正的Experience初始化:
38 | ```c++
39 | void ULyraExperienceManagerComponent::ServerSetCurrentExperience(FPrimaryAssetId ExperienceId)
40 | {
41 | ULyraAssetManager& AssetManager = ULyraAssetManager::Get();
42 | FSoftObjectPath AssetPath = AssetManager.GetPrimaryAssetPath(ExperienceId);
43 | TSubclassOf AssetClass = Cast(AssetPath.TryLoad());
44 | check(AssetClass);
45 | const ULyraExperienceDefinition* Experience = GetDefault(AssetClass);
46 |
47 | check(Experience != nullptr);
48 | check(CurrentExperience == nullptr);
49 | CurrentExperience = Experience;
50 | StartExperienceLoad();
51 | }
52 | ```
53 | 显然这是在Server上调用的方法,给定一个Experience DataAsset的Id,然后开始加载,这个Id会被设置为CurrentExperience,这个变量会被同步到Client,Client收到这个Id后,在On_Rep中调用同样的初始化方法`StartExperienceLoad()`。
54 |
55 | ## StartExperienceLoad
56 | 在确定好CurrentExperience后,所有端都会开始加载Experience。这里主要就是处理加载Experience中的软引用资产。其中包括`FPrimaryAssetId`中的Bundle,根据项目自定义逻辑添加的与Experience直接相关的软引用资产:
57 | ```c++
58 | TSet BundleAssetList;
59 | TSet RawAssetList;
60 | ```
61 | `BundleAssetList`除了Experience本身,还包括所有它引用的DataAsset,因为这些DataAsset可能通过`UpdateAssetBundleData()`的自定义逻辑添加Bundle,而不是仅仅通过属性上的Bundle标记。
62 | ```c++
63 | BundleAssetList.Add(CurrentExperience->GetPrimaryAssetId());
64 | for (const TObjectPtr& ActionSet : CurrentExperience->ActionSets)
65 | {
66 | if (ActionSet != nullptr)
67 | {
68 | BundleAssetList.Add(ActionSet->GetPrimaryAssetId());
69 | }
70 | }
71 | ```
72 | 然后需要确定加载的Bundle:
73 | ```c++
74 | TArray BundlesToLoad;
75 | BundlesToLoad.Add(FLyraBundles::Equipped);
76 |
77 | //@TODO: Centralize this client/server stuff into the LyraAssetManager
78 | const ENetMode OwnerNetMode = GetOwner()->GetNetMode();
79 | const bool bLoadClient = GIsEditor || (OwnerNetMode != NM_DedicatedServer);
80 | const bool bLoadServer = GIsEditor || (OwnerNetMode != NM_Client);
81 | if (bLoadClient)
82 | {
83 | BundlesToLoad.Add(UGameFeaturesSubsystemSettings::LoadStateClient);
84 | }
85 | if (bLoadServer)
86 | {
87 | BundlesToLoad.Add(UGameFeaturesSubsystemSettings::LoadStateServer);
88 | }
89 | ```
90 | 通常这些Bundle的定义都应该放在AssetManager中,用Static变量定义。
91 |
92 | 随后用AssetManger的方法加载这些资产,并绑定回调:
93 | ```c++
94 | const TSharedPtr BundleLoadHandle = AssetManager.ChangeBundleStateForPrimaryAssets(BundleAssetList.Array(), BundlesToLoad, {}, false, FStreamableDelegate(), FStreamableManager::AsyncLoadHighPriority);
95 | const TSharedPtr RawLoadHandle = AssetManager.LoadAssetList(RawAssetList.Array(), FStreamableDelegate(), FStreamableManager::AsyncLoadHighPriority, TEXT("StartExperienceLoad()"));
96 |
97 | // If both async loads are running, combine them
98 | TSharedPtr Handle = nullptr;
99 | if (BundleLoadHandle.IsValid() && RawLoadHandle.IsValid())
100 | {
101 | Handle = AssetManager.GetStreamableManager().CreateCombinedHandle({ BundleLoadHandle, RawLoadHandle });
102 | }
103 | else
104 | {
105 | Handle = BundleLoadHandle.IsValid() ? BundleLoadHandle : RawLoadHandle;
106 | }
107 |
108 | FStreamableDelegate OnAssetsLoadedDelegate = FStreamableDelegate::CreateUObject(this, &ThisClass::OnExperienceLoadComplete);
109 | if (!Handle.IsValid() || Handle->HasLoadCompleted())
110 | {
111 | // Assets were already loaded, call the delegate now
112 | FStreamableHandle::ExecuteDelegate(OnAssetsLoadedDelegate);
113 | }
114 | else
115 | {
116 | Handle->BindCompleteDelegate(OnAssetsLoadedDelegate);
117 |
118 | Handle->BindCancelDelegate(FStreamableDelegate::CreateLambda([OnAssetsLoadedDelegate]()
119 | {
120 | OnAssetsLoadedDelegate.ExecuteIfBound();
121 | }));
122 | }
123 | ```
124 |
125 | 最后还可以加载一些不需要阻塞初始化流程的预加载资产:
126 | ```c++
127 | // This set of assets gets preloaded, but we don't block the start of the experience based on it
128 | TSet PreloadAssetList;
129 | //@TODO: Determine assets to preload (but not blocking-ly)
130 | if (PreloadAssetList.Num() > 0)
131 | {
132 | AssetManager.ChangeBundleStateForPrimaryAssets(PreloadAssetList.Array(), BundlesToLoad, {});
133 | }
134 | ```
135 | ## OnExperienceLoadComplete
136 | 加载完资产后,就要开始处理其对应的初始化逻辑。主要是两类,GameFeatureAction和GaemFeaturesPlugin。除了Experience本身有配置这些,ActionSets中也有配置:
137 | ```c++
138 | GameFeaturePluginURLs.Reset();
139 |
140 | auto CollectGameFeaturePluginURLs = [This=this](const UPrimaryDataAsset* Context, const TArray& FeaturePluginList)
141 | {
142 | for (const FString& PluginName : FeaturePluginList)
143 | {
144 | FString PluginURL;
145 | if (UGameFeaturesSubsystem::Get().GetPluginURLByName(PluginName, /*out*/ PluginURL))
146 | {
147 | This->GameFeaturePluginURLs.AddUnique(PluginURL);
148 | }
149 | else
150 | {
151 | ensureMsgf(false, TEXT("OnExperienceLoadComplete failed to find plugin URL from PluginName %s for experience %s - fix data, ignoring for this run"), *PluginName, *Context->GetPrimaryAssetId().ToString());
152 | }
153 | }
154 | };
155 |
156 | CollectGameFeaturePluginURLs(CurrentExperience, CurrentExperience->GameFeaturesToEnable);
157 | for (const TObjectPtr& ActionSet : CurrentExperience->ActionSets)
158 | {
159 | if (ActionSet != nullptr)
160 | {
161 | CollectGameFeaturePluginURLs(ActionSet, ActionSet->GameFeaturesToEnable);
162 | }
163 | }
164 | ```
165 | 搜集完需要激活的GameFeature后,就可以调用GaemFeaturesSubsystem的方法激活这些GameFeature:
166 | ```c++
167 | NumGameFeaturePluginsLoading = GameFeaturePluginURLs.Num();
168 | if (NumGameFeaturePluginsLoading > 0)
169 | {
170 | LoadState = ELyraExperienceLoadState::LoadingGameFeatures;
171 | for (const FString& PluginURL : GameFeaturePluginURLs)
172 | {
173 | ULyraExperienceManager::NotifyOfPluginActivation(PluginURL);
174 | UGameFeaturesSubsystem::Get().LoadAndActivateGameFeaturePlugin(PluginURL, FGameFeaturePluginLoadComplete::CreateUObject(this, &ThisClass::OnGameFeaturePluginLoadComplete));
175 | }
176 | }
177 | else
178 | {
179 | OnExperienceFullLoadCompleted();
180 | }
181 | ```
182 | ## OnExperienceFullLoadCompleted
183 | 所有GameFeature激活完后,需要把所有直接配置的Action激活:
184 | ```c++
185 | auto ActivateListOfActions = [&Context](const TArray& ActionList)
186 | {
187 | for (UGameFeatureAction* Action : ActionList)
188 | {
189 | if (Action != nullptr)
190 | {
191 | //@TODO: The fact that these don't take a world are potentially problematic in client-server PIE
192 | // The current behavior matches systems like gameplay tags where loading and registering apply to the entire process,
193 | // but actually applying the results to actors is restricted to a specific world
194 | Action->OnGameFeatureRegistering();
195 | Action->OnGameFeatureLoading();
196 | Action->OnGameFeatureActivating(Context);
197 | }
198 | }
199 | };
200 |
201 | ActivateListOfActions(CurrentExperience->Actions);
202 | for (const TObjectPtr& ActionSet : CurrentExperience->ActionSets)
203 | {
204 | if (ActionSet != nullptr)
205 | {
206 | ActivateListOfActions(ActionSet->Actions);
207 | }
208 | }
209 | ```
210 | 至此就完成了所有Experience的初始化操作,随后就可以调用OnExperienceLoaded的回调:
211 | ```c++
212 | OnExperienceLoaded_HighPriority.Broadcast(CurrentExperience);
213 | OnExperienceLoaded_HighPriority.Clear();
214 |
215 | OnExperienceLoaded.Broadcast(CurrentExperience);
216 | OnExperienceLoaded.Clear();
217 |
218 | OnExperienceLoaded_LowPriority.Broadcast(CurrentExperience);
219 | OnExperienceLoaded_LowPriority.Clear();
220 | ```
221 | 这里设置了三个Loaded回调,按顺序执行。当一些系统期望在另一些系统初始化之前执行操作时,就可以把自己注册为高优先级的回调,而另一些注册为低优先级的。、
222 |
223 | 在注册执行回调时,通常会根据当前的状态选择直接调用或者注册:
224 | ```c++
225 | void ULyraExperienceManagerComponent::CallOrRegister_OnExperienceLoaded_HighPriority(FOnLyraExperienceLoaded::FDelegate&& Delegate)
226 | {
227 | if (IsExperienceLoaded())
228 | {
229 | Delegate.Execute(CurrentExperience);
230 | }
231 | else
232 | {
233 | OnExperienceLoaded_HighPriority.Add(MoveTemp(Delegate));
234 | }
235 | }
236 | ```
237 | 这样避免了注册的时序问题,统一了不同情况的操作,方便使用。
238 |
--------------------------------------------------------------------------------
/UE/Lyra.UI.ExperienceSelection.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 78hs23ajc9w7amf7zsenj2l
3 | title: ExperienceSelection
4 | desc: ''
5 | updated: 1680594358046
6 | created: 1680590618914
7 | ---
8 |
9 | Lyra中一个游戏模式的具体内容称为Experience`(ULyraExperienceDefinition)`,从`L_LyraFrontEnd`中,可以选择一种游戏Experience开始游戏:
10 |
11 | 
12 |
13 | 实现这一功能时,期望可以灵活扩展Experience的数量,方便制定外观。所以这里再定义了一种`ULyraUserFacingExperienceDefinition`资产,描述用于展示一种Experiences的UI和开始一个Session的设置:
14 | - MapID
15 | - ExperienceID 均用FPrimaryAssetId,在属性上加上`meta=(AllowedTypes="Map")`可以限定类型.
16 | - ExtraArgs 会被写到OpenLevel的URL参数里,最终会出现在GameMode的OptionStirng中。
17 | - 多人相关的配置,最大玩家数量
18 | - UI相关的Description配置,加载界面
19 |
20 | 在ExperienceList初始化时,可以通过`FPrimaryAssetType`直接拿到`ULyraUserFacingExperienceDefinition`的所有AssetId,用蓝图调用时,可以通过下拉菜单选择当前项目中所有的`FPrimaryAssetType`:
21 | ```c++
22 | void UKismetSystemLibrary::GetPrimaryAssetIdList(FPrimaryAssetType PrimaryAssetType, TArray& OutPrimaryAssetIdList)
23 | {
24 | if (UAssetManager* Manager = UAssetManager::GetIfValid())
25 | {
26 | Manager->GetPrimaryAssetIdList(PrimaryAssetType, OutPrimaryAssetIdList);
27 | }
28 | }
29 | ```
30 | 然后通过异步节点`AsyncLoadPrimaryAssetList`加载所有的`FPrimaryAssetId`,这里最终调用的是`UAssetManager::LoadPrimaryAssets()`,加载出来的Asset会永远存在内存中,直到你显式Unload。随后创建对应的UI,然后玩家选择模式,构建`UCommonSession_HostSessionRequest`,通过选择的`ULyraUserFacingExperienceDefinition`构建加载URL,再通过`UCommonSessionSubsystem`(GameInstanceSubsystem)开始游戏。
31 |
32 | 随后GameMode会解析出选择的`ULyraExperienceDefinition`,并初始化整个游戏系统。
33 |
34 | 这里定义的`ULyraUserFacingExperienceDefinition`把实际的Experience与它的选择完全隔离开。通过Map URL更是将Experience的初始化完全与局外的Experience选择完全分离。
--------------------------------------------------------------------------------
/UE/Lyra.UI.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: q6788di4shgkrl1kty53lr8
3 | title: UI
4 | desc: ''
5 | updated: 1680590524408
6 | created: 1680590524408
7 | ---
8 |
--------------------------------------------------------------------------------
/UE/Lyra.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: luhql4n9diqnhp9dua411b3
3 | title: Lyra
4 | desc: ''
5 | updated: 1683420048859
6 | created: 1680481817352
7 | ---
8 | 新坑
9 |
10 | 分析Lyra各个Gameplay系统的架构。
11 |
12 | # Reference
13 | * 各个版本的[Release nots](https://docs.unrealengine.com/5.1/en-US/upgrading-the-lyra-starter-game-to-the-latest-engine-release-in-unreal-engine/)
14 |
15 | - GameModes
16 | - Character
17 | - AbilitySystem
18 | - Camera
19 | - System
20 | - UI
21 | - Weapons
22 | - Equipment
23 | - GameFeatures
24 |
25 |
--------------------------------------------------------------------------------
/UE/MVVM.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 5sd65jcaaz4cv1mhpetqdrk
3 | title: MVVM
4 | desc: ''
5 | updated: 1679728955010
6 | created: 1679444341978
7 | ---
8 | ## Viewmodel
9 | Viewmodel中的属性应该是Private的,必须有UPROPERTY宏和FieldNotify。
10 |
11 | FieldNotify表明可以向Widget广播这个Property的改变,且会出现在ViewBinding界面。
12 | Setter或Setter="FUNCTION_NAME"表明允许通过指定的函数设置这个属性。如果不指定函数名则默认为函数Set[VariableName].
13 | Getter或Setter="FUNCTION_NAME"同理。
14 |
15 | MVVM
16 | 
17 |
18 |
19 | Reference :
20 | - https://docs.unrealengine.com/5.1/zh-CN/umg-viewmodel/
21 | - https://www.bilibili.com/video/BV1Dj411N735/
--------------------------------------------------------------------------------
/UE/Nanite.md:
--------------------------------------------------------------------------------
1 | * https://zhuanlan.zhihu.com/p/376267968
2 | * https://zhuanlan.zhihu.com/p/376786001
3 |
--------------------------------------------------------------------------------
/UE/Pro.md:
--------------------------------------------------------------------------------
1 |
2 | 这几年一直从事UE引擎开发。我熟悉UE5引擎的各个模块,地形,渲染、Animation(渲染相关)、WorldParitition等。
3 | 熟悉各种调试工具,UnrealInsights、PIX、NSight graphics、RenderDoc等,用于排查项目中遇到的各种问题。过去3年,我主要深度参与了《重装前哨》的开发,一款RTS/FPS于一体的缝合怪游戏,我在其中主要负责引擎相关工作,包括大规模SkeltonMesh绘制、地形、CPU/GPU性能、风场动画、引擎一些功能的扩展,运行时随机生成植被,疑难BUG排查,扩展引擎支持Gameplay功能,部分gameplay系统的开发,等。
4 |
5 | 我热爱引擎技术,对游戏引擎尤其UE5有深刻的理解以及快速学习的能力,并善于挖掘(分析)引擎的底层实现原理,帮助项目更恰当地使用引擎功能,还能够在充分理解引擎实现原理的基础上恰当地扩展引擎功能。
6 |
7 | ---
8 |
9 | 深度参与《重装前哨》预研、开发、上线全过程,这是一款集RTS/FPS、生存建造等特性于一体的3D游戏,负责UE4/UE5引擎相关工作,根据项目需求制定技术方案,从技术预研,到方案制定、落地全流程。
10 |
11 | * 制定并实现大规模敌人渲染方案,实现GPUIsntancedSkeletonMesh,在同时渲染5000个SkelotonMesh情况下,GPU耗时2ms,不同的Instance都有自己的动画,切动画时也有混合效果。GPU ComputeShader 剔除,FSceneViewExtensionBase。
12 | * Animation budget allocator
13 | * Vertex Animation,Notify,灵活,
14 | * GPU剔除
15 | * 制定使用UE5WorldPartition制作大世界的规范,包括GridLayer划分策略、HLOD、DataLayer。
16 | * 修改引擎源码,实现Runtime下修改地形,实现动态生成建筑时平滑地形、添加凹陷,弹坑等功能,包括地形材质、地形碰撞、Grass、导航网格在内都能正常发生改变。
17 | * 扩展、修改引擎编辑器功能,加速美术、策划的工作。
18 | * 自动合批Instanced,runtime 随机生成植被,Blender风场动画Texture,
19 | * 资产验证,命名,设置(Nanite > 1W 面 没有LOD)
20 | * 负责持续监控并优化游戏性能,为性能热点问题提供解决方案。
21 | * UnrealInsights,PIX,NSight Graphics,RenderDoc
22 | * 复杂碰撞,TriMesh,物理内存2G
23 | * 分帧操作,Parallel For,
24 | * 每次打包材质没有变化,ushaderbytecode,几百MB,都会变,Cook时资源加载顺序不一样,导致里面内容顺序不一样,修改源码,给他们按Hash排序。
25 | * 图形渲染设置,Nanite,Lumen,VSM,Grass
26 | * 制定UE5 Nanite模型以及植被的使用规范,以达到最佳性能。
27 | * Mask,WPO,Rasterize BINS,Empty Draw,DrawCall。Blender,风场动画,
28 | * 负责排查并修复任何疑难致命BUG,包括引擎或我们自己写的。
29 | * 连续SeamlessTravel 导致掉线
30 | * 各种迭代器失效导致的随机崩溃
31 | * TransientAllocator 导致的GPU崩溃,debuggpu,d3ddebug,
32 | * AMD显卡,编译PSO卡死
33 | * HISM 导航网格错误,
34 | * PVS 静态检查,UPROPERTY,内存泄漏
35 | * ISM负缩放时,导航网格生成在反面,生成导航网格是上下面的判断错误,检查到负缩放时,把Indices也反过来。
36 | * 当BodyInstance作为DataTable的RowStruct的Member时,在DataTableEditor中点击空的区域,会使用None RowName刷新DetailPanel,此时没有数据,会导致BodyInstnace的自定义PropertyPanel中的代码Check失败。
37 | * 负责实现计算任意技能树UI布局算法(因为我们的技能树是完全随机的),并申请专利。
--------------------------------------------------------------------------------
/UE/RenderMesh.md:
--------------------------------------------------------------------------------
1 | * https://dev.epicgames.com/documentation/en-us/unreal-engine/graphics-programming-for-unreal-engine
2 |
3 | * [InstancedDraw ISM HISM](https://www.jianshu.com/p/a086bd856634)
4 | * [模型绘制机制](https://blog.csdn.net/ttod/article/details/134377780)
5 |
6 |
7 | 一种情况,创建一个AStaticMeshActor,调用SetStaticMesh:
8 | * UStaticMeshComponent::SetStaticMesh()
9 | * 如果已经创建了渲染状态
10 | * MarkRenderStateDirty()
11 | * bRenderStateDirty = true;
12 | * MarkForNeededEndOfFrameRecreate()
13 | * 没有,则马上创建,RecreateRenderState_Concurrent()
14 | * UPrimitiveComponent::CreateRenderState_Concurrent()
15 | * 用UWorld上的`FSceneInterface* Scene;`进行创建
16 | * FScene::AddPrimitive() -> FScene::BatchAddPrimitivesInternal<>()
17 |
18 | 这里通过这段代码创建`FPrimitiveSceneProxy`:
19 |
20 | 
21 |
22 | 这里的`GetPrimitiveComponentInterface()`是在`UPrimitiveComponent`中用一个宏实现的:
23 | ```c++
24 | UE_DECLARE_COMPONENT_ACTOR_INTERFACE(PrimitiveComponent)
25 | ```
26 | 
27 |
28 | 就是定义了一个`FActorPrimitiveComponentInterface`成员变量,它实现了接口`IPrimitiveComponent`,全是获取`UPrimitiveComponent`状态相关的接口,里面的实现都是调用前面的宏实现的`UPrimitiveComponent::GetPrimitiveComponent()`,用地址偏移,得到当前`FActorPrimitiveComponentInterface`成员变量所在对象的地址,不理解为什么一定要这么做(=_=)。例如这里用到的
29 | `CreateSceneProxy()`:
30 |
31 | 
32 |
33 | 将创建好的`FPrimitiveSceneProxy`和`FPrimitiveSceneInfo`构成一个`FCreateCommand`,用`ENQUEUE_RENDER_COMMAND`送到渲染线程处理:
34 |
35 | 
36 |
37 | 等RenderThread执行到这个命令时,最终把PrimitiveSceneInfo添加到FScene中:
38 |
39 | 
40 |
41 | 这里的AddedPrimitiveSceneInfos会在`FDeferredShadingSceneRenderer::Render()`中处理,在`FSceneRenderer::OnRenderBegin()`的最后调用`FScene::Update()`,更新渲染Scene的相关信息,处理各种Primitive上的数据改变,包括Primitve添加删除、Transform、VirtualTexture更新等。处理新加进来的`AddedPrimitiveSceneInfos`,完成后清空它。
42 |
43 | 构建GPUScene,场景有多少个`FPrimitiveSceneInfo`就要构建多少个实例。
44 |
45 | AddStaticMesh, StaticPath
46 |
47 | 
48 |
49 | 初始化View,计算Visibiliy,搜集可见元素的Mesh。
50 | ```
51 | FDeferredShadingSceneRenderer::BeginInitViews()
52 | FVisibilityTaskData::ProcessRenderThreadTasks()
53 | FVisibilityViewPacket::BeginInitVisibility()
54 | 如果场景种FPrimitiveSceneInfo太多,这里会创建超级多的数据,用于计算每个Primitive的Visibility
55 | 每个Primitive至少循环处理一次
56 | UpdateAlwaysVisible() 处理标记为总是可见的对象
57 | SceneVisibility.cpp FrustumCull() 处理所有Primitive的视锥剔除
58 | Scene.PrimitiveBounds[Index] 半径小于0直接剔除
59 | FPrimitiveSceneInfo::AddToScene()中初始化为Proxy->GetBounds()
60 |
61 | ```
62 |
63 | void FRelevancePacket::ComputeRelevance(FDynamicPrimitiveIndexList& DynamicPrimitiveIndexList)
64 | 对所有可见的Primitive计算相关性,
65 | PrimitiveSceneProxy->GetViewRelevance(&View);
66 | DynamicPrimitiveViewMasks->Primitives[PrimitiveIndex]
67 | FDynamicMeshElementContext::GatherDynamicMeshElementsForPrimitive(FPrimitiveSceneInfo* Primitive, uint8 ViewMask)
68 |
69 |
70 | FNaniteMeshProcessor
71 |
72 | # Primitive的Transform和Bound的更新
73 | ```c++
74 | UActorComponent::DoDeferredRenderUpdates_Concurrent()
75 | if(bRenderTransformDirty)
76 | void UPrimitiveComponent::SendRenderTransform_Concurrent()
77 | void FScene::UpdatePrimitiveTransformInternal(T* Primitive)
78 | ENQUEUE_RENDER_COMMAND Scene->UpdatePrimitiveTransform_RenderThread()
79 | 添加到FScene::UpdatedTransforms
80 | ```
81 | 随后在FScene::Update中处理
82 | * FPrimitiveSceneProxy::SetTransform()
83 |
84 | # 移除Primitive
85 | 实际也是在FScene::Update中delete的。
86 |
87 | 
88 |
89 | 实际是先把要移除的Primitive添加到RemovedPrimitiveSceneInfos中。通过FScene::RemovePrimitiveSceneInfo_RenderThread()。
90 |
91 |
92 | 从GameThread触发:
93 | ```c++
94 | void UActorComponent::DestroyRenderState_Concurrent()
95 | void UPrimitiveComponent::DestroyRenderState_Concurrent()override
96 | FScene::RemovePrimitive(UPrimitiveComponent* Primitive)
97 | FScene::BatchRemovePrimitivesInternal(TArrayView InPrimitives)
98 | ENQUEUE_RENDER_COMMAND FScene::RemovePrimitiveSceneInfo_RenderThread()
99 | ```
100 |
101 | GameThread多个地方会触发DestroyRenderState:
102 | ```
103 | UActorComponent::ExecuteUnregisterEvents()
104 | UActorComponent::RecreateRenderState_Concurrent()
105 | ```
106 |
107 | UStaticMesh的IndexBuffer、VertexBuffer创建、释放时机:
108 | * 创建,加载资源好了之后就从原始数据初始化各种Buffer、VertexFactory,发送渲染命令到RenderThread创建RHIBuffer,Resource->InitResource(RHICmdList);
109 | * 释放, BeginDestroy的时候,发命令到RenderThread调用Resource->ReleaseResource();
--------------------------------------------------------------------------------
/UE/ShaderDev.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 5v6dxkiak6x6ntf0iaemlri
3 | title: ShaderDev
4 | desc: ''
5 | updated: 1699773374282
6 | created: 1699772443313
7 | ---
8 |
9 | # shader相关的Debug方式
10 | * https://docs.unrealengine.com/5.3/zh-CN/graphics-programming-overview-for-unreal-engine/
11 |
12 | Ctrl+Shift+. 或 recompileshaders changed -- 重新编译上次保存 .usf 文件后发生变化的着色器。这将在加载后自动进行。
13 |
14 | # 调试着色器编译过程
15 | * https://docs.unrealengine.com/5.3/zh-CN/debugging-the-shader-compile-process-in-unreal-engine/
16 |
17 | Engine/Config/ConsoleVariables.ini中:
18 | r.ShaderDevelopmentMode=1
19 |
20 |
21 | # 着色器调试工作流程
22 | * https://docs.unrealengine.com/5.3/zh-CN/shader-debugging-workflows-unreal-engine/
23 |
24 |
25 | ## dump command
26 |
27 | dumpmaterialstats // dump材质统计信息到MaterialStats-2020.12.15-13.12.23.csv
28 |
29 | dumpparticlecounts // 输出ParticleSystemComponent信息
30 |
31 | dumpparticlemem // 输出Particel的内存占用信息
32 |
33 | particlemeshusage // 打印particle中staticmesh使用情况
34 |
35 | DumpShaderPipelineStats // 输出Shader Pipeline统计信息到ShaderPipelineStats-2020.12.15-13.17.00.csv
36 |
37 | dumpshaderstats // 输出Shader统计信息到ShaderStats-2020.12.15-13.18.10.csv
38 |
39 | rhi.DumpMemory // 打印RenderTarget的内存信息
40 |
41 | DumpAvailableResolutions // 打印当前可使用的屏幕分辨率和刷新频率
42 |
43 | # Gpu Scene
44 |
45 | * Scene Uniform Buffer : https://www.bilibili.com/video/BV1fM4m1U7Tp
46 |
47 | # Shader resource
48 | [The book of shaders](https://thebookofshaders.com/)
--------------------------------------------------------------------------------
/UE/UE.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: lgxdx0yy47ogsxoseswn9j7
3 | title: UE
4 | desc: ''
5 | updated: 1683420180597
6 | created: 1667027440217
7 | ---
8 |
9 | Note for unreal engine development.
10 |
11 | ## 基础知识
12 | 图形学基础:https://www.bilibili.com/video/BV1X7411F744
13 |
14 | 游戏引擎基础:https://www.bilibili.com/video/BV1oU4y1R7Km
15 |
16 | 其它Games系列的课程,感兴趣的话都可以看。
17 |
18 | ## UE
19 | 1. 看官方文档,把所有编辑器相关的操作都熟悉一下,所有示例都动手做一遍。
20 | > https://docs.unrealengine.com/5.0/zh-CN/
21 |
22 |
23 | 2. 熟悉UE中C++开发
24 | 这个专栏中有UE中程序相关的一些基本概念的介绍
25 | > https://www.zhihu.com/column/insideue4
26 |
27 | 3. 向官方给的一个完整的游戏案例学习
28 | > https://docs.unrealengine.com/5.0/zh-CN/lyra-sample-game-in-unreal-engine/
29 |
30 | 这其中有用UE进行游戏开发的所有方面,包括C++,蓝图,各个游戏系统等等,值得花大量时间把这个项目掌握透彻。知乎上可以搜索到大量分析这个项目的文章。
31 |
32 | 4. 官方每周会搜集大家在知乎写的关于UE的文章, 可以看看这些大佬是怎么学习UE的。
33 |
34 | > https://www.zhihu.com/org/xu-huan-yin-qing-24/posts
35 |
36 |
37 |
--------------------------------------------------------------------------------
/UE/UE5_IndirectDraw.md:
--------------------------------------------------------------------------------
1 | 利用FSceneViewExtensionBase,注入自定义的CS Pass,对大量Instance进行剔除,构建IndirectDrawArgumentBuffer,用ExecuteIndirect实现绘制。
2 |
3 | 关键是构建FMeshBatchElement::IndirectArgsBuffer.
4 |
5 | * 参考引擎实现的FLandscapeSceneViewExtension、ApplyViewDependentMeshArguments(),实现地形Tile的剔除。
6 |
7 | * FWaterViewExtension::PreRenderBasePass_RenderThread()、FWaterMeshSceneProxy::GetDynamicMeshElements()也用到了IndirectDraw。
8 |
9 | * FNiagaraRendererMeshes::CreateMeshBatchForSection()
10 | 应用场景:
11 | *
--------------------------------------------------------------------------------
/UE/UnrealFest2024.md:
--------------------------------------------------------------------------------
1 |
2 | # 基于PCG做程序化生成 - 室内
3 | https://www.youtube.com/watch?v=FW5U_IsV3Pw
4 |
5 | Streamlining Indoor Environment Creation with PCG and Geometry Script in UE5 | Unreal Fest 2024Streamlining Indoor Environment Creation with PCG and Geometry Script in UE5 | Unreal Fest 2024
--------------------------------------------------------------------------------
/UE/VirtualTexture.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: ezzbf9i42su9qilq1b5nuya
3 | title: VirtualTexture
4 | desc: ''
5 | updated: 1670901151228
6 | created: 1670901151229
7 | ---
8 |
--------------------------------------------------------------------------------
/UE/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/UE/image.png
--------------------------------------------------------------------------------
/UE/optimization.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: jmbldi5n1nb3fr87vicrwsg
3 | title: optimization
4 | desc: ''
5 | updated: 1667042620061
6 | created: 1667027481667
7 | ---
8 | UE 相关的优化操作。
9 |
10 | # Asset reduction
11 |
12 | 优化Asset,以获取更好的渲染性能。
13 |
14 | ## LODs & Polygon Reduction
15 |
16 | 找到顶点计算消耗最大的对象
17 |
18 | - r.screenpacentage 10 降低渲染的分辨率,排除PixelShader的影响
19 |
20 | - r.RHISetGPUGaptureOptions 1, 在`ProgileGPU`中会显示每一个DrawCall的消耗
21 |
22 | * https://www.bilibili.com/video/BV1cK4y1V7bv/?vd_source=b9fb6109477c7f517e916955290f758b
--------------------------------------------------------------------------------
/UE/ue5_opt.md:
--------------------------------------------------------------------------------
1 | Optimizing UE5
2 | https://linktr.ee/epicmattoztalay?utm_source=qr_code
3 |
4 | # Nanite
5 | https://zhuanlan.zhihu.com/p/687141143
6 |
7 | https://www.youtube.com/watch?v=xSUV8BahmI0&list=WL&index=3&t=272s
8 |
9 | Rethinking Performance Paradigms for High-Quality Visuals - Part 1
10 |
11 | https://www.youtube.com/watch?v=Cb63bHkWkwk&t=11963s
12 | 1:50:26 Lumen
13 |
14 | Nanite:
15 |
16 | - Not just for hi-res meshes
17 | - 采用Nanite的低分辨率Mesh还是比普通StaticMesh渲染得快
18 | - Smaller data footprint
19 | - if VSMs, then Nanite
20 | - Other systems run faster
21 | - Nanite everything,eventually
22 |
23 | Considerations
24 | * NaniteVisBuffer
25 | * Occlusion
26 | * HZB
27 | * Primitives
28 | * Instances
29 | * Clusters
30 | * Rasterization
31 | * What materials are covered by what pixel
32 | * nanitestats
33 | * HW
34 | * 大三角形,覆盖大于一个像素
35 | * SW
36 | * 小三角形,覆盖小于一个像素
37 | * r.nanite.visualize.advanced 1 可以看到更多可视化选项
38 | * Fixed Function
39 | * Opaque
40 | * Non-deforming
41 | * 就是顶点的位置不会变的,顶点数据里面说在哪儿就在哪儿。非常快,整个场景的可以一次就光栅化完
42 | * Programmable Rasterization
43 | * 顶点位置,会发生变化,WPO,MaskedMaterials,PDO(PixelDepthOffset),Displacement
44 | * Raster Bin可视化中,彩色的为一种可编程光栅化,黑色为固定函数光栅化
45 | * r.Nanite.ShowMeshDrawEvents 1,然后profileGPU,可以看到HWRasterize下,可以看到所有要求可编程光栅化的材质名字。
46 | * WPO
47 | * static mesh component上有bool值可以关EvaluateWorldPositionOffset
48 | * 或者设置个关闭的距离
49 | * 材质里可以设置MaxWOPDistance
50 | * Nanite Visualization 可以看什么地方在计算WPO
51 | * Masked Material
52 | * Always programmable
53 | * 增加Overdraw
54 | * Overdraw
55 | * Masked材质尤为严重
56 | * "Draw Calls"
57 | * CPU pre-allocate bins for material
58 | * 同样材质的物体,在resterize后,标记了屏幕像素对应的材质id,即使不同模型,后续也只需要一次draw。
59 | * 想办法减少材质种类
60 | * custom primitive data
61 | * per instance custom data
62 | * material parameter collection
63 | * Empty draws
64 | * 对场景里所有Unique的材质pre-allcoate material bins,但对应的geo可能在光栅化之前就被剔除了
65 | * 这就是empty draws
66 | * nanitestats
67 | * 减少Bins,空的Bins也对性能有影响。
68 | * Instancing
69 | * Scalability
70 |
71 |
72 | * Mesh construction
73 | * Poly Budgets
74 | * Cluster Size
75 | * Long, Thin Tris
76 | * Disk Size vs. Cooked Size
77 |
78 | Lumen:
79 |
80 | Ray Tracing - 软光追,MeshSDF,GlobalSDF。硬件光追。
81 |
82 | Radiance injection, Caching:
83 | * Cards,Lumen捕获光线的位置
84 | * Mesh Card,Rutnime捕获,Mesh遮挡,Mesh的材质信息:Albedo,Normal,Depth,Emissive
85 | * Atlas ,Surface Cache,4096x4096
86 | * 显存压力大
87 | 
88 | * Indirect Light,Radiance cache
89 | * VoxelLighting 给下一帧
90 | * 使用上一帧的VoxelLighting得到Indirect Lighting。每帧逐渐积累。
91 | * 加上Surface cache的DirectLighting 得到这一帧当前lighting。
92 |
93 | 1. Lumen scene update
94 | * Mesh card capture
95 | * CopyCardsToSurfaceCache(Alas)
96 | * BuildCardUpdateContext
97 | 2. Lumen scene direct lighting
98 | * CullDirectLightingTiles
99 | * CombineLighting
100 | 3. VoxelLigthing3D
101 | * UpdateVoxelVisBufferN with clipmap
102 | * TranslucencyVolumenLighting
103 | 4. LumenScreenProbeGather
104 | * UniformPlacement+AdaptivePlacement
105 | * RenderLumenScreenProbeGather
106 | * TraceScreen
107 | * TraceMeshSDF
108 | * TraceVoxels
109 | * CompositeTraces
110 | * TemporalReprojection
111 | 5. Lumen Reflection
112 |
113 | # Lumen
114 |
115 | https://www.youtube.com/watch?v=Cb63bHkWkwk&t=11963s
116 | 1:50:26 Lumen
117 |
118 | Considerations
119 | - SWRT vs HWRT
120 | - SWRT fast,good when you've got a lot of Kit bash stuff that's overlapping instances,
121 | - HWRT high quality, a lot of shinned meshes that might be significantly affecting GI and mirror-like Reflections
122 | - 性能目标:
123 | - 30FPS ~8ms HW, for lighting and refections, Console
124 | - 60FPS ~4ms SW,
125 | - Lumen Scene Lighting
126 | - Lumen Screen Probe Gather
127 | - Lumen Reflections
128 | - Async Compute
129 | - Reponsiveness
130 | - Mesh and Scene Construction
131 |
132 | HWRT
133 | - BVH Traces
134 | - Rebuild TLAS every frame
135 | - - Instance Counts, Overlaps
136 | - Trace Performance
137 | - Features:
138 | - - Hit Lighting
139 | - - Far Field
140 |
141 | SWRT
142 | - DF Traces
143 | - GDF(Global distance field) Build
144 | - Independent of instance count
145 |
146 | Action Items
147 | - HWRT
148 | - - Instance Counts
149 | - - Instanc Overlap
150 | - SWRT
151 | - - Affects DF
152 | - Roughness to Trace
153 |
154 |
155 | Matt Oztalay
156 | ## Real Action
157 | * 超高(Epic) 级别对应的帧率为30FPS。 - 主机
158 | * 高(High) 级别对应的目标帧率为60FPS。
159 |
160 | 试图让间接光照的品质在不同质量级别下保持相似,不启用Lumen:
161 |
162 | 中
163 | * 对于大规模的环境光遮蔽, 距离场环境光遮蔽(Distance Field Ambient Occlusion) 会取代 Lumen全局光照(Lumen Global Illumination) 。
164 | * 对于小规模的环境光遮蔽,会启用 屏幕空间环境光遮蔽(Screen Space Ambient Occlusion) 。
165 |
166 | 低
167 | * 仅使用无阴影的天空光照。
168 | * 降低天空光照强度(r.SkylightIntensityMultiplier=0.7),以近似模拟 中(Medium) 质量级别中的效果,因为此时没有天空光照阴影。
169 |
170 | 软光追
171 | * 超高(Epic)会启用 细节追踪(Detail Traces),追踪单个Mesh的DSF,性能受实例数量和重叠实例数量影响。
172 | * 考虑禁用部分StaticMeshComponent的Affects Distance Field Lighting。
173 | * 高(High)禁用DetailTraces,追踪合并后的全局距离场,不受实例数量及与其它实例重叠的影响。
174 | * r.Lumen.TraceMeshSDFs.Allow
175 |
176 | 硬件光追
177 |
178 | 对实例数量敏感,对场景进行细致优化。
179 | * 加速结构需要更复杂且更深的层级来代表这些重叠区域
180 | * 当实例高度重叠时,为更好地判定哪个实例与光线相交,会带来更多的条件分支和复杂计算,这会影响执行效率。
181 |
182 | 主机,剔除后,光追场景实例数量少于10w。stat SceneRendering
183 |
184 | Actor上禁用在光线追踪中可见(Visible In Ray Tracing)。
185 |
186 | 远场(Far Field) 激进剔除。
187 |
188 | ### Hint
189 | Lumen反射开销会因为屏幕中`低粗造度材质`数量不同而变化。默认情况下,
190 | * Roughness < 0.4 都会追踪反射光线,
191 | * Roughness > 0.4 会根据Lumen全局光照,获得免费的反射近似效果。(无粗糙镜面反射近似值)
192 |
193 | 项目设置和后处理中可调整,
194 | r.Lumen.Reflections.MaxRoughnessToTraceClamp 可在Scalability中调整。
195 |
196 | 双面植被(Two Sided Foliage) 或 次表面(Subsurface) 着色模型 都归为植被。
197 | > r.Lumen.Reflections.MaxRoughnessToTraceForFoliage=0.4
198 | 植被的反射通常都不明显,可以关掉。
199 |
200 | 
201 |
202 | ### 用屏幕空间反射取代Lumen反射
203 | r.Lumen.Reflections.Allow=0 屏幕空间反射 (SSR)取代Lumen反射
204 |
205 | Xbox Series S 节约1ms。
206 |
207 | 
208 |
209 | ### 表面缓存更新速度
210 | 直接光更新速度: r.LumenScene.DirectLighting.MaxLightsPerTile
211 | 间接光更新速度: r.LumenScene.Radiosity.UpdateFactor
212 |
213 | "Lumen场景光照(Lumen Scene Lighting)"在每个表面缓存图块上只选择一小部分最重要的光源,这使其性能不太容易受到场景中光源总数的影响。每个图块的光源数量可由 r.LumenScene.DirectLighting.MaxLightsPerTile 控制。
214 |
215 | 三个
216 |
217 | Lumen场景光照的性能取决于每帧更新的表面缓存的比例,此外还取决于半透明全局光照体积的分辨率。
218 | - Lumen Scene Lighting 0.8 对表面缓存光照求值
219 | - r.LumenScene.DirectLighting.UpdateFactor
220 | - r.LumenScene.Radiosity.UpdateFactor
221 |
222 | 全局光照性能取决于内部渲染分辨率和屏幕探头追踪分辨率。
223 | - Lumen Screen Probe Gather 2.88 用于对漫反射全局光照和粗糙反射以及半透明全局光照求值。
224 | - r.Lumen.ScreenProbeGather.RadianceCache.ProbeResolution 16 32 32
225 | - r.Lumen.ScreenProbeGather.RadianceCache.NumProbesToTraceBudget 300 300 1000
226 | - r.Lumen.ScreenProbeGather.DownsampleFactor 32 16 8
227 |
228 | Lumen反射(Lumen Reflections) 性能取决于专用反射光线的数量。只有粗糙度值低于阈值的像素才会被追踪。影响性能的另一个重要因素是内部渲染分辨率和反射分辨率。
229 | - Lumen Reflections 1.77 用于对光滑表面上的专用反射光线求值。
230 | - r.Lumen.Reflections.MaxRoughnessToTrace
231 | - r.Lumen.Reflections.MaxRoughnessToTraceClamp
232 | - r.Lumen.Reflections.MaxRoughnessToTraceForFoliage
233 | # Virtual Shadow Map
234 | Elevator Pitch
235 |
236 | - High res geo? High res shadows!
237 | - Don't render all the shadows
238 | - Virtualize shadow pages
239 | - Cache results
240 | - At ideal resolution
241 |
242 | Considerations
243 | - Shadow depths
244 | - - Cache Invalidations
245 | - - Geometry
246 | - Shadow Projection
247 | - - Ray Count
248 | - - Penumbra Size
249 |
250 | Cache Invalidations
251 | - Moving Camera
252 | - Moving Lights
253 | - Moving Objects
254 |
255 | StaticMeshComponent -> Shadow Cache invalidation Behavior
256 | * 控制要不要在发生顶点偏移时InvalidShadow
257 | * 可以在Runtime下更新
258 |
259 | NaniteMesh被分为Cluster,可以以Cluster为单位绘制需要的区域。但是,非Nanite就只能整个对象都要绘制一遍。
260 |
261 |
262 | r.Shadow.Virtual.OnePassProjection 1 多个光源也只有一次ShadowProjection
263 | r.Shadow.Virutal.Visualize.LightName
264 |
265 | r.Shadow.Virutal.Visualize.Layout 2
266 | r.Shadow.Virutal.Visualize.Advanced 1
267 |
268 |
269 | Action Items
270 | - Shadow Depths
271 | - - Cache Invalidations
272 | - Shadow Project
273 | - - Soft Shadows, Overlaps
274 |
275 | stat scenerendering
276 | # World Partition
277 |
278 | Other:
279 |
280 | * Listenserver,Steam P2P,连续SeamlessTravel后,Client断开连接。在连续SeamlessTravel后,因为Client释放了一些GUID,但Server没有释放它,导致随后Server认为这个GUID仍然是有效的,但在Client上已经找不到,导致CLient因为解析不了这个GUID而强制断开连接。
281 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Jekyll!
2 | #
3 | # This config file is meant for settings that affect your whole blog, values
4 | # which you are expected to set up once and rarely edit after that. If you find
5 | # yourself editing this file very often, consider using Jekyll's data files
6 | # feature for the data you need to update frequently.
7 | #
8 | # For technical reasons, this file is *NOT* reloaded automatically when you use
9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10 | #
11 | # If you need help with YAML syntax, here are some quick references for you:
12 | # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
13 | # https://learnxinyminutes.com/docs/yaml/
14 | #
15 | # Site settings
16 | # These are used to personalize your new site. If you look in the HTML files,
17 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
18 | # You can create any custom variable you would like, and they will be accessible
19 | # in the templates via {{ site.myvariable }}.
20 |
21 | title: Note
22 | email: liuyuanyu12138@gmail.com
23 | description: >- # this means to ignore newlines until "baseurl:"
24 | Write an awesome description for your new site here. You can edit this
25 | line in _config.yml. It will appear in your document head meta (for
26 | Google search results) and in your feed.xml site description.
27 | domain: floating-light.github.io
28 | baseurl: "/Note/" # the subpath of your site, e.g. /blog
29 | url: "https://floating-light.github.io" # the base hostname & protocol for your site, e.g. http://example.com
30 | twitter_username: jekyllrb
31 | github_username: jekyll
32 |
33 | # Build settings
34 | theme: minima
35 | plugins:
36 | - jekyll-feed
37 |
38 | # Exclude from processing.
39 | # The following items will not be processed, by default.
40 | # Any item listed under the `exclude:` key here will be automatically added to
41 | # the internal "default list".
42 | #
43 | # Excluded items can be processed by explicitly listing the directories or
44 | # their entries' file path in the `include:` list.
45 | #
46 | # exclude:
47 | # - .sass-cache/
48 | # - .jekyll-cache/
49 | # - gemfiles/
50 | # - Gemfile
51 | # - Gemfile.lock
52 | # - node_modules/
53 | # - vendor/bundle/
54 | # - vendor/cache/
55 | # - vendor/gems/
56 | # - vendor/ruby/
57 |
--------------------------------------------------------------------------------
/_posts/2024-09-07-welcome-to-jekyll.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "Welcome to Jekyll!"
4 | date: 2024-09-07 06:23:13 +0800
5 | categories: jekyll update
6 | ---
7 | You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
8 |
9 | Jekyll requires blog post files to be named according to the following format:
10 |
11 | `YEAR-MONTH-DAY-title.MARKUP`
12 |
13 | Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
14 |
15 | Jekyll also offers powerful support for code snippets:
16 |
17 | {% highlight ruby %}
18 | def print_hi(name)
19 | puts "Hi, #{name}"
20 | end
21 | print_hi('Tom')
22 | #=> prints 'Hi, Tom' to STDOUT.
23 | {% endhighlight %}
24 |
25 | Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
26 |
27 | [jekyll-docs]: https://jekyllrb.com/docs/home
28 | [jekyll-gh]: https://github.com/jekyll/jekyll
29 | [jekyll-talk]: https://talk.jekyllrb.com/
30 |
--------------------------------------------------------------------------------
/about.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: About
4 | permalink: /about/
5 | ---
6 |
7 | This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/)
8 |
9 | You can find the source code for Minima at GitHub:
10 | [jekyll][jekyll-organization] /
11 | [minima](https://github.com/jekyll/minima)
12 |
13 | You can find the source code for Jekyll at GitHub:
14 | [jekyll][jekyll-organization] /
15 | [jekyll](https://github.com/jekyll/jekyll)
16 |
17 |
18 | [jekyll-organization]: https://github.com/jekyll
19 |
--------------------------------------------------------------------------------
/assets/DX12/PSOHash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/PSOHash.png
--------------------------------------------------------------------------------
/assets/DX12/me_common_cbv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/me_common_cbv.png
--------------------------------------------------------------------------------
/assets/DX12/me_initModelInstance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/me_initModelInstance.png
--------------------------------------------------------------------------------
/assets/DX12/me_root_parameter_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/me_root_parameter_setting.png
--------------------------------------------------------------------------------
/assets/DX12/me_skin_matrices.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/me_skin_matrices.png
--------------------------------------------------------------------------------
/assets/DX12/render_loop_fence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/DX12/render_loop_fence.png
--------------------------------------------------------------------------------
/assets/MiniEngine.Model/SamplerParm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/MiniEngine.Model/SamplerParm.png
--------------------------------------------------------------------------------
/assets/MiniEngine/DescriptorHandleInc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/MiniEngine/DescriptorHandleInc.png
--------------------------------------------------------------------------------
/assets/MiniEngine/DescriptorOffset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/MiniEngine/DescriptorOffset.png
--------------------------------------------------------------------------------
/assets/MiniEngine/MaterialTextureDescriptor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/MiniEngine/MaterialTextureDescriptor.png
--------------------------------------------------------------------------------
/assets/MiniEngine/SamplerDescriptor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/MiniEngine/SamplerDescriptor.png
--------------------------------------------------------------------------------
/assets/UE/CS_HoudiniGraph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/CS_HoudiniGraph.png
--------------------------------------------------------------------------------
/assets/UE/CellCoordsCaculate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/CellCoordsCaculate.png
--------------------------------------------------------------------------------
/assets/UE/City_Stats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/City_Stats.png
--------------------------------------------------------------------------------
/assets/UE/CreateRuntimeCell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/CreateRuntimeCell.png
--------------------------------------------------------------------------------
/assets/UE/FourUDIMTex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/FourUDIMTex.png
--------------------------------------------------------------------------------
/assets/UE/GS_PrimitiveIdVertexBufferPool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/GS_PrimitiveIdVertexBufferPool.png
--------------------------------------------------------------------------------
/assets/UE/GridSize_LevelNum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/GridSize_LevelNum.png
--------------------------------------------------------------------------------
/assets/UE/HISM_InnerNodeMergejpg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HISM_InnerNodeMergejpg.jpg
--------------------------------------------------------------------------------
/assets/UE/HISM_InstanceData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HISM_InstanceData.png
--------------------------------------------------------------------------------
/assets/UE/HISM_InstanceReorderTable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HISM_InstanceReorderTable.png
--------------------------------------------------------------------------------
/assets/UE/HISM_LeafNodeSplit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HISM_LeafNodeSplit.jpg
--------------------------------------------------------------------------------
/assets/UE/HISM_StateUpdate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HISM_StateUpdate.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_ApproxActorsResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_ApproxActorsResult.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_ApproxResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_ApproxResult.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_BatchPolicy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_BatchPolicy.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_BuilderBuild.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_BuilderBuild.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_CustomHLODBuilderClass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_CustomHLODBuilderClass.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_DetermineLOD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_DetermineLOD.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_ForceLod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_ForceLod.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_Interface_ApproxActors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_Interface_ApproxActors.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_MergeMesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_MergeMesh.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_SimplifiedMesh_Material.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_SimplifiedMesh_Material.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_TestSimplifiedMesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_TestSimplifiedMesh.png
--------------------------------------------------------------------------------
/assets/UE/HLOD_VirtualBuild.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/HLOD_VirtualBuild.png
--------------------------------------------------------------------------------
/assets/UE/IntersectingCellNum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/IntersectingCellNum.png
--------------------------------------------------------------------------------
/assets/UE/LS_MatID.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/LS_MatID.png
--------------------------------------------------------------------------------
/assets/UE/LU_PerformanceOverview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/LU_PerformanceOverview.png
--------------------------------------------------------------------------------
/assets/UE/NonAlignedGridLevels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/NonAlignedGridLevels.png
--------------------------------------------------------------------------------
/assets/UE/OpenWorld_Stat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/OpenWorld_Stat.png
--------------------------------------------------------------------------------
/assets/UE/RM_DeletePrimitive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_DeletePrimitive.png
--------------------------------------------------------------------------------
/assets/UE/RM_InterfaceCreateProxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_InterfaceCreateProxy.png
--------------------------------------------------------------------------------
/assets/UE/RM_StaticPass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_StaticPass.png
--------------------------------------------------------------------------------
/assets/UE/RM_addprimitivecommand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_addprimitivecommand.png
--------------------------------------------------------------------------------
/assets/UE/RM_create_sceneproxy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_create_sceneproxy.png
--------------------------------------------------------------------------------
/assets/UE/RM_scene_addPrimitive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/RM_scene_addPrimitive.png
--------------------------------------------------------------------------------
/assets/UE/SM_expand_interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SM_expand_interface.png
--------------------------------------------------------------------------------
/assets/UE/SS_Actor_GetWorld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_Actor_GetWorld.png
--------------------------------------------------------------------------------
/assets/UE/SS_BuildPlayerSource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_BuildPlayerSource.png
--------------------------------------------------------------------------------
/assets/UE/SS_CellActivate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_CellActivate.png
--------------------------------------------------------------------------------
/assets/UE/SS_CellShowOrHidden.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_CellShowOrHidden.jpg
--------------------------------------------------------------------------------
/assets/UE/SS_CellSortCompare.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_CellSortCompare.png
--------------------------------------------------------------------------------
/assets/UE/SS_GetOuterWorldPartition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_GetOuterWorldPartition.png
--------------------------------------------------------------------------------
/assets/UE/SS_GetPerformanceCell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_GetPerformanceCell.png
--------------------------------------------------------------------------------
/assets/UE/SS_GetWorldPartition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_GetWorldPartition.png
--------------------------------------------------------------------------------
/assets/UE/SS_HLODActorGrid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_HLODActorGrid.jpg
--------------------------------------------------------------------------------
/assets/UE/SS_HLODActorRegister.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_HLODActorRegister.png
--------------------------------------------------------------------------------
/assets/UE/SS_HLODActorRegistered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_HLODActorRegistered.png
--------------------------------------------------------------------------------
/assets/UE/SS_HLODBuilderRequiresWarmup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_HLODBuilderRequiresWarmup.png
--------------------------------------------------------------------------------
/assets/UE/SS_OnCellHidden.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_OnCellHidden.png
--------------------------------------------------------------------------------
/assets/UE/SS_PartitionHLODData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_PartitionHLODData.png
--------------------------------------------------------------------------------
/assets/UE/SS_PlayMainWorld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_PlayMainWorld.png
--------------------------------------------------------------------------------
/assets/UE/SS_PlayerGetSource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_PlayerGetSource.png
--------------------------------------------------------------------------------
/assets/UE/SS_ProccessBlockLoading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_ProccessBlockLoading.png
--------------------------------------------------------------------------------
/assets/UE/SS_RealActorGetWorld.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_RealActorGetWorld.png
--------------------------------------------------------------------------------
/assets/UE/SS_ServerWaitClientVisi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_ServerWaitClientVisi.png
--------------------------------------------------------------------------------
/assets/UE/SS_SkipOnSlowLoading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_SkipOnSlowLoading.png
--------------------------------------------------------------------------------
/assets/UE/SS_SphereAABBIntersection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_SphereAABBIntersection.png
--------------------------------------------------------------------------------
/assets/UE/SS_StreamingCellDataLayer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_StreamingCellDataLayer.png
--------------------------------------------------------------------------------
/assets/UE/SS_ToUnloadCell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_ToUnloadCell.png
--------------------------------------------------------------------------------
/assets/UE/SS_WorldPartitionInit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/SS_WorldPartitionInit.png
--------------------------------------------------------------------------------
/assets/UE/StreamingData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/StreamingData.png
--------------------------------------------------------------------------------
/assets/UE/UDIM_Texture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/UDIM_Texture.png
--------------------------------------------------------------------------------
/assets/UE/VF_ActuallParamBind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ActuallParamBind.png
--------------------------------------------------------------------------------
/assets/UE/VF_AnimationCollectionCfg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_AnimationCollectionCfg.png
--------------------------------------------------------------------------------
/assets/UE/VF_BeginInitResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_BeginInitResource.png
--------------------------------------------------------------------------------
/assets/UE/VF_BindPosition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_BindPosition.png
--------------------------------------------------------------------------------
/assets/UE/VF_BindUniformBuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_BindUniformBuffer.png
--------------------------------------------------------------------------------
/assets/UE/VF_BindUniformBufferData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_BindUniformBufferData.png
--------------------------------------------------------------------------------
/assets/UE/VF_CalcBoneMatrixNew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_CalcBoneMatrixNew.png
--------------------------------------------------------------------------------
/assets/UE/VF_ComplieResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ComplieResult.png
--------------------------------------------------------------------------------
/assets/UE/VF_CreateConstantbuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_CreateConstantbuffer.png
--------------------------------------------------------------------------------
/assets/UE/VF_DecalreUniformBuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_DecalreUniformBuffer.png
--------------------------------------------------------------------------------
/assets/UE/VF_DeclareVFType.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_DeclareVFType.png
--------------------------------------------------------------------------------
/assets/UE/VF_DiffVSLightMapHQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_DiffVSLightMapHQ.png
--------------------------------------------------------------------------------
/assets/UE/VF_FillVertexPerLod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_FillVertexPerLod.png
--------------------------------------------------------------------------------
/assets/UE/VF_GPUSkinVFPermutations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GPUSkinVFPermutations.png
--------------------------------------------------------------------------------
/assets/UE/VF_GameThreadUpdateData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GameThreadUpdateData.png
--------------------------------------------------------------------------------
/assets/UE/VF_GetBoneMatrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GetBoneMatrix.png
--------------------------------------------------------------------------------
/assets/UE/VF_GetEleBindings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GetEleBindings.png
--------------------------------------------------------------------------------
/assets/UE/VF_GetInstanceDataFull.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GetInstanceDataFull.png
--------------------------------------------------------------------------------
/assets/UE/VF_GetVFIntermediates.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GetVFIntermediates.png
--------------------------------------------------------------------------------
/assets/UE/VF_GlobalParamUsf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_GlobalParamUsf.png
--------------------------------------------------------------------------------
/assets/UE/VF_HLSLFactoryInput.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_HLSLFactoryInput.png
--------------------------------------------------------------------------------
/assets/UE/VF_ImplShaderParam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ImplShaderParam.png
--------------------------------------------------------------------------------
/assets/UE/VF_ImplUniformForVF.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ImplUniformForVF.png
--------------------------------------------------------------------------------
/assets/UE/VF_ImplementVFType.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ImplementVFType.png
--------------------------------------------------------------------------------
/assets/UE/VF_IncludeGlobalShaderParameter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_IncludeGlobalShaderParameter.png
--------------------------------------------------------------------------------
/assets/UE/VF_IndexBuffer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_IndexBuffer.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_InitMeshResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_InitMeshResource.png
--------------------------------------------------------------------------------
/assets/UE/VF_InputElement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_InputElement.png
--------------------------------------------------------------------------------
/assets/UE/VF_InterpolantVSToPSResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_InterpolantVSToPSResult.png
--------------------------------------------------------------------------------
/assets/UE/VF_LightMapIndex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_LightMapIndex.png
--------------------------------------------------------------------------------
/assets/UE/VF_LocalVFParam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_LocalVFParam.png
--------------------------------------------------------------------------------
/assets/UE/VF_LocalVertexFactoryG.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_LocalVertexFactoryG.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_MaxBoneInfluence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_MaxBoneInfluence.png
--------------------------------------------------------------------------------
/assets/UE/VF_MeshVertexBuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_MeshVertexBuffer.png
--------------------------------------------------------------------------------
/assets/UE/VF_MeshvertexBuffer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_MeshvertexBuffer.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_ParameterBindInfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ParameterBindInfo.png
--------------------------------------------------------------------------------
/assets/UE/VF_PostLoadInitResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_PostLoadInitResource.png
--------------------------------------------------------------------------------
/assets/UE/VF_RefenecePositionData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_RefenecePositionData.png
--------------------------------------------------------------------------------
/assets/UE/VF_ResultVS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ResultVS.png
--------------------------------------------------------------------------------
/assets/UE/VF_SerializeRenderData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SerializeRenderData.png
--------------------------------------------------------------------------------
/assets/UE/VF_SerializeSourceModel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SerializeSourceModel.png
--------------------------------------------------------------------------------
/assets/UE/VF_ShaderParamMemebrDecl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_ShaderParamMemebrDecl.png
--------------------------------------------------------------------------------
/assets/UE/VF_SkelotBuffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkelotBuffer.png
--------------------------------------------------------------------------------
/assets/UE/VF_SkelotCalcBoneMatrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkelotCalcBoneMatrix.png
--------------------------------------------------------------------------------
/assets/UE/VF_SkelotUpdateDataThread.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkelotUpdateDataThread.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_SkelotVertexFactoryResource.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkelotVertexFactoryResource.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_SkelotVertexParameter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkelotVertexParameter.png
--------------------------------------------------------------------------------
/assets/UE/VF_SkinWeight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkinWeight.png
--------------------------------------------------------------------------------
/assets/UE/VF_SkinWorldPosition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_SkinWorldPosition.png
--------------------------------------------------------------------------------
/assets/UE/VF_StaticMeshVertexBuffers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_StaticMeshVertexBuffers.png
--------------------------------------------------------------------------------
/assets/UE/VF_VFDefineMa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFDefineMa.png
--------------------------------------------------------------------------------
/assets/UE/VF_VFInitRenderThread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFInitRenderThread.png
--------------------------------------------------------------------------------
/assets/UE/VF_VFInitResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFInitResource.png
--------------------------------------------------------------------------------
/assets/UE/VF_VFMemberProperty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFMemberProperty.png
--------------------------------------------------------------------------------
/assets/UE/VF_VFMeshData.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFMeshData.jpg
--------------------------------------------------------------------------------
/assets/UE/VF_VFShaderParam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VFShaderParam.png
--------------------------------------------------------------------------------
/assets/UE/VF_VertexBondIndicesWeight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/VF_VertexBondIndicesWeight.png
--------------------------------------------------------------------------------
/assets/UE/WP_SetContainerInstanceCollection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/WP_SetContainerInstanceCollection.png
--------------------------------------------------------------------------------
/assets/UE/evn_tex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/UE/evn_tex.png
--------------------------------------------------------------------------------
/assets/images/2023-04-23-17-36-21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/2023-04-23-17-36-21.png
--------------------------------------------------------------------------------
/assets/images/2023-04-23-17-45-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/2023-04-23-17-45-19.png
--------------------------------------------------------------------------------
/assets/images/2023-04-23-17-47-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/2023-04-23-17-47-32.png
--------------------------------------------------------------------------------
/assets/images/2023-04-23-17-50-22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/2023-04-23-17-50-22.png
--------------------------------------------------------------------------------
/assets/images/ActorDescContainer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/ActorDescContainer.jpg
--------------------------------------------------------------------------------
/assets/images/AddCBV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/AddCBV.png
--------------------------------------------------------------------------------
/assets/images/AlphaBrush.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/AlphaBrush.png
--------------------------------------------------------------------------------
/assets/images/Anim_AddExtention.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_AddExtention.png
--------------------------------------------------------------------------------
/assets/images/Anim_AnimSubsystem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_AnimSubsystem.png
--------------------------------------------------------------------------------
/assets/images/Anim_BuildProperties.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_BuildProperties.png
--------------------------------------------------------------------------------
/assets/images/Anim_Crouch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_Crouch.png
--------------------------------------------------------------------------------
/assets/images/Anim_ForEachSubsystem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_ForEachSubsystem.png
--------------------------------------------------------------------------------
/assets/images/Anim_MultThread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_MultThread.png
--------------------------------------------------------------------------------
/assets/images/Anim_RecreateSparseClassData.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_RecreateSparseClassData.png
--------------------------------------------------------------------------------
/assets/images/Anim_SparseClass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Anim_SparseClass.png
--------------------------------------------------------------------------------
/assets/images/Animation_ParallelTask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Animation_ParallelTask.png
--------------------------------------------------------------------------------
/assets/images/Animation_PropertyAccess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Animation_PropertyAccess.png
--------------------------------------------------------------------------------
/assets/images/Animation_PropertyAccessSubsystem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Animation_PropertyAccessSubsystem.png
--------------------------------------------------------------------------------
/assets/images/AxisAnalysis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/AxisAnalysis.png
--------------------------------------------------------------------------------
/assets/images/BindDescriptorHeap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/BindDescriptorHeap.png
--------------------------------------------------------------------------------
/assets/images/BindingDescriptorTable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/BindingDescriptorTable.png
--------------------------------------------------------------------------------
/assets/images/Buffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Buffer.png
--------------------------------------------------------------------------------
/assets/images/BundleToAFrame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/BundleToAFrame.png
--------------------------------------------------------------------------------
/assets/images/CONSTANTS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/CONSTANTS.png
--------------------------------------------------------------------------------
/assets/images/Crask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Crask.png
--------------------------------------------------------------------------------
/assets/images/CreateTextureResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/CreateTextureResource.png
--------------------------------------------------------------------------------
/assets/images/Descriptor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Descriptor.png
--------------------------------------------------------------------------------
/assets/images/DescriptorTable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/DescriptorTable.png
--------------------------------------------------------------------------------
/assets/images/Direct3D12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Direct3D12.png
--------------------------------------------------------------------------------
/assets/images/DisplaySystem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/DisplaySystem.png
--------------------------------------------------------------------------------
/assets/images/EditInSequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/EditInSequence.png
--------------------------------------------------------------------------------
/assets/images/ExperienceSelection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/ExperienceSelection.png
--------------------------------------------------------------------------------
/assets/images/Family.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Family.png
--------------------------------------------------------------------------------
/assets/images/FullBodyCache.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/FullBodyCache.png
--------------------------------------------------------------------------------
/assets/images/InitializeCommonState.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/InitializeCommonState.png
--------------------------------------------------------------------------------
/assets/images/MVVM_Relation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/MVVM_Relation.png
--------------------------------------------------------------------------------
/assets/images/MapResource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/MapResource.png
--------------------------------------------------------------------------------
/assets/images/ModelVariations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/ModelVariations.png
--------------------------------------------------------------------------------
/assets/images/Montage_FullUpper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Montage_FullUpper.png
--------------------------------------------------------------------------------
/assets/images/Montage_Notify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/Montage_Notify.png
--------------------------------------------------------------------------------
/assets/images/OffsetLookup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/OffsetLookup.png
--------------------------------------------------------------------------------
/assets/images/OnConstantBind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/OnConstantBind.png
--------------------------------------------------------------------------------
/assets/images/ResourceDimension.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/ResourceDimension.png
--------------------------------------------------------------------------------
/assets/images/RootParameter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/RootParameter.png
--------------------------------------------------------------------------------
/assets/images/RootSignatureDesc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/RootSignatureDesc.png
--------------------------------------------------------------------------------
/assets/images/RootSignature_MoreComplex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/RootSignature_MoreComplex.png
--------------------------------------------------------------------------------
/assets/images/StartInsights.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/StartInsights.png
--------------------------------------------------------------------------------
/assets/images/StreamingShaderResourceViews.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/StreamingShaderResourceViews.png
--------------------------------------------------------------------------------
/assets/images/TextureManager.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/TextureManager.png
--------------------------------------------------------------------------------
/assets/images/TreeAnimLookup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/TreeAnimLookup.png
--------------------------------------------------------------------------------
/assets/images/UpdateAnimation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/UpdateAnimation.png
--------------------------------------------------------------------------------
/assets/images/UpperBodyCache.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/UpperBodyCache.png
--------------------------------------------------------------------------------
/assets/images/WP_ActorDescViewMap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WP_ActorDescViewMap.jpg
--------------------------------------------------------------------------------
/assets/images/WP_BeginGenerate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WP_BeginGenerate.jpg
--------------------------------------------------------------------------------
/assets/images/WP_GenPersistenDesc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WP_GenPersistenDesc.png
--------------------------------------------------------------------------------
/assets/images/WP_GenerateActorsContainer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WP_GenerateActorsContainer.jpg
--------------------------------------------------------------------------------
/assets/images/WP_RuntimePartition.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WP_RuntimePartition.jpg
--------------------------------------------------------------------------------
/assets/images/WorldPartition_CellName.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WorldPartition_CellName.png
--------------------------------------------------------------------------------
/assets/images/WorldPartition_LHGridLevel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/WorldPartition_LHGridLevel.png
--------------------------------------------------------------------------------
/assets/images/controlrig_ik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/assets/images/controlrig_ik.png
--------------------------------------------------------------------------------
/graphicNotes/Lyra_GameSetting.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/graphicNotes/Lyra_GameSetting.pptx
--------------------------------------------------------------------------------
/graphicNotes/Lyra_Item.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/graphicNotes/Lyra_Item.pptx
--------------------------------------------------------------------------------
/index.markdown:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | layout: home
6 | ---
7 |
--------------------------------------------------------------------------------
/other/7zip_.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: gsteud5545xzjdk7hcb00em
3 | title: Other
4 | desc: ''
5 | updated: 1713850780725
6 | created: 1713850768993
7 | ---
8 |
9 | ## 7zip 解压乱码
10 | 如果开启了: Time&language > Language®ion > Administrative language settings > Change system locale > √Beta:Use Unicode UTF-8 for worldwide language support
11 |
12 | 解压非UTF-8操作系统压缩出来的压缩文件时就会乱码。
13 |
14 | 或者本身解压和压缩的两个操作系统的编码就是不一样的。不一样的语言。
15 |
16 | 可以用chcp在压缩的机器上看它是什么编码的,然后用命令行解压:
17 | ```
18 | 7z x -mcp=936 -o"./" -- 94F9C1014AEFFAB42F9D949220CF10E8.zip
19 | ```
20 | 936是 Supports Simplified Chinese GBK
21 |
22 | ## 压缩时指定编码
23 | 指定utf-8
24 |
25 | 
26 |
27 | reference:
28 | * https://blog.miniasp.com/post/2020/09/14/7-Zip-with-Chinese-filenames-should-use-UTF-8
29 |
30 | * https://superuser.com/questions/1668449/is-it-possible-to-extract-foreign-zip-files-with-7zip-without-adding-a-region-to
31 | * https://en.wikipedia.org/wiki/Code_page
--------------------------------------------------------------------------------
/other/Other/specifyCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Floating-light/Note/780926555a75decbe13b75392bd4c4af14b469d9/other/Other/specifyCode.png
--------------------------------------------------------------------------------
/other/automic.md:
--------------------------------------------------------------------------------
1 | std::memory_order_release
2 | * 保证当前原子操作之前的所有写入操作都在本次原子操作之前完成。
3 | * 即之前的写入操作不会被重排到后面
4 |
5 | std::memory_order_acquire
6 | * 保证当前原子操作之后的读取操作不会被重排到本次操作之前
7 | * 保证在获取锁(原子操作)之后,可以看到(std::memory_order_release)发布方所作的所有内存写入结果。
8 |
9 | std::memory_order_relaxed - EMemoryOrder::Relaxed
10 | * 仅保证单个原子操作的原子性,不保证前后操作的执行顺序
11 | * 没有顺序约束,更高效
12 |
13 | std::memory_order_seq_cst - EMemoryOrder::SequentiallyConsistent
14 | * 不仅保证原子操作的原子性,还保证所有操作按照程序代码的顺序执行,无论哪个线程。
15 | * 确保不同线程上的SC操作能观察到一致的执行顺序,使程序的行为更可预测。
--------------------------------------------------------------------------------
/other/git.md:
--------------------------------------------------------------------------------
1 | ## 各种仓库损坏修复
2 | https://git.seveas.net/repairing-and-recovering-broken-git-repositories.html
3 |
4 | ## 查看提交记录
5 | 1. 查看特定文件的提交记录
6 | git log --
7 | 例如,如果你想查看文件 example.txt 的提交记录:
8 | git log -- example.txt
9 | 1. 查看特定文件夹的提交记录
10 | git log -- /
11 | 例如,如果你想查看文件夹 src 下任何文件的提交记录:
12 | git log -- src/
13 | 1. 更详细的输出格式
14 | 如果你想要更详细的信息,比如每个提交的差异,你可以使用 -p 选项:
15 | git log -p --
16 | 例如查看 example.txt 中每个提交的差异:
17 | git log -p -- example.txt
18 | 1. 简洁的输出格式
19 | 如果你希望输出更加简洁,可以使用 --oneline 选项:
20 | git log --oneline --
21 | 例如简要查看 src 文件夹的提交记录:
22 | git log --oneline -- src/
23 | 1. 显示附加信息
24 | 例如显示每个提交的作者、日期等附加信息,你可以使用以下选项组合:
25 | git log --pretty=format:"%h - %an, %ar : %s" --
26 | 该命令的输出格式包括:
27 | %h: 提交哈希值的缩写
28 | %an: 作者名称
29 | %ar: 相对的提交时间
30 | %s: 提交消息
31 | 例如查看 docs/ 文件夹的提交记录:
32 | git log --pretty=format:"%h - %an, %ar : %s" -- docs/
33 | 1. 输出包含特定关键字的提交信息
34 | 你可以使用 -G 选项来筛选包含特定关键字的提交信息。例如,查找包含 "fix bug" 的提交:
35 | git log -G"fix bug" --
36 | 例如查看文件 example.txt 中包含 "fix bug" 的提交:
37 | git log -G"fix bug" -- example.txt
38 | 通过这些命令,你可以根据需求查看指定文件或文件夹的提交历史。根据需要,你可以调整以上命令中的选项来获取更加适合的信息格式。
39 |
40 | ## fork point, rebase
41 | 本质是对比两个分支的历史提交线,对所有的commitid按顺序做相减,把另一分支不存在的,都cherry-pick过去,再移动HEAD到最新Commitid。
42 |
43 | - git merge-base --fork-point origin/TestBranch TestBranch
44 | - 查看公共起点,可以试试不加--fork-point
45 |
46 | 远端如果强推掉了一些历史提交记录,本地pull下来时,如果加了--fork-point,会参考本地reflog,如果一些commitid之前存在,但是现在不在了,git也会跳过它们的pick。
47 |
48 | git pull --rebase 默认加了这个--fork-point
49 |
50 | 如果是手动rebase,如果不想把别人推掉的提交pick回来,需要自己加上--fork-point
51 |
52 | git rebase --fork-point
53 |
54 | git rebase --onto
55 |
56 | https://stackoverflow.com/questions/42536989/git-pull-rebase-lost-commits-after-coworkers-git-push-force
57 |
58 | https://stackoverflow.com/questions/42486141/git-rebase-commit-select-in-fork-point-mode
59 |
60 | # git Submodule
61 | git submodule add https://github.com/example/mysubmodule.git libs/mysubmodule
62 | git submodule init
63 | git submodule update
64 | git submodule update --init
65 | git submodule update --init --recursive
66 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: 8ae865spua67os02ak9wirc
3 | title: CG
4 | desc: 'Computational Geometry'
5 | updated: 1714615718087
6 | created: 1714614686413
7 | ---
8 | * vscode-markdown-paste-image,Markdown 粘贴图片,积极维护的[fork](https://github.com/telesoho/vscode-markdown-paste-image)
9 |
10 |
11 | ## markdown reference
12 | - https://code.visualstudio.com/Docs/languages/markdown
13 |
14 | Suggest:
15 | - https://code.visualstudio.com/docs/editor/profiles#_doc-writer-profile-template
16 |
17 | 必装插件:
18 | - https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image
19 | - https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
20 | - https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles
21 | - https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview
22 | -
23 | ## example
24 |
25 | :smirk:
26 |
27 | - [x] tasklists
28 |
29 | 强调
30 |
31 | *This text will be italic*
32 |
33 | _This text will be italic_
34 |
35 | **This text will be bold**
36 |
37 | __This text will be bold__
38 |
39 | * 图片设置大小,居中
40 |
41 |
42 |
43 | * github要这个才能正常居中:
44 |
45 |
46 |
47 |
48 | ## D3D12
49 |
50 | * https://developer.nvidia.com/dx12-dos-and-donts
51 |
52 | ## Game Rendering Engine Design
53 |
54 | - [RenderEngineForGames](https://enginearchitecture.realtimerendering.com/2021_course/)
55 | - [All Resource you need](https://github.com/Gforcex/OpenGraphic)
56 |
--------------------------------------------------------------------------------
/script/move_file.ps1:
--------------------------------------------------------------------------------
1 | # 定义源文件夹路径
2 | $sourceFolderPath = "E:\Workspace\Note\"
3 |
4 | # 获取所有以 .md 结尾的文件
5 | $files = Get-ChildItem -Path $sourceFolderPath -Filter "*.md"
6 |
7 | foreach ($file in $files) {
8 | # 获取文件名(不含扩展名)
9 | $fileNameWithoutExtension = [System.IO.Path]::GetFileNameWithoutExtension($file.Name)
10 |
11 | # 以 "." 分割文件名
12 | $fileNameParts = $fileNameWithoutExtension.Split(".")
13 |
14 | # 取第一个部分作为文件夹名
15 | $folderName = $fileNameParts[0]
16 |
17 | # 如果文件名分割后有两个或更多部分,则去掉第一个部分组织新的文件名
18 | if ($fileNameParts.Length -ge 2) {
19 | $newFileName = ($fileNameParts[1..($fileNameParts.Length - 1)] -join ".") + ".md"
20 | } else {
21 | $newFileName = $file.Name
22 | }
23 |
24 | # 创建目标文件夹路径
25 | $destinationFolderPath = Join-Path -Path $sourceFolderPath -ChildPath $folderName
26 |
27 | # 如果目标文件夹不存在,则创建它
28 | if (-not (Test-Path -Path $destinationFolderPath)) {
29 | New-Item -Path $destinationFolderPath -ItemType Directory | Out-Null
30 | }
31 |
32 | # 构建目标文件路径
33 | $destinationFilePath = Join-Path -Path $destinationFolderPath -ChildPath $newFileName
34 |
35 | # 移动文件并重命名
36 | Move-Item -Path $file.FullName -Destination $destinationFilePath
37 | }
38 |
39 | Write-Output "文件移动完成。"
--------------------------------------------------------------------------------