์ด๋ฒ์๋ RDG๋ฅผ ์ฌ์ฉํ์ฌ ๋จธํฐ๋ฆฌ์ผ ๊ทธ๋ํ ์์ด C++ ์ฝ๋(+ ์์ด๋ ์ฝ๋)๋ก ์์ด๋๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์๋ ค๋๋ฆฌ๊ฒ ์ผ
#5.1 ๋ฒ์ ๊ธฐ์ค์
๋ ๋ ํ๋์จ์ด ์ธํฐํ์ด์ค(RHI), ๋ ๋ ๋ํ๋์ ๊ทธ๋ํ(RDG)
RHI๋ ์ธํฐํ์ด์ค๋ผ๋ ๋จ์ด์์ ์ ์ ์๋ฏ์ด
๋ค์ํ ๋ ๋๋ง API(DX12, Vulkan ๋ฑ)์ ์ ์ฐํ๊ฒ ๋์ํ ์ ์๊ฒ ํด์ฃผ๋ ๋ ์ด์ด์
์ฌ์ค RHI์ ๊ธฐ๋ฅ์ ๋ณด๋ฉด ์๋นํ ๋์กํ๊ณ ์๋์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ
์ด๋ฐRHI์ ๋ ๋ ์ปค๋งจ๋๋ค์ ์ด๋์ ๋ ์๋ํํด์ฃผ๋ ๊ฒ RDG์ธ๊ฑฐ์ฌ
์์ํ ์ ๋๋ก ์ธ์ธํ๊ณ ์น์ ํ ์ฅ๋ฌธ์ ์ฃผ์๋ค์ ๋ณด๊ณ ์์ผ๋ฉด ๋๋ฌผ์ด ์์ ๊ฐ๋ฆด ์ ๋์;;
์ฌํผ ๋์ถฉ ์ด๋ฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ ์์ด๋๋ฅผ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ผ
ํ๋ก์ ํธ์ ๋ชจ๋ ์์ฑํ๊ธฐ
๊ธ๋ก๋ฒ ์์ด๋๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๊ธฐ ์ํด์๋ ์์ง์ด ๋ค ๋ก๋๋๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๋ก๋๋์ด์ผ ํจ
๊ทธ๋์ ์ ๋ชจ๋์ ๋ง๋ค๊ณ ๋ก๋ฉ ํ์ด์ฆ๋ฅผ ์ข ์๋น๊ฒจ ์ค๊ฑฐ์
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | // .uproject ํ์ผ "Modules": [ { // ํ๋ก์ ํธ ์์ฑํ๋ฉด ์๋์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ๋ถ๋ถ "Name": "๋์ถฉ ํ๋ก์ ํธ ์ด๋ฆ", "Type": "Runtime", "LoadingPhase": "Default", "AdditionalDependencies": [ "Engine" ] }, // ์๋ก ์ถ๊ฐํ ๋ชจ๋ ์ ๋ณด { "Name": "CustomShaderModule", "Type": "Runtime", "LoadingPhase": "PostConfigInit" } ], // Source/"ํ๋ก์ ํธ ์ด๋ฆ".Target.cs ํ์ผ using UnrealBuildTool; using System.Collections.Generic; public class UpTarget : TargetRules { public UpTarget( TargetInfo Target) : base(Target) { Type = TargetType.Game; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.AddRange(new string[]{ "Up", "CustomShaderModule" }); } } // Source/"ํ๋ก์ ํธ ์ด๋ฆ"Editor.Target.cs ํ์ผ using UnrealBuildTool; using System.Collections.Generic; public class UpEditorTarget : TargetRules { public UpEditorTarget( TargetInfo Target) : base(Target) { Type = TargetType.Editor; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.AddRange(new string[]{ "Up", "CustomShaderModule" }); } } | cs |
์ฐ์ , "ํ๋ก์ ํธ์ด๋ฆ".uproject, Target.cs, Editor.Target.cs์ ๊ฐ๊ฐ ๋ชจ๋ ์ ๋ณด๋ฅผ ์ถ๊ฐํด์ฃผ์ผ
.uproject ํ์ผ์ json ํ์์ด๋ผ ์ฃผ์์ ์ง์ฐ์
๋๋ ํ๋ก์ ํธ ์ด๋ฆ์ Up๋ก ์ง์ด์ ์ ๋ ๊ฒ ์ผ๋๋ฐ
๋์ถฉ ์์๋ฑํ๊ฒ ํด๋์ค๋ AddRange๋ถ๋ถ ๋ฐ๊พธ์ผ
๊ทธ ํ, ํ๋ก์ ํธ Source ํด๋ ์์ ์ ํด๋ ๋ฐ ํ์ผ๋ค์ ์์ฑํด์ฃผ๊ณ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | //CustomShaderModule.h #pragma once #include "CoreMinimal.h" class FCustomShaderModule : public IModuleInterface { public: virtual void StartupModule() override; virtual void ShutdownModule() override {} }; //CustomShaderModule.cpp #include "CustomShaderModule.h" #include "Modules/ModuleManager.h" IMPLEMENT_MODULE(FCustomShaderModule, CustomShaderModule); void FCustomShaderModule::StartupModule() { FString ModuleDir = FPaths::GameSourceDir() + TEXT("CustomShaderModule/"); FString ShaderDir = FPaths::Combine(ModuleDir, TEXT("Shaders")); AddShaderSourceDirectoryMapping(TEXT("/CustomShaderModule"), ShaderDir); } //CustomShaderModule.Build.cs using UnrealBuildTool; using System.IO; public class CustomShaderModule : ModuleRules { public CustomShaderModule(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" }); PrivateDependencyModuleNames.AddRange(new string[] { "Renderer", "RenderCore", "RHI" }); string EnginePath = Path.GetFullPath(Target.RelativeEnginePath); PublicIncludePaths.Add(EnginePath + "Source/Runtime/Renderer/Private"); } } | cs |
CustomShaderModule.h, cpp, build.cs ํ์ผ์ ์ด๋ ๊ฒ ์์ฑํด์ฃผ์ผ
์ด์ ์๋ก์ด ๋ชจ๋์ด ์ถ๊ฐ๋์์ผ๋ ํ๋ก์ ํธ ํด๋์ ๊ฐ์ binaries, intermediate ํด๋ ์ญ์ ํ
.uproject ํ์ผ ์ฐํด๋ฆญ ํ generate ์ด์ฉ๊ตฌ ๋๋ฅด๊ณ ์๋ฃ๋๋ฉด ๋ฆฌ๋น๋ ํ๋ฒ ๋๋ฆฌ์
์์ด๋ ์ฝ๋ ์์ฑ์ ๋ฐฅ๋จน๊ตฌ ์์ ์ฐ๊ฒ ์ฌ
ํน์ ๊ถ๊ธํ๊ฑฐ ์์ผ๋ฉด ๋๊ธ๋ก ์ง๋ฌธ ์ฃผ์ผ
๊ฐ๋ง์ ์ธ๋ฆฌ์ผ ์๋ฃ๊ตฐ