zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    数据库表结构查询SQL
    Java实现数据库备份并利用ant导入SQL脚本
    生死看淡,不服就干。SQL常见的一些优化。
    mybatis + PageHelper 实现分页
    自定义数据库连接池实现方式 MySQL
    Docker 镜像基础(三)
    Docker 镜像管理及基础命令(二)
    Docker 介绍和安装(一)
    Docker 镜像管理及基础命令(二)
    Tomcat-8 安装和配置
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/15090886.html
Copyright © 2011-2022 走看看