【转载】UE4.24 中实现简单 Shader 插件

451 阅读3分钟

原文链接:

  1. UE4.24中实现简单Shader插件(1)-Color
  2. UE4.24中实现简单Shader插件(2)-Texture
  3. UE4.24中实现简单Shader插件(3)-Uniform

Color

前言

UE 中 Shader 主要分成两种:一种是 Global Shader,另外一种是 Material Shader。本文将参考下面两位大佬文章在插件中实现 Global Shader

  1. YivanLee:虚幻4渲染编程(Shader篇)【第二卷:不用虚幻4Shader管线使用自己的shader】

  2. bluerose:(虚幻4Shader篇)开始编写最简单的Shader

本文重点要把开发步骤介绍清楚。文章中代码大部分将使用截图,真实的代码请参考:

步骤

1. 新建插件 ShadertestPlugin

  • ShadertestPlugin 目录下新建 Shaders/Private/MyShader.usf 文件
  • Public 目录下新建 MyShaderTest.h 文件,以及在 Private 目录下新建 MyShaderTest.cpp 文件

2. 为 MyShader.usf 添加代码

将外部变量 SimpleColor 传入 Pixel Shader 函数,修改 Pixel 的颜色

3. 在 MyShaderTest.h 新建 UBlueprintFunctionLibrary

image.png

image.png

其中

  • DrawTestShaderRenderTarget 为蓝图要调用函数
  • 参数 OutputRenderTargetRenderTarget
  • 参数 MyColor为FLinearColor ,要传入 Shader 中的变量

4. 在 UEditor 建立资源,调用 DrawTestShaderRenderTarget 函数

(1) 在 UEditor 中新建 Actor(BP_ShaderTest)、Material(M_ShaderTest)、 RenderTarget(ShaderTest_RT)

(2) 将 M_ShaderTest 赋值给场景中 StaticMeshActor

(3) 将 ShaderTest_RT 作为纹理资源,引入 M_ShaderTest 材质

(4) 在 BP_ShaderTest 中调用 DrawTestShaderRenderTarget 函数,更新 RenderTarget(ShaderTest_RT),进而修改 Material(M_ShaderTest),从而改变 StaticMeshActor 外观属性

其中键盘上 1,2,3 用于修改前面提到 MyColor 的值。这个值用于修改 MyShader.usfSimpleColor 值。

5. 剖析上图中的 DrawTestShaderRenderTarget 函数

image.png

该函数调用另外一个静态全局函数DrawTestShaderToRenderTarget_RenderThread 来完成渲染

6. 剖析 DrawTestShaderToRenderTarget_RenderThread 函数

  • 图1

image.png

6.1. 剖析 FMyShaderTestVSFMyShaderTestPS 定义(图1中红框1中)

FMyShaderTestVSFMyShaderTestPS 都是继承 FMyShaderTest

image.png

FMyShaderTest 继承自 FGlobalShader,其中 SetParameters 函数将外部 SimpleColorValueFShaderParameter 参数 SimpleColorVal

FMyShaderTestVSFMyShaderTestPSMyShader.usf 进行绑定,这样使用 FMyShaderTest::SetParameters 就能直接将颜色值赋值到 MyShader.usfSimpleColor 变量

其中,

MyShaders 是一个虚拟路径,需要在插件 Module::StartupModule 中构建

6.2. 调用 FMyShaderTestPS::SetParameters 将外部颜色赋值给 Shader 文件中 SimpleColor 变量(图1中蓝图框2)

6.3. 传入三角形顶点与索引数据到 Shader 中进行绘制(图1中绿色框3)

其中在 FMyVertexBuffer 创建顶点,在 FMyIndexBuffer 创建索引。

另外,还需要对顶点做下 VertexDeclartion

FMyVertexDeclartion图1 中黄色框 4 中用到。

image.png

7. 配置 .build.cs 文件,修改 PublicDependencyModuleNamesPrivateDependencyModuleNames

8. 配置 .uplugin 文件,修改 LoadingPhase

Texture

新建简单 Shader 插件,请参考前一节内容。

本文将介绍如何往 Shader 中传入纹理数据。

.Build.cs.uplugin 文件、蓝图资源跟上面文档中是完全一样的,不同的地方在下面图中有红色标出。

1. MyShader.usf

2. TextureShaderTest.h

image.png

3. TextureShaderTest.cpp

image.png

image.png

image.png

image.png

image.png

image.png

Uniform

往 Shader 中添加颜色和纹理变量,请参考前两节内容

本文章主要介绍如何向 Shader 添加常用的 Uniform 变量。本文重点介绍过程,如果想知道 Why 可以看看下面这篇文章。

1. 在 MyShader.usf 使用 Uniform 变量

2. 在 .cpp 文件申明与 .usfFMyUniform 绑定的变量

3. 在 .h 文件申明用于往 FMyUniformStructData 传输数据的结构体 FMyShadersStructData

4. 调用 SetUniformBufferParameterImmediate 将 C++ 值传递到 GPU 中 Shader 中去

image.png

5. 蓝图中调用绘制函数和修改 FMyShaderStructData

image.png

创建 Shader 插件找不到 Shader 文件

UE4.24/4.25 参考官网文档创建 Shader 插件

有两个问题需要注意

  1. 文档中代码都比较老,不能用于参考。如果要参考,建议直接可以读源码中的代码。
  2. 启动 UE 时候,报 “找不到 MyShader.USF 文件” 错误。

需要在模块启动中 StartupModule(),为 Shader 注册一个映射路径

FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("TemaranShaderTutorial"))->GetBaseDir(), TEXT("Shaders"));
	AddShaderSourceDirectoryMapping(TEXT("/TutorialShaders"), PluginShaderDir);

然后,再调用

IMPLEMENT_GLOBAL_SHADER(FSimplePassThroughVS, "/TutorialShaders/Private/PixelShader.usf", "MainVertexShader", SF_Vertex);
IMPLEMENT_GLOBAL_SHADER(FPixelShaderExamplePS, "/TutorialShaders/Private/PixelShader.usf

延申阅读

【转载】UE4.24 中实现简单 Shader 插件(4) —— Compute Shader