当前位置:网站首页>(UE4 4.27) add globalshder to the plug-in
(UE4 4.27) add globalshder to the plug-in
2022-06-12 06:04:00 【Senior brother Dai Dai】
Preface
In the last section, we introduced UE4 GlobalShader The situation of , And some modifications have been made in the engine code to explain GlobalShader Statement of - Definition - Use . In fact, UE4 In development , GlobalShader Not necessarily used in modifying engine code , It may also be used in plug-ins , such as LensDistortion The plug-in is to use GlobalShader Customize one RenderToTexture The function of . Of course, in the plug-in ,GlobalShader The usage scenarios for are not limited to RenderToTexture, Sure ComputeShader And so on to speed up some parallel computing ( Based on GPU Vegetation plug-ins, etc ).(UE4 4.27) Customize GlobalShader
https://blog.csdn.net/qq_29523119/article/details/120573174?spm=1001.2014.3001.5501
GlobalShader Plug in declaration steps
function
Let's do one to color the picture and render it to RenderTexture The function of

Declaration definition GlobalShader
#pragma once
#include "CoreMinimal.h"
#include "GlobalShader.h"
#include "ShaderParameters.h"
#include "Shader.h"
/**
*
*/
class FDrawVS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FDrawVS, Global);
public:
FDrawVS() {};
FDrawVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
:FGlobalShader(Initializer)
{
}
static bool ShouldCompilePermutation(const FShaderPermutationParameters& Parameters)
{
return true;
}
};
class FDrawPS : public FGlobalShader
{
DECLARE_SHADER_TYPE(FDrawPS, Global);
public:
FDrawPS() {};
FDrawPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
:FGlobalShader(Initializer)
{
Color.Bind(Initializer.ParameterMap, TEXT("MyColor"));
ColorScale.Bind(Initializer.ParameterMap, TEXT("MyColorScale"));
Texture.Bind(Initializer.ParameterMap, TEXT("InTexture"));
TextureSampler.Bind(Initializer.ParameterMap, TEXT("InTextureSampler"));
}
/** Should the shader be cached? Always. */
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
}
void SetParam(FRHICommandList& RHICmdList, const FTexture* TextureValue, const FLinearColor& InColor, float InColorScale)
{
FRHIPixelShader* PS = RHICmdList.GetBoundPixelShader();
SetTextureParameter(RHICmdList, PS, Texture, TextureSampler, TextureValue);
SetShaderValue(RHICmdList, PS, Color, InColor);
SetShaderValue(RHICmdList, PS, ColorScale, InColorScale);
}
private:
LAYOUT_FIELD(FShaderParameter, Color);
LAYOUT_FIELD(FShaderParameter, ColorScale);
LAYOUT_FIELD(FShaderResourceParameter, Texture);
LAYOUT_FIELD(FShaderResourceParameter, TextureSampler);
};Redirect Shader Path and Shader Code
void FTestShader::StartupModule()
{
FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("TestShader"))->GetBaseDir(), TEXT("Shaders"));
AddShaderSourceDirectoryMapping(TEXT("/Plugin/TestShader"), PluginShaderDir);
}IMPLEMENT_SHADER_TYPE(, FDrawVS, TEXT("/Plugin/TestShader/DrawShader.usf"), TEXT("MainVS"), SF_Vertex);
IMPLEMENT_SHADER_TYPE(, FDrawPS, TEXT("/Plugin/TestShader/DrawShader.usf"), TEXT("MainPS"), SF_Pixel);DrawShader.usf
#include "/Engine/Public/Platform.ush"
void MainVS(
in float3 InPostion : ATTRIBUTE0,
in float2 UV : ATTRIBUTE1,
out float2 OutUV : TEXCOORD0,
out float4 Output : SV_POSITION)
{
OutUV = UV;
Output = float4(InPostion, 1.0f);
}
Texture2D InTexture;
SamplerState InTextureSampler;
float4 MyColor;
float MyColorScale;
void MainPS(
in float2 UV : TEXCOORD0,
out float4 OutColor : SV_Target0)
{
float4 TextureColor = InTexture.Sample(InTextureSampler, UV);
OutColor = MyColor * TextureColor * MyColorScale;
//return float4(1.0f, 1.0f, 1.0f, 1.0f);
}Blue library static RT function
void UMyShaderBPFunctionLibrary::DrawTestShaderToRenderTexture(
const UObject* WorldContextObject,
const UTexture2D* InTexture,
class UTextureRenderTarget2D* OutputRenderTarget,
const FLinearColor& Color,
float ColorScale)
{
UWorld* World = WorldContextObject->GetWorld();
ERHIFeatureLevel::Type FeatureLevel = World->Scene->GetFeatureLevel();
if (FeatureLevel < ERHIFeatureLevel::SM5)
{
UE_LOG(LogTemp, Warning, TEXT("FeatureLevel < ERHIFeatureLevel::SM5"));
return;
}
if (nullptr == InTexture)
{
UE_LOG(LogTemp, Warning, TEXT("InTexture Is NULL"));
return;
}
FTextureRenderTargetResource* TextureRenderTargetSource = OutputRenderTarget->GameThread_GetRenderTargetResource();
FTexture* TextureSource = InTexture->Resource;
ENQUEUE_RENDER_COMMAND(TestShaderCommand)(
[TextureSource, TextureRenderTargetSource, FeatureLevel, Color, ColorScale](FRHICommandListImmediate& RHICmdList)
{
DrawTestShaderToRenderTexture_RenderThread(RHICmdList, TextureSource, TextureRenderTargetSource, FeatureLevel, Color, ColorScale);
}
);
}here ENQUEUE_RENDER_COMMAND Indicates that the rendering instruction is sent from the game thread to the rendering thread , and FRHICommandListImmediate And the last one FRHICommandList It's different ,FRHICommandListImmediate Represents the immediate mode , Represents rendering immediately after sending it to the rendering thread , You can get the rendering results . and FRHICommandList There is a queue of rendering instructions , The instruction collection will be different from the delayed rendering .
Vertex data structures and VertexFormat Statement
struct FCustomVertex
{
FVector Pos;
FVector2D UV;
FCustomVertex()
{
}
FCustomVertex(const FVector& VertexPos, const FVector2D& VertexUV)
:Pos(VertexPos), UV(VertexUV)
{
}
};
//declare custom vertex format
class FMyTestVertexDeclaration : public FRenderResource
{
public:
FVertexDeclarationRHIRef VertexDeclarationRHI;
virtual void InitRHI() override
{
FVertexDeclarationElementList Elements;
uint16 Stride = sizeof(FCustomVertex);
//Pos-float3
Elements.Add(FVertexElement(0, STRUCT_OFFSET(FCustomVertex, Pos), VET_Float3, 0, Stride));
//UV-float2
Elements.Add(FVertexElement(0, STRUCT_OFFSET(FCustomVertex, UV), VET_Float2, 1, Stride));
VertexDeclarationRHI = PipelineStateCache::GetOrCreateVertexDeclaration(Elements);
}
virtual void ReleaseRHI() override
{
VertexDeclarationRHI.SafeRelease();
}
};
TGlobalResource<FMyTestVertexDeclaration> GCustomVertexDeclaration;Render data preparation , Draw
static void DrawTestShaderToRenderTexture_RenderThread(
FRHICommandListImmediate& RHICmdList,
FTexture* InTextureResource,
FTextureRenderTargetResource* OutTextureRenderTargetResource,
ERHIFeatureLevel::Type FeatureLevel,
const FLinearColor& Color,
float ColorScale)
{
check(IsInRenderingThread());
FRHITexture2D* RenderTargetTexture = OutTextureRenderTargetResource->GetRenderTargetTexture();
RHICmdList.Transition(FRHITransitionInfo(RenderTargetTexture, ERHIAccess::SRVMask, ERHIAccess::RTV));
FRHIRenderPassInfo RPInfo(RenderTargetTexture, ERenderTargetActions::DontLoad_Store);
RHICmdList.BeginRenderPass(RPInfo, TEXT("Render Test Shader To Texture"));
{
FIntPoint ViewportSize(OutTextureRenderTargetResource->GetSizeX(), OutTextureRenderTargetResource->GetSizeY());
// Upate viewport
RHICmdList.SetViewport(0, 0, 0.0f, ViewportSize.X, ViewportSize.Y, 1.0f);
// Get Shaders
FGlobalShaderMap* GlobalShaderMap = GetGlobalShaderMap(FeatureLevel);
TShaderMapRef<FDrawVS> VertexShader(GlobalShaderMap);
TShaderMapRef<FDrawPS> PixelShader(GlobalShaderMap);
// Setup Pipeline state
FGraphicsPipelineStateInitializer GraphicsPSOInit;
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
GraphicsPSOInit.PrimitiveType = PT_TriangleStrip;
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GCustomVertexDeclaration.VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = VertexShader.GetVertexShader();
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = PixelShader.GetPixelShader();
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
// update shader uniform parameters
PixelShader->SetParam(RHICmdList, InTextureResource, Color, ColorScale);
// Create VertexBuffer and setup
static const uint32 VERTEX_SIZE = sizeof(FCustomVertex) * 4;
FRHIResourceCreateInfo CreateInfo;
FVertexBufferRHIRef VertexBufferRHI = RHICreateVertexBuffer(VERTEX_SIZE, BUF_Static, CreateInfo);
void* VoidPtr = RHILockVertexBuffer(VertexBufferRHI, 0, VERTEX_SIZE, RLM_WriteOnly);
FCustomVertex Vertices[4];
Vertices[0] = FCustomVertex(FVector(-1.0f, 1.0f, 0.0f), FVector2D(0.0f, 0.0f));
Vertices[1] = FCustomVertex(FVector(1.0f, 1.0f, 0), FVector2D(1.0f, 0.0f));
Vertices[2] = FCustomVertex(FVector(-1.0f, -1.0f, 0), FVector2D(0.0f, 1.0f));
Vertices[3] = FCustomVertex(FVector(1.0f, -1.0f, 0), FVector2D(1.0f, 1.0f));
FMemory::Memcpy(VoidPtr, (void*)Vertices, VERTEX_SIZE);
RHIUnlockVertexBuffer(VertexBufferRHI);
RHICmdList.SetStreamSource(0, VertexBufferRHI, 0);
RHICmdList.DrawPrimitive(0, 2, 1);
}
RHICmdList.EndRenderPass();
RHICmdList.Transition(FRHITransitionInfo(RenderTargetTexture, ERHIAccess::RTV, ERHIAccess::SRVMask));
}Results show


