UE4自定義shader實現高斯模糊效果


項目是根據網上的教程來實現的(資源也是網上的),最終示例效果如下圖

imageimage


這是網上教程的鏈接:https://www.raywenderlich.com/57-unreal-engine-4-custom-shaders-tutorial


教程使用的是后處理技術(Post Process),引用了 PPI_Blur 這個材質實例(Material Instance)

image

材質實例可以修改 PP_GaussianBlur 暴露的參數Radius(模糊半徑),保存后便瀏覽(Browse)不同的模糊效果。




按照教程步驟操作,遇到二個問題:

(1)#include "/Project/Gaussian.usf" 報錯

(2)SceneTextureIndex要選擇”Post Process Input 0”(后期處理輸入0,對應索引值14),教程截圖給的是 WorldNormal(場景法線)


先看如何解決無法使用 #include ‘xx.usf’這個問題

IMG20210728_205234


(1)先將藍圖工程轉為 C++ 工程,選中工程文件右擊“生成 Visual Studio 工程文件”

image


(2)在當前項目的根目錄創建 Shader 文件夾,里面編寫自定義的 shader 文件(文件以.usf或.ush為后綴)

image


(3)打開< ProjectName >.build.cs文件,為工程添加“RenderCore”組件

image


(4)為工程定義一個自定義的主模塊( ProjectName .h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FCustomShadersModule : public IModuleInterface
{

public:
    virtual void StartupModule() override;
    virtual void ShutdownModule() override;
};

模塊名稱為 F< ProjectName >Module,需要覆寫二個方法:StartupModule、ShutdownModule


在對應的 cpp 文件中,映射“/Project”路徑

// Fill out your copyright notice in the Description page of Project Settings.

#include "CustomShaders.h"
#include "Modules/ModuleManager.h"
#include "Logging/LogMacros.h"
#include "Misc/Paths.h"

void FCustomShadersModule::StartupModule()
{
#if (ENGINE_MINOR_VERSION >= 21)    
    FString ShaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shaders"));
    AddShaderSourceDirectoryMapping("/Project", ShaderDirectory);
#endif
}

void FCustomShadersModule::ShutdownModule()
{

}

IMPLEMENT_PRIMARY_GAME_MODULE(FCustomShadersModule, CustomShaders, "CustomShaders");


到這里便解決了 #include "/Project/Gaussian.usf" 報錯的問題。



PP_GaussianBlur 關鍵的實現部分,我用紅色線框圈了起來。

image

SceneTextureIndex要選擇”Post Process Input 0”(后期處理輸入0,對應索引值14),而不是 WorldNormal。


因為上面我們定義了 Global 函數(全局函數),所以具體實現的 shader 里,結合網上的其它示例,用了二種方法(等價的):一種是調用全局函數,另一種是直接調用當前 shader 內的函數。

// return SceneTextureLookup(GetDefaultSceneTextureUV(Parameters, 2), 2, false);

struct FunctionStruct
{
    //計算一維高斯模糊
    float Cal_1DGaussian(float x)
    {
        return exp(-0.5f * pow(3.141 * x, 2));
    }
};

FunctionStruct FS;


//需要獲得的場景貼圖index
static const int SceneTextureID = 14;

//紋素大小,比如一張512 X 512大小的紋理,那么紋素大小為(1/512)
//用於UV的偏移
float2 TexelSize = View.ViewSizeAndInvSize.zw;

//獲取當前像素的UV
float2 UV = GetDefaultSceneTextureUV(Parameters, SceneTextureID);

//用於存儲累積的顏色
float3 PixelSum = float3(0, 0, 0);

//累積權重值
float WeightSum = 0;


//水平與垂直模糊
for (int x = -BlurRadius; x <= BlurRadius; x++) 
{
    for (int y = -BlurRadius; y <= BlurRadius; y++) 
    {
        //計算偏移的UV
        float2 offsetUV = UV + float2(x, y) * TexelSize;

        //采樣偏移后的貼圖顏色
        float3 PixelColor = SceneTextureLookup(offsetUV, SceneTextureID, false).rgb;

        //計算采樣像素的權重,/Raduis的原因是為了限制輸入范圍為-1到1
        // float weight = FS.Cal_1DGaussian(x / BlurRadius) * FS.Cal_1DGaussian(y / BlurRadius);
        float weight = Calculate1DGaussian(x / BlurRadius) * Calculate1DGaussian(y / BlurRadius);        

        //累加顏色
        PixelSum += PixelColor * weight;

        //累加權重值
        WeightSum += weight;
    }
}

//返回加權平均值
return PixelSum / WeightSum;

上面的代碼注釋,參考:http://opda.tech/2021/01/03/UE4高斯模糊后處理/




參考鏈接:

- UE4 Doc :Post Process Materials

- Virtual Shader Source Path - Link custom Shaders - Shadertoy Demo download

- UE4 – Loading shaders from within the project folder


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM