├── .gitignore ├── Config ├── DefaultEditor.ini ├── DefaultEngine.ini └── DefaultGame.ini ├── Content ├── Demo │ └── DemoRoom │ │ ├── BluePrint │ │ ├── BPInterface_Button.uasset │ │ ├── BP_Audio_Trigger.uasset │ │ ├── BP_DemoDisplay.uasset │ │ ├── BP_DemoDisplay_Enum.uasset │ │ ├── BP_DemoRoom.uasset │ │ ├── BP_DemoRoom_Enum.uasset │ │ ├── BP_DemoTrigger.uasset │ │ ├── BP_LightScultpureDynamic.uasset │ │ ├── DemoRoomStruct.uasset │ │ └── RoomDescription.uasset │ │ ├── Materials │ │ ├── DefaultTextMaterialTranslucentUnlit.uasset │ │ ├── M_Button.uasset │ │ ├── M_Button_Chrome.uasset │ │ ├── M_Button_Inst.uasset │ │ ├── M_DemoAnimated.uasset │ │ ├── M_DemoAnimated_Inst.uasset │ │ ├── M_DemoAnimated_Vertex.uasset │ │ ├── M_DemoLightFunktion.uasset │ │ ├── M_DemoLightFunktion_Inst.uasset │ │ ├── M_DemoMinRoughnesS_Inst.uasset │ │ ├── M_DemoRoomTiles.uasset │ │ ├── M_DemoRoomTiles_Inst.uasset │ │ ├── M_DemoRoomTiles_Inst_Color1.uasset │ │ ├── M_DemoRoomTiles_Inst_Color2.uasset │ │ ├── M_DemoRoomTiles_Inst_Color3.uasset │ │ ├── M_DemoRoomTiles_Inst_Color5_Inst.uasset │ │ ├── M_DemoWall.uasset │ │ ├── M_DemoWallPattern.uasset │ │ ├── M_DemoWallPattern_Inst.uasset │ │ ├── M_DemoWallPattern_Inst_Mirrored.uasset │ │ ├── M_DemoWallPattern_NoText.uasset │ │ ├── M_DemoWall_Inst.uasset │ │ ├── M_DemoWall_Inst2.uasset │ │ ├── M_DemoWall_Inst_3.uasset │ │ ├── M_DemoWall_Inst_BaseFloor_Inst.uasset │ │ ├── M_DemoWall_Inst_NamePlate.uasset │ │ ├── M_DemoWall_MattPlastic.uasset │ │ ├── M_Emissive.uasset │ │ ├── M_Emissive_1.uasset │ │ ├── M_Emissive_2.uasset │ │ ├── M_GlasDoor.uasset │ │ ├── M_GlasDoor_Inst.uasset │ │ ├── M_Glass.uasset │ │ ├── M_Glass_Inst.uasset │ │ ├── M_Gradient.uasset │ │ ├── M_Gradient_Blue.uasset │ │ ├── M_Gradient_EmissiveOverbright.uasset │ │ ├── M_Gradient_Green.uasset │ │ ├── M_Gradient_Red.uasset │ │ ├── M_LightSculpture.uasset │ │ ├── M_LightSculpture_Blue.uasset │ │ ├── M_LightSculpture_Green.uasset │ │ ├── M_LightSculpture_Red.uasset │ │ ├── M_LightTube.uasset │ │ ├── M_LightTube_Inst.uasset │ │ ├── M_ReflectionDemo_1.uasset │ │ ├── M_ReflectionDemo_2.uasset │ │ ├── M_ReflectionDemo_3.uasset │ │ ├── M_ReflectionDemo_MAT.uasset │ │ ├── M_ReflectionDemo_Metallic_1.uasset │ │ ├── M_ReflectionDemo_Metallic_2.uasset │ │ ├── M_ReflectionDemo_Metallic_3.uasset │ │ ├── M_SceneCapture2d.uasset │ │ ├── M_SceneCaptureCube.uasset │ │ ├── M_TestSky.uasset │ │ ├── M_TestSky_Inst.uasset │ │ ├── M_UE4_Logo_2.uasset │ │ ├── M_UE4_Logo_Door.uasset │ │ └── M_UE4_Logo_Doors.uasset │ │ ├── Meshes │ │ ├── SM_Base.uasset │ │ ├── SM_Base2.uasset │ │ ├── SM_BaseRoom.uasset │ │ ├── SM_BaseTrimSquare.uasset │ │ ├── SM_Base_FlatWall.uasset │ │ ├── SM_Button.uasset │ │ ├── SM_DemoCube.uasset │ │ ├── SM_DemoDivider_1.uasset │ │ ├── SM_DemoDivider_2.uasset │ │ ├── SM_DemoPlate.uasset │ │ ├── SM_DemoRoomBackWall.uasset │ │ ├── SM_DemoRoomBackWall2.uasset │ │ ├── SM_DemoRoomBox.uasset │ │ ├── SM_DemoRoomClamp.uasset │ │ ├── SM_DemoRoomClamp2.uasset │ │ ├── SM_DemoRoomL.uasset │ │ ├── SM_DemoRoomLTrim.uasset │ │ ├── SM_DemoRoomTrim.uasset │ │ ├── SM_DemoRoomTrim2.uasset │ │ ├── SM_DemoRoomTrimAdd.uasset │ │ ├── SM_DemoRoomU.uasset │ │ ├── SM_DemoRoomU2.uasset │ │ ├── SM_DemoRoomU_Hole.uasset │ │ ├── SM_DemoSurface.uasset │ │ ├── SM_Door.uasset │ │ ├── SM_DoorLock.uasset │ │ ├── SM_GraphFrame.uasset │ │ ├── SM_LightSculpture.uasset │ │ ├── SM_NamePlate.uasset │ │ ├── SM_Slider1.uasset │ │ ├── SM_SliderBase.uasset │ │ ├── SM_UE4_Logo.uasset │ │ ├── SM_URoom_Wall.uasset │ │ └── SM_URoom_Wall2.uasset │ │ ├── SkeletalMeshes │ │ ├── PHYSMAT_SK_RigidBodyDemo.uasset │ │ ├── SK_RigidBodyDemo.uasset │ │ ├── SK_RigidBodyDemo_PhysicsAsset.uasset │ │ └── SK_RigidBodyDemo_Skeleton.uasset │ │ └── Textures │ │ ├── NewTextureRenderTarget2D.uasset │ │ ├── NewTextureRenderTargetCube.uasset │ │ ├── T_Pattern_M.uasset │ │ ├── T_RoomTiles_M.uasset │ │ ├── T_RoomTiles_N.uasset │ │ ├── T_UE4_Logo_M.uasset │ │ └── T_UnrealEngineDecal.uasset ├── Examples │ ├── ClearTexture │ │ ├── BP_ClearTextureActor.uasset │ │ ├── MAP_ClearTexture.umap │ │ ├── MAP_ClearTexture_BuiltData.uasset │ │ ├── M_UnlitTexture.uasset │ │ └── unreal_logo.uasset │ ├── NiagaraInput │ │ └── NS_PlayerInput.uasset │ ├── NiagaraSplines │ │ ├── Cylinder.uasset │ │ ├── EditorScript │ │ │ └── WBP_CalculateSplineParams.uasset │ │ ├── MAP_NiagaraSplines.umap │ │ ├── MAP_NiagaraSplines_BuiltData.uasset │ │ ├── M_NiagaraSplines.uasset │ │ ├── NS_NiagaraSplines.uasset │ │ └── T_DummyArray.uasset │ ├── PBD │ │ ├── EditorScripts │ │ │ └── EW_PBD.uasset │ │ ├── MAP_NiagaraPBD.umap │ │ ├── MAP_NiagaraPBD_BuiltData.uasset │ │ ├── M_RubberToy.uasset │ │ ├── NS_PBDBasic.uasset │ │ ├── SM_RubberToy.uasset │ │ ├── SoftBody │ │ │ └── Bunny │ │ │ │ ├── MAP_SoftBunny.umap │ │ │ │ ├── MAP_SoftBunny_BuiltData.uasset │ │ │ │ ├── MI_PBD_SoftBody_Bunny.uasset │ │ │ │ ├── M_PBD_SoftBody.uasset │ │ │ │ ├── NS_PBD_SoftBody.uasset │ │ │ │ ├── SM_BunnyBaked.uasset │ │ │ │ ├── T_Bunny_ParticleConstraintList.uasset │ │ │ │ ├── T_Bunny_ParticlePositions.uasset │ │ │ │ └── T_Bunny_ShapeMatchingConstraints.uasset │ │ ├── T_PBDShapes.uasset │ │ └── T_RubberToyParticles.uasset │ └── ProceduralMesh │ │ ├── BP_CubeMarchingActor.uasset │ │ ├── BP_HelloTriangleActor.uasset │ │ ├── MAP_ProceduralMesh.umap │ │ ├── MAP_ProceduralMesh_BuiltData.uasset │ │ ├── M_Normals.uasset │ │ ├── M_Normals_Wireframe.uasset │ │ ├── M_Transparent.uasset │ │ └── M_VertexColor.uasset ├── MAP_Main.umap └── MAP_Main_BuiltData.uasset ├── GraphicsExamples.uproject ├── LICENSE ├── Plugins └── GraphicsPlugin │ ├── GraphicsPlugin.uplugin │ ├── Resources │ └── Icon128.png │ ├── Shaders │ ├── ClearTexture.usf │ ├── MarchingCubes │ │ ├── GenerateTriangles.usf │ │ ├── MarchingCubesCommon.ush │ │ └── ResetIndirectDraw.usf │ └── NiagaraSplines │ │ └── SplinesDeform.ush │ └── Source │ ├── GraphicsPlugin │ ├── GraphicsPlugin.Build.cs │ ├── Private │ │ ├── ClearTextureShader.cpp │ │ ├── GraphicsPlugin.cpp │ │ ├── NiagaraDataInterfaces │ │ │ └── NiagaraDataInterfaceAtomicBuffer.cpp │ │ ├── NiagaraInput │ │ │ └── NiagaraDataInterfacePlayerInput.cpp │ │ └── ProceduralMesh │ │ │ ├── ComputeShaderProceduralMeshActor.cpp │ │ │ ├── ComputeShaderProceduralMeshComponent.cpp │ │ │ ├── ComputeShaderProceduralMeshProxy.cpp │ │ │ └── MarchingCubeShaders │ │ │ └── MarchingCubeShaders.cpp │ └── Public │ │ ├── ClearTextureShader.h │ │ ├── NiagaraDataInterfaces │ │ └── NiagaraDataInterfaceAtomicBuffer.h │ │ ├── NiagaraInput │ │ └── NiagaraDataInterfacePlayerInput.h │ │ └── ProceduralMesh │ │ ├── ComputeFriendlyBuffers.h │ │ ├── ComputeShaderProceduralMeshActor.h │ │ ├── ComputeShaderProceduralMeshComponent.h │ │ ├── ComputeShaderProceduralMeshProxy.h │ │ └── MarchingCubeShaders │ │ └── MarchingCubeShaders.h │ └── GraphicsPluginEditor │ ├── GraphicsPluginEditor.Build.cs │ ├── Private │ ├── GraphicsPluginEditor.cpp │ ├── GraphicsPluginFunctionLibrary.cpp │ ├── PBDEditorFunctionLibrary.cpp │ ├── PBDEditorFunctionLibrary.h │ └── Widgets │ │ ├── AssetPicker.cpp │ │ └── AssetPicker.h │ └── Public │ └── GraphicsPluginFunctionLibrary.h ├── README.md └── Source ├── GraphicsExamples.Target.cs ├── GraphicsExamples ├── ClearTextureExample │ ├── ClearTextureActor.cpp │ └── ClearTextureActor.h ├── GraphicsExamples.Build.cs ├── GraphicsExamples.cpp ├── GraphicsExamples.h └── ProceduralMeshExample │ ├── ComputeShader │ └── MarchingCubes │ │ ├── MarchingCubeTables.h │ │ ├── MarchingCubesProceduralMeshActor.cpp │ │ └── MarchingCubesProceduralMeshActor.h │ └── CpuToGpu │ ├── HelloTriangleProceduralMeshActor.cpp │ └── HelloTriangleProceduralMeshActor.h └── GraphicsExamplesEditor.Target.cs /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | enc_temp_folder/ 3 | Binaries/ 4 | DerivedDataCache/ 5 | Intermediate/ 6 | Platforms/ 7 | Saved/ 8 | Script/ 9 | Build/ 10 | 11 | *.lnk 12 | *.pdb 13 | *.dll 14 | *.lib 15 | *.exe 16 | *.sln -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Config/DefaultEditor.ini -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [/Script/Engine.RendererSettings] 4 | r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True 5 | 6 | [/Script/HardwareTargeting.HardwareTargetingSettings] 7 | TargetedHardwareClass=Desktop 8 | AppliedTargetedHardwareClass=Desktop 9 | DefaultGraphicsPerformance=Maximum 10 | AppliedDefaultGraphicsPerformance=Maximum 11 | 12 | [/Script/EngineSettings.GameMapsSettings] 13 | EditorStartupMap=/Game/MAP_Main.MAP_Main 14 | GameDefaultMap=/Game/MAP_Main.MAP_Main 15 | 16 | -------------------------------------------------------------------------------- /Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=8C9CB43B478C5D1B73A3E4B8F1A2BE45 3 | -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BPInterface_Button.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BPInterface_Button.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_Audio_Trigger.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_Audio_Trigger.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_DemoDisplay.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_DemoDisplay.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_DemoDisplay_Enum.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_DemoDisplay_Enum.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_DemoRoom.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_DemoRoom.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_DemoRoom_Enum.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_DemoRoom_Enum.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_DemoTrigger.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_DemoTrigger.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/BP_LightScultpureDynamic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/BP_LightScultpureDynamic.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/DemoRoomStruct.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/DemoRoomStruct.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/BluePrint/RoomDescription.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/BluePrint/RoomDescription.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/DefaultTextMaterialTranslucentUnlit.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/DefaultTextMaterialTranslucentUnlit.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Button.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Button.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Button_Chrome.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Button_Chrome.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Button_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Button_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoAnimated.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoAnimated.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoAnimated_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoAnimated_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoAnimated_Vertex.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoAnimated_Vertex.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoLightFunktion.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoLightFunktion.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoLightFunktion_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoLightFunktion_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoMinRoughnesS_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoMinRoughnesS_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color3.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color3.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color5_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoRoomTiles_Inst_Color5_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWallPattern.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWallPattern.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWallPattern_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWallPattern_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWallPattern_Inst_Mirrored.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWallPattern_Inst_Mirrored.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWallPattern_NoText.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWallPattern_NoText.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_Inst2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_Inst2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_3.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_3.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_BaseFloor_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_BaseFloor_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_NamePlate.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_Inst_NamePlate.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_DemoWall_MattPlastic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_DemoWall_MattPlastic.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Emissive.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Emissive.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Emissive_1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Emissive_1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Emissive_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Emissive_2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_GlasDoor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_GlasDoor.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_GlasDoor_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_GlasDoor_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Glass.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Glass.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Glass_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Glass_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Gradient.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Gradient.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Gradient_Blue.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Gradient_Blue.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Gradient_EmissiveOverbright.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Gradient_EmissiveOverbright.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Gradient_Green.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Gradient_Green.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_Gradient_Red.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_Gradient_Red.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightSculpture.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightSculpture.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightSculpture_Blue.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightSculpture_Blue.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightSculpture_Green.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightSculpture_Green.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightSculpture_Red.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightSculpture_Red.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightTube.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightTube.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_LightTube_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_LightTube_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_3.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_3.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_MAT.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_MAT.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_3.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_ReflectionDemo_Metallic_3.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_SceneCapture2d.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_SceneCapture2d.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_SceneCaptureCube.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_SceneCaptureCube.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_TestSky.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_TestSky.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_TestSky_Inst.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_TestSky_Inst.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_UE4_Logo_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_UE4_Logo_2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_UE4_Logo_Door.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_UE4_Logo_Door.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Materials/M_UE4_Logo_Doors.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Materials/M_UE4_Logo_Doors.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Base.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Base.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Base2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Base2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_BaseRoom.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_BaseRoom.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_BaseTrimSquare.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_BaseTrimSquare.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Base_FlatWall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Base_FlatWall.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Button.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Button.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoCube.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoCube.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoDivider_1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoDivider_1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoDivider_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoDivider_2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoPlate.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoPlate.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomBackWall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomBackWall.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomBackWall2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomBackWall2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomBox.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomBox.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomClamp.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomClamp.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomClamp2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomClamp2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomL.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomL.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomLTrim.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomLTrim.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrim.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrim.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrim2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrim2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrimAdd.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomTrimAdd.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomU.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomU.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomU2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomU2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoRoomU_Hole.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoRoomU_Hole.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DemoSurface.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DemoSurface.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Door.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Door.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_DoorLock.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_DoorLock.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_GraphFrame.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_GraphFrame.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_LightSculpture.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_LightSculpture.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_NamePlate.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_NamePlate.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_Slider1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_Slider1.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_SliderBase.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_SliderBase.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_UE4_Logo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_UE4_Logo.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_URoom_Wall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_URoom_Wall.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Meshes/SM_URoom_Wall2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Meshes/SM_URoom_Wall2.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/SkeletalMeshes/PHYSMAT_SK_RigidBodyDemo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/SkeletalMeshes/PHYSMAT_SK_RigidBodyDemo.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/SkeletalMeshes/SK_RigidBodyDemo_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/NewTextureRenderTarget2D.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/NewTextureRenderTarget2D.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/NewTextureRenderTargetCube.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/NewTextureRenderTargetCube.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/T_Pattern_M.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/T_Pattern_M.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/T_RoomTiles_M.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/T_RoomTiles_M.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/T_RoomTiles_N.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/T_RoomTiles_N.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/T_UE4_Logo_M.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/T_UE4_Logo_M.uasset -------------------------------------------------------------------------------- /Content/Demo/DemoRoom/Textures/T_UnrealEngineDecal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Demo/DemoRoom/Textures/T_UnrealEngineDecal.uasset -------------------------------------------------------------------------------- /Content/Examples/ClearTexture/BP_ClearTextureActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ClearTexture/BP_ClearTextureActor.uasset -------------------------------------------------------------------------------- /Content/Examples/ClearTexture/MAP_ClearTexture.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ClearTexture/MAP_ClearTexture.umap -------------------------------------------------------------------------------- /Content/Examples/ClearTexture/MAP_ClearTexture_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ClearTexture/MAP_ClearTexture_BuiltData.uasset -------------------------------------------------------------------------------- /Content/Examples/ClearTexture/M_UnlitTexture.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ClearTexture/M_UnlitTexture.uasset -------------------------------------------------------------------------------- /Content/Examples/ClearTexture/unreal_logo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ClearTexture/unreal_logo.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraInput/NS_PlayerInput.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraInput/NS_PlayerInput.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/Cylinder.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/Cylinder.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/EditorScript/WBP_CalculateSplineParams.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/EditorScript/WBP_CalculateSplineParams.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/MAP_NiagaraSplines.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/MAP_NiagaraSplines.umap -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/MAP_NiagaraSplines_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/MAP_NiagaraSplines_BuiltData.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/M_NiagaraSplines.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/M_NiagaraSplines.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/NS_NiagaraSplines.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/NS_NiagaraSplines.uasset -------------------------------------------------------------------------------- /Content/Examples/NiagaraSplines/T_DummyArray.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/NiagaraSplines/T_DummyArray.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/EditorScripts/EW_PBD.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/EditorScripts/EW_PBD.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/MAP_NiagaraPBD.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/MAP_NiagaraPBD.umap -------------------------------------------------------------------------------- /Content/Examples/PBD/MAP_NiagaraPBD_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/MAP_NiagaraPBD_BuiltData.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/M_RubberToy.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/M_RubberToy.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/NS_PBDBasic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/NS_PBDBasic.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SM_RubberToy.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SM_RubberToy.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/MAP_SoftBunny.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/MAP_SoftBunny.umap -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/MAP_SoftBunny_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/MAP_SoftBunny_BuiltData.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/MI_PBD_SoftBody_Bunny.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/MI_PBD_SoftBody_Bunny.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/M_PBD_SoftBody.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/M_PBD_SoftBody.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/NS_PBD_SoftBody.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/NS_PBD_SoftBody.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/SM_BunnyBaked.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/SM_BunnyBaked.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ParticleConstraintList.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ParticleConstraintList.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ParticlePositions.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ParticlePositions.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ShapeMatchingConstraints.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/SoftBody/Bunny/T_Bunny_ShapeMatchingConstraints.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/T_PBDShapes.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/T_PBDShapes.uasset -------------------------------------------------------------------------------- /Content/Examples/PBD/T_RubberToyParticles.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/PBD/T_RubberToyParticles.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/BP_CubeMarchingActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/BP_CubeMarchingActor.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/BP_HelloTriangleActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/BP_HelloTriangleActor.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/MAP_ProceduralMesh.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/MAP_ProceduralMesh.umap -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/MAP_ProceduralMesh_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/MAP_ProceduralMesh_BuiltData.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/M_Normals.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/M_Normals.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/M_Normals_Wireframe.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/M_Normals_Wireframe.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/M_Transparent.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/M_Transparent.uasset -------------------------------------------------------------------------------- /Content/Examples/ProceduralMesh/M_VertexColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/Examples/ProceduralMesh/M_VertexColor.uasset -------------------------------------------------------------------------------- /Content/MAP_Main.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/MAP_Main.umap -------------------------------------------------------------------------------- /Content/MAP_Main_BuiltData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Content/MAP_Main_BuiltData.uasset -------------------------------------------------------------------------------- /GraphicsExamples.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "4.27", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "GraphicsExamples", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default" 11 | } 12 | ], 13 | "Plugins": [ 14 | { 15 | "Name": "GraphicsPlugin", 16 | "Enabled": true 17 | }, 18 | { 19 | "Name": "RenderDocPlugin", 20 | "Enabled": true 21 | }, 22 | { 23 | "Name": "HDRIBackdrop", 24 | "Enabled": true 25 | } 26 | ], 27 | "TargetPlatforms": [ 28 | "Android", 29 | "IOS", 30 | "Linux", 31 | "Mac", 32 | "Windows" 33 | ] 34 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Amit Kumar Mehar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/GraphicsPlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 1, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "Graphics Plugin", 6 | "Description": "Code samples to show how to use Rendering features in Unreal :)", 7 | "Category": "Rendering", 8 | "CreatedBy": "Amit Mehar", 9 | "CreatedByURL": "https://twitter.com/amu_mhr", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "EnabledByDefault": false, 14 | "CanContainContent": true, 15 | "IsBetaVersion": true, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "GraphicsPlugin", 20 | "Type": "Runtime", 21 | "LoadingPhase": "PostConfigInit" 22 | }, 23 | { 24 | "Name": "GraphicsPluginEditor", 25 | "Type": "Editor", 26 | "LoadingPhase": "Default" 27 | } 28 | ], 29 | "Plugins": [ 30 | { 31 | "Name": "Niagara", 32 | "Enabled": true 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amuTBKT/UE4GraphicsSample/5d4f715416377c8fe685c3f32965122f820fe92b/Plugins/GraphicsPlugin/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Shaders/ClearTexture.usf: -------------------------------------------------------------------------------- 1 | // every shader needs to include this 2 | #include "/Engine/Private/Common.ush" 3 | 4 | // in case we forget to set 'USE_ANIMATION' definition in code 5 | #ifndef USE_ANIMATION 6 | #define USE_ANIMATION 0 7 | #endif 8 | 9 | // in case we forget to set 'USE_TEXTURE' definition in code 10 | #ifndef USE_TEXTURE 11 | #define USE_TEXTURE 0 12 | #endif 13 | 14 | // Parameters, should match the ones in code 15 | RWTexture2D OutputTexture; 16 | Texture2D SourceTexture; 17 | SamplerState SourceSampler; 18 | float4 ClearColor; 19 | float4 TextureDimensions; // Width, Height, 1/Width, 1/Height 20 | float AnimationTime; 21 | 22 | // numthreads can also be set from code 23 | [numthreads(8, 8, 8)] 24 | void Main(uint3 DispatchThreadId : SV_DispatchThreadID) 25 | { 26 | float2 ScreenPosition = float2(DispatchThreadId.xy); 27 | if (ScreenPosition.x < TextureDimensions.x && ScreenPosition.y < TextureDimensions.y) 28 | { 29 | float4 OutputColor = ClearColor; 30 | 31 | // shows that we can enable/disable logic based on definition set from code 32 | #if USE_ANIMATION 33 | float2 UV = ScreenPosition * TextureDimensions.zw; 34 | OutputColor.xyz = 0.5f + 0.5f * cos(AnimationTime + UV.xyx + float3(0.f, 2.f, 4.f)); 35 | OutputColor.w = 1.f; 36 | #elif USE_TEXTURE 37 | float2 UV = ScreenPosition * TextureDimensions.zw; 38 | OutputColor = SourceTexture.SampleLevel(SourceSampler, UV, 0); 39 | #endif 40 | 41 | OutputTexture[DispatchThreadId.xy] = OutputColor; 42 | } 43 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Shaders/MarchingCubes/GenerateTriangles.usf: -------------------------------------------------------------------------------- 1 | #include "MarchingCubesCommon.ush" 2 | 3 | RWBuffer PositionBuffer; 4 | RWBuffer TangentBuffer; 5 | RWBuffer IndirectDrawArgsBuffer; 6 | Texture2D TriangleVerticesLookupTable; 7 | Buffer NumVerticesLookupTable; 8 | int3 VoxelCount; 9 | float VoxelSize; 10 | float IsoValue; 11 | float Time; 12 | uint MaxVertices; 13 | 14 | [numthreads(4, 4, 4)] 15 | void Main(uint3 DispatchThreadId : SV_DispatchThreadID) 16 | { 17 | if (all(DispatchThreadId < VoxelCount)) 18 | { 19 | float3 GridPos = float3(DispatchThreadId); 20 | 21 | float3 p = (GridPos * 2.f - VoxelCount) * VoxelSize * 0.5f; 22 | 23 | // calculate cell vertex positions 24 | float2 Offset = float2(VoxelSize, 0.f); 25 | 26 | float3 CornerVerts[8]; 27 | CornerVerts[0] = p; 28 | CornerVerts[1] = p + Offset.xyy; 29 | CornerVerts[2] = p + Offset.xxy; 30 | CornerVerts[3] = p + Offset.yxy; 31 | CornerVerts[4] = p + Offset.yyx; 32 | CornerVerts[5] = p + Offset.xyx; 33 | CornerVerts[6] = p + Offset.xxx; 34 | CornerVerts[7] = p + Offset.yxx; 35 | 36 | // evaluate SDF at corners 37 | float4 CornerValues[8]; 38 | CornerValues[0] = GetNormalAndDist(CornerVerts[0], Time); 39 | CornerValues[1] = GetNormalAndDist(CornerVerts[1], Time); 40 | CornerValues[2] = GetNormalAndDist(CornerVerts[2], Time); 41 | CornerValues[3] = GetNormalAndDist(CornerVerts[3], Time); 42 | CornerValues[4] = GetNormalAndDist(CornerVerts[4], Time); 43 | CornerValues[5] = GetNormalAndDist(CornerVerts[5], Time); 44 | CornerValues[6] = GetNormalAndDist(CornerVerts[6], Time); 45 | CornerValues[7] = GetNormalAndDist(CornerVerts[7], Time); 46 | 47 | uint Cubeindex; 48 | Cubeindex = uint(CornerValues[0].w < IsoValue); 49 | Cubeindex += uint(CornerValues[1].w < IsoValue) * 2; 50 | Cubeindex += uint(CornerValues[2].w < IsoValue) * 4; 51 | Cubeindex += uint(CornerValues[3].w < IsoValue) * 8; 52 | Cubeindex += uint(CornerValues[4].w < IsoValue) * 16; 53 | Cubeindex += uint(CornerValues[5].w < IsoValue) * 32; 54 | Cubeindex += uint(CornerValues[6].w < IsoValue) * 64; 55 | Cubeindex += uint(CornerValues[7].w < IsoValue) * 128; 56 | 57 | // output triangle vertices 58 | uint NumVerts = NumVerticesLookupTable[Cubeindex]; 59 | if (NumVerts > 0) 60 | { 61 | // find the vertices where the surface intersects the cube 62 | float3 VertList[12]; 63 | float3 NormList[12]; 64 | VertexInterp2(IsoValue, CornerVerts[0], CornerVerts[1], CornerValues[0], CornerValues[1], VertList[0], NormList[0]); 65 | VertexInterp2(IsoValue, CornerVerts[1], CornerVerts[2], CornerValues[1], CornerValues[2], VertList[1], NormList[1]); 66 | VertexInterp2(IsoValue, CornerVerts[2], CornerVerts[3], CornerValues[2], CornerValues[3], VertList[2], NormList[2]); 67 | VertexInterp2(IsoValue, CornerVerts[3], CornerVerts[0], CornerValues[3], CornerValues[0], VertList[3], NormList[3]); 68 | 69 | VertexInterp2(IsoValue, CornerVerts[4], CornerVerts[5], CornerValues[4], CornerValues[5], VertList[4], NormList[4]); 70 | VertexInterp2(IsoValue, CornerVerts[5], CornerVerts[6], CornerValues[5], CornerValues[6], VertList[5], NormList[5]); 71 | VertexInterp2(IsoValue, CornerVerts[6], CornerVerts[7], CornerValues[6], CornerValues[7], VertList[6], NormList[6]); 72 | VertexInterp2(IsoValue, CornerVerts[7], CornerVerts[4], CornerValues[7], CornerValues[4], VertList[7], NormList[7]); 73 | 74 | VertexInterp2(IsoValue, CornerVerts[0], CornerVerts[4], CornerValues[0], CornerValues[4], VertList[8], NormList[8]); 75 | VertexInterp2(IsoValue, CornerVerts[1], CornerVerts[5], CornerValues[1], CornerValues[5], VertList[9], NormList[9]); 76 | VertexInterp2(IsoValue, CornerVerts[2], CornerVerts[6], CornerValues[2], CornerValues[6], VertList[10], NormList[10]); 77 | VertexInterp2(IsoValue, CornerVerts[3], CornerVerts[7], CornerValues[3], CornerValues[7], VertList[11], NormList[11]); 78 | 79 | uint WriteIndex; 80 | InterlockedAdd(IndirectDrawArgsBuffer[0], NumVerts, WriteIndex); 81 | 82 | for (int i = 0; i < NumVerts; i++) 83 | { 84 | uint TriVertex = TriangleVerticesLookupTable.Load(uint3(i, Cubeindex, 0)); 85 | 86 | uint Index = WriteIndex + i; 87 | if (Index < MaxVertices) 88 | { 89 | PositionBuffer[Index * 3 + 0] = VertList[TriVertex].x; 90 | PositionBuffer[Index * 3 + 1] = VertList[TriVertex].y; 91 | PositionBuffer[Index * 3 + 2] = VertList[TriVertex].z; 92 | 93 | TangentBuffer[Index * 2 + 0] = float4(1.f, 0.f, 0.f, 0.f); //[TODO] 94 | TangentBuffer[Index * 2 + 1] = float4(NormList[TriVertex], 0.0f); 95 | } 96 | } 97 | } 98 | } 99 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Shaders/MarchingCubes/MarchingCubesCommon.ush: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "/Engine/Private/Common.ush" 4 | 5 | ////////////////////////////////////////////////////// 6 | /** SDF logic from https://www.shadertoy.com/view/ltXcWN */ 7 | 8 | float sphere(float3 p, float r) 9 | { 10 | return length(p) - r; 11 | } 12 | 13 | float blob5(float d1, float d2, float d3, float d4, float d5) 14 | { 15 | float k = 2.0; 16 | return -log(exp(-k * d1) + exp(-k * d2) + exp(-k * d3) + exp(-k * d4) + exp(-k * d5)) / k; 17 | } 18 | 19 | float map(float3 p, float T) 20 | { 21 | // scale to fit SDF logic (this is basically a magic number to make it work with ue4 units and the actor setup I am using) 22 | p *= 0.004f; 23 | 24 | float s = smoothstep(-0.7, 0.7, sin(0.5 * T)); 25 | float a = lerp(0.5, 2.0, s); 26 | float t = 1.0 * T; 27 | 28 | float s1 = sphere(p + a * float3(cos(t * 1.1), cos(t * 1.3), cos(t * 1.7)), 1.0); 29 | float s2 = sphere(p + a * float3(cos(t * 0.7), cos(t * 1.9), cos(t * 2.3)), 1.2); 30 | float s3 = sphere(p + a * float3(cos(t * 0.3), cos(t * 2.9), sin(t * 1.1)), 1.5); 31 | float s4 = sphere(p + a * float3(sin(t * 1.3), sin(t * 1.7), sin(t * 0.7)), 0.4); 32 | float s5 = sphere(p + a * float3(sin(t * 2.3), sin(t * 1.9), sin(t * 2.9)), 1.0); 33 | 34 | return blob5(s1, s2, s3, s4, s5); 35 | } 36 | ////////////////////////////////////////////////////// 37 | 38 | float GetDist(float3 p, float time) 39 | { 40 | return map(p * 16.f, time); 41 | 42 | return length(p) - 15.f; 43 | } 44 | 45 | float4 GetNormalAndDist(float3 p, float time) 46 | { 47 | float v = GetDist(p, time); 48 | const float2 e = float2(0.001f, 0.f); 49 | float dx = GetDist(p + e.xyy, time) - v; 50 | float dy = GetDist(p + e.yxy, time) - v; 51 | float dz = GetDist(p + e.yyx, time) - v; 52 | return float4(dx, dy, dz, v); 53 | } 54 | 55 | void VertexInterp2(float isolevel, float3 p0, float3 p1, float4 f0, float4 f1, out float3 p, out float3 n) 56 | { 57 | float t = (isolevel - f0.w) / (f1.w - f0.w); 58 | p = lerp(p0, p1, t); 59 | n.x = lerp(f0.x, f1.x, t); 60 | n.y = lerp(f0.y, f1.y, t); 61 | n.z = lerp(f0.z, f1.z, t); 62 | n = normalize(n); 63 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Shaders/MarchingCubes/ResetIndirectDraw.usf: -------------------------------------------------------------------------------- 1 | // every shader needs to include this 2 | #include "/Engine/Private/Common.ush" 3 | 4 | RWBuffer IndirectDrawArgsBuffer; 5 | 6 | // numthreads can also be set from code 7 | [numthreads(1, 1, 1)] 8 | void Main(uint3 DispatchThreadId : SV_DispatchThreadID) 9 | { 10 | // IndirectDrawArgsBuffer[0] : VertexCountPerInstance 11 | // IndirectDrawArgsBuffer[1] : InstanceCount 12 | // IndirectDrawArgsBuffer[2] : StartVertexLocation 13 | // IndirectDrawArgsBuffer[3] : StartInstanceLocation 14 | 15 | IndirectDrawArgsBuffer[0] = 0; 16 | IndirectDrawArgsBuffer[1] = 1; //We are only rendering one instance 17 | IndirectDrawArgsBuffer[2] = 0; 18 | IndirectDrawArgsBuffer[3] = 0; 19 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Shaders/NiagaraSplines/SplinesDeform.ush: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct FSplineHelper 4 | { 5 | /** 6 | * this function assumes the texutre size is (NuSegmentCountPerInstance by NumInstances) 7 | * we can do some packing to make sure the texture is uniformly scaled (not too long in X or Y axis) 8 | that would need modifying Niagra system writing texture data as well. 9 | */ 10 | void GetSplineParams( 11 | float Alpha, 12 | float SegmentCountPerInstance, 13 | in float SplineId, 14 | in float CurrentFrameIndex, 15 | in Texture2DArray SplinePositionTexture, 16 | in Texture2DArray SplineTangentTexture, 17 | in Texture2DArray SplineNormalTexture, 18 | out float3 SplineStartPos, 19 | out float3 SplineStartTangent, 20 | out float3 SplineEndPos, 21 | out float3 SplineEndTangent, 22 | out float3 SplineStartNormal, 23 | out float3 SplineEndNormal, 24 | out float StartScale, 25 | out float EndScale, 26 | out float StartRoll, 27 | out float EndRoll) 28 | { 29 | int SegmentIndex0 = floor(saturate(Alpha) * (float)(SegmentCountPerInstance-1)); 30 | int SegmentIndex1 = min(SegmentCountPerInstance-1, SegmentIndex0 + 1); 31 | 32 | float4 SplineStartPosScale = SplinePositionTexture.Load(int4(SegmentIndex0, SplineId, CurrentFrameIndex, 0)); 33 | float4 SplineEndPosScale = SplinePositionTexture.Load(int4(SegmentIndex1, SplineId, CurrentFrameIndex, 0)); 34 | float4 SplineStartTangentRoll = SplineTangentTexture.Load(int4(SegmentIndex0, SplineId, CurrentFrameIndex, 0)); 35 | float4 SplineEndTangentRoll = SplineTangentTexture.Load(int4(SegmentIndex1, SplineId, CurrentFrameIndex, 0)); 36 | 37 | SplineStartNormal = SplineNormalTexture.Load(int4(SegmentIndex0, SplineId, CurrentFrameIndex, 0)).xyz * 2.f - 1.f; 38 | SplineEndNormal = SplineNormalTexture.Load(int4(SegmentIndex1, SplineId, CurrentFrameIndex, 0)).xyz * 2.f - 1.f; 39 | 40 | SplineStartPos = SplineStartPosScale.xyz; 41 | SplineEndPos = SplineEndPosScale.xyz; 42 | StartScale = SplineStartPosScale.w; 43 | EndScale = SplineEndPosScale.w; 44 | 45 | SplineStartTangent = SplineStartTangentRoll.xyz * 2.f - 1.f; 46 | SplineEndTangent = SplineEndTangentRoll.xyz * 2.f - 1.f; 47 | StartRoll = SplineStartTangentRoll.w; 48 | EndRoll = SplineEndTangentRoll.w; 49 | } 50 | 51 | // the code from this point is taken from LocalVertexFactory.ush with changes to load SplineParams from texture so that they can change per instance 52 | float3 SplineEvalPos(float3 StartPos, float3 StartTangent, float3 EndPos, float3 EndTangent, float A) 53 | { 54 | float A2 = A * A; 55 | float A3 = A2 * A; 56 | 57 | return (((2*A3)-(3*A2)+1) * StartPos) + ((A3-(2*A2)+A) * StartTangent) + ((A3-A2) * EndTangent) + (((-2*A3)+(3*A2)) * EndPos); 58 | } 59 | 60 | float3 SplineEvalDir(float3 StartPos, float3 StartTangent, float3 EndPos, float3 EndTangent, float A) 61 | { 62 | float3 C = (6*StartPos) + (3*StartTangent) + (3*EndTangent) - (6*EndPos); 63 | float3 D = (-6*StartPos) - (4*StartTangent) - (2*EndTangent) + (6*EndPos); 64 | float3 E = StartTangent; 65 | 66 | float A2 = A * A; 67 | 68 | return normalize((C * A2) + (D * A) + E); 69 | } 70 | 71 | float4 TransformLocalToTranslatedWorld(float3 LocalPosition, uint PrimitiveId) 72 | { 73 | float4x4 LocalToWorld = GetPrimitiveData(PrimitiveId).LocalToWorld; 74 | float3 RotatedPosition = LocalToWorld[0].xyz * LocalPosition.xxx + LocalToWorld[1].xyz * LocalPosition.yyy + LocalToWorld[2].xyz * LocalPosition.zzz; 75 | return float4(RotatedPosition + (LocalToWorld[3].xyz + ResolvedView.PreViewTranslation.xyz),1); 76 | } 77 | 78 | void CalcSliceTransform( 79 | float SegmentCountPerInstance, 80 | float SplineMeshScaleZ, 81 | float SplineMeshMinZ, 82 | float3 SplineMeshDir, 83 | float3 SplineMeshX, 84 | float3 SplineMeshY, 85 | Texture2DArray SplinePositionTexture, 86 | Texture2DArray SplineTangentTexture, 87 | Texture2DArray SplineNormalTexture, 88 | float SplineId, 89 | float CurrentFrameIndex, 90 | float3 LocalPosition, 91 | float3 LocalNormal, 92 | out float3 TransformedPosition, 93 | out float3 TransformedNormal) 94 | { 95 | // HARDCODED PARAMETERS 96 | const bool SmoothInterpRollScale = true; 97 | const float2 SplineStartOffset = float2(0.f, 0.f); 98 | const float2 SplineEndOffset = float2(0.f, 0.f); 99 | // HARDCODED PARAMETERS 100 | 101 | // Find how far 'along' mesh we are 102 | float Alpha = dot(SplineMeshDir, LocalPosition) * SplineMeshScaleZ - SplineMeshMinZ; 103 | 104 | // Apply hermite interp to Alpha if desired 105 | float HermiteAlpha = SmoothInterpRollScale ? smoothstep(0.0, 1.0, Alpha) : Alpha; 106 | 107 | //////////////////////////////////////////////////////// 108 | float3 SplineStartPos, SplineStartTangent, SplineEndPos, SplineEndTangent; 109 | float3 SplineStartNormal, SplineEndNormal; 110 | float SplineStartScale, SplineEndScale; 111 | float SplineStartRoll, SplineEndRoll; 112 | 113 | GetSplineParams( 114 | Alpha, SegmentCountPerInstance, SplineId, CurrentFrameIndex, 115 | SplinePositionTexture, SplineTangentTexture, SplineNormalTexture, 116 | SplineStartPos, SplineStartTangent, SplineEndPos, SplineEndTangent, 117 | SplineStartNormal, SplineEndNormal, 118 | SplineStartScale, SplineEndScale, SplineStartRoll, SplineEndRoll); 119 | 120 | float3 SplineUpDir = normalize(lerp(SplineStartNormal, SplineEndNormal, HermiteAlpha)); 121 | //////////////////////////////////////////////////////// 122 | 123 | // Then find the point and direction of the spline at this point along 124 | float3 SplinePos = SplineEvalPos( SplineStartPos, SplineStartTangent, SplineEndPos, SplineEndTangent, Alpha ); 125 | float3 SplineDir = SplineEvalDir( SplineStartPos, SplineStartTangent, SplineEndPos, SplineEndTangent, Alpha ); 126 | 127 | // Find base frenet frame 128 | float3 BaseXVec = normalize( cross(SplineUpDir, SplineDir) ); 129 | float3 BaseYVec = normalize( cross(SplineDir, BaseXVec) ); 130 | 131 | // Offset from the spline, using the frenet frame 132 | float2 SliceOffset = lerp(SplineStartOffset, SplineEndOffset, HermiteAlpha); 133 | SplinePos += SliceOffset.x * BaseXVec; 134 | SplinePos += SliceOffset.y * BaseYVec; 135 | 136 | // Apply roll to frame around spline 137 | float UseRoll = lerp(SplineStartRoll, SplineEndRoll, HermiteAlpha); 138 | float SinAng, CosAng; 139 | sincos(UseRoll, SinAng, CosAng); 140 | float3 XVec = (CosAng * BaseXVec) - (SinAng * BaseYVec); 141 | float3 YVec = (CosAng * BaseYVec) + (SinAng * BaseXVec); 142 | 143 | // Find scale at this point along spline 144 | float UseScale = lerp(SplineStartScale, SplineEndScale, HermiteAlpha); 145 | 146 | XVec *= UseScale; 147 | YVec *= UseScale; 148 | 149 | // Build overall transform 150 | float3x3 SliceTransform3 = mul(transpose(float3x3(SplineMeshDir, SplineMeshX, SplineMeshY)), float3x3(float3(0,0,0), XVec, YVec)); 151 | float4x3 SliceTransform = float4x3(SliceTransform3[0], SliceTransform3[1], SliceTransform3[2], SplinePos); 152 | 153 | TransformedPosition = float3(mul(float4(LocalPosition, 1.f), SliceTransform).xyz); 154 | 155 | TransformedNormal = float3(mul(float4(LocalNormal, 0.f), SliceTransform).xyz); 156 | } 157 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/GraphicsPlugin.Build.cs: -------------------------------------------------------------------------------- 1 | namespace UnrealBuildTool.Rules 2 | { 3 | public class GraphicsPlugin : ModuleRules 4 | { 5 | public GraphicsPlugin(ReadOnlyTargetRules Target) : base(Target) 6 | { 7 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 8 | 9 | PublicDependencyModuleNames.AddRange( 10 | new string[] 11 | { 12 | "Core", 13 | "CoreUObject", 14 | "InputCore", 15 | "Projects", 16 | "Engine", 17 | } 18 | ); 19 | 20 | // these modules are needed to use rendering features 21 | PublicDependencyModuleNames.AddRange( 22 | new string[] 23 | { 24 | "RHI", 25 | "RenderCore", 26 | "Renderer", 27 | }); 28 | 29 | // these modules are needed to use Niagara 30 | PublicDependencyModuleNames.AddRange( 31 | new string[] 32 | { 33 | "Niagara", 34 | "VectorVM", 35 | "NiagaraCore", 36 | }); 37 | 38 | PublicIncludePaths.AddRange( 39 | new string[] 40 | { 41 | "../Shaders/Shared" 42 | } 43 | ); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/ClearTextureShader.cpp: -------------------------------------------------------------------------------- 1 | #include "ClearTextureShader.h" 2 | 3 | // ShaderClass, SourceFile, EntryPoint, ShaderType {VS, PS, CS...} 4 | IMPLEMENT_GLOBAL_SHADER(FClearTextureCS, "/Plugin/GraphicsPlugin/ClearTexture.usf", "Main", SF_Compute); -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/GraphicsPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include "CoreMinimal.h" 2 | #include "Modules/ModuleInterface.h" 3 | #include "Modules/ModuleManager.h" 4 | #include "Interfaces/IPluginManager.h" 5 | #include "Misc/Paths.h" 6 | #include "ShaderCore.h" 7 | 8 | class FGraphicsPlugin : public IModuleInterface 9 | { 10 | /** IModuleInterface implementation */ 11 | virtual void StartupModule() override; 12 | virtual void ShutdownModule() override; 13 | }; 14 | 15 | IMPLEMENT_MODULE(FGraphicsPlugin, GraphicsPlugin) 16 | 17 | /** 18 | * Shaders needs to be loaded before engine is initialized, this Plugin makes sures we add our shaders into ShaderMap 19 | */ 20 | void FGraphicsPlugin::StartupModule() 21 | { 22 | const FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("GraphicsPlugin"))->GetBaseDir(), TEXT("Shaders")); 23 | AddShaderSourceDirectoryMapping(TEXT("/Plugin/GraphicsPlugin"), PluginShaderDir); 24 | } 25 | 26 | 27 | void FGraphicsPlugin::ShutdownModule() 28 | { 29 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/NiagaraDataInterfaces/NiagaraDataInterfaceAtomicBuffer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | #include "NiagaraDataInterfaces/NiagaraDataInterfaceAtomicBuffer.h" 3 | #include "NiagaraShader.h" 4 | #include "NiagaraRenderer.h" 5 | #include "ShaderParameterUtils.h" 6 | #include "NiagaraSystemInstance.h" 7 | #include "NiagaraEmitterInstanceBatcher.h" 8 | 9 | #define LOCTEXT_NAMESPACE "NiagaraDataInterfaceAtomicBuffer" 10 | 11 | PRAGMA_DISABLE_OPTIMIZATION 12 | 13 | const FString UNiagaraDataInterfaceAtomicBuffer::NumElements_VarName("NumElements_"); 14 | const FString UNiagaraDataInterfaceAtomicBuffer::ResetValue_VarName("ResetValue_"); 15 | const FString UNiagaraDataInterfaceAtomicBuffer::AtomicBuffer_VarName("AtomicBuffer_"); 16 | 17 | const FName UNiagaraDataInterfaceAtomicBuffer::SetNumElements_FuncName("SetNumElements"); 18 | const FName UNiagaraDataInterfaceAtomicBuffer::SetResetValue_FuncName("SetResetValue"); 19 | const FName UNiagaraDataInterfaceAtomicBuffer::SetClearEveryFrame_FuncName("SetClearEveryFrame"); 20 | 21 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedAdd_FuncName("InterlockedAdd"); 22 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedMin_FuncName("InterlockedMin"); 23 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedMax_FuncName("InterlockedMax"); 24 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedOr_FuncName("InterlockedOr"); 25 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedAnd_FuncName("InterlockedAnd"); 26 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedXor_FuncName("InterlockedXor"); 27 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedCompareStore_FuncName("InterlockedCompareStore"); 28 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedCompareExchange_FuncName("InterlockedCompareExchange"); 29 | const FName UNiagaraDataInterfaceAtomicBuffer::InterlockedExchange_FuncName("InterlockedExchange"); 30 | 31 | const FName UNiagaraDataInterfaceAtomicBuffer::GetValue_FuncName("GetValue"); 32 | const FName UNiagaraDataInterfaceAtomicBuffer::SetValue_FuncName("SetValue"); 33 | 34 | class FAtomicBufferInstanceData_GT 35 | { 36 | public: 37 | int32 NumElements = 0; 38 | int32 ResetValue = 0; 39 | bool ClearEveryFrame = true; 40 | bool NeedsRealloc = false; 41 | }; 42 | 43 | class FAtomicBufferInstanceData_GTtoRT 44 | { 45 | public: 46 | int32 ResetValue = 0; 47 | bool ClearEveryFrame = true; 48 | }; 49 | 50 | class FAtomicBufferInstanceData_RT 51 | { 52 | public: 53 | ~FAtomicBufferInstanceData_RT() 54 | { 55 | AtomicBuffer.Release(); 56 | } 57 | 58 | void ResizeBuffers() 59 | { 60 | AtomicBuffer.Initialize(sizeof(int32), NumElements, EPixelFormat::PF_R32_SINT, BUF_Static, TEXT("AtomicBufferDI")); 61 | } 62 | 63 | public: 64 | FRWBuffer AtomicBuffer; 65 | int32 NumElements = 0; 66 | int32 ResetValue = 0; 67 | bool ClearEveryFrame = true; 68 | }; 69 | 70 | struct FNiagaraDataInterfaceProxyAtomicBuffer : public FNiagaraDataInterfaceProxyRW 71 | { 72 | virtual void PreStage(FRHICommandList& RHICmdList, const FNiagaraDataInterfaceStageArgs& Context) override 73 | { 74 | if (const FAtomicBufferInstanceData_RT* ProxyData = SystemInstancesToProxyData.Find(Context.SystemInstanceID)) 75 | { 76 | if (Context.IsOutputStage && ProxyData->ClearEveryFrame) 77 | { 78 | SCOPED_DRAW_EVENT(RHICmdList, NiagaraDIAtomicBuffer_Clear); 79 | 80 | FRHITransitionInfo TransitionInfos[] = 81 | { 82 | FRHITransitionInfo(ProxyData->AtomicBuffer.UAV, ERHIAccess::Unknown, ERHIAccess::UAVCompute), 83 | }; 84 | RHICmdList.Transition(MakeArrayView(TransitionInfos, UE_ARRAY_COUNT(TransitionInfos))); 85 | 86 | RHICmdList.ClearUAVUint(ProxyData->AtomicBuffer.UAV, FUintVector4(ProxyData->ResetValue, ProxyData->ResetValue, ProxyData->ResetValue, ProxyData->ResetValue)); 87 | } 88 | } 89 | } 90 | 91 | virtual FIntVector GetElementCount(FNiagaraSystemInstanceID SystemInstanceID) const override 92 | { 93 | if (const FAtomicBufferInstanceData_RT* TargetData = SystemInstancesToProxyData.Find(SystemInstanceID)) 94 | { 95 | return FIntVector(TargetData->NumElements, 1, 1); 96 | } 97 | return FIntVector::ZeroValue; 98 | } 99 | 100 | virtual void ConsumePerInstanceDataFromGameThread(void* PerInstanceData, const FNiagaraSystemInstanceID& SystemInstanceID) override 101 | { 102 | if (FAtomicBufferInstanceData_RT* InstanceData_RT = SystemInstancesToProxyData.Find(SystemInstanceID)) 103 | { 104 | FAtomicBufferInstanceData_GTtoRT* DataPassedToRT = (FAtomicBufferInstanceData_GTtoRT*)PerInstanceData; 105 | 106 | InstanceData_RT->ResetValue = DataPassedToRT->ResetValue; 107 | InstanceData_RT->ClearEveryFrame = DataPassedToRT->ClearEveryFrame; 108 | 109 | DataPassedToRT->~FAtomicBufferInstanceData_GTtoRT(); 110 | } 111 | } 112 | 113 | virtual int32 PerInstanceDataPassedToRenderThreadSize() const override { return sizeof(FAtomicBufferInstanceData_GTtoRT); } 114 | 115 | /* List of proxy data for each system instances*/ 116 | // #todo(dmp): this should all be refactored to avoid duplicate code 117 | TMap SystemInstancesToProxyData; 118 | }; 119 | 120 | /*--------------------------------------------------------------------------------------------------------------------------*/ 121 | struct FNiagaraDataInterfaceParametersCS_AtomicBuffer : public FNiagaraDataInterfaceParametersCS 122 | { 123 | DECLARE_TYPE_LAYOUT(FNiagaraDataInterfaceParametersCS_AtomicBuffer, NonVirtual); 124 | public: 125 | void Bind(const FNiagaraDataInterfaceGPUParamInfo& ParameterInfo, const class FShaderParameterMap& ParameterMap) 126 | { 127 | OutputParam.Bind(ParameterMap, *("RW" + UNiagaraDataInterfaceAtomicBuffer::AtomicBuffer_VarName + ParameterInfo.DataInterfaceHLSLSymbol)); 128 | InputParam.Bind(ParameterMap, *(UNiagaraDataInterfaceAtomicBuffer::AtomicBuffer_VarName + ParameterInfo.DataInterfaceHLSLSymbol)); 129 | NumElementsParam.Bind(ParameterMap, *(UNiagaraDataInterfaceAtomicBuffer::NumElements_VarName + ParameterInfo.DataInterfaceHLSLSymbol)); 130 | ResetValueParam.Bind(ParameterMap, *(UNiagaraDataInterfaceAtomicBuffer::ResetValue_VarName + ParameterInfo.DataInterfaceHLSLSymbol)); 131 | } 132 | 133 | // #todo(dmp): make resource transitions batched 134 | void Set(FRHICommandList& RHICmdList, const FNiagaraDataInterfaceSetArgs& Context) const 135 | { 136 | check(IsInRenderingThread()); 137 | 138 | FRHIComputeShader* ComputeShaderRHI = Context.Shader.GetComputeShader(); 139 | FNiagaraDataInterfaceProxyAtomicBuffer* Proxy = static_cast(Context.DataInterface); 140 | 141 | FAtomicBufferInstanceData_RT* ProxyData = Proxy->SystemInstancesToProxyData.Find(Context.SystemInstanceID); 142 | 143 | if (!(ProxyData && ProxyData->AtomicBuffer.Buffer.IsValid())) 144 | { 145 | SetShaderValue(RHICmdList, ComputeShaderRHI, NumElementsParam , 0); 146 | SetShaderValue(RHICmdList, ComputeShaderRHI, ResetValueParam, 0); 147 | if (OutputParam.IsBound()) 148 | { 149 | SetUAVParameter(RHICmdList, ComputeShaderRHI, OutputParam, Context.Batcher->GetEmptyUAVFromPool(RHICmdList, PF_R32_SINT, ENiagaraEmptyUAVType::Buffer)); 150 | } 151 | if (InputParam.IsBound()) 152 | { 153 | SetSRVParameter(RHICmdList, ComputeShaderRHI, InputParam, FNiagaraRenderer::GetDummyIntBuffer()); 154 | } 155 | return; 156 | } 157 | 158 | SetShaderValue(RHICmdList, ComputeShaderRHI, NumElementsParam, ProxyData->NumElements); 159 | SetShaderValue(RHICmdList, ComputeShaderRHI, ResetValueParam, ProxyData->ResetValue); 160 | 161 | const bool bIsOutputBound = OutputParam.IsBound(); 162 | if (bIsOutputBound) 163 | { 164 | FRHIUnorderedAccessView* OutputUAV = ProxyData->AtomicBuffer.UAV; 165 | RHICmdList.Transition(FRHITransitionInfo(OutputUAV, ERHIAccess::Unknown, ERHIAccess::UAVCompute)); 166 | SetUAVParameter(RHICmdList, ComputeShaderRHI, OutputParam, OutputUAV); 167 | } 168 | 169 | if (InputParam.IsBound()) 170 | { 171 | if (bIsOutputBound) 172 | { 173 | UE_LOG(LogTemp, Warning, TEXT("NiagaraDIAtomicBuffer(%s) is bound as both read & write, read will be ignored."), *Context.DataInterface->SourceDIName.ToString()); 174 | SetSRVParameter(RHICmdList, ComputeShaderRHI, InputParam, FNiagaraRenderer::GetDummyIntBuffer()); 175 | } 176 | else 177 | { 178 | FRHIUnorderedAccessView* OutputUAV = ProxyData->AtomicBuffer.UAV; 179 | RHICmdList.Transition(FRHITransitionInfo(OutputUAV, ERHIAccess::Unknown, ERHIAccess::SRVCompute)); 180 | SetSRVParameter(RHICmdList, ComputeShaderRHI, InputParam, ProxyData->AtomicBuffer.SRV); 181 | } 182 | } 183 | } 184 | 185 | void Unset(FRHICommandList& RHICmdList, const FNiagaraDataInterfaceSetArgs& Context) const 186 | { 187 | FRHIComputeShader* ComputeShaderRHI = Context.Shader.GetComputeShader(); 188 | 189 | if (OutputParam.IsBound()) 190 | { 191 | SetUAVParameter(RHICmdList, ComputeShaderRHI, OutputParam, FUnorderedAccessViewRHIRef()); 192 | } 193 | } 194 | 195 | private: 196 | LAYOUT_FIELD(FShaderResourceParameter, OutputParam); 197 | LAYOUT_FIELD(FShaderResourceParameter, InputParam); 198 | LAYOUT_FIELD(FShaderParameter, NumElementsParam); 199 | LAYOUT_FIELD(FShaderParameter, ResetValueParam); 200 | }; 201 | 202 | IMPLEMENT_TYPE_LAYOUT(FNiagaraDataInterfaceParametersCS_AtomicBuffer); 203 | 204 | IMPLEMENT_NIAGARA_DI_PARAMETER(UNiagaraDataInterfaceAtomicBuffer, FNiagaraDataInterfaceParametersCS_AtomicBuffer); 205 | 206 | UNiagaraDataInterfaceAtomicBuffer::UNiagaraDataInterfaceAtomicBuffer(FObjectInitializer const& ObjectInitializer) 207 | : Super(ObjectInitializer) 208 | { 209 | Proxy.Reset(new FNiagaraDataInterfaceProxyAtomicBuffer()); 210 | } 211 | 212 | int32 UNiagaraDataInterfaceAtomicBuffer::PerInstanceDataSize() const 213 | { 214 | return sizeof(FAtomicBufferInstanceData_GT); 215 | } 216 | 217 | void UNiagaraDataInterfaceAtomicBuffer::GetFunctions(TArray& OutFunctions) 218 | { 219 | Super::GetFunctions(OutFunctions); 220 | 221 | { 222 | FNiagaraFunctionSignature Sig = {}; 223 | Sig.Name = SetNumElements_FuncName; 224 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 225 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("NumElements"))); 226 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Success"))); 227 | 228 | Sig.ModuleUsageBitmask = ENiagaraScriptUsageMask::Emitter | ENiagaraScriptUsageMask::System; 229 | Sig.bExperimental = true; 230 | Sig.bMemberFunction = true; 231 | Sig.bRequiresExecPin = true; 232 | Sig.bRequiresContext = false; 233 | Sig.bSupportsCPU = true; 234 | Sig.bSupportsGPU = false; 235 | OutFunctions.Add(Sig); 236 | } 237 | 238 | { 239 | FNiagaraFunctionSignature Sig = {}; 240 | Sig.Name = SetResetValue_FuncName; 241 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 242 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("ResetValue"))); 243 | 244 | Sig.ModuleUsageBitmask = ENiagaraScriptUsageMask::Emitter | ENiagaraScriptUsageMask::System; 245 | Sig.bExperimental = true; 246 | Sig.bMemberFunction = true; 247 | Sig.bRequiresExecPin = true; 248 | Sig.bRequiresContext = false; 249 | Sig.bSupportsCPU = true; 250 | Sig.bSupportsGPU = false; 251 | OutFunctions.Add(Sig); 252 | } 253 | 254 | { 255 | auto GetFunctionSignature = [this](FName FuncName) -> FNiagaraFunctionSignature 256 | { 257 | FNiagaraFunctionSignature Sig = {}; 258 | Sig.Name = FuncName; 259 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 260 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Enabled"))); 261 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Index"))); 262 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Value"))); 263 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("OriginalValue"))); 264 | 265 | Sig.bExperimental = true; 266 | Sig.bWriteFunction = true; 267 | Sig.bMemberFunction = true; 268 | Sig.bRequiresContext = false; 269 | Sig.bSupportsCPU = false; 270 | Sig.bSupportsGPU = true; 271 | 272 | return Sig; 273 | }; 274 | 275 | OutFunctions.Add(GetFunctionSignature(InterlockedAdd_FuncName)); 276 | OutFunctions.Add(GetFunctionSignature(InterlockedMin_FuncName)); 277 | OutFunctions.Add(GetFunctionSignature(InterlockedMax_FuncName)); 278 | OutFunctions.Add(GetFunctionSignature(InterlockedOr_FuncName)); 279 | OutFunctions.Add(GetFunctionSignature(InterlockedAnd_FuncName)); 280 | OutFunctions.Add(GetFunctionSignature(InterlockedXor_FuncName)); 281 | OutFunctions.Add(GetFunctionSignature(InterlockedExchange_FuncName)); 282 | } 283 | 284 | { 285 | FNiagaraFunctionSignature Sig = {}; 286 | Sig.Name = InterlockedCompareStore_FuncName; 287 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 288 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Enabled"))); 289 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Index"))); 290 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("CompareValue"))); 291 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("OriginalValue"))); 292 | 293 | Sig.bExperimental = true; 294 | Sig.bWriteFunction = true; 295 | Sig.bMemberFunction = true; 296 | Sig.bRequiresContext = false; 297 | Sig.bSupportsCPU = false; 298 | Sig.bSupportsGPU = true; 299 | 300 | OutFunctions.Add(Sig); 301 | } 302 | 303 | { 304 | FNiagaraFunctionSignature Sig = {}; 305 | Sig.Name = InterlockedCompareExchange_FuncName; 306 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 307 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Enabled"))); 308 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Index"))); 309 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("CompareValue"))); 310 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Value"))); 311 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("OriginalValue"))); 312 | 313 | Sig.bExperimental = true; 314 | Sig.bWriteFunction = true; 315 | Sig.bMemberFunction = true; 316 | Sig.bRequiresContext = false; 317 | Sig.bSupportsCPU = false; 318 | Sig.bSupportsGPU = true; 319 | 320 | OutFunctions.Add(Sig); 321 | } 322 | 323 | { 324 | FNiagaraFunctionSignature Sig = {}; 325 | Sig.Name = GetValue_FuncName; 326 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 327 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Index"))); 328 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Value"))); 329 | 330 | Sig.bExperimental = true; 331 | Sig.bWriteFunction = false; 332 | Sig.bMemberFunction = true; 333 | Sig.bRequiresContext = false; 334 | Sig.bSupportsCPU = false; 335 | Sig.bSupportsGPU = true; 336 | 337 | OutFunctions.Add(Sig); 338 | } 339 | 340 | { 341 | FNiagaraFunctionSignature Sig = {}; 342 | Sig.Name = SetValue_FuncName; 343 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("AtomicBuffer"))); 344 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Enabled"))); 345 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Index"))); 346 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetIntDef(), TEXT("Value"))); 347 | 348 | Sig.bExperimental = true; 349 | Sig.bWriteFunction = true; 350 | Sig.bMemberFunction = true; 351 | Sig.bRequiresExecPin = true; 352 | Sig.bRequiresContext = false; 353 | Sig.bSupportsCPU = false; 354 | Sig.bSupportsGPU = true; 355 | 356 | OutFunctions.Add(Sig); 357 | } 358 | } 359 | 360 | void UNiagaraDataInterfaceAtomicBuffer::GetVMExternalFunction(const FVMExternalFunctionBindingInfo& BindingInfo, void* InstanceData, FVMExternalFunction &OutFunc) 361 | { 362 | Super::GetVMExternalFunction(BindingInfo, InstanceData, OutFunc); 363 | 364 | if (BindingInfo.Name == UNiagaraDataInterfaceAtomicBuffer::SetNumElements_FuncName) 365 | { 366 | check(BindingInfo.GetNumInputs() == 2 && BindingInfo.GetNumOutputs() == 1); 367 | OutFunc = FVMExternalFunction::CreateLambda([](FVectorVMContext& Context) 368 | { 369 | VectorVM::FUserPtrHandler InstanceData(Context); 370 | VectorVM::FExternalFuncInputHandler InElementsCount(Context); 371 | VectorVM::FExternalFuncRegisterHandler OutSuccess(Context); 372 | 373 | for (int32 InstanceIdx = 0; InstanceIdx < Context.GetNumInstances(); ++InstanceIdx) 374 | { 375 | const int NewElementsCount = InElementsCount.GetAndAdvance(); 376 | const bool bSuccess = (InstanceData.Get() != nullptr && Context.GetNumInstances() == 1 && NewElementsCount > 0); 377 | *OutSuccess.GetDestAndAdvance() = bSuccess; 378 | if (bSuccess) 379 | { 380 | int32 OldElementsCount = InstanceData->NumElements; 381 | InstanceData->NumElements = NewElementsCount; 382 | InstanceData->NeedsRealloc = OldElementsCount != InstanceData->NumElements; 383 | } 384 | } 385 | }); 386 | } 387 | else if (BindingInfo.Name == UNiagaraDataInterfaceAtomicBuffer::SetResetValue_FuncName) 388 | { 389 | check(BindingInfo.GetNumInputs() == 2 && BindingInfo.GetNumOutputs() == 0); 390 | OutFunc = FVMExternalFunction::CreateLambda([](FVectorVMContext& Context) 391 | { 392 | VectorVM::FUserPtrHandler InstanceData(Context); 393 | VectorVM::FExternalFuncInputHandler InResetValue(Context); 394 | 395 | for (int32 InstanceIdx = 0; InstanceIdx < Context.GetNumInstances(); ++InstanceIdx) 396 | { 397 | InstanceData->ResetValue = InResetValue.GetAndAdvance(); 398 | } 399 | }); 400 | } 401 | } 402 | 403 | bool UNiagaraDataInterfaceAtomicBuffer::Equals(const UNiagaraDataInterface* Other) const 404 | { 405 | if (!Super::Equals(Other)) 406 | { 407 | return false; 408 | } 409 | const UNiagaraDataInterfaceAtomicBuffer* OtherTyped = CastChecked(Other); 410 | 411 | return OtherTyped->ResetValue == ResetValue && OtherTyped->ClearEveryFrame == ClearEveryFrame; 412 | } 413 | 414 | #if WITH_EDITORONLY_DATA 415 | void UNiagaraDataInterfaceAtomicBuffer::GetParameterDefinitionHLSL(const FNiagaraDataInterfaceGPUParamInfo& ParamInfo, FString& OutHLSL) 416 | { 417 | Super::GetParameterDefinitionHLSL(ParamInfo, OutHLSL); 418 | 419 | static const TCHAR* FormatDeclarations = TEXT(R"( 420 | RWBuffer RW{BufferName}; 421 | Buffer {BufferName}; 422 | int {NumElementsName}; 423 | int {ResetValueName}; 424 | )"); 425 | TMap ArgsDeclarations = 426 | { 427 | { TEXT("BufferName"), AtomicBuffer_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 428 | { TEXT("NumElementsName"), NumElements_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 429 | { TEXT("ResetValueName"), ResetValue_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 430 | }; 431 | OutHLSL += FString::Format(FormatDeclarations, ArgsDeclarations); 432 | } 433 | 434 | bool UNiagaraDataInterfaceAtomicBuffer::GetFunctionHLSL(const FNiagaraDataInterfaceGPUParamInfo& ParamInfo, const FNiagaraDataInterfaceGeneratedFunction& FunctionInfo, int FunctionInstanceIndex, FString& OutHLSL) 435 | { 436 | const bool ParentRet = Super::GetFunctionHLSL(ParamInfo, FunctionInfo, FunctionInstanceIndex, OutHLSL); 437 | if (ParentRet) 438 | { 439 | return true; 440 | } 441 | 442 | TMap ArgsBounds = 443 | { 444 | { TEXT("FunctionName"), FunctionInfo.InstanceName }, 445 | { TEXT("HLSLFunctionName"), FunctionInfo.DefinitionName.ToString()}, 446 | { TEXT("BufferName"), AtomicBuffer_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 447 | { TEXT("NumElementsName"), NumElements_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 448 | { TEXT("ResetValueName"), ResetValue_VarName + ParamInfo.DataInterfaceHLSLSymbol }, 449 | }; 450 | 451 | if (FunctionInfo.DefinitionName == InterlockedCompareExchange_FuncName) 452 | { 453 | static const TCHAR* FormatBounds = TEXT(R"( 454 | void {FunctionName}(in bool In_bEnabled, int In_Index, int In_CompareValue, int In_Value, out int Out_OriginalValue) 455 | { 456 | Out_OriginalValue = {ResetValueName}; 457 | 458 | if (In_bEnabled && (In_Index < {NumElementsName})) 459 | { 460 | {HLSLFunctionName}(RW{BufferName}[In_Index], In_CompareValue, In_Value, Out_OriginalValue); 461 | } 462 | } 463 | )"); 464 | OutHLSL += FString::Format(FormatBounds, ArgsBounds); 465 | 466 | return true; 467 | } 468 | else if (FunctionInfo.DefinitionName == GetValue_FuncName) 469 | { 470 | static const TCHAR* FormatBounds = TEXT(R"( 471 | void {FunctionName}(int In_Index, out int Out_Value) 472 | { 473 | Out_Value = {ResetValueName}; 474 | 475 | if ((In_Index < {NumElementsName})) 476 | { 477 | Out_Value = {BufferName}[In_Index]; 478 | } 479 | } 480 | )"); 481 | OutHLSL += FString::Format(FormatBounds, ArgsBounds); 482 | 483 | return true; 484 | } 485 | else if (FunctionInfo.DefinitionName == SetValue_FuncName) 486 | { 487 | static const TCHAR* FormatBounds = TEXT(R"( 488 | void {FunctionName}(in bool In_bEnabled, int In_Index, in int In_Value) 489 | { 490 | if (In_bEnabled && (In_Index < {NumElementsName})) 491 | { 492 | RW{BufferName}[In_Index] = In_Value; 493 | } 494 | } 495 | )"); 496 | OutHLSL += FString::Format(FormatBounds, ArgsBounds); 497 | 498 | return true; 499 | } 500 | else 501 | { 502 | static const TCHAR* FormatBounds = TEXT(R"( 503 | void {FunctionName}(in bool In_bEnabled, int In_Index, int In_Value, out int Out_OriginalValue) 504 | { 505 | Out_OriginalValue = {ResetValueName}; 506 | 507 | if (In_bEnabled && (In_Index < {NumElementsName})) 508 | { 509 | {HLSLFunctionName}(RW{BufferName}[In_Index], In_Value, Out_OriginalValue); 510 | } 511 | } 512 | )"); 513 | OutHLSL += FString::Format(FormatBounds, ArgsBounds); 514 | 515 | return true; 516 | } 517 | 518 | return false; 519 | } 520 | #endif 521 | 522 | void UNiagaraDataInterfaceAtomicBuffer::ProvidePerInstanceDataForRenderThread(void* DataForRenderThread, void* PerInstanceData, const FNiagaraSystemInstanceID& SystemInstance) 523 | { 524 | check(Proxy); 525 | 526 | FAtomicBufferInstanceData_GT* InstanceData = static_cast(PerInstanceData); 527 | FAtomicBufferInstanceData_GTtoRT* DataToPass = new (DataForRenderThread) FAtomicBufferInstanceData_GTtoRT; 528 | 529 | DataToPass->ResetValue = InstanceData->ResetValue; 530 | DataToPass->ClearEveryFrame = InstanceData->ClearEveryFrame; 531 | } 532 | 533 | bool UNiagaraDataInterfaceAtomicBuffer::InitPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) 534 | { 535 | FAtomicBufferInstanceData_GT* InstanceData_GT = new (PerInstanceData) FAtomicBufferInstanceData_GT(); 536 | 537 | FNiagaraDataInterfaceProxyAtomicBuffer* RT_Proxy = GetProxyAs(); 538 | 539 | InstanceData_GT->NumElements = FMath::Max(1, NumElements); 540 | InstanceData_GT->ResetValue = ResetValue; 541 | InstanceData_GT->ClearEveryFrame = ClearEveryFrame; 542 | InstanceData_GT->NeedsRealloc = false; 543 | 544 | ENQUEUE_RENDER_COMMAND(FUpdateData)( 545 | [RT_Proxy, GameThreadData=*InstanceData_GT, InstanceID = SystemInstance->GetId()](FRHICommandListImmediate& RHICmdList) 546 | { 547 | check(!RT_Proxy->SystemInstancesToProxyData.Contains(InstanceID)); 548 | FAtomicBufferInstanceData_RT* InstanceData_RT = &RT_Proxy->SystemInstancesToProxyData.Add(InstanceID); 549 | InstanceData_RT->NumElements = GameThreadData.NumElements; 550 | InstanceData_RT->ResetValue = GameThreadData.ResetValue; 551 | InstanceData_RT->ClearEveryFrame = GameThreadData.ClearEveryFrame; 552 | 553 | InstanceData_RT->ResizeBuffers(); 554 | 555 | RHICmdList.ClearUAVUint(InstanceData_RT->AtomicBuffer.UAV, FUintVector4(InstanceData_RT->ResetValue, InstanceData_RT->ResetValue, InstanceData_RT->ResetValue, InstanceData_RT->ResetValue)); 556 | }); 557 | 558 | return true; 559 | } 560 | 561 | bool UNiagaraDataInterfaceAtomicBuffer::PerInstanceTickPostSimulate(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance, float DeltaSeconds) 562 | { 563 | FAtomicBufferInstanceData_GT* InstanceData_GT = static_cast(PerInstanceData); 564 | bool bNeedsReset = false; 565 | 566 | if (InstanceData_GT->NeedsRealloc && InstanceData_GT->NumElements > 0) 567 | { 568 | InstanceData_GT->NeedsRealloc = false; 569 | 570 | FNiagaraDataInterfaceProxyAtomicBuffer* RT_Proxy = GetProxyAs(); 571 | ENQUEUE_RENDER_COMMAND(FUpdateData)( 572 | [RT_Proxy, GameThreadData = *InstanceData_GT, InstanceID = SystemInstance->GetId()](FRHICommandListImmediate& RHICmdList) 573 | { 574 | check(RT_Proxy->SystemInstancesToProxyData.Contains(InstanceID)); 575 | FAtomicBufferInstanceData_RT* InstanceData_RT = &RT_Proxy->SystemInstancesToProxyData.FindOrAdd(InstanceID); 576 | InstanceData_RT->NumElements = GameThreadData.NumElements; 577 | InstanceData_RT->ResetValue = GameThreadData.ResetValue; 578 | InstanceData_RT->ClearEveryFrame = GameThreadData.ClearEveryFrame; 579 | 580 | InstanceData_RT->ResizeBuffers(); 581 | }); 582 | } 583 | 584 | return false; 585 | } 586 | 587 | 588 | void UNiagaraDataInterfaceAtomicBuffer::DestroyPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) 589 | { 590 | FAtomicBufferInstanceData_GT* InstanceData = static_cast(PerInstanceData); 591 | InstanceData->~FAtomicBufferInstanceData_GT(); 592 | 593 | FNiagaraDataInterfaceProxyAtomicBuffer* ThisProxy = GetProxyAs(); 594 | if (!ThisProxy) 595 | { 596 | return; 597 | } 598 | 599 | ENQUEUE_RENDER_COMMAND(FNiagaraDIDestroyInstanceData) ( 600 | [ThisProxy, InstanceID = SystemInstance->GetId()](FRHICommandListImmediate& CmdList) 601 | { 602 | //check(ThisProxy->SystemInstancesToProxyData.Contains(InstanceID)); 603 | ThisProxy->SystemInstancesToProxyData.Remove(InstanceID); 604 | }); 605 | } 606 | 607 | bool UNiagaraDataInterfaceAtomicBuffer::CopyToInternal(UNiagaraDataInterface* Destination) const 608 | { 609 | if (!Super::CopyToInternal(Destination)) 610 | { 611 | return false; 612 | } 613 | 614 | UNiagaraDataInterfaceAtomicBuffer* OtherTyped = CastChecked(Destination); 615 | 616 | OtherTyped->NumElements = NumElements; 617 | OtherTyped->ResetValue = ResetValue; 618 | OtherTyped->ClearEveryFrame = ClearEveryFrame; 619 | 620 | return true; 621 | } 622 | 623 | PRAGMA_ENABLE_OPTIMIZATION 624 | 625 | #undef LOCTEXT_NAMESPACE 626 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/NiagaraInput/NiagaraDataInterfacePlayerInput.cpp: -------------------------------------------------------------------------------- 1 | #include "NiagaraInput/NiagaraDataInterfacePlayerInput.h" 2 | 3 | #include "NiagaraShader.h" 4 | #include "NiagaraSystemInstance.h" 5 | #include "NiagaraEmitterInstanceBatcher.h" 6 | 7 | #include "KeyState.h" 8 | #include "GameFramework/PlayerInput.h" 9 | 10 | #define LOCTEXT_NAMESPACE "UNiagaraDataInterfacePlayerInput" 11 | 12 | const FName UNiagaraDataInterfacePlayerInput::InputKeyNameSpecifier_VarName(TEXT("KeyName")); 13 | 14 | // function names 15 | const FName UNiagaraDataInterfacePlayerInput::GetInputAxisValue_FuncName(TEXT("GetInputAxisValue")); 16 | const FName UNiagaraDataInterfacePlayerInput::IsInputKeyDown_FuncName(TEXT("IsInputKeyDown")); 17 | const FName UNiagaraDataInterfacePlayerInput::WasInputKeyJustPressed_FuncName(TEXT("WasInputKeyJustPressed")); 18 | const FName UNiagaraDataInterfacePlayerInput::WasInputKeyJustReleased_FuncName(TEXT("WasInputKeyJustReleased")); 19 | 20 | //------------------------------------------------------------------------------------------------------------ 21 | 22 | struct FPerInstanceData_GT 23 | { 24 | TWeakObjectPtr PlayerController = nullptr; 25 | int32 PlayerControllerIndex = -1; 26 | }; 27 | 28 | int32 UNiagaraDataInterfacePlayerInput::PerInstanceDataSize() const 29 | { 30 | return sizeof(FPerInstanceData_GT); 31 | } 32 | 33 | //------------------------------------------------------------------------------------------------------------ 34 | 35 | UNiagaraDataInterfacePlayerInput::UNiagaraDataInterfacePlayerInput(FObjectInitializer const& ObjectInitializer) 36 | : Super(ObjectInitializer) 37 | { 38 | Proxy.Reset(nullptr); 39 | } 40 | 41 | void UNiagaraDataInterfacePlayerInput::PostInitProperties() 42 | { 43 | Super::PostInitProperties(); 44 | 45 | if (HasAnyFlags(RF_ClassDefaultObject)) 46 | { 47 | ENiagaraTypeRegistryFlags Flags = ENiagaraTypeRegistryFlags::AllowAnyVariable | ENiagaraTypeRegistryFlags::AllowParameter; 48 | FNiagaraTypeRegistry::Register(FNiagaraTypeDefinition(GetClass()), Flags); 49 | } 50 | } 51 | 52 | bool UNiagaraDataInterfacePlayerInput::CopyToInternal(UNiagaraDataInterface* Destination) const 53 | { 54 | if (!Super::CopyToInternal(Destination)) 55 | { 56 | return false; 57 | } 58 | 59 | UNiagaraDataInterfacePlayerInput* DstDataInterface = CastChecked(Destination); 60 | DstDataInterface->PlayerControllerIndex = PlayerControllerIndex; 61 | 62 | return true; 63 | } 64 | 65 | bool UNiagaraDataInterfacePlayerInput::Equals(const UNiagaraDataInterface* Other) const 66 | { 67 | if (!Super::Equals(Other)) 68 | { 69 | return false; 70 | } 71 | 72 | const UNiagaraDataInterfacePlayerInput* OtherDataInterface = CastChecked(Other); 73 | 74 | return OtherDataInterface->PlayerControllerIndex == PlayerControllerIndex; 75 | } 76 | 77 | ETickingGroup UNiagaraDataInterfacePlayerInput::CalculateTickGroup(const void* PerInstanceData) const 78 | { 79 | return ETickingGroup::TG_PostUpdateWork; 80 | } 81 | 82 | bool UNiagaraDataInterfacePlayerInput::InitPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) 83 | { 84 | FPerInstanceData_GT* InstanceData = new (PerInstanceData) FPerInstanceData_GT(); 85 | SystemInstancesToProxyData_GT.Emplace(SystemInstance->GetId(), InstanceData); 86 | 87 | InstanceData->PlayerController.Reset(); 88 | InstanceData->PlayerControllerIndex = -1; 89 | 90 | return true; 91 | } 92 | 93 | void UNiagaraDataInterfacePlayerInput::DestroyPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) 94 | { 95 | SystemInstancesToProxyData_GT.Remove(SystemInstance->GetId()); 96 | 97 | FPerInstanceData_GT* InstanceData = static_cast(PerInstanceData); 98 | 99 | InstanceData->~FPerInstanceData_GT(); 100 | } 101 | 102 | 103 | bool UNiagaraDataInterfacePlayerInput::PerInstanceTick(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance, float DeltaSeconds) 104 | { 105 | FPerInstanceData_GT* InstanceData = static_cast(PerInstanceData); 106 | 107 | if ((!InstanceData->PlayerController.IsValid()) || (PlayerControllerIndex != InstanceData->PlayerControllerIndex)) 108 | { 109 | UWorld* World = SystemInstance->GetWorld(); 110 | if (World && PlayerControllerIndex < World->GetNumPlayerControllers()) 111 | { 112 | int32 i = 0; 113 | for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator) 114 | { 115 | APlayerController* PlayerController = Iterator->Get(); 116 | if (i == PlayerControllerIndex && PlayerController) 117 | { 118 | InstanceData->PlayerController = PlayerController; 119 | 120 | return false; 121 | } 122 | i++; 123 | } 124 | } 125 | } 126 | 127 | return false; 128 | } 129 | 130 | void UNiagaraDataInterfacePlayerInput::GetFunctions(TArray& OutFunctions) 131 | { 132 | Super::GetFunctions(OutFunctions); 133 | 134 | auto GetDefaultFunctionSignature = [this](FName FuncName) -> FNiagaraFunctionSignature 135 | { 136 | FNiagaraFunctionSignature Sig; 137 | Sig.Name = FuncName; 138 | Sig.bMemberFunction = true; 139 | Sig.bRequiresContext = false; 140 | Sig.bSupportsCPU = true; 141 | Sig.bSupportsGPU = false; 142 | Sig.Inputs.Add(FNiagaraVariable(FNiagaraTypeDefinition(GetClass()), TEXT("PlayerInput"))); 143 | 144 | Sig.FunctionSpecifiers.Add(UNiagaraDataInterfacePlayerInput::InputKeyNameSpecifier_VarName); 145 | 146 | Sig.bExperimental = true; 147 | 148 | #if WITH_EDITORONLY_DATA 149 | Sig.ExperimentalMessage = NSLOCTEXT("Niagara", "PlayerInputDIFunctionExperimental", "This DataInterface was just a test, please don't use this at work ;)"); 150 | #endif 151 | 152 | return Sig; 153 | }; 154 | 155 | { 156 | FNiagaraFunctionSignature Sig = GetDefaultFunctionSignature(UNiagaraDataInterfacePlayerInput::GetInputAxisValue_FuncName); 157 | Sig.SetDescription(LOCTEXT("GetInputAxisValue", "Returns the analog value for the given key/button.")); 158 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetFloatDef(), TEXT("Value"))); 159 | OutFunctions.Add(Sig); 160 | } 161 | 162 | { 163 | FNiagaraFunctionSignature Sig = GetDefaultFunctionSignature(UNiagaraDataInterfacePlayerInput::IsInputKeyDown_FuncName); 164 | Sig.SetDescription(LOCTEXT("IsInputKeyDown", "Returns true if the given key/button is pressed on the input of the controller (if present).")); 165 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Value"))); 166 | OutFunctions.Add(Sig); 167 | } 168 | 169 | { 170 | FNiagaraFunctionSignature Sig = GetDefaultFunctionSignature(UNiagaraDataInterfacePlayerInput::WasInputKeyJustPressed_FuncName); 171 | Sig.SetDescription(LOCTEXT("WasInputKeyJustPressed", "Returns true if the given key/button was up last frame and down this frame.")); 172 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Value"))); 173 | OutFunctions.Add(Sig); 174 | } 175 | 176 | { 177 | FNiagaraFunctionSignature Sig = GetDefaultFunctionSignature(UNiagaraDataInterfacePlayerInput::WasInputKeyJustReleased_FuncName); 178 | Sig.SetDescription(LOCTEXT("WasInputKeyJustReleased", "Returns true if the given key/button was down last frame and up this frame.")); 179 | Sig.Outputs.Add(FNiagaraVariable(FNiagaraTypeDefinition::GetBoolDef(), TEXT("Value"))); 180 | OutFunctions.Add(Sig); 181 | } 182 | } 183 | 184 | void UNiagaraDataInterfacePlayerInput::GetVMExternalFunction(const FVMExternalFunctionBindingInfo& BindingInfo, void* InstanceData, FVMExternalFunction &OutFunc) 185 | { 186 | Super::GetVMExternalFunction(BindingInfo, InstanceData, OutFunc); 187 | 188 | if (BindingInfo.Name == UNiagaraDataInterfacePlayerInput::GetInputAxisValue_FuncName) 189 | { 190 | const FName InputKeyName = BindingInfo.FindSpecifier(UNiagaraDataInterfacePlayerInput::InputKeyNameSpecifier_VarName)->Value; 191 | const FKey InputKey = FKey(InputKeyName); 192 | 193 | check(BindingInfo.GetNumInputs() == 1 && BindingInfo.GetNumOutputs() == 1); 194 | OutFunc = FVMExternalFunction::CreateLambda([InputKey](FVectorVMContext& Context) 195 | { 196 | VectorVM::FUserPtrHandler InstanceData(Context); 197 | FNDIOutputParam OutValues(Context); 198 | 199 | // this is same for all the instances/threads 200 | float Value = 0.f; 201 | if (APlayerController* PlayerController = InstanceData->PlayerController.Get()) 202 | { 203 | Value = PlayerController->GetInputAnalogKeyState(InputKey); 204 | } 205 | 206 | for (int32 InstanceIdx = 0; InstanceIdx < Context.NumInstances; ++InstanceIdx) 207 | { 208 | OutValues.SetAndAdvance(Value); 209 | } 210 | }); 211 | } 212 | else //boolean functions 213 | { 214 | using GetKeyStateBoolFunc = bool(APlayerController::*)(FKey) const; 215 | GetKeyStateBoolFunc Func = nullptr; 216 | 217 | if (BindingInfo.Name == UNiagaraDataInterfacePlayerInput::IsInputKeyDown_FuncName) 218 | { 219 | check(BindingInfo.GetNumInputs() == 1 && BindingInfo.GetNumOutputs() == 1); 220 | Func = &APlayerController::IsInputKeyDown; 221 | } 222 | else if (BindingInfo.Name == UNiagaraDataInterfacePlayerInput::WasInputKeyJustPressed_FuncName) 223 | { 224 | check(BindingInfo.GetNumInputs() == 1 && BindingInfo.GetNumOutputs() == 1); 225 | Func = &APlayerController::WasInputKeyJustPressed; 226 | } 227 | else if (BindingInfo.Name == UNiagaraDataInterfacePlayerInput::WasInputKeyJustReleased_FuncName) 228 | { 229 | check(BindingInfo.GetNumInputs() == 1 && BindingInfo.GetNumOutputs() == 1); 230 | Func = &APlayerController::WasInputKeyJustReleased; 231 | } 232 | 233 | if (Func) 234 | { 235 | const FName InputKeyName = BindingInfo.FindSpecifier(UNiagaraDataInterfacePlayerInput::InputKeyNameSpecifier_VarName)->Value; 236 | const FKey InputKey = FKey(InputKeyName); 237 | 238 | OutFunc = FVMExternalFunction::CreateLambda([InputKey, Func](FVectorVMContext& Context) 239 | { 240 | VectorVM::FUserPtrHandler InstanceData(Context); 241 | FNDIOutputParam OutValues(Context); 242 | 243 | // this is same for all the instances/threads 244 | bool Value = false; 245 | if (APlayerController* PlayerController = InstanceData->PlayerController.Get()) 246 | { 247 | Value = (PlayerController->*Func)(InputKey); 248 | } 249 | 250 | for (int32 InstanceIdx = 0; InstanceIdx < Context.NumInstances; ++InstanceIdx) 251 | { 252 | OutValues.SetAndAdvance(Value); 253 | } 254 | }); 255 | } 256 | } 257 | } 258 | 259 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/ProceduralMesh/ComputeShaderProceduralMeshActor.cpp: -------------------------------------------------------------------------------- 1 | #include "ProceduralMesh/ComputeShaderProceduralMeshActor.h" 2 | 3 | #include "ProceduralMesh/ComputeShaderProceduralMeshComponent.h" 4 | #include "ProceduralMesh/ComputeShaderProceduralMeshProxy.h" 5 | 6 | AComputeShaderProceduralMeshActor::AComputeShaderProceduralMeshActor() 7 | { 8 | PrimaryActorTick.bCanEverTick = true; 9 | 10 | ProceduralMeshComponent = CreateDefaultSubobject(TEXT("ProceduralMeshComponent")); 11 | 12 | #if WITH_EDITOR 13 | ProceduralMeshComponent->OnCreatedSceneProxy.BindUObject(this, &AComputeShaderProceduralMeshActor::OnCreatedSceneProxy); 14 | #endif 15 | } 16 | 17 | #if WITH_EDITOR 18 | void AComputeShaderProceduralMeshActor::OnCreatedSceneProxy(FCSProceduralMeshSceneProxy* SceneProxy) 19 | { 20 | if (SceneProxy) 21 | { 22 | SceneProxy->OnCreatedRendererResources.BindUObject(this, &AComputeShaderProceduralMeshActor::OnCreatedSceneProxyRendererResources); 23 | } 24 | } 25 | #endif 26 | 27 | void AComputeShaderProceduralMeshActor::BeginPlay() 28 | { 29 | // When playing with NonEditor config SceneProxy is not created in a conventional way so the OnCreatedSceneProxy callback is never called 30 | // for such cases we need to manually call this in BeginPlay 31 | FWorldContext* WorldContext = GEngine->GetWorldContextFromWorld(GetWorld()); 32 | if (WorldContext && WorldContext->WorldType != EWorldType::PIE) 33 | { 34 | ENQUEUE_RENDER_COMMAND(MarchingCubesProceduralMeshActor_DestroyResources)( 35 | [this](FRHICommandListImmediate& RHICmdList) 36 | { 37 | OnCreatedSceneProxyRendererResources((FCSProceduralMeshSceneProxy*)ProceduralMeshComponent->SceneProxy); 38 | }); 39 | } 40 | 41 | Super::BeginPlay(); 42 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/ProceduralMesh/ComputeShaderProceduralMeshComponent.cpp: -------------------------------------------------------------------------------- 1 | #include "ProceduralMesh/ComputeShaderProceduralMeshComponent.h" 2 | #include "Engine/CollisionProfile.h" 3 | 4 | UComputeShaderProceduralMeshComponent::UComputeShaderProceduralMeshComponent(const FObjectInitializer& ObjectInitializer) 5 | : Super(ObjectInitializer) 6 | { 7 | SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); 8 | } 9 | 10 | #if WITH_EDITOR 11 | void UComputeShaderProceduralMeshComponent::CreateRenderState_Concurrent(FRegisterComponentContext* Context) 12 | { 13 | Super::CreateRenderState_Concurrent(Context); 14 | 15 | OnCreatedSceneProxy.ExecuteIfBound((FCSProceduralMeshSceneProxy*)SceneProxy); 16 | } 17 | #endif 18 | 19 | FBoxSphereBounds UComputeShaderProceduralMeshComponent::CalcBounds(const FTransform& LocalToWorld) const 20 | { 21 | const FVector ScaledBounds = FixedLocalBounds * LocalToWorld.GetScale3D() * 0.5f; 22 | return FBoxSphereBounds(LocalToWorld.GetLocation(), ScaledBounds, ScaledBounds.Size()); 23 | } 24 | 25 | UMaterialInterface* UComputeShaderProceduralMeshComponent::GetMaterial(int32 Index) const 26 | { 27 | return Material; 28 | } 29 | 30 | void UComputeShaderProceduralMeshComponent::SetMaterial(int32 ElementIndex, class UMaterialInterface* InMaterial) 31 | { 32 | Material = InMaterial; 33 | 34 | MarkRenderStateDirty(); 35 | } 36 | 37 | void UComputeShaderProceduralMeshComponent::GetUsedMaterials(TArray& OutMaterials, bool bGetDebugMaterials) const 38 | { 39 | if (Material) 40 | { 41 | OutMaterials.AddUnique(Material); 42 | } 43 | } 44 | 45 | void UComputeShaderProceduralMeshComponent::SetMaxPrimitiveCount(int32 PrimitiveCount) 46 | { 47 | MaxPrimitives = FMath::Max(0, PrimitiveCount); 48 | 49 | MarkRenderStateDirty(); 50 | } 51 | 52 | #if WITH_EDITOR 53 | void UComputeShaderProceduralMeshComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) 54 | { 55 | bool bRecreateRenderState = false; 56 | 57 | if (PropertyChangedEvent.Property != nullptr) 58 | { 59 | const FName PropertyName(PropertyChangedEvent.Property->GetFName()); 60 | if (PropertyName == GET_MEMBER_NAME_CHECKED(UComputeShaderProceduralMeshComponent, Material)) 61 | { 62 | bRecreateRenderState = true; 63 | } 64 | else if (PropertyName == GET_MEMBER_NAME_CHECKED(UComputeShaderProceduralMeshComponent, MaxPrimitives)) 65 | { 66 | bRecreateRenderState = true; 67 | } 68 | } 69 | 70 | if (bRecreateRenderState) 71 | { 72 | MarkRenderStateDirty(); 73 | } 74 | 75 | Super::PostEditChangeProperty(PropertyChangedEvent); 76 | } 77 | #endif -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/ProceduralMesh/ComputeShaderProceduralMeshProxy.cpp: -------------------------------------------------------------------------------- 1 | #include "ProceduralMesh/ComputeShaderProceduralMeshProxy.h" 2 | #include "RenderResource.h" 3 | #include "PrimitiveViewRelevance.h" 4 | #include "Materials/MaterialInterface.h" 5 | #include "ProceduralMesh/ComputeShaderProceduralMeshComponent.h" 6 | 7 | FCSProceduralMeshSceneProxy::FCSProceduralMeshSceneProxy(const UComputeShaderProceduralMeshComponent* InComponent) 8 | : FPrimitiveSceneProxy(InComponent) 9 | , RenderMaterial(InComponent->GetMaterial(0)) 10 | , VertexFactory(GetScene().GetFeatureLevel(), "FCSProceduralMeshSceneProxy") 11 | , MaxPrimitiveCount(InComponent->GetMaxPrimitiveCount()) 12 | { 13 | checkf(RenderMaterial, TEXT("Material can not be null")); 14 | MaterialRelevance = RenderMaterial->GetRelevance_Concurrent(GetScene().GetFeatureLevel()); 15 | } 16 | 17 | FCSProceduralMeshSceneProxy::~FCSProceduralMeshSceneProxy() 18 | { 19 | } 20 | 21 | void FCSProceduralMeshSceneProxy::CreateRenderThreadResources() 22 | { 23 | // initialize buffers used by Graphics and Compute shaders 24 | const uint32 VertexCount = MaxPrimitiveCount * 3; 25 | PositionBuffer.Initialize(sizeof(float), 3 * VertexCount, PF_R32_FLOAT, BUF_Static, TEXT("PositionBuffer")); 26 | TangentBuffer.Initialize(sizeof(FPackedNormal), 2 * VertexCount, PF_R8G8B8A8_SNORM, BUF_Static, TEXT("TangentBuffer")); 27 | TexCoordBuffer.Initialize(sizeof(FVector2D), VertexCount, PF_G32R32F, BUF_Static, TEXT("TexCoordBuffer")); 28 | ColorBuffer.Initialize(sizeof(FColor), VertexCount, PF_R8G8B8A8, BUF_Static, TEXT("ColorBuffer")); 29 | IndirectDrawArgs.Initialize(sizeof(uint32), sizeof(FRHIDrawIndirectParameters) / sizeof(uint32), PF_R32_UINT, BUF_DrawIndirect | BUF_Static, TEXT("IndirectDrawArgs")); 30 | 31 | // make sure to reset this so that we don't use garbage data 32 | if (FRHIDrawIndirectParameters* ArgParams = (FRHIDrawIndirectParameters*)RHILockVertexBuffer(IndirectDrawArgs.VertexBufferRHI, 0, sizeof(FRHIDrawIndirectParameters), RLM_WriteOnly)) 33 | { 34 | ArgParams->VertexCountPerInstance = 0; 35 | ArgParams->InstanceCount = 0; 36 | ArgParams->StartVertexLocation = 0; 37 | ArgParams->StartInstanceLocation = 0; 38 | 39 | RHIUnlockVertexBuffer(IndirectDrawArgs.VertexBufferRHI); 40 | } 41 | 42 | // this is analogous to D3D12_INPUT_ELEMENT_DESC (https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_input_element_desc) 43 | // tells the InputAssembler how to load vertex attributes 44 | FLocalVertexFactory::FDataType Data; 45 | 46 | // Position stream 47 | Data.PositionComponent = FVertexStreamComponent( 48 | &PositionBuffer, 49 | 0, 50 | PositionStride, 51 | VET_Float3 52 | ); 53 | 54 | // Tangent stream 55 | Data.TangentBasisComponents[0] = FVertexStreamComponent( 56 | &TangentBuffer, 57 | 0, 58 | TangentStride, 59 | VET_PackedNormal 60 | ); 61 | 62 | // Normal stream 63 | Data.TangentBasisComponents[1] = FVertexStreamComponent( 64 | &TangentBuffer, 65 | TangentStride / 2, 66 | TangentStride, 67 | VET_PackedNormal 68 | ); 69 | 70 | // TexCoord stream, using only one channel 71 | Data.TextureCoordinates.Add(FVertexStreamComponent( 72 | &TexCoordBuffer, 73 | 0, 74 | TexCoordStride, 75 | VET_Float2 76 | )); 77 | 78 | // Color stream 79 | Data.ColorComponent = FVertexStreamComponent( 80 | &ColorBuffer, 81 | 0, 82 | ColorStride, 83 | VET_Color 84 | ); 85 | 86 | // set Buffer pointers 87 | Data.PositionComponentSRV = PositionBuffer.SRV; 88 | Data.TangentsSRV = TangentBuffer.SRV; 89 | Data.TextureCoordinatesSRV = TexCoordBuffer.SRV; 90 | Data.ColorComponentsSRV = ColorBuffer.SRV; 91 | 92 | // not using 93 | Data.LightMapCoordinateIndex = -1; 94 | Data.LightMapCoordinateComponent = {}; 95 | Data.LODLightmapDataIndex = 0; 96 | 97 | Data.NumTexCoords = 1; 98 | Data.ColorIndexMask = ~0u; 99 | 100 | // initialize vertex factory 101 | VertexFactory.SetData(Data); 102 | VertexFactory.InitResource(); 103 | 104 | #if WITH_EDITOR 105 | OnCreatedRendererResources.ExecuteIfBound(this); 106 | #endif 107 | } 108 | 109 | void FCSProceduralMeshSceneProxy::DestroyRenderThreadResources() 110 | { 111 | FPrimitiveSceneProxy::DestroyRenderThreadResources(); 112 | 113 | VertexFactory.ReleaseResource(); 114 | 115 | PositionBuffer.Release(); 116 | TangentBuffer.Release(); 117 | TexCoordBuffer.Release(); 118 | ColorBuffer.Release(); 119 | IndirectDrawArgs.Release(); 120 | } 121 | 122 | void FCSProceduralMeshSceneProxy::GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const 123 | { 124 | QUICK_SCOPE_CYCLE_COUNTER( STAT_ProceduralMeshSceneProxy_GetDynamicMeshElements ); 125 | 126 | for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) 127 | { 128 | if (VisibilityMap & (1 << ViewIndex)) 129 | { 130 | const FSceneView* View = Views[ViewIndex]; 131 | 132 | // Set up the FMeshElement. 133 | FMeshBatch& Mesh = Collector.AllocateMesh(); 134 | 135 | Mesh.VertexFactory = &VertexFactory; 136 | Mesh.MaterialRenderProxy = RenderMaterial->GetRenderProxy(); 137 | Mesh.LCI = NULL; 138 | Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); 139 | Mesh.CastShadow = true; 140 | Mesh.DepthPriorityGroup = (ESceneDepthPriorityGroup)GetDepthPriorityGroup(View); 141 | Mesh.Type = PT_TriangleList; 142 | Mesh.bDisableBackfaceCulling = false; 143 | 144 | // Set up the FMeshBatchElement. 145 | FMeshBatchElement& BatchElement = Mesh.Elements[0]; 146 | BatchElement.FirstIndex = 0; 147 | BatchElement.MinVertexIndex = 0; 148 | BatchElement.MaxVertexIndex = (PositionBuffer.NumBytes / sizeof(FVector)) - 1; 149 | BatchElement.BaseVertexIndex = 0; 150 | BatchElement.IndexBuffer = nullptr; //not using index buffer 151 | 152 | // setup required to use IndirectDraw (NumPrimitives=0 + Set IndirectArg parameters) 153 | BatchElement.NumPrimitives = 0; 154 | BatchElement.IndirectArgsOffset = 0; 155 | BatchElement.IndirectArgsBuffer = IndirectDrawArgs.VertexBufferRHI; 156 | 157 | // for debug 158 | Mesh.bCanApplyViewModeOverrides = true; 159 | Mesh.bUseWireframeSelectionColoring = IsSelected(); 160 | 161 | Collector.AddMesh(ViewIndex, Mesh); 162 | 163 | #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) 164 | RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); 165 | #endif 166 | } 167 | } 168 | } 169 | 170 | FPrimitiveSceneProxy* UComputeShaderProceduralMeshComponent::CreateSceneProxy() 171 | { 172 | checkf(GRHISupportsDrawIndirect, TEXT("GPU doesn't support DrawIndirect :(")); 173 | 174 | if (GRHISupportsDrawIndirect && Material && MaxPrimitives > 0) 175 | { 176 | return new FCSProceduralMeshSceneProxy(this); 177 | } 178 | 179 | return nullptr; 180 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Private/ProceduralMesh/MarchingCubeShaders/MarchingCubeShaders.cpp: -------------------------------------------------------------------------------- 1 | #include "ProceduralMesh/MarchingCubeShaders/MarchingCubeShaders.h" 2 | 3 | IMPLEMENT_GLOBAL_SHADER(FResetIndirectArgsCS, "/Plugin/GraphicsPlugin/MarchingCubes/ResetIndirectDraw.usf", "Main", SF_Compute); 4 | IMPLEMENT_GLOBAL_SHADER(FGenerateTrianglesCS, "/Plugin/GraphicsPlugin/MarchingCubes/GenerateTriangles.usf", "Main", SF_Compute); -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ClearTextureShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shader.h" 4 | #include "GlobalShader.h" 5 | #include "ShaderParameters.h" 6 | #include "ShaderPermutation.h" 7 | #include "ShaderParameterStruct.h" 8 | 9 | // GlobalShader has only one instance active in the application, refer Engine/Source/Runtime/RenderCore/Public/GlobalShader.h for more details 10 | class GRAPHICSPLUGIN_API FClearTextureCS : public FGlobalShader 11 | { 12 | DECLARE_GLOBAL_SHADER(FClearTextureCS) 13 | 14 | // used to pass parameters to shader (much better than legacy code, kindof means we need to use RenderGraph) 15 | SHADER_USE_PARAMETER_STRUCT(FClearTextureCS, FGlobalShader) 16 | 17 | // Permutations are used to enable/disable shader code at compile time 18 | class FUseAnimation : SHADER_PERMUTATION_BOOL("USE_ANIMATION"); 19 | class FUseTexture : SHADER_PERMUTATION_BOOL("USE_TEXTURE"); 20 | using FPermutationDomain = TShaderPermutationDomain; 21 | 22 | /** 23 | * Mirror variables defined in shader 24 | * You can expect this error if the variables don't match b/w code and shader 25 | * "Shader FClearTextureCS, permutation 0 has unbound parameters not represented in the parameter struct: {VAR_NAME}" 26 | */ 27 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 28 | SHADER_PARAMETER_UAV(RWTexture, OutputTexture) 29 | SHADER_PARAMETER_SRV(Texture2D, SourceTexture) 30 | SHADER_PARAMETER_SAMPLER(SamplerState, SourceSampler) 31 | SHADER_PARAMETER(FVector4, ClearColor) 32 | SHADER_PARAMETER(FVector4, TextureDimensions) 33 | SHADER_PARAMETER(float, AnimationTime) 34 | END_SHADER_PARAMETER_STRUCT() 35 | 36 | public: 37 | // we can override this to check if we can compile this shader 38 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 39 | { 40 | return RHISupportsComputeShaders(Parameters.Platform); 41 | } 42 | 43 | // this is useful if we want to set additional arguments 44 | static inline void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 45 | { 46 | FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); 47 | 48 | // for example we can add this flag to enable Wave Ops 49 | // needs #include "ShaderCompilerCore.h" 50 | //OutEnvironment.CompilerFlags.Add(CFLAG_WaveOperations); 51 | 52 | // or set ThreadGroupSize instead of hard coding inside shader 53 | // make sure numthreads in shader are using these instead of hardcoded values 54 | //OutEnvironment.SetDefine(TEXT("THREADGROUPSIZE_X"), 8); 55 | //OutEnvironment.SetDefine(TEXT("THREADGROUPSIZE_Y"), 8); 56 | } 57 | 58 | public: 59 | // alternatively we can set ThreadGroupSize through ModifyCompilationEnvironment 60 | static constexpr int32 ThreadGroupSizeX = 8; 61 | static constexpr int32 ThreadGroupSizeY = 8; 62 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/NiagaraDataInterfaces/NiagaraDataInterfaceAtomicBuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "NiagaraDataInterfaceRW.h" 5 | #include "NiagaraCommon.h" 6 | 7 | #include "NiagaraDataInterfaceAtomicBuffer.generated.h" 8 | 9 | class FNiagaraSystemInstance; 10 | 11 | UCLASS(EditInlineNew, Category = "Buffer", meta = (DisplayName = "Atomic Buffer")) 12 | class GRAPHICSPLUGIN_API UNiagaraDataInterfaceAtomicBuffer : public UNiagaraDataInterfaceRWBase 13 | { 14 | GENERATED_UCLASS_BODY() 15 | 16 | public: 17 | 18 | DECLARE_NIAGARA_DI_PARAMETER(); 19 | 20 | virtual void PostInitProperties() override 21 | { 22 | Super::PostInitProperties(); 23 | 24 | //Can we register data interfaces as regular types and fold them into the FNiagaraVariable framework for UI and function calls etc? 25 | if (HasAnyFlags(RF_ClassDefaultObject)) 26 | { 27 | ENiagaraTypeRegistryFlags Flags = ENiagaraTypeRegistryFlags::AllowAnyVariable | ENiagaraTypeRegistryFlags::AllowParameter; 28 | FNiagaraTypeRegistry::Register(FNiagaraTypeDefinition(GetClass()), Flags); 29 | } 30 | } 31 | 32 | //~ UNiagaraDataInterface interface 33 | // VM functionality 34 | virtual void GetFunctions(TArray& OutFunctions) override; 35 | virtual void GetVMExternalFunction(const FVMExternalFunctionBindingInfo& BindingInfo, void* InstanceData, FVMExternalFunction &OutFunc) override; 36 | 37 | virtual bool Equals(const UNiagaraDataInterface* Other) const override; 38 | 39 | // GPU sim functionality 40 | #if WITH_EDITORONLY_DATA 41 | virtual void GetParameterDefinitionHLSL(const FNiagaraDataInterfaceGPUParamInfo& ParamInfo, FString& OutHLSL) override; 42 | virtual bool GetFunctionHLSL(const FNiagaraDataInterfaceGPUParamInfo& ParamInfo, const FNiagaraDataInterfaceGeneratedFunction& FunctionInfo, int FunctionInstanceIndex, FString& OutHLSL) override; 43 | #endif 44 | 45 | virtual void ProvidePerInstanceDataForRenderThread(void* DataForRenderThread, void* PerInstanceData, const FNiagaraSystemInstanceID& SystemInstance) override; 46 | virtual bool InitPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) override; 47 | virtual void DestroyPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) override; 48 | virtual bool PerInstanceTick(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance, float DeltaSeconds) override { return false; } 49 | virtual int32 PerInstanceDataSize() const override; 50 | virtual bool PerInstanceTickPostSimulate(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance, float DeltaSeconds) override; 51 | virtual bool HasPostSimulateTick() const override { return true; } 52 | virtual bool HasPreSimulateTick() const override { return true; } 53 | //~ UNiagaraDataInterface interface END 54 | 55 | protected: 56 | virtual bool CopyToInternal(UNiagaraDataInterface* Destination) const override; 57 | 58 | public: 59 | UPROPERTY(EditAnywhere) 60 | int32 NumElements = 0; 61 | 62 | UPROPERTY(EditAnywhere) 63 | int32 ResetValue = 0; 64 | 65 | UPROPERTY(EditAnywhere) 66 | bool ClearEveryFrame = true; 67 | 68 | public: 69 | // variable names 70 | static const FString NumElements_VarName; 71 | static const FString ResetValue_VarName; 72 | static const FString AtomicBuffer_VarName; 73 | 74 | // function names 75 | static const FName SetNumElements_FuncName; 76 | static const FName SetResetValue_FuncName; 77 | static const FName SetClearEveryFrame_FuncName; 78 | 79 | static const FName InterlockedAdd_FuncName; 80 | static const FName InterlockedMin_FuncName; 81 | static const FName InterlockedMax_FuncName; 82 | static const FName InterlockedOr_FuncName; 83 | static const FName InterlockedAnd_FuncName; 84 | static const FName InterlockedXor_FuncName; 85 | static const FName InterlockedCompareStore_FuncName; 86 | static const FName InterlockedCompareExchange_FuncName; 87 | static const FName InterlockedExchange_FuncName; 88 | static const FName GetValue_FuncName; 89 | static const FName SetValue_FuncName; 90 | }; 91 | 92 | 93 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/NiagaraInput/NiagaraDataInterfacePlayerInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NiagaraDataInterface.h" 4 | #include "NiagaraCommon.h" 5 | #include "VectorVM.h" 6 | #include "NiagaraDataInterfacePlayerInput.generated.h" 7 | 8 | struct FPerInstanceData_GT; 9 | 10 | //------------------------------------------------------------------------------------------------------------ 11 | 12 | /** Data Interface for querying Player Input */ 13 | UCLASS(EditInlineNew, Category = "PlayerInput", meta = (DisplayName = "PlayerInput"), Blueprintable, BlueprintType) 14 | class UNiagaraDataInterfacePlayerInput : public UNiagaraDataInterface 15 | { 16 | GENERATED_UCLASS_BODY() 17 | 18 | public: 19 | //UObject Interface 20 | virtual void PostInitProperties() override; 21 | //UObject Interface End 22 | 23 | virtual bool CanExecuteOnTarget(ENiagaraSimTarget Target) const override { return Target == ENiagaraSimTarget::CPUSim; } 24 | virtual bool Equals(const UNiagaraDataInterface* Other) const override; 25 | 26 | virtual void GetFunctions(TArray& OutFunctions) override; 27 | 28 | // VM functions 29 | virtual void GetVMExternalFunction(const FVMExternalFunctionBindingInfo& BindingInfo, void* InstanceData, FVMExternalFunction& OutFunc) override; 30 | 31 | virtual void ProvidePerInstanceDataForRenderThread(void* DataForRenderThread, void* PerInstanceData, const FNiagaraSystemInstanceID& SystemInstance) override {} 32 | virtual bool InitPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) override; 33 | virtual void DestroyPerInstanceData(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance) override; 34 | virtual bool PerInstanceTick(void* PerInstanceData, FNiagaraSystemInstance* SystemInstance, float DeltaSeconds) override; 35 | virtual int32 PerInstanceDataSize() const override; 36 | virtual bool HasPreSimulateTick() const override { return true; } 37 | 38 | virtual bool HasTickGroupPrereqs() const override { return true; } 39 | virtual ETickingGroup CalculateTickGroup(const void* PerInstanceData) const override; 40 | 41 | protected: 42 | virtual bool CopyToInternal(UNiagaraDataInterface* Destination) const override; 43 | 44 | protected: 45 | TMap SystemInstancesToProxyData_GT; 46 | 47 | UPROPERTY(EditAnywhere) 48 | int32 PlayerControllerIndex = 0; 49 | 50 | private: 51 | static const FName InputKeyNameSpecifier_VarName; 52 | 53 | // function names 54 | static const FName GetInputAxisValue_FuncName; 55 | static const FName IsInputKeyDown_FuncName; 56 | static const FName WasInputKeyJustPressed_FuncName; 57 | static const FName WasInputKeyJustReleased_FuncName; 58 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ProceduralMesh/ComputeFriendlyBuffers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RHI.h" 4 | 5 | struct FRWVertexBuffer : public FVertexBuffer 6 | { 7 | FUnorderedAccessViewRHIRef UAV; 8 | FShaderResourceViewRHIRef SRV; 9 | uint32 NumBytes; 10 | 11 | FRWVertexBuffer() 12 | : NumBytes(0) 13 | {} 14 | 15 | FRWVertexBuffer(FRWVertexBuffer&& Other) 16 | : UAV(MoveTemp(Other.UAV)) 17 | , SRV(MoveTemp(Other.SRV)) 18 | , NumBytes(Other.NumBytes) 19 | { 20 | VertexBufferRHI = MoveTemp(Other.VertexBufferRHI); 21 | Other.NumBytes = 0; 22 | } 23 | 24 | FRWVertexBuffer(const FRWVertexBuffer& Other) 25 | : UAV(Other.UAV) 26 | , SRV(Other.SRV) 27 | , NumBytes(Other.NumBytes) 28 | { 29 | VertexBufferRHI = Other.VertexBufferRHI; 30 | } 31 | 32 | FRWVertexBuffer& operator=(FRWVertexBuffer&& Other) 33 | { 34 | VertexBufferRHI = MoveTemp(Other.VertexBufferRHI); 35 | UAV = MoveTemp(Other.UAV); 36 | SRV = MoveTemp(Other.SRV); 37 | NumBytes = Other.NumBytes; 38 | Other.NumBytes = 0; 39 | 40 | return *this; 41 | } 42 | 43 | FRWVertexBuffer& operator=(const FRWVertexBuffer& Other) 44 | { 45 | VertexBufferRHI = Other.VertexBufferRHI; 46 | UAV = Other.UAV; 47 | SRV = Other.SRV; 48 | NumBytes = Other.NumBytes; 49 | 50 | return *this; 51 | } 52 | 53 | ~FRWVertexBuffer() 54 | { 55 | Release(); 56 | } 57 | 58 | // @param AdditionalUsage passed down to RHICreateVertexBuffer(), get combined with "BUF_UnorderedAccess | BUF_ShaderResource" e.g. BUF_Static 59 | void Initialize(uint32 BytesPerElement, uint32 NumElements, EPixelFormat Format, ERHIAccess InResourceState, uint32 AdditionalUsage = 0, const TCHAR* InDebugName = NULL, FResourceArrayInterface *InResourceArray = nullptr) 60 | { 61 | check(GMaxRHIFeatureLevel == ERHIFeatureLevel::SM5 62 | || IsVulkanPlatform(GMaxRHIShaderPlatform) 63 | || IsMetalPlatform(GMaxRHIShaderPlatform) 64 | || (GMaxRHIFeatureLevel == ERHIFeatureLevel::ES3_1 && GSupportsResourceView) 65 | ); 66 | 67 | InitResource(); 68 | 69 | // Provide a debug name if using Fast VRAM so the allocators diagnostics will work 70 | ensure(!((AdditionalUsage & BUF_FastVRAM) && !InDebugName)); 71 | NumBytes = BytesPerElement * NumElements; 72 | FRHIResourceCreateInfo CreateInfo; 73 | CreateInfo.ResourceArray = InResourceArray; 74 | CreateInfo.DebugName = InDebugName; 75 | VertexBufferRHI = RHICreateVertexBuffer(NumBytes, BUF_UnorderedAccess | BUF_ShaderResource | AdditionalUsage, InResourceState, CreateInfo); 76 | UAV = RHICreateUnorderedAccessView(VertexBufferRHI, Format); 77 | SRV = RHICreateShaderResourceView(VertexBufferRHI, BytesPerElement, Format); 78 | } 79 | 80 | void Initialize(uint32 BytesPerElement, uint32 NumElements, EPixelFormat Format, uint32 AdditionalUsage = 0, const TCHAR* InDebugName = NULL, FResourceArrayInterface* InResourceArray = nullptr) 81 | { 82 | Initialize(BytesPerElement, NumElements, Format, ERHIAccess::UAVCompute, AdditionalUsage, InDebugName, InResourceArray); 83 | } 84 | 85 | void AcquireTransientResource() 86 | { 87 | RHIAcquireTransientResource(VertexBufferRHI); 88 | } 89 | void DiscardTransientResource() 90 | { 91 | RHIDiscardTransientResource(VertexBufferRHI); 92 | } 93 | 94 | void Release() 95 | { 96 | int32 BufferRefCount = VertexBufferRHI ? VertexBufferRHI->GetRefCount() : -1; 97 | 98 | if (BufferRefCount == 1) 99 | { 100 | DiscardTransientResource(); 101 | } 102 | 103 | NumBytes = 0; 104 | ReleaseRHI(); 105 | UAV.SafeRelease(); 106 | SRV.SafeRelease(); 107 | 108 | ReleaseResource(); 109 | } 110 | }; 111 | 112 | struct FRWIndexBuffer : public FIndexBuffer 113 | { 114 | FUnorderedAccessViewRHIRef UAV; 115 | FShaderResourceViewRHIRef SRV; 116 | uint32 NumBytes; 117 | 118 | FRWIndexBuffer() 119 | : NumBytes(0) 120 | {} 121 | 122 | FRWIndexBuffer(FRWIndexBuffer&& Other) 123 | : UAV(MoveTemp(Other.UAV)) 124 | , SRV(MoveTemp(Other.SRV)) 125 | , NumBytes(Other.NumBytes) 126 | { 127 | IndexBufferRHI = MoveTemp(Other.IndexBufferRHI); 128 | Other.NumBytes = 0; 129 | } 130 | 131 | FRWIndexBuffer(const FRWIndexBuffer& Other) 132 | : UAV(Other.UAV) 133 | , SRV(Other.SRV) 134 | , NumBytes(Other.NumBytes) 135 | { 136 | IndexBufferRHI = Other.IndexBufferRHI; 137 | } 138 | 139 | FRWIndexBuffer& operator=(FRWIndexBuffer&& Other) 140 | { 141 | IndexBufferRHI = MoveTemp(Other.IndexBufferRHI); 142 | UAV = MoveTemp(Other.UAV); 143 | SRV = MoveTemp(Other.SRV); 144 | NumBytes = Other.NumBytes; 145 | Other.NumBytes = 0; 146 | 147 | return *this; 148 | } 149 | 150 | FRWIndexBuffer& operator=(const FRWIndexBuffer& Other) 151 | { 152 | IndexBufferRHI = Other.IndexBufferRHI; 153 | UAV = Other.UAV; 154 | SRV = Other.SRV; 155 | NumBytes = Other.NumBytes; 156 | 157 | return *this; 158 | } 159 | 160 | ~FRWIndexBuffer() 161 | { 162 | Release(); 163 | } 164 | 165 | // @param AdditionalUsage passed down to RHICreateVertexBuffer(), get combined with "BUF_UnorderedAccess | BUF_ShaderResource" e.g. BUF_Static 166 | void Initialize(uint32 Stride, uint32 NumElements, EPixelFormat Format, ERHIAccess InResourceState, uint32 AdditionalUsage = 0, const TCHAR* InDebugName = NULL, FResourceArrayInterface *InResourceArray = nullptr) 167 | { 168 | check(GMaxRHIFeatureLevel == ERHIFeatureLevel::SM5 169 | || IsVulkanPlatform(GMaxRHIShaderPlatform) 170 | || IsMetalPlatform(GMaxRHIShaderPlatform) 171 | || (GMaxRHIFeatureLevel == ERHIFeatureLevel::ES3_1 && GSupportsResourceView) 172 | ); 173 | 174 | InitResource(); 175 | 176 | // Provide a debug name if using Fast VRAM so the allocators diagnostics will work 177 | ensure(!((AdditionalUsage & BUF_FastVRAM) && !InDebugName)); 178 | NumBytes = Stride * NumElements; 179 | FRHIResourceCreateInfo CreateInfo; 180 | CreateInfo.ResourceArray = InResourceArray; 181 | CreateInfo.DebugName = InDebugName; 182 | IndexBufferRHI = RHICreateIndexBuffer(Stride, NumBytes, BUF_UnorderedAccess | BUF_ShaderResource | AdditionalUsage, CreateInfo); 183 | UAV = RHICreateUnorderedAccessView(IndexBufferRHI, Format); 184 | SRV = RHICreateShaderResourceView(IndexBufferRHI); 185 | } 186 | 187 | void Initialize(uint32 BytesPerElement, uint32 NumElements, EPixelFormat Format, uint32 AdditionalUsage = 0, const TCHAR* InDebugName = NULL, FResourceArrayInterface* InResourceArray = nullptr) 188 | { 189 | Initialize(BytesPerElement, NumElements, Format, ERHIAccess::UAVCompute, AdditionalUsage, InDebugName, InResourceArray); 190 | } 191 | 192 | void AcquireTransientResource() 193 | { 194 | //RHIAcquireTransientResource(IndexBufferRHI); 195 | } 196 | void DiscardTransientResource() 197 | { 198 | //RHIDiscardTransientResource(IndexBufferRHI); 199 | } 200 | 201 | void Release() 202 | { 203 | int32 BufferRefCount = IndexBufferRHI ? IndexBufferRHI->GetRefCount() : -1; 204 | 205 | if (BufferRefCount == 1) 206 | { 207 | DiscardTransientResource(); 208 | } 209 | 210 | NumBytes = 0; 211 | ReleaseRHI(); 212 | UAV.SafeRelease(); 213 | SRV.SafeRelease(); 214 | 215 | ReleaseResource(); 216 | } 217 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ProceduralMesh/ComputeShaderProceduralMeshActor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameFramework/Actor.h" 4 | #include "ComputeShaderProceduralMeshActor.generated.h" 5 | 6 | class UComputeShaderProceduralMeshComponent; 7 | class FCSProceduralMeshSceneProxy; 8 | 9 | UCLASS(Abstract) 10 | class GRAPHICSPLUGIN_API AComputeShaderProceduralMeshActor : public AActor 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AComputeShaderProceduralMeshActor(); 16 | 17 | protected: 18 | virtual void BeginPlay() override; 19 | 20 | // since we are manipulating the SceneProxy ourselves, this callback is fired when SceneProxy is ready. 21 | virtual void OnCreatedSceneProxyRendererResources(FCSProceduralMeshSceneProxy* SceneProxy) {} 22 | 23 | #if WITH_EDITOR 24 | private: 25 | void OnCreatedSceneProxy(FCSProceduralMeshSceneProxy* SceneProxy); 26 | #endif 27 | 28 | public: 29 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="ProceduralMesh") 30 | UComputeShaderProceduralMeshComponent* ProceduralMeshComponent = nullptr; 31 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ProceduralMesh/ComputeShaderProceduralMeshComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "UObject/ObjectMacros.h" 5 | #include "Components/PrimitiveComponent.h" 6 | #include "ComputeShaderProceduralMeshComponent.generated.h" 7 | 8 | class UMaterialInterface; 9 | class FPrimitiveSceneProxy; 10 | class FRegisterComponentContext; 11 | class FCSProceduralMeshSceneProxy; 12 | 13 | UCLASS(hidecategories=(Collision,Object,Physics,SceneComponent,Activation,"Components|Activation"), ClassGroup=Rendering, meta=(BlueprintSpawnableComponent)) 14 | class GRAPHICSPLUGIN_API UComputeShaderProceduralMeshComponent : public UPrimitiveComponent 15 | { 16 | GENERATED_UCLASS_BODY() 17 | 18 | public: 19 | //~ Begin UPrimitiveComponent Interface 20 | virtual FPrimitiveSceneProxy* CreateSceneProxy() override; 21 | virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override; 22 | virtual UMaterialInterface* GetMaterial(int32 Index) const override; 23 | virtual void SetMaterial(int32 ElementIndex, class UMaterialInterface* InMaterial) override; 24 | virtual void GetUsedMaterials(TArray& OutMaterials, bool bGetDebugMaterials = false) const override; 25 | #if WITH_EDITOR 26 | virtual void CreateRenderState_Concurrent(FRegisterComponentContext* Context) override; 27 | #endif 28 | //~ End UPrimitiveComponent Interface 29 | 30 | #if WITH_EDITOR 31 | virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; 32 | #endif 33 | 34 | UFUNCTION(BlueprintCallable, Category = "ProceduralMesh") 35 | void SetMaxPrimitiveCount(int32 PrimitiveCount); 36 | 37 | UFUNCTION(BlueprintCallable, Category = "ProceduralMesh") 38 | int32 GetMaxPrimitiveCount() const { return MaxPrimitives; } 39 | 40 | #if WITH_EDITOR 41 | DECLARE_DELEGATE_OneParam(FOnCreatedSceneProxy, FCSProceduralMeshSceneProxy*); 42 | FOnCreatedSceneProxy OnCreatedSceneProxy; 43 | #endif 44 | 45 | public: 46 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "ProceduralMesh") 47 | FVector FixedLocalBounds = FVector(64, 64, 64); 48 | 49 | private: 50 | UPROPERTY(EditAnywhere, Category = "ProceduralMesh") 51 | UMaterialInterface* Material = nullptr; 52 | 53 | UPROPERTY(EditAnywhere, Category = "ProceduralMesh", meta = (ClampMin = "1")) 54 | int32 MaxPrimitives = 1; 55 | }; 56 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ProceduralMesh/ComputeShaderProceduralMeshProxy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RHI.h" 4 | #include "PrimitiveSceneProxy.h" 5 | #include "LocalVertexFactory.h" 6 | #include "ComputeFriendlyBuffers.h" 7 | 8 | class UComputeShaderProceduralMeshComponent; 9 | 10 | class GRAPHICSPLUGIN_API FCSProceduralMeshSceneProxy final : public FPrimitiveSceneProxy 11 | { 12 | public: 13 | FCSProceduralMeshSceneProxy(const UComputeShaderProceduralMeshComponent* InComponent); 14 | ~FCSProceduralMeshSceneProxy(); 15 | 16 | // Begin FPrimitiveSceneProxy interface 17 | virtual void CreateRenderThreadResources() override; 18 | virtual void DestroyRenderThreadResources() override; 19 | // RenderThread calls this to fetch data we need to render for the proxy 20 | virtual void GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override; 21 | // End FPrimitiveSceneProxy interface 22 | 23 | bool HasValidBuffers() const { return PositionBuffer.IsInitialized(); } //one initalized all initialized :) 24 | 25 | // accessor for GPU buffers 26 | FRWVertexBuffer& GetPositionBuffer() { return PositionBuffer; } 27 | FRWVertexBuffer& GetTangentBuffer() { return TangentBuffer; } 28 | FRWVertexBuffer& GetTexCoordBuffer() { return TexCoordBuffer; } 29 | FRWVertexBuffer& GetColorBuffer() { return ColorBuffer; } 30 | FRWVertexBuffer& GetIndirectDrawArgsBuffer() { return IndirectDrawArgs; } 31 | 32 | uint32 GetMaxPrimitiveCount() const { return MaxPrimitiveCount; } 33 | 34 | #if WITH_EDITOR 35 | DECLARE_DELEGATE_OneParam(FOnCreatedRendererResources, FCSProceduralMeshSceneProxy*); 36 | FOnCreatedRendererResources OnCreatedRendererResources; 37 | #endif 38 | 39 | // {BOILER_PLATE BEGIN} 40 | #pragma region Hidden 41 | SIZE_T GetTypeHash() const override 42 | { 43 | static size_t UniquePointer; 44 | return reinterpret_cast(&UniquePointer); 45 | } 46 | 47 | virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override 48 | { 49 | FPrimitiveViewRelevance Result; 50 | Result.bDrawRelevance = IsShown(View); 51 | Result.bDynamicRelevance = true; 52 | Result.bShadowRelevance = IsShadowCast(View); 53 | MaterialRelevance.SetPrimitiveViewRelevance(Result); 54 | return Result; 55 | } 56 | 57 | virtual bool CanBeOccluded() const override { return !MaterialRelevance.bDisableDepthTest; } 58 | virtual uint32 GetMemoryFootprint() const override { return sizeof(*this) + GetAllocatedSize(); } 59 | uint32 GetAllocatedSize() const { return FPrimitiveSceneProxy::GetAllocatedSize(); } 60 | #pragma endregion Hidden 61 | // {BOILER_PLATE END} 62 | 63 | private: 64 | // copy of Material used by owning component 65 | const UMaterialInterface* RenderMaterial = nullptr; 66 | 67 | // this is boiler plate stuff, check documentation for this. I didn't look too much at this (boring :p) 68 | FMaterialRelevance MaterialRelevance = {}; 69 | 70 | // this is vanilla UE4 vertex factory, we can create our own but it'll be too much work :| 71 | // VertexFactory tells shader pipeline how to fetch vertex attributes 72 | // Nanite uses texture (visibility buffers) to fetch attributes (no InputAssembler involved), so possibilities are endless 73 | FLocalVertexFactory VertexFactory; 74 | 75 | // resources used by ComputeShader 76 | // Note: we can use RWBuffer, RWByteAddressBuffer, RWStructuredBuffer with CS too, but LocalVertexFactory used by Unreal needs VertexBuffer 77 | FRWVertexBuffer PositionBuffer; 78 | FRWVertexBuffer TangentBuffer; 79 | FRWVertexBuffer TexCoordBuffer; 80 | FRWVertexBuffer ColorBuffer; 81 | FRWVertexBuffer IndirectDrawArgs; 82 | 83 | // We allocate for worst case :>| 84 | int32 MaxPrimitiveCount = 0; 85 | 86 | static constexpr uint32 PositionStride = sizeof(FVector); // Position 87 | static constexpr uint32 TangentStride = sizeof(FPackedNormal) * 2; // Tangent and Normals are interleaved and packed as uints 88 | static constexpr uint32 TexCoordStride = sizeof(FVector2D); // NOTE: using full precision UVs for simplicity 89 | static constexpr uint32 ColorStride = sizeof(FColor); // Color is stored as uint 90 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPlugin/Public/ProceduralMesh/MarchingCubeShaders/MarchingCubeShaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Shader.h" 4 | #include "GlobalShader.h" 5 | #include "ShaderParameters.h" 6 | #include "ShaderPermutation.h" 7 | #include "ShaderParameterStruct.h" 8 | 9 | class GRAPHICSPLUGIN_API FResetIndirectArgsCS : public FGlobalShader 10 | { 11 | DECLARE_GLOBAL_SHADER(FResetIndirectArgsCS) 12 | 13 | SHADER_USE_PARAMETER_STRUCT(FResetIndirectArgsCS, FGlobalShader) 14 | 15 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 16 | SHADER_PARAMETER_UAV(RWBuffer, IndirectDrawArgsBuffer) 17 | END_SHADER_PARAMETER_STRUCT() 18 | 19 | public: 20 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 21 | { 22 | return RHISupportsComputeShaders(Parameters.Platform); 23 | } 24 | 25 | static inline void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 26 | { 27 | FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); 28 | } 29 | 30 | public: 31 | static constexpr int32 ThreadGroupSizeX = 1; 32 | static constexpr int32 ThreadGroupSizeY = 1; 33 | static constexpr int32 ThreadGroupSizeZ = 1; 34 | }; 35 | 36 | class GRAPHICSPLUGIN_API FGenerateTrianglesCS : public FGlobalShader 37 | { 38 | DECLARE_GLOBAL_SHADER(FGenerateTrianglesCS) 39 | 40 | SHADER_USE_PARAMETER_STRUCT(FGenerateTrianglesCS, FGlobalShader) 41 | 42 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 43 | SHADER_PARAMETER_UAV(RWBuffer, PositionBuffer) 44 | SHADER_PARAMETER_UAV(RWBuffer, TangentBuffer) 45 | SHADER_PARAMETER_UAV(RWBuffer, IndirectDrawArgsBuffer) 46 | SHADER_PARAMETER_SRV(Texture3D, NumVertsPerVoxel) 47 | SHADER_PARAMETER_SRV(Texture2D, NumVerticesLookupTable) 48 | SHADER_PARAMETER_SRV(Texture2D, TriangleVerticesLookupTable) 49 | SHADER_PARAMETER(FIntVector, VoxelCount) 50 | SHADER_PARAMETER(float, VoxelSize) 51 | SHADER_PARAMETER(float, IsoValue) 52 | SHADER_PARAMETER(float, Time) 53 | SHADER_PARAMETER(uint32, MaxVertices) 54 | END_SHADER_PARAMETER_STRUCT() 55 | 56 | public: 57 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 58 | { 59 | return RHISupportsComputeShaders(Parameters.Platform); 60 | } 61 | 62 | static inline void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 63 | { 64 | FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); 65 | } 66 | 67 | public: 68 | static constexpr int32 ThreadGroupSizeX = 4; 69 | static constexpr int32 ThreadGroupSizeY = 4; 70 | static constexpr int32 ThreadGroupSizeZ = 4; 71 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/GraphicsPluginEditor.Build.cs: -------------------------------------------------------------------------------- 1 | namespace UnrealBuildTool.Rules 2 | { 3 | public class GraphicsPluginEditor : ModuleRules 4 | { 5 | public GraphicsPluginEditor(ReadOnlyTargetRules Target) : base(Target) 6 | { 7 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 8 | 9 | PublicDependencyModuleNames.AddRange( 10 | new string[] 11 | { 12 | "Core", 13 | "CoreUObject", 14 | "Engine", 15 | "ApplicationCore", 16 | } 17 | ); 18 | 19 | PrivateDependencyModuleNames.AddRange( 20 | new string[] 21 | { 22 | "UnrealEd", 23 | "UMG", 24 | "Slate", 25 | "SlateCore", 26 | "LevelEditor", 27 | "PropertyEditor", 28 | } 29 | ); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/GraphicsPluginEditor.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | 5 | #include "Modules/ModuleInterface.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | DECLARE_LOG_CATEGORY_EXTERN(GraphicsPluginEditor, All, All) 9 | 10 | class FGraphicsPluginEditorModule : public IModuleInterface 11 | { 12 | public: 13 | virtual void StartupModule() override {} 14 | virtual void ShutdownModule() override {} 15 | }; 16 | 17 | IMPLEMENT_MODULE(FGraphicsPluginEditorModule, GraphicsPluginEditor); 18 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/GraphicsPluginFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphicsPluginFunctionLibrary.h" 2 | #include "HAL/PlatformApplicationMisc.h" 3 | 4 | bool UGraphicsPluginEditorFunctionLibrary::CalculateSplineParameters( 5 | UStaticMesh* StaticMesh, 6 | ESplineMeshAxis::Type ForwardAxis, 7 | FVector& OutSplineMeshDir, 8 | FVector& OutSplineMeshX, 9 | FVector& OutSplineMeshY, 10 | float& OutSplineMeshScaleZ, 11 | float& OutSplineMeshMinZ) 12 | { 13 | if (StaticMesh) 14 | { 15 | // direction vectors 16 | FVector DirMask(0, 0, 0); 17 | DirMask = FVector::ZeroVector; 18 | DirMask[ForwardAxis] = 1; 19 | OutSplineMeshDir = DirMask; 20 | DirMask = FVector::ZeroVector; 21 | DirMask[(ForwardAxis + 1) % 3] = 1; 22 | OutSplineMeshX = DirMask; 23 | DirMask = FVector::ZeroVector; 24 | DirMask[(ForwardAxis + 2) % 3] = 1; 25 | OutSplineMeshY = DirMask; 26 | 27 | FBoxSphereBounds StaticMeshBounds = StaticMesh->GetBounds(); 28 | OutSplineMeshScaleZ = 0.5f / USplineMeshComponent::GetAxisValue(StaticMeshBounds.BoxExtent, ForwardAxis); 29 | OutSplineMeshMinZ = USplineMeshComponent::GetAxisValue(StaticMeshBounds.Origin, ForwardAxis) * OutSplineMeshScaleZ - 0.5f; 30 | 31 | return true; 32 | } 33 | 34 | return false; 35 | } 36 | 37 | void UGraphicsPluginEditorFunctionLibrary::CopyTextToClipboard(const FString& Text) 38 | { 39 | FPlatformApplicationMisc::ClipboardCopy(*Text); 40 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/PBDEditorFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | #include "PBDEditorFunctionLibrary.h" 2 | #include "Runtime/AssetRegistry/Public/AssetRegistryModule.h" 3 | #include "Internationalization/Regex.h" 4 | #include "Misc/FileHelper.h" 5 | 6 | static TArray LoadPolyModel(const FString& InFilePath) 7 | { 8 | TArray Points = {}; 9 | { 10 | TArray FileContentLines; 11 | if (FFileHelper::LoadFileToStringArray(FileContentLines, *InFilePath)) 12 | { 13 | for (const FString& Line : FileContentLines) 14 | { 15 | FString PatternString(TEXT(R"( ?+[0-9]*: +([^\s]+) +([^\s]+) +([^\s]+))")); 16 | FRegexPattern Pattern(PatternString); 17 | FRegexMatcher Matcher(Pattern, Line); 18 | 19 | if (Matcher.FindNext()) 20 | { 21 | FVector Position; 22 | 23 | Position.X = FCString::Atof(*Matcher.GetCaptureGroup(1)); 24 | Position.Z = FCString::Atof(*Matcher.GetCaptureGroup(2)); 25 | Position.Y = FCString::Atof(*Matcher.GetCaptureGroup(3)); 26 | 27 | Points.Add(Position); 28 | } 29 | } 30 | } 31 | 32 | FVector CenterOfMass = FVector::ZeroVector; 33 | for (const FVector& Position : Points) 34 | { 35 | CenterOfMass += Position; 36 | } 37 | const float NumPoints = (float)Points.Num(); 38 | CenterOfMass /= NumPoints; 39 | 40 | for (FVector& Position : Points) 41 | { 42 | Position -= CenterOfMass; 43 | } 44 | } 45 | return Points; 46 | } 47 | 48 | static void CreateTexture(const FString& PackagePath, const FString& FileName, int32 TextureWidth, int32 TextureHeight, int32 PixelSize, ETextureSourceFormat eTextureFormat, uint8* PixelData) 49 | { 50 | // Create Package 51 | UPackage* Package = CreatePackage(*(PackagePath + FileName)); 52 | 53 | // Create the Texture 54 | FName TextureName = FName(*FileName); 55 | UTexture2D* Texture = NewObject(Package, TextureName, RF_Public | RF_Standalone | RF_MarkAsRootSet); 56 | 57 | // compression and mip settings 58 | Texture->CompressionSettings = TextureCompressionSettings::TC_HDR; 59 | Texture->LODGroup = TEXTUREGROUP_Pixels2D; 60 | Texture->MipGenSettings = TMGS_NoMipmaps; 61 | Texture->SRGB = false; 62 | Texture->AddressX = TextureAddress::TA_Clamp; 63 | Texture->AddressY = TextureAddress::TA_Clamp; 64 | 65 | // Updating Texture & mark it as unsaved 66 | Texture->AddToRoot(); 67 | Texture->Source.Init(TextureWidth, TextureHeight, 1, 1, eTextureFormat, PixelData); // make sure the data is saved on disk 68 | 69 | Texture->UpdateResource(); 70 | Texture->PostEditChange(); 71 | 72 | Package->MarkPackageDirty(); 73 | 74 | FAssetRegistryModule::AssetCreated(Texture); 75 | Texture->MarkPackageDirty(); 76 | Package->SetDirtyFlag(true); 77 | 78 | UE_LOG(LogTemp, Log, TEXT("Texture created: %s"), *FileName); 79 | } 80 | 81 | bool UPBDEditorFunctionLibrary::GeneratePBDShapeMatchingTextures( 82 | const FString& ParticlesFilePath, 83 | const FString& PackagePath, 84 | const FString& BaseFileName, 85 | float DistanceThreshold) 86 | { 87 | TArray ParticlePositions = LoadPolyModel(ParticlesFilePath); 88 | const int32 NumParticles = ParticlePositions.Num(); 89 | if (NumParticles > 0) 90 | { 91 | // unreal doesn't support R32/R16 so create RGBAFloat textures :( 92 | const int32 PixelSize = sizeof(FFloat16) * 4; 93 | 94 | struct FShapeConstraint 95 | { 96 | TArray ParticleIndices = {}; 97 | }; 98 | 99 | struct FParticleConstraintList 100 | { 101 | TArray Constraints = {}; 102 | }; 103 | 104 | TArray ShapeConstraints; 105 | ShapeConstraints.SetNum(NumParticles); // one shape matching constraint per particle 106 | int32 MaxParticlesPerConstraint = 0; 107 | 108 | TArray ParticleConstraintList; 109 | ParticleConstraintList.SetNum(NumParticles); 110 | int32 MaxConstraintsPerParticles = 0; 111 | 112 | // generate constraint data 113 | { 114 | for (int32 CurrentParticleIndex = 0; CurrentParticleIndex < NumParticles; ++CurrentParticleIndex) 115 | { 116 | const int32 CurrentShapeConstraintIndex = CurrentParticleIndex; 117 | 118 | // add current particle to constraint 119 | ShapeConstraints[CurrentParticleIndex].ParticleIndices.Add(CurrentParticleIndex); 120 | 121 | // add current constraint to current particle 122 | ParticleConstraintList[CurrentParticleIndex].Constraints.Add(CurrentShapeConstraintIndex); 123 | 124 | for (int32 OtherParticleIndex = 0; OtherParticleIndex < NumParticles; ++OtherParticleIndex) 125 | { 126 | if (CurrentParticleIndex != OtherParticleIndex) 127 | { 128 | const FVector& P0 = ParticlePositions[CurrentParticleIndex]; 129 | const FVector& P1 = ParticlePositions[OtherParticleIndex]; 130 | 131 | const float Distance = FVector::Distance(P0, P1); 132 | if (Distance <= DistanceThreshold) 133 | { 134 | // add other particle to constraint 135 | ShapeConstraints[CurrentParticleIndex].ParticleIndices.Add(OtherParticleIndex); 136 | 137 | // add current cosntraint to other particle 138 | ParticleConstraintList[OtherParticleIndex].Constraints.Add(CurrentShapeConstraintIndex); 139 | 140 | MaxConstraintsPerParticles = FMath::Max(MaxConstraintsPerParticles, ParticleConstraintList[OtherParticleIndex].Constraints.Num()); 141 | } 142 | } 143 | } 144 | 145 | MaxParticlesPerConstraint = FMath::Max(MaxParticlesPerConstraint, ShapeConstraints[CurrentParticleIndex].ParticleIndices.Num()); 146 | } 147 | } 148 | 149 | if (MaxParticlesPerConstraint <= 0 || MaxConstraintsPerParticles <= 0) 150 | { 151 | UE_LOG(LogTemp, Error, TEXT("[PBD] Unable to create constraint info, check \"Distance Threshold\"")); 152 | 153 | return false; 154 | } 155 | 156 | // create position texture 157 | { 158 | TArray ParticlePositionData; 159 | ParticlePositionData.SetNum(NumParticles * 4); 160 | for (int32 Index = 0; Index < NumParticles; ++Index) 161 | { 162 | ParticlePositionData[Index * 4 + 0] = ParticlePositions[Index].X; 163 | ParticlePositionData[Index * 4 + 1] = ParticlePositions[Index].Y; 164 | ParticlePositionData[Index * 4 + 2] = ParticlePositions[Index].Z; 165 | ParticlePositionData[Index * 4 + 3] = 1.f; 166 | } 167 | CreateTexture(PackagePath, BaseFileName + "_Positions", NumParticles, 1, PixelSize, ETextureSourceFormat::TSF_RGBA16F, (uint8*)ParticlePositionData.GetData()); 168 | } 169 | 170 | // create shape constraint texture 171 | { 172 | const size_t TextureWidth = NumParticles; 173 | const size_t TextureHeight = MaxParticlesPerConstraint; 174 | TArray TextureData; 175 | TextureData.SetNum(TextureWidth * TextureHeight * 4); 176 | for (int32 Index = 0; Index < (TextureWidth * TextureHeight); ++Index) 177 | { 178 | TextureData[Index * 4 + 0] = NumParticles; 179 | TextureData[Index * 4 + 1] = NumParticles; 180 | TextureData[Index * 4 + 2] = NumParticles; 181 | TextureData[Index * 4 + 3] = 1.f; 182 | } 183 | 184 | for (int32 i = 0; i < ShapeConstraints.Num(); ++i) 185 | { 186 | const FShapeConstraint& Constraint = ShapeConstraints[i]; 187 | 188 | for (int32 j = 0; j < Constraint.ParticleIndices.Num(); ++j) 189 | { 190 | TextureData[(j * TextureWidth + i) * 4] = Constraint.ParticleIndices[j]; 191 | } 192 | } 193 | 194 | CreateTexture(PackagePath, BaseFileName + "_ShapeConstraints", TextureWidth, TextureHeight, PixelSize, ETextureSourceFormat::TSF_RGBA16F, (uint8*)TextureData.GetData()); 195 | } 196 | 197 | // create particle constraint list texture 198 | { 199 | const size_t TextureWidth = NumParticles; 200 | const size_t TextureHeight = MaxConstraintsPerParticles; 201 | TArray TextureData; 202 | TextureData.SetNum(TextureWidth * TextureHeight * 4); 203 | for (int32 Index = 0; Index < (TextureWidth * TextureHeight); ++Index) 204 | { 205 | TextureData[Index * 4 + 0] = NumParticles; 206 | TextureData[Index * 4 + 1] = NumParticles; 207 | TextureData[Index * 4 + 2] = NumParticles; 208 | TextureData[Index * 4 + 3] = 1.f; 209 | } 210 | 211 | for (int32 i = 0; i < NumParticles; ++i) 212 | { 213 | for (int32 j = 0; j < ParticleConstraintList[i].Constraints.Num(); ++j) 214 | { 215 | TextureData[(j * TextureWidth + i) * 4] = ParticleConstraintList[i].Constraints[j]; 216 | } 217 | } 218 | 219 | CreateTexture(PackagePath, BaseFileName + "_ConstraintList", TextureWidth, TextureHeight, PixelSize, ETextureSourceFormat::TSF_RGBA16F, (uint8*)TextureData.GetData()); 220 | } 221 | 222 | return true; 223 | } 224 | 225 | UE_LOG(LogTemp, Error, TEXT("[PBD] File(%s) contains no particle data"), *ParticlesFilePath); 226 | return false; 227 | } -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/PBDEditorFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Kismet/BlueprintFunctionLibrary.h" 5 | #include "PBDEditorFunctionLibrary.generated.h" 6 | 7 | UCLASS() 8 | class GRAPHICSPLUGINEDITOR_API UPBDEditorFunctionLibrary : public UBlueprintFunctionLibrary 9 | { 10 | GENERATED_BODY() 11 | 12 | public: 13 | /** 14 | * Generate position and constraint textures used with PBD sim 15 | * @param ParticlesFilePath Absolute disk path for .poly file. 16 | * @param PackagePath Output directory to save the generated textures. 17 | * @param BaseFileName Texture will be saved using this as Prefix. {BaseFileName}_****.uasset. 18 | * @param DistanceThreshold Distance threshold to consider particles neighbors. 19 | */ 20 | UFUNCTION(BlueprintCallable, Category = "PBD") 21 | static bool GeneratePBDShapeMatchingTextures( 22 | const FString& ParticlesFilePath, 23 | const FString& PackagePath, 24 | const FString& BaseFileName, 25 | float DistanceThreshold); 26 | }; -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/Widgets/AssetPicker.cpp: -------------------------------------------------------------------------------- 1 | #include "AssetPicker.h" 2 | #include "LevelEditor.h" 3 | #include "PropertyCustomizationHelpers.h" 4 | 5 | #define LOCTEXT_NAMESPACE "UMG" 6 | 7 | ///////////////////////////////////////////////////// 8 | // UAssetPicker 9 | 10 | UAssetPicker::UAssetPicker(const FObjectInitializer& ObjectInitializer) 11 | : Super(ObjectInitializer) 12 | { 13 | bIsVariable = true; 14 | Visibility = ESlateVisibility::SelfHitTestInvisible; 15 | } 16 | 17 | void UAssetPicker::ReleaseSlateResources(bool bReleaseChildren) 18 | { 19 | Super::ReleaseSlateResources(bReleaseChildren); 20 | 21 | EntryBox.Reset(); 22 | } 23 | 24 | TSharedRef UAssetPicker::RebuildWidget() 25 | { 26 | FResetToDefaultOverride ResetToDefaultOverride = FResetToDefaultOverride::Create( 27 | FIsResetToDefaultVisible::CreateUObject(this, &UAssetPicker::GetResetVisibility), 28 | FResetToDefaultHandler::CreateUObject(this, &UAssetPicker::OnResetToBaseClicked) 29 | ); 30 | 31 | FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked("LevelEditor"); 32 | TSharedPtr ThumbnailPool = LevelEditorModule.GetFirstLevelEditor()->GetThumbnailPool(); 33 | 34 | EntryBox = SNew(SObjectPropertyEntryBox) 35 | .AllowedClass(AssetType) 36 | .AllowClear(true) 37 | .CustomResetToDefault(ResetToDefaultOverride) 38 | .ThumbnailPool(ThumbnailPool) 39 | .ObjectPath_UObject(this, &UAssetPicker::GetCurrentAssetPath) 40 | .OnObjectChanged_UObject(this, &UAssetPicker::OnObjectChanged); 41 | 42 | return EntryBox.ToSharedRef(); 43 | } 44 | 45 | bool UAssetPicker::GetResetVisibility(TSharedPtr PropertyHandle) 46 | { 47 | return SelectedAsset.IsValid(); 48 | } 49 | 50 | void UAssetPicker::OnResetToBaseClicked(TSharedPtr PropertyHandle) 51 | { 52 | SelectedAsset = nullptr; 53 | OnAssetChanged.Broadcast(SelectedAsset.Get()); 54 | } 55 | 56 | FString UAssetPicker::GetCurrentAssetPath() const 57 | { 58 | return SelectedAsset.IsValid() ? SelectedAsset->GetPathName() : FString(""); 59 | } 60 | 61 | void UAssetPicker::OnObjectChanged(const FAssetData& AssetData) 62 | { 63 | SelectedAsset = AssetData.GetAsset(); 64 | OnAssetChanged.Broadcast(SelectedAsset.Get()); 65 | } 66 | 67 | #if WITH_EDITOR 68 | 69 | const FText UAssetPicker::GetPaletteCategory() 70 | { 71 | return LOCTEXT("Editor", "Editor"); 72 | } 73 | 74 | #endif 75 | 76 | ///////////////////////////////////////////////////// 77 | 78 | #undef LOCTEXT_NAMESPACE 79 | -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Private/Widgets/AssetPicker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Widgets/SWidget.h" 5 | #include "Components/ContentWidget.h" 6 | 7 | #include "AssetPicker.generated.h" 8 | 9 | class SObjectPropertyEntryBox; 10 | 11 | UCLASS() 12 | class UAssetPicker : public UContentWidget 13 | { 14 | GENERATED_UCLASS_BODY() 15 | 16 | public: 17 | 18 | // UVisual interface 19 | virtual void ReleaseSlateResources(bool bReleaseChildren) override; 20 | // End of UVisual interface 21 | 22 | #if WITH_EDITOR 23 | virtual const FText GetPaletteCategory() override; 24 | #endif 25 | 26 | protected: 27 | // UWidget interface 28 | virtual TSharedRef RebuildWidget() override; 29 | // End of UWidget interface 30 | 31 | private: 32 | bool GetResetVisibility(TSharedPtr PropertyHandle); 33 | void OnResetToBaseClicked(TSharedPtr PropertyHandle); 34 | FString GetCurrentAssetPath() const; 35 | void OnObjectChanged(const FAssetData& AssetData); 36 | 37 | public: 38 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAssetChanged, UObject*, Asset); 39 | /** Called when the button is clicked */ 40 | UPROPERTY(BlueprintAssignable, Category = "AssetPicker|Event") 41 | FOnAssetChanged OnAssetChanged; 42 | 43 | /** Called when the button is clicked */ 44 | UPROPERTY(EditAnywhere, Category = "AssetPicker") 45 | UClass* AssetType = UObject::StaticClass(); 46 | 47 | protected: 48 | TSharedPtr EntryBox; 49 | TWeakObjectPtr SelectedAsset = nullptr; 50 | }; 51 | 52 | //////////////////////////////////////////////////////////////////////////////////// -------------------------------------------------------------------------------- /Plugins/GraphicsPlugin/Source/GraphicsPluginEditor/Public/GraphicsPluginFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Kismet/BlueprintFunctionLibrary.h" 5 | 6 | #include "Components/SplineMeshComponent.h" 7 | 8 | #include "GraphicsPluginFunctionLibrary.generated.h" 9 | 10 | class UStaticMesh; 11 | 12 | UCLASS() 13 | class GRAPHICSPLUGINEDITOR_API UGraphicsPluginEditorFunctionLibrary : public UBlueprintFunctionLibrary 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | UFUNCTION(BlueprintCallable, Category = "SplineMesh") 19 | static bool CalculateSplineParameters( 20 | UStaticMesh* StaticMesh, 21 | ESplineMeshAxis::Type ForwardAxis, 22 | UPARAM(ref) FVector& OutSplineMeshDir, 23 | UPARAM(ref) FVector& OutSplineMeshX, 24 | UPARAM(ref) FVector& OutSplineMeshY, 25 | UPARAM(ref) float& OutSplineMeshScaleZ, 26 | UPARAM(ref) float& OutSplineMeshMinZ); 27 | 28 | UFUNCTION(BlueprintCallable, Category = "EditorUtils") 29 | static void CopyTextToClipboard(const FString& Text); 30 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UE4GraphicsSample 2 | Code samples to show how to use Rendering features in Unreal :) 3 | 4 | ### Clear Texture Example (MAP_ClearTexture) 5 | Shows basics of how to use Compute Shader to write to texture. 6 | 7 | ### Procedural Mesh (MAP_ProceduralMesh) 8 | Shows how to use GPU buffer with ComputeShaders and DrawIndirect API to render mesh generated using CS. 9 | 10 | ### Niagara GPU Splines (MAP_NiagaraSplines) 11 | Shows how to use SimulationStages to render StaticMesh as SplineMesh. 12 | -------------------------------------------------------------------------------- /Source/GraphicsExamples.Target.cs: -------------------------------------------------------------------------------- 1 | using UnrealBuildTool; 2 | using System.Collections.Generic; 3 | 4 | public class GraphicsExamplesTarget : TargetRules 5 | { 6 | public GraphicsExamplesTarget(TargetInfo Target) : base(Target) 7 | { 8 | Type = TargetType.Game; 9 | DefaultBuildSettings = BuildSettingsVersion.V2; 10 | 11 | ExtraModuleNames.AddRange( new string[] { "GraphicsExamples" } ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/GraphicsExamples/ClearTextureExample/ClearTextureActor.cpp: -------------------------------------------------------------------------------- 1 | #include "ClearTextureActor.h" 2 | #include "Engine/TextureRenderTarget2D.h" 3 | #include "Engine/Texture2D.h" 4 | 5 | // shader from Graphics plugin. [TODO] How to make it nested into GraphicsPlugin/ 6 | #include "ClearTextureShader.h" 7 | 8 | // for using RenderGraph 9 | #include "RenderGraph.h" 10 | #include "RenderGraphUtils.h" 11 | 12 | AClearTextureActor::AClearTextureActor() 13 | { 14 | PrimaryActorTick.bCanEverTick = true; 15 | } 16 | 17 | void AClearTextureActor::BeginPlay() 18 | { 19 | // we can remove this line if the RenderTarget is coming from ContentBrowser 20 | ResultTexture = NewObject(); 21 | checkf(ResultTexture, TEXT("ResultTexture should not be invalid here!")); 22 | 23 | ResultTexture->bCanCreateUAV = true; //needed to create UAV 24 | ResultTexture->bAutoGenerateMips = false; //need additional work to update mips 25 | ResultTexture->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8; 26 | ResultTexture->MipsSamplerFilter = TextureFilter::TF_Bilinear; 27 | ResultTexture->ClearColor = FLinearColor::Black; 28 | ResultTexture->InitAutoFormat(TextureWidth, TextureHeight); 29 | ResultTexture->UpdateResourceImmediate(true); 30 | 31 | // queue task on RenderThread to create UAV resource 32 | ENQUEUE_RENDER_COMMAND(ClearTextureActor_InitializeUAV)( 33 | [this](FRHICommandListImmediate& RHICmdList) 34 | { 35 | FTextureRenderTarget2DResource* TextureResource = (FTextureRenderTarget2DResource*)ResultTexture->Resource; 36 | ResultTextureUAV = RHICreateUnorderedAccessView(TextureResource->TextureRHI, /*MipLevel=*/ 0); //we are rendering to first mip 37 | 38 | // texture to be used by Material (graphics). Looks like we don't need them if using RenderGraph 39 | // RHICmdList.Transition(FRHITransitionInfo(ResultTextureUAV, ERHIAccess::Unknown, ERHIAccess::SRVGraphics)); 40 | }); 41 | 42 | Super::BeginPlay(); 43 | } 44 | 45 | void AClearTextureActor::BeginDestroy() 46 | { 47 | // queue task on RenderThread to release UAV resource 48 | ENQUEUE_RENDER_COMMAND(ClearTextureActor_DestroyResources)( 49 | [this](FRHICommandListImmediate& RHICmdList) 50 | { 51 | ResultTextureUAV.SafeRelease(); 52 | }); 53 | 54 | Super::BeginDestroy(); 55 | } 56 | 57 | void AClearTextureActor::Tick(float DeltaSeconds) 58 | { 59 | const auto FeatureLevel = GetWorld()->Scene->GetFeatureLevel(); 60 | AnimationTime += DeltaSeconds; 61 | 62 | // we can copy some values that can be modified on GameThread 63 | struct FParametersRTCopy 64 | { 65 | FShaderResourceViewRHIRef SourceTextureRHI; 66 | FLinearColor ClearColor; 67 | float AnimationTime; 68 | bool UseAnimation; 69 | bool UseTexture; 70 | }; 71 | FParametersRTCopy RTCopy = {}; 72 | RTCopy.ClearColor = ClearColor; 73 | RTCopy.AnimationTime = AnimationTime; 74 | RTCopy.UseAnimation = bUseAnimation; 75 | RTCopy.UseTexture = bUseTexture && (SourceTexture != nullptr); 76 | if (RTCopy.UseTexture) 77 | { 78 | // we can cache SRV, recreating to make the code easier to follow 79 | RTCopy.SourceTextureRHI = RHICreateShaderResourceView(SourceTexture->Resource->TextureRHI, 0); 80 | // we can use this as SourceSampler, SourceTexture->Resource->SamplerStateRHI 81 | } 82 | else 83 | { 84 | // use dummy texture to make sure we bind something 85 | RTCopy.SourceTextureRHI = GBlackTextureWithSRV->ShaderResourceViewRHI; 86 | } 87 | 88 | // queue work on RenderThread to update texture 89 | ENQUEUE_RENDER_COMMAND(ClearTextureActor_ClearTexture)( 90 | [this, FeatureLevel, RTCopy](FRHICommandListImmediate& RHICmdList) 91 | { 92 | FMemMark Mark(FMemStack::Get()); //required for tracking 93 | FRDGBuilder GraphBuilder(RHICmdList); //https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScripting/Rendering/RenderDependencyGraph/ 94 | 95 | const float RTWidth = ResultTexture->GetSurfaceWidth(); 96 | const float RTHeight = ResultTexture->GetSurfaceHeight(); 97 | 98 | const FIntVector GroupCount( 99 | FMath::CeilToInt(RTWidth / (float)FClearTextureCS::ThreadGroupSizeX), 100 | FMath::CeilToInt(RTHeight / (float)FClearTextureCS::ThreadGroupSizeY), 101 | 1); 102 | 103 | // update Permutation to select proper shader 104 | FClearTextureCS::FPermutationDomain Permutation; 105 | Permutation.Set(RTCopy.UseAnimation); 106 | Permutation.Set(RTCopy.UseTexture); 107 | 108 | // get GlobalShaderMap 109 | FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(FeatureLevel); 110 | // if the shader is not using Permutation, we can remove the second argument 111 | TShaderMapRef ComputeShader(GlobalShaderMap, Permutation); 112 | 113 | // this is the new way of adding parameters, very easy to use :) 114 | FClearTextureCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 115 | PassParameters->OutputTexture = ResultTextureUAV; 116 | PassParameters->SourceTexture = RTCopy.SourceTextureRHI; 117 | PassParameters->SourceSampler = TStaticSamplerState::GetRHI(); 118 | PassParameters->ClearColor = FVector4(RTCopy.ClearColor); 119 | PassParameters->TextureDimensions = FVector4(RTWidth, RTHeight, 1.f / RTWidth, 1.f / RTHeight); 120 | PassParameters->AnimationTime = RTCopy.AnimationTime; 121 | 122 | // some validation (refer to link above) 123 | ValidateShaderParameters(ComputeShader, *PassParameters); 124 | 125 | // texture needs to be in writable state from compute shader. Looks like we don't need them if using RenderGraph 126 | // RHICmdList.Transition(FRHITransitionInfo(ResultTextureUAV, ERHIAccess::SRVGraphics, ERHIAccess::UAVCompute)); 127 | 128 | // add our pass 129 | FComputeShaderUtils::AddPass( 130 | GraphBuilder, 131 | RDG_EVENT_NAME("ClearTexture"), 132 | ComputeShader, PassParameters, GroupCount); 133 | 134 | // texture to be used by Material (graphics). Looks like we don't need them if using RenderGraph 135 | // RHICmdList.Transition(FRHITransitionInfo(ResultTextureUAV, ERHIAccess::UAVCompute, ERHIAccess::SRVGraphics)); 136 | 137 | // we can add more work here 138 | 139 | // finally execute 140 | GraphBuilder.Execute(); 141 | }); 142 | 143 | Super::Tick(DeltaSeconds); 144 | } -------------------------------------------------------------------------------- /Source/GraphicsExamples/ClearTextureExample/ClearTextureActor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GameFramework/Actor.h" 4 | #include "ClearTextureActor.generated.h" 5 | 6 | class UTexture2D; 7 | class UTextureRenderTarget2D; 8 | 9 | UCLASS() 10 | class GRAPHICSEXAMPLES_API AClearTextureActor : public AActor 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AClearTextureActor(); 16 | 17 | virtual void Tick(float DeltaSeconds) override; 18 | 19 | protected: 20 | virtual void BeginPlay() override; 21 | virtual void BeginDestroy() override; 22 | 23 | public: 24 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Texture", meta=(EditCondition="bUseTexture")) 25 | UTexture2D* SourceTexture = nullptr; 26 | 27 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Texture", meta=(EditCondition="!bUseAnimation && !bUseTexture")) 28 | FLinearColor ClearColor = FLinearColor::Red; 29 | 30 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Texture") 31 | UTextureRenderTarget2D* ResultTexture = nullptr; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Texture", meta = (ClampMin = "16")) 34 | int32 TextureWidth = 256; 35 | 36 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Texture", meta=(ClampMin="16")) 37 | int32 TextureHeight = 256; 38 | 39 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Texture", meta=(EditCondition="!bUseTexture")) 40 | bool bUseAnimation = false; 41 | 42 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Texture", meta=(EditCondition="!bUseAnimation")) 43 | bool bUseTexture = false; 44 | 45 | private: 46 | FUnorderedAccessViewRHIRef ResultTextureUAV = nullptr; 47 | float AnimationTime = 0.f; 48 | }; -------------------------------------------------------------------------------- /Source/GraphicsExamples/GraphicsExamples.Build.cs: -------------------------------------------------------------------------------- 1 | using UnrealBuildTool; 2 | 3 | public class GraphicsExamples : ModuleRules 4 | { 5 | public GraphicsExamples(ReadOnlyTargetRules Target) : base(Target) 6 | { 7 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 8 | 9 | PublicDependencyModuleNames.AddRange( 10 | new string[] 11 | { 12 | "Core", 13 | "CoreUObject", 14 | "Engine", 15 | "InputCore", 16 | }); 17 | 18 | // these modules are needed to use rendering features 19 | PublicDependencyModuleNames.AddRange( 20 | new string[] 21 | { 22 | "RHI", 23 | "RenderCore", 24 | "Renderer", 25 | }); 26 | 27 | // Graphics plugin to reference the shaders 28 | PublicDependencyModuleNames.Add("GraphicsPlugin"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/GraphicsExamples/GraphicsExamples.cpp: -------------------------------------------------------------------------------- 1 | #include "GraphicsExamples.h" 2 | #include "Modules/ModuleManager.h" 3 | 4 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, GraphicsExamples, "GraphicsExamples" ); 5 | -------------------------------------------------------------------------------- /Source/GraphicsExamples/GraphicsExamples.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | 5 | -------------------------------------------------------------------------------- /Source/GraphicsExamples/ProceduralMeshExample/ComputeShader/MarchingCubes/MarchingCubeTables.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Tables for Marching Cubes 5 | http://paulbourke.net/geometry/polygonise/ 6 | */ 7 | 8 | #include "RHI.h" 9 | 10 | namespace MarchingCubesResourceProvider 11 | { 12 | // triangle table maps same cube vertex index to a list of up to 5 triangles 13 | // which are built from the interpolated edge vertices 14 | class FTriTableBulkData : public FResourceBulkDataInterface 15 | { 16 | public: 17 | using ElementType = uint8; 18 | static constexpr uint32 SizeX = 16; 19 | static constexpr uint32 SizeY = 256; 20 | static constexpr uint32 BytesPerElement = sizeof(ElementType); 21 | 22 | virtual const void* GetResourceBulkData() const override 23 | { 24 | #define X 255 25 | static constexpr ElementType TriTable[SizeY][SizeX] = 26 | { 27 | {X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X}, 28 | {0, 8, 3, X, X, X, X, X, X, X, X, X, X, X, X, X}, 29 | {0, 1, 9, X, X, X, X, X, X, X, X, X, X, X, X, X}, 30 | {1, 8, 3, 9, 8, 1, X, X, X, X, X, X, X, X, X, X}, 31 | {1, 2, 10, X, X, X, X, X, X, X, X, X, X, X, X, X}, 32 | {0, 8, 3, 1, 2, 10, X, X, X, X, X, X, X, X, X, X}, 33 | {9, 2, 10, 0, 2, 9, X, X, X, X, X, X, X, X, X, X}, 34 | {2, 8, 3, 2, 10, 8, 10, 9, 8, X, X, X, X, X, X, X}, 35 | {3, 11, 2, X, X, X, X, X, X, X, X, X, X, X, X, X}, 36 | {0, 11, 2, 8, 11, 0, X, X, X, X, X, X, X, X, X, X}, 37 | {1, 9, 0, 2, 3, 11, X, X, X, X, X, X, X, X, X, X}, 38 | {1, 11, 2, 1, 9, 11, 9, 8, 11, X, X, X, X, X, X, X}, 39 | {3, 10, 1, 11, 10, 3, X, X, X, X, X, X, X, X, X, X}, 40 | {0, 10, 1, 0, 8, 10, 8, 11, 10, X, X, X, X, X, X, X}, 41 | {3, 9, 0, 3, 11, 9, 11, 10, 9, X, X, X, X, X, X, X}, 42 | {9, 8, 10, 10, 8, 11, X, X, X, X, X, X, X, X, X, X}, 43 | {4, 7, 8, X, X, X, X, X, X, X, X, X, X, X, X, X}, 44 | {4, 3, 0, 7, 3, 4, X, X, X, X, X, X, X, X, X, X}, 45 | {0, 1, 9, 8, 4, 7, X, X, X, X, X, X, X, X, X, X}, 46 | {4, 1, 9, 4, 7, 1, 7, 3, 1, X, X, X, X, X, X, X}, 47 | {1, 2, 10, 8, 4, 7, X, X, X, X, X, X, X, X, X, X}, 48 | {3, 4, 7, 3, 0, 4, 1, 2, 10, X, X, X, X, X, X, X}, 49 | {9, 2, 10, 9, 0, 2, 8, 4, 7, X, X, X, X, X, X, X}, 50 | {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, X, X, X, X}, 51 | {8, 4, 7, 3, 11, 2, X, X, X, X, X, X, X, X, X, X}, 52 | {11, 4, 7, 11, 2, 4, 2, 0, 4, X, X, X, X, X, X, X}, 53 | {9, 0, 1, 8, 4, 7, 2, 3, 11, X, X, X, X, X, X, X}, 54 | {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, X, X, X, X}, 55 | {3, 10, 1, 3, 11, 10, 7, 8, 4, X, X, X, X, X, X, X}, 56 | {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, X, X, X, X}, 57 | {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, X, X, X, X}, 58 | {4, 7, 11, 4, 11, 9, 9, 11, 10, X, X, X, X, X, X, X}, 59 | {9, 5, 4, X, X, X, X, X, X, X, X, X, X, X, X, X}, 60 | {9, 5, 4, 0, 8, 3, X, X, X, X, X, X, X, X, X, X}, 61 | {0, 5, 4, 1, 5, 0, X, X, X, X, X, X, X, X, X, X}, 62 | {8, 5, 4, 8, 3, 5, 3, 1, 5, X, X, X, X, X, X, X}, 63 | {1, 2, 10, 9, 5, 4, X, X, X, X, X, X, X, X, X, X}, 64 | {3, 0, 8, 1, 2, 10, 4, 9, 5, X, X, X, X, X, X, X}, 65 | {5, 2, 10, 5, 4, 2, 4, 0, 2, X, X, X, X, X, X, X}, 66 | {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, X, X, X, X}, 67 | {9, 5, 4, 2, 3, 11, X, X, X, X, X, X, X, X, X, X}, 68 | {0, 11, 2, 0, 8, 11, 4, 9, 5, X, X, X, X, X, X, X}, 69 | {0, 5, 4, 0, 1, 5, 2, 3, 11, X, X, X, X, X, X, X}, 70 | {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, X, X, X, X}, 71 | {10, 3, 11, 10, 1, 3, 9, 5, 4, X, X, X, X, X, X, X}, 72 | {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, X, X, X, X}, 73 | {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, X, X, X, X}, 74 | {5, 4, 8, 5, 8, 10, 10, 8, 11, X, X, X, X, X, X, X}, 75 | {9, 7, 8, 5, 7, 9, X, X, X, X, X, X, X, X, X, X}, 76 | {9, 3, 0, 9, 5, 3, 5, 7, 3, X, X, X, X, X, X, X}, 77 | {0, 7, 8, 0, 1, 7, 1, 5, 7, X, X, X, X, X, X, X}, 78 | {1, 5, 3, 3, 5, 7, X, X, X, X, X, X, X, X, X, X}, 79 | {9, 7, 8, 9, 5, 7, 10, 1, 2, X, X, X, X, X, X, X}, 80 | {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, X, X, X, X}, 81 | {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, X, X, X, X}, 82 | {2, 10, 5, 2, 5, 3, 3, 5, 7, X, X, X, X, X, X, X}, 83 | {7, 9, 5, 7, 8, 9, 3, 11, 2, X, X, X, X, X, X, X}, 84 | {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, X, X, X, X}, 85 | {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, X, X, X, X}, 86 | {11, 2, 1, 11, 1, 7, 7, 1, 5, X, X, X, X, X, X, X}, 87 | {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, X, X, X, X}, 88 | {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, X}, 89 | {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, X}, 90 | {11, 10, 5, 7, 11, 5, X, X, X, X, X, X, X, X, X, X}, 91 | {10, 6, 5, X, X, X, X, X, X, X, X, X, X, X, X, X}, 92 | {0, 8, 3, 5, 10, 6, X, X, X, X, X, X, X, X, X, X}, 93 | {9, 0, 1, 5, 10, 6, X, X, X, X, X, X, X, X, X, X}, 94 | {1, 8, 3, 1, 9, 8, 5, 10, 6, X, X, X, X, X, X, X}, 95 | {1, 6, 5, 2, 6, 1, X, X, X, X, X, X, X, X, X, X}, 96 | {1, 6, 5, 1, 2, 6, 3, 0, 8, X, X, X, X, X, X, X}, 97 | {9, 6, 5, 9, 0, 6, 0, 2, 6, X, X, X, X, X, X, X}, 98 | {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, X, X, X, X}, 99 | {2, 3, 11, 10, 6, 5, X, X, X, X, X, X, X, X, X, X}, 100 | {11, 0, 8, 11, 2, 0, 10, 6, 5, X, X, X, X, X, X, X}, 101 | {0, 1, 9, 2, 3, 11, 5, 10, 6, X, X, X, X, X, X, X}, 102 | {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, X, X, X, X}, 103 | {6, 3, 11, 6, 5, 3, 5, 1, 3, X, X, X, X, X, X, X}, 104 | {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, X, X, X, X}, 105 | {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, X, X, X, X}, 106 | {6, 5, 9, 6, 9, 11, 11, 9, 8, X, X, X, X, X, X, X}, 107 | {5, 10, 6, 4, 7, 8, X, X, X, X, X, X, X, X, X, X}, 108 | {4, 3, 0, 4, 7, 3, 6, 5, 10, X, X, X, X, X, X, X}, 109 | {1, 9, 0, 5, 10, 6, 8, 4, 7, X, X, X, X, X, X, X}, 110 | {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, X, X, X, X}, 111 | {6, 1, 2, 6, 5, 1, 4, 7, 8, X, X, X, X, X, X, X}, 112 | {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, X, X, X, X}, 113 | {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, X, X, X, X}, 114 | {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, X}, 115 | {3, 11, 2, 7, 8, 4, 10, 6, 5, X, X, X, X, X, X, X}, 116 | {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, X, X, X, X}, 117 | {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, X, X, X, X}, 118 | {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, X}, 119 | {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, X, X, X, X}, 120 | {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, X}, 121 | {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, X}, 122 | {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, X, X, X, X}, 123 | {10, 4, 9, 6, 4, 10, X, X, X, X, X, X, X, X, X, X}, 124 | {4, 10, 6, 4, 9, 10, 0, 8, 3, X, X, X, X, X, X, X}, 125 | {10, 0, 1, 10, 6, 0, 6, 4, 0, X, X, X, X, X, X, X}, 126 | {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, X, X, X, X}, 127 | {1, 4, 9, 1, 2, 4, 2, 6, 4, X, X, X, X, X, X, X}, 128 | {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, X, X, X, X}, 129 | {0, 2, 4, 4, 2, 6, X, X, X, X, X, X, X, X, X, X}, 130 | {8, 3, 2, 8, 2, 4, 4, 2, 6, X, X, X, X, X, X, X}, 131 | {10, 4, 9, 10, 6, 4, 11, 2, 3, X, X, X, X, X, X, X}, 132 | {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, X, X, X, X}, 133 | {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, X, X, X, X}, 134 | {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, X}, 135 | {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, X, X, X, X}, 136 | {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, X}, 137 | {3, 11, 6, 3, 6, 0, 0, 6, 4, X, X, X, X, X, X, X}, 138 | {6, 4, 8, 11, 6, 8, X, X, X, X, X, X, X, X, X, X}, 139 | {7, 10, 6, 7, 8, 10, 8, 9, 10, X, X, X, X, X, X, X}, 140 | {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, X, X, X, X}, 141 | {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, X, X, X, X}, 142 | {10, 6, 7, 10, 7, 1, 1, 7, 3, X, X, X, X, X, X, X}, 143 | {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, X, X, X, X}, 144 | {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, X}, 145 | {7, 8, 0, 7, 0, 6, 6, 0, 2, X, X, X, X, X, X, X}, 146 | {7, 3, 2, 6, 7, 2, X, X, X, X, X, X, X, X, X, X}, 147 | {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, X, X, X, X}, 148 | {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, X}, 149 | {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, X}, 150 | {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, X, X, X, X}, 151 | {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, X}, 152 | {0, 9, 1, 11, 6, 7, X, X, X, X, X, X, X, X, X, X}, 153 | {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, X, X, X, X}, 154 | {7, 11, 6, X, X, X, X, X, X, X, X, X, X, X, X, X}, 155 | {7, 6, 11, X, X, X, X, X, X, X, X, X, X, X, X, X}, 156 | {3, 0, 8, 11, 7, 6, X, X, X, X, X, X, X, X, X, X}, 157 | {0, 1, 9, 11, 7, 6, X, X, X, X, X, X, X, X, X, X}, 158 | {8, 1, 9, 8, 3, 1, 11, 7, 6, X, X, X, X, X, X, X}, 159 | {10, 1, 2, 6, 11, 7, X, X, X, X, X, X, X, X, X, X}, 160 | {1, 2, 10, 3, 0, 8, 6, 11, 7, X, X, X, X, X, X, X}, 161 | {2, 9, 0, 2, 10, 9, 6, 11, 7, X, X, X, X, X, X, X}, 162 | {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, X, X, X, X}, 163 | {7, 2, 3, 6, 2, 7, X, X, X, X, X, X, X, X, X, X}, 164 | {7, 0, 8, 7, 6, 0, 6, 2, 0, X, X, X, X, X, X, X}, 165 | {2, 7, 6, 2, 3, 7, 0, 1, 9, X, X, X, X, X, X, X}, 166 | {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, X, X, X, X}, 167 | {10, 7, 6, 10, 1, 7, 1, 3, 7, X, X, X, X, X, X, X}, 168 | {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, X, X, X, X}, 169 | {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, X, X, X, X}, 170 | {7, 6, 10, 7, 10, 8, 8, 10, 9, X, X, X, X, X, X, X}, 171 | {6, 8, 4, 11, 8, 6, X, X, X, X, X, X, X, X, X, X}, 172 | {3, 6, 11, 3, 0, 6, 0, 4, 6, X, X, X, X, X, X, X}, 173 | {8, 6, 11, 8, 4, 6, 9, 0, 1, X, X, X, X, X, X, X}, 174 | {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, X, X, X, X}, 175 | {6, 8, 4, 6, 11, 8, 2, 10, 1, X, X, X, X, X, X, X}, 176 | {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, X, X, X, X}, 177 | {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, X, X, X, X}, 178 | {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, X}, 179 | {8, 2, 3, 8, 4, 2, 4, 6, 2, X, X, X, X, X, X, X}, 180 | {0, 4, 2, 4, 6, 2, X, X, X, X, X, X, X, X, X, X}, 181 | {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, X, X, X, X}, 182 | {1, 9, 4, 1, 4, 2, 2, 4, 6, X, X, X, X, X, X, X}, 183 | {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, X, X, X, X}, 184 | {10, 1, 0, 10, 0, 6, 6, 0, 4, X, X, X, X, X, X, X}, 185 | {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, X}, 186 | {10, 9, 4, 6, 10, 4, X, X, X, X, X, X, X, X, X, X}, 187 | {4, 9, 5, 7, 6, 11, X, X, X, X, X, X, X, X, X, X}, 188 | {0, 8, 3, 4, 9, 5, 11, 7, 6, X, X, X, X, X, X, X}, 189 | {5, 0, 1, 5, 4, 0, 7, 6, 11, X, X, X, X, X, X, X}, 190 | {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, X, X, X, X}, 191 | {9, 5, 4, 10, 1, 2, 7, 6, 11, X, X, X, X, X, X, X}, 192 | {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, X, X, X, X}, 193 | {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, X, X, X, X}, 194 | {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, X}, 195 | {7, 2, 3, 7, 6, 2, 5, 4, 9, X, X, X, X, X, X, X}, 196 | {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, X, X, X, X}, 197 | {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, X, X, X, X}, 198 | {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, X}, 199 | {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, X, X, X, X}, 200 | {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, X}, 201 | {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, X}, 202 | {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, X, X, X, X}, 203 | {6, 9, 5, 6, 11, 9, 11, 8, 9, X, X, X, X, X, X, X}, 204 | {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, X, X, X, X}, 205 | {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, X, X, X, X}, 206 | {6, 11, 3, 6, 3, 5, 5, 3, 1, X, X, X, X, X, X, X}, 207 | {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, X, X, X, X}, 208 | {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, X}, 209 | {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, X}, 210 | {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, X, X, X, X}, 211 | {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, X, X, X, X}, 212 | {9, 5, 6, 9, 6, 0, 0, 6, 2, X, X, X, X, X, X, X}, 213 | {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, X}, 214 | {1, 5, 6, 2, 1, 6, X, X, X, X, X, X, X, X, X, X}, 215 | {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, X}, 216 | {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, X, X, X, X}, 217 | {0, 3, 8, 5, 6, 10, X, X, X, X, X, X, X, X, X, X}, 218 | {10, 5, 6, X, X, X, X, X, X, X, X, X, X, X, X, X}, 219 | {11, 5, 10, 7, 5, 11, X, X, X, X, X, X, X, X, X, X}, 220 | {11, 5, 10, 11, 7, 5, 8, 3, 0, X, X, X, X, X, X, X}, 221 | {5, 11, 7, 5, 10, 11, 1, 9, 0, X, X, X, X, X, X, X}, 222 | {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, X, X, X, X}, 223 | {11, 1, 2, 11, 7, 1, 7, 5, 1, X, X, X, X, X, X, X}, 224 | {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, X, X, X, X}, 225 | {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, X, X, X, X}, 226 | {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, X}, 227 | {2, 5, 10, 2, 3, 5, 3, 7, 5, X, X, X, X, X, X, X}, 228 | {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, X, X, X, X}, 229 | {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, X, X, X, X}, 230 | {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, X}, 231 | {1, 3, 5, 3, 7, 5, X, X, X, X, X, X, X, X, X, X}, 232 | {0, 8, 7, 0, 7, 1, 1, 7, 5, X, X, X, X, X, X, X}, 233 | {9, 0, 3, 9, 3, 5, 5, 3, 7, X, X, X, X, X, X, X}, 234 | {9, 8, 7, 5, 9, 7, X, X, X, X, X, X, X, X, X, X}, 235 | {5, 8, 4, 5, 10, 8, 10, 11, 8, X, X, X, X, X, X, X}, 236 | {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, X, X, X, X}, 237 | {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, X, X, X, X}, 238 | {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, X}, 239 | {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, X, X, X, X}, 240 | {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, X}, 241 | {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, X}, 242 | {9, 4, 5, 2, 11, 3, X, X, X, X, X, X, X, X, X, X}, 243 | {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, X, X, X, X}, 244 | {5, 10, 2, 5, 2, 4, 4, 2, 0, X, X, X, X, X, X, X}, 245 | {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, X}, 246 | {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, X, X, X, X}, 247 | {8, 4, 5, 8, 5, 3, 3, 5, 1, X, X, X, X, X, X, X}, 248 | {0, 4, 5, 1, 0, 5, X, X, X, X, X, X, X, X, X, X}, 249 | {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, X, X, X, X}, 250 | {9, 4, 5, X, X, X, X, X, X, X, X, X, X, X, X, X}, 251 | {4, 11, 7, 4, 9, 11, 9, 10, 11, X, X, X, X, X, X, X}, 252 | {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, X, X, X, X}, 253 | {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, X, X, X, X}, 254 | {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, X}, 255 | {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, X, X, X, X}, 256 | {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, X}, 257 | {11, 7, 4, 11, 4, 2, 2, 4, 0, X, X, X, X, X, X, X}, 258 | {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, X, X, X, X}, 259 | {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, X, X, X, X}, 260 | {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, X}, 261 | {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, X}, 262 | {1, 10, 2, 8, 7, 4, X, X, X, X, X, X, X, X, X, X}, 263 | {4, 9, 1, 4, 1, 7, 7, 1, 3, X, X, X, X, X, X, X}, 264 | {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, X, X, X, X}, 265 | {4, 0, 3, 7, 4, 3, X, X, X, X, X, X, X, X, X, X}, 266 | {4, 8, 7, X, X, X, X, X, X, X, X, X, X, X, X, X}, 267 | {9, 10, 8, 10, 11, 8, X, X, X, X, X, X, X, X, X, X}, 268 | {3, 0, 9, 3, 9, 11, 11, 9, 10, X, X, X, X, X, X, X}, 269 | {0, 1, 10, 0, 10, 8, 8, 10, 11, X, X, X, X, X, X, X}, 270 | {3, 1, 10, 11, 3, 10, X, X, X, X, X, X, X, X, X, X}, 271 | {1, 2, 11, 1, 11, 9, 9, 11, 8, X, X, X, X, X, X, X}, 272 | {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, X, X, X, X}, 273 | {0, 2, 11, 8, 0, 11, X, X, X, X, X, X, X, X, X, X}, 274 | {3, 2, 11, X, X, X, X, X, X, X, X, X, X, X, X, X}, 275 | {2, 3, 8, 2, 8, 10, 10, 8, 9, X, X, X, X, X, X, X}, 276 | {9, 10, 2, 0, 9, 2, X, X, X, X, X, X, X, X, X, X}, 277 | {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, X, X, X, X}, 278 | {1, 10, 2, X, X, X, X, X, X, X, X, X, X, X, X, X}, 279 | {1, 3, 8, 9, 1, 8, X, X, X, X, X, X, X, X, X, X}, 280 | {0, 9, 1, X, X, X, X, X, X, X, X, X, X, X, X, X}, 281 | {0, 3, 8, X, X, X, X, X, X, X, X, X, X, X, X, X}, 282 | {X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X} 283 | }; 284 | #undef X 285 | 286 | return TriTable; 287 | } 288 | virtual uint32 GetResourceBulkDataSize() const override 289 | { 290 | return SizeX * SizeY * BytesPerElement; 291 | } 292 | virtual void Discard() override { } 293 | }; 294 | 295 | // number of vertices for each case above 296 | class FNumVertsResourceArray : public FResourceArrayInterface 297 | { 298 | public: 299 | using ElementType = uint8; 300 | static constexpr uint32 NumElements = 256; 301 | static constexpr uint32 BytesPerElement = sizeof(ElementType); 302 | 303 | virtual const void* GetResourceData() const override 304 | { 305 | static constexpr ElementType NumVertsTable[256] = 306 | { 307 | 0, 308 | 3, 309 | 3, 310 | 6, 311 | 3, 312 | 6, 313 | 6, 314 | 9, 315 | 3, 316 | 6, 317 | 6, 318 | 9, 319 | 6, 320 | 9, 321 | 9, 322 | 6, 323 | 3, 324 | 6, 325 | 6, 326 | 9, 327 | 6, 328 | 9, 329 | 9, 330 | 12, 331 | 6, 332 | 9, 333 | 9, 334 | 12, 335 | 9, 336 | 12, 337 | 12, 338 | 9, 339 | 3, 340 | 6, 341 | 6, 342 | 9, 343 | 6, 344 | 9, 345 | 9, 346 | 12, 347 | 6, 348 | 9, 349 | 9, 350 | 12, 351 | 9, 352 | 12, 353 | 12, 354 | 9, 355 | 6, 356 | 9, 357 | 9, 358 | 6, 359 | 9, 360 | 12, 361 | 12, 362 | 9, 363 | 9, 364 | 12, 365 | 12, 366 | 9, 367 | 12, 368 | 15, 369 | 15, 370 | 6, 371 | 3, 372 | 6, 373 | 6, 374 | 9, 375 | 6, 376 | 9, 377 | 9, 378 | 12, 379 | 6, 380 | 9, 381 | 9, 382 | 12, 383 | 9, 384 | 12, 385 | 12, 386 | 9, 387 | 6, 388 | 9, 389 | 9, 390 | 12, 391 | 9, 392 | 12, 393 | 12, 394 | 15, 395 | 9, 396 | 12, 397 | 12, 398 | 15, 399 | 12, 400 | 15, 401 | 15, 402 | 12, 403 | 6, 404 | 9, 405 | 9, 406 | 12, 407 | 9, 408 | 12, 409 | 6, 410 | 9, 411 | 9, 412 | 12, 413 | 12, 414 | 15, 415 | 12, 416 | 15, 417 | 9, 418 | 6, 419 | 9, 420 | 12, 421 | 12, 422 | 9, 423 | 12, 424 | 15, 425 | 9, 426 | 6, 427 | 12, 428 | 15, 429 | 15, 430 | 12, 431 | 15, 432 | 6, 433 | 12, 434 | 3, 435 | 3, 436 | 6, 437 | 6, 438 | 9, 439 | 6, 440 | 9, 441 | 9, 442 | 12, 443 | 6, 444 | 9, 445 | 9, 446 | 12, 447 | 9, 448 | 12, 449 | 12, 450 | 9, 451 | 6, 452 | 9, 453 | 9, 454 | 12, 455 | 9, 456 | 12, 457 | 12, 458 | 15, 459 | 9, 460 | 6, 461 | 12, 462 | 9, 463 | 12, 464 | 9, 465 | 15, 466 | 6, 467 | 6, 468 | 9, 469 | 9, 470 | 12, 471 | 9, 472 | 12, 473 | 12, 474 | 15, 475 | 9, 476 | 12, 477 | 12, 478 | 15, 479 | 12, 480 | 15, 481 | 15, 482 | 12, 483 | 9, 484 | 12, 485 | 12, 486 | 9, 487 | 12, 488 | 15, 489 | 15, 490 | 12, 491 | 12, 492 | 9, 493 | 15, 494 | 6, 495 | 15, 496 | 12, 497 | 6, 498 | 3, 499 | 6, 500 | 9, 501 | 9, 502 | 12, 503 | 9, 504 | 12, 505 | 12, 506 | 15, 507 | 9, 508 | 12, 509 | 12, 510 | 15, 511 | 6, 512 | 9, 513 | 9, 514 | 6, 515 | 9, 516 | 12, 517 | 12, 518 | 15, 519 | 12, 520 | 15, 521 | 15, 522 | 6, 523 | 12, 524 | 9, 525 | 15, 526 | 12, 527 | 9, 528 | 6, 529 | 12, 530 | 3, 531 | 9, 532 | 12, 533 | 12, 534 | 15, 535 | 12, 536 | 15, 537 | 9, 538 | 12, 539 | 12, 540 | 15, 541 | 15, 542 | 6, 543 | 9, 544 | 12, 545 | 6, 546 | 3, 547 | 6, 548 | 9, 549 | 9, 550 | 6, 551 | 9, 552 | 12, 553 | 6, 554 | 3, 555 | 9, 556 | 6, 557 | 12, 558 | 3, 559 | 6, 560 | 3, 561 | 3, 562 | 0, 563 | }; 564 | 565 | return NumVertsTable; 566 | } 567 | virtual uint32 GetResourceDataSize() const override 568 | { 569 | return NumElements * BytesPerElement; 570 | } 571 | virtual void Discard() override { } 572 | virtual bool IsStatic() const override { return false; } 573 | virtual bool GetAllowCPUAccess() const override { return false; } 574 | virtual void SetAllowCPUAccess(bool bInNeedsCPUAccess) override { } 575 | }; 576 | } -------------------------------------------------------------------------------- /Source/GraphicsExamples/ProceduralMeshExample/ComputeShader/MarchingCubes/MarchingCubesProceduralMeshActor.cpp: -------------------------------------------------------------------------------- 1 | #include "MarchingCubesProceduralMeshActor.h" 2 | 3 | #include "MarchingCubeTables.h" 4 | #include "ProceduralMesh/ComputeShaderProceduralMeshProxy.h" 5 | #include "ProceduralMesh/ComputeShaderProceduralMeshComponent.h" 6 | #include "ProceduralMesh/MarchingCubeShaders/MarchingCubeShaders.h" 7 | 8 | // for using RenderGraph 9 | #include "RenderGraph.h" 10 | #include "RenderGraphUtils.h" 11 | 12 | AMarchingCubesProceduralMeshActor::AMarchingCubesProceduralMeshActor() 13 | { 14 | PrimaryActorTick.bCanEverTick = true; 15 | } 16 | 17 | void AMarchingCubesProceduralMeshActor::OnCreatedSceneProxyRendererResources(FCSProceduralMeshSceneProxy* SceneProxy) 18 | { 19 | ensure(IsInRenderingThread()); 20 | 21 | // initialize lookup buffers 22 | { 23 | ensure(IsInRenderingThread()); 24 | 25 | using namespace MarchingCubesResourceProvider; 26 | 27 | FNumVertsResourceArray NumVertsResourceArray = {}; 28 | NumVerticesLookupTable.Initialize(FNumVertsResourceArray::BytesPerElement, FNumVertsResourceArray::NumElements, EPixelFormat::PF_R8_UINT, BUF_Static, TEXT("NumVerticesLookupTable"), &NumVertsResourceArray); 29 | 30 | FTriTableBulkData TriTableBulkData; 31 | FRHIResourceCreateInfo CreateInfo = FRHIResourceCreateInfo(&TriTableBulkData); 32 | CreateInfo.DebugName = TEXT("TriangleVerticesLookupTable"); 33 | TriangleVerticesLookupTable.Initialize(FTriTableBulkData::BytesPerElement, FTriTableBulkData::SizeX, FTriTableBulkData::SizeY, EPixelFormat::PF_R8_UINT, TexCreate_ShaderResource, CreateInfo); 34 | } 35 | 36 | // Tick scene proxy once 37 | { 38 | FRHICommandListImmediate& RHICmdList = FRHICommandListExecutor::GetImmediateCommandList(); 39 | 40 | FRTParams RTParams = {}; 41 | RTParams.SceneProxy = SceneProxy; 42 | RTParams.IsoValue = IsoValue; 43 | RTParams.Time = AnimationTime; 44 | 45 | TickSceneProxy_RT(RHICmdList, RTParams); 46 | } 47 | } 48 | 49 | void AMarchingCubesProceduralMeshActor::BeginDestroy() 50 | { 51 | ENQUEUE_RENDER_COMMAND(MarchingCubesProceduralMeshActor_DestroyResources)( 52 | [this](FRHICommandListImmediate& RHICmdList) 53 | { 54 | NumVerticesLookupTable.Release(); 55 | TriangleVerticesLookupTable.Release(); 56 | }); 57 | 58 | Super::BeginDestroy(); 59 | } 60 | 61 | void AMarchingCubesProceduralMeshActor::ResetIndirectDrawArgs(FRDGBuilder& GraphBuilder, const FRTParams& RTParams) 62 | { 63 | ensure(IsInRenderingThread()); 64 | 65 | const FIntVector GroupCount(1, 1, 1); 66 | 67 | FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(RTParams.SceneProxy->GetScene().GetFeatureLevel()); 68 | TShaderMapRef ComputeShader(GlobalShaderMap); 69 | 70 | FResetIndirectArgsCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 71 | PassParameters->IndirectDrawArgsBuffer = RTParams.SceneProxy->GetIndirectDrawArgsBuffer().UAV; 72 | 73 | ValidateShaderParameters(ComputeShader, *PassParameters); 74 | 75 | FComputeShaderUtils::AddPass( 76 | GraphBuilder, 77 | RDG_EVENT_NAME("ResetIndirectDrawArgs"), 78 | ComputeShader, PassParameters, GroupCount); 79 | } 80 | 81 | void AMarchingCubesProceduralMeshActor::GenerateTriangles(FRDGBuilder& GraphBuilder, const FRTParams& RTParams) 82 | { 83 | ensure(IsInRenderingThread()); 84 | 85 | const FIntVector GroupCount( 86 | FMath::CeilToInt((float)VoxelCount.X / (float)FGenerateTrianglesCS::ThreadGroupSizeX), 87 | FMath::CeilToInt((float)VoxelCount.Y / (float)FGenerateTrianglesCS::ThreadGroupSizeY), 88 | FMath::CeilToInt((float)VoxelCount.Z / (float)FGenerateTrianglesCS::ThreadGroupSizeZ)); 89 | 90 | FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(RTParams.SceneProxy->GetScene().GetFeatureLevel()); 91 | TShaderMapRef ComputeShader(GlobalShaderMap); 92 | 93 | FGenerateTrianglesCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 94 | PassParameters->PositionBuffer = RTParams.SceneProxy->GetPositionBuffer().UAV; 95 | PassParameters->TangentBuffer = RTParams.SceneProxy->GetTangentBuffer().UAV; 96 | PassParameters->IndirectDrawArgsBuffer = RTParams.SceneProxy->GetIndirectDrawArgsBuffer().UAV; 97 | PassParameters->NumVerticesLookupTable = NumVerticesLookupTable.SRV; 98 | PassParameters->TriangleVerticesLookupTable = TriangleVerticesLookupTable.SRV; 99 | PassParameters->VoxelCount = VoxelCount; 100 | PassParameters->VoxelSize = VoxelSize; 101 | PassParameters->IsoValue = RTParams.IsoValue; 102 | PassParameters->Time = RTParams.Time; 103 | PassParameters->MaxVertices = RTParams.SceneProxy->GetMaxPrimitiveCount() * 3; 104 | 105 | ValidateShaderParameters(ComputeShader, *PassParameters); 106 | 107 | FComputeShaderUtils::AddPass( 108 | GraphBuilder, 109 | RDG_EVENT_NAME("GenerateTriangles"), 110 | ComputeShader, PassParameters, GroupCount); 111 | } 112 | 113 | void AMarchingCubesProceduralMeshActor::TickSceneProxy_RT(FRHICommandListImmediate& RHICmdList, const FRTParams& RTParams) 114 | { 115 | ensure(IsInRenderingThread()); 116 | 117 | if (RTParams.SceneProxy && RTParams.SceneProxy->HasValidBuffers()) 118 | { 119 | FMemMark Mark(FMemStack::Get()); 120 | FRDGBuilder GraphBuilder(RHICmdList); 121 | 122 | ResetIndirectDrawArgs(GraphBuilder, RTParams); 123 | 124 | GenerateTriangles(GraphBuilder, RTParams); 125 | 126 | GraphBuilder.Execute(); 127 | } 128 | } 129 | 130 | void AMarchingCubesProceduralMeshActor::Tick(float DeltaSeconds) 131 | { 132 | FRTParams RTParams = {}; 133 | RTParams.SceneProxy = (FCSProceduralMeshSceneProxy*)ProceduralMeshComponent->SceneProxy; 134 | RTParams.IsoValue = IsoValue; 135 | RTParams.Time = AnimationTime; 136 | 137 | ENQUEUE_RENDER_COMMAND(MarchingCubesProceduralMeshActor_TickSceneProxy)( 138 | [this, RTParams](FRHICommandListImmediate& RHICmdList) 139 | { 140 | TickSceneProxy_RT(RHICmdList, RTParams); 141 | }); 142 | 143 | AnimationTime += DeltaSeconds; 144 | 145 | Super::Tick(DeltaSeconds); 146 | } -------------------------------------------------------------------------------- /Source/GraphicsExamples/ProceduralMeshExample/ComputeShader/MarchingCubes/MarchingCubesProceduralMeshActor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RHI.h" 4 | #include "ProceduralMesh/ComputeShaderProceduralMeshActor.h" 5 | #include "MarchingCubesProceduralMeshActor.generated.h" 6 | 7 | class FRDGBuilder; 8 | class FRHICommandListImmediate; 9 | 10 | UCLASS() 11 | class GRAPHICSEXAMPLES_API AMarchingCubesProceduralMeshActor : public AComputeShaderProceduralMeshActor 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | AMarchingCubesProceduralMeshActor(); 17 | 18 | virtual void Tick(float DeltaSeconds) override; 19 | 20 | protected: 21 | virtual void OnCreatedSceneProxyRendererResources(FCSProceduralMeshSceneProxy* SceneProxy) override; 22 | virtual void BeginDestroy() override; 23 | 24 | private: 25 | struct FRTParams 26 | { 27 | FCSProceduralMeshSceneProxy* SceneProxy = nullptr; 28 | float IsoValue = 0.f; 29 | float Time = 0.f; 30 | }; 31 | void TickSceneProxy_RT(FRHICommandListImmediate& RHICmdList, const FRTParams& RTParams); 32 | void ResetIndirectDrawArgs(FRDGBuilder& GraphBuilder, const FRTParams& RTParams); 33 | void GenerateTriangles(FRDGBuilder& GraphBuilder, const FRTParams& RTParams); 34 | 35 | public: 36 | UPROPERTY(EditAnywhere, Category = "Voxels") 37 | FIntVector VoxelCount = FIntVector(32, 32, 32); 38 | 39 | UPROPERTY(EditAnywhere, Category = "Voxels") 40 | float VoxelSize = 4.f; 41 | 42 | UPROPERTY(EditAnywhere, BlueprintReadwrite, Category = "Voxels") 43 | float IsoValue = 0.1; 44 | 45 | private: 46 | // GPU readonly data, these can be global params since they are same for all the actors 47 | FReadBuffer NumVerticesLookupTable; 48 | FTextureReadBuffer2D TriangleVerticesLookupTable; 49 | 50 | float AnimationTime = 0.f; 51 | }; -------------------------------------------------------------------------------- /Source/GraphicsExamples/ProceduralMeshExample/CpuToGpu/HelloTriangleProceduralMeshActor.cpp: -------------------------------------------------------------------------------- 1 | #include "HelloTriangleProceduralMeshActor.h" 2 | 3 | #include "ProceduralMesh/ComputeShaderProceduralMeshComponent.h" 4 | #include "ProceduralMesh/ComputeShaderProceduralMeshProxy.h" 5 | 6 | AHelloTriangleProceduralMeshActor::AHelloTriangleProceduralMeshActor() 7 | { 8 | PrimaryActorTick.bCanEverTick = false; 9 | } 10 | 11 | void AHelloTriangleProceduralMeshActor::OnCreatedSceneProxyRendererResources(FCSProceduralMeshSceneProxy* SceneProxy) 12 | { 13 | ensure(IsInRenderingThread()); 14 | 15 | if (SceneProxy && SceneProxy->HasValidBuffers()) 16 | { 17 | if (FVector* VertPositions = (FVector*)RHILockVertexBuffer(SceneProxy->GetPositionBuffer().VertexBufferRHI, 0, sizeof(FVector) * 3, RLM_WriteOnly)) 18 | { 19 | VertPositions[0] = FVector(-TriangleSize, -TriangleSize, 0); 20 | VertPositions[1] = FVector(0, TriangleSize, 0); 21 | VertPositions[2] = FVector(TriangleSize, -TriangleSize, 0); 22 | RHIUnlockVertexBuffer(SceneProxy->GetPositionBuffer().VertexBufferRHI); 23 | } 24 | 25 | if (FPackedNormal* VertTangents = (FPackedNormal*)RHILockVertexBuffer(SceneProxy->GetTangentBuffer().VertexBufferRHI, 0, sizeof(FPackedNormal) * 6, RLM_WriteOnly)) 26 | { 27 | VertTangents[0] = FPackedNormal(FVector(1, 0, 0)); 28 | VertTangents[1] = FPackedNormal(FVector(0, 0, 1)); 29 | 30 | VertTangents[2] = FPackedNormal(FVector(1, 0, 0)); 31 | VertTangents[3] = FPackedNormal(FVector(0, 0, 1)); 32 | 33 | VertTangents[4] = FPackedNormal(FVector(1, 0, 0)); 34 | VertTangents[5] = FPackedNormal(FVector(0, 0, 1)); 35 | 36 | RHIUnlockVertexBuffer(SceneProxy->GetTangentBuffer().VertexBufferRHI); 37 | } 38 | 39 | if (FVector2D* VertTexCoords = (FVector2D*)RHILockVertexBuffer(SceneProxy->GetTexCoordBuffer().VertexBufferRHI, 0, sizeof(FVector2D) * 3, RLM_WriteOnly)) 40 | { 41 | VertTexCoords[0] = FVector2D(0.f, 0.f); 42 | VertTexCoords[1] = FVector2D(0.5f, 1.f); 43 | VertTexCoords[2] = FVector2D(1.f, 0.f);; 44 | 45 | RHIUnlockVertexBuffer(SceneProxy->GetTexCoordBuffer().VertexBufferRHI); 46 | } 47 | 48 | if (FColor* VertColors = (FColor*)RHILockVertexBuffer(SceneProxy->GetColorBuffer().VertexBufferRHI, 0, sizeof(FColor) * 3, RLM_WriteOnly)) 49 | { 50 | VertColors[0] = FColor::Red; 51 | VertColors[1] = FColor::Green; 52 | VertColors[2] = FColor::Blue; 53 | 54 | RHIUnlockVertexBuffer(SceneProxy->GetColorBuffer().VertexBufferRHI); 55 | } 56 | 57 | if (FRHIDrawIndirectParameters* ArgParams = (FRHIDrawIndirectParameters*)RHILockVertexBuffer(SceneProxy->GetIndirectDrawArgsBuffer().VertexBufferRHI, 0, sizeof(FRHIDrawIndirectParameters), RLM_WriteOnly)) 58 | { 59 | ArgParams->VertexCountPerInstance = 3; 60 | ArgParams->InstanceCount = 1; 61 | ArgParams->StartVertexLocation = 0; 62 | ArgParams->StartInstanceLocation = 0; 63 | 64 | RHIUnlockVertexBuffer(SceneProxy->GetIndirectDrawArgsBuffer().VertexBufferRHI); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Source/GraphicsExamples/ProceduralMeshExample/CpuToGpu/HelloTriangleProceduralMeshActor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ProceduralMesh/ComputeShaderProceduralMeshActor.h" 4 | #include "HelloTriangleProceduralMeshActor.generated.h" 5 | 6 | UCLASS() 7 | class GRAPHICSEXAMPLES_API AHelloTriangleProceduralMeshActor : public AComputeShaderProceduralMeshActor 8 | { 9 | GENERATED_BODY() 10 | 11 | public: 12 | AHelloTriangleProceduralMeshActor(); 13 | 14 | private: 15 | virtual void OnCreatedSceneProxyRendererResources(FCSProceduralMeshSceneProxy* SceneProxy) override; 16 | 17 | public: 18 | UPROPERTY(EditAnywhere, Category="ProceduralMesh") 19 | float TriangleSize = 128; 20 | }; -------------------------------------------------------------------------------- /Source/GraphicsExamplesEditor.Target.cs: -------------------------------------------------------------------------------- 1 | using UnrealBuildTool; 2 | using System.Collections.Generic; 3 | 4 | public class GraphicsExamplesEditorTarget : TargetRules 5 | { 6 | public GraphicsExamplesEditorTarget(TargetInfo Target) : base(Target) 7 | { 8 | Type = TargetType.Editor; 9 | DefaultBuildSettings = BuildSettingsVersion.V2; 10 | 11 | ExtraModuleNames.AddRange( new string[] { "GraphicsExamples" } ); 12 | } 13 | } 14 | --------------------------------------------------------------------------------