summary
In general, the declaration and definition of various rendering data Directx11 Very similar .
Plug in code link
https://download.csdn.net/download/qq_29523119/33147630
Reference
【1】https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/Rendering/ShaderInPlugin/Overview/
【2】UE4 Of LensDistortion Plug ins and Texture2DPreview.cpp
边栏推荐
- The application could not be installed: INSTALL_FAILED_TEST_ONLY
- Database Experiment 3: data query
- Database Experiment 2: data update
- MySQL master-slave, 6 minutes to master
- Guns框架多数据源配置,不修改配置文件
- 468. verifying the IP address
- Tabulation skills and matrix processing skills
- sqlite交叉編譯動態庫
- Mysql笔记
- Brief introduction to project development process
猜你喜欢

Front desk display LED number (number type on calculator)

User login 【 I 】

Unable to access this account. You may need to update your password or grant the account permission to synchronize to this device. Tencent corporate email

Introduction to thread pool: ThreadPoolExecutor

Leetcode-1535. Find the winner of the array game

Data integration framework seatunnel learning notes

Leetcode simple problem: converting an integer to the sum of two zero free integers

Poisson disk sampling for procedural placement

Login authentication filter

Findasync and include LINQ statements - findasync and include LINQ statements
随机推荐
March 23, 2021
Leetcode-1705. Maximum number of apples to eat
User login [next]
Directx11 advanced tutorial cluster based deffered shading
Mysql笔记
Unity vscode cannot jump to definition
Why don't databases use hash tables?
Leetcode-1604. Warning people who use the same employee card more than or equal to three times within one hour
User login 【 I 】
Heap classical problem
IDEA常用配置
Introduction to redis high availability
Research Report on water sports shoes industry - market status analysis and development prospect forecast
Win10 desktop unlimited refresh
项目开发流程简单介绍
Guns框架多数据源配置,不修改配置文件
Stack and queue classic interview questions
Automatic annotation of target detection based on lffd model to generate XML file
Directx11 advanced tutorial PBR (1) summary of physical phenomena of light
[PowerShell] command line output and adding system environment variables