SceneViewExtension 是 Unreal Engine 提供的一个接口类(ISceneViewExtension),它允许开发者在渲染管线的特定阶段插入自定义逻辑。 简单来说,它是引擎预留的渲染钩子 。通过继承并实现它,你可以访问到每一帧的 FSceneViewFSceneViewFamily,并在 Base Pass 之前、之后,或者后期处理(Post-processing)等环节修改渲染状态或缓冲区数据。

主要回调函数(生命周期)

要用好这个工具,必须理解它在渲染线程中的执行时机。以下是几个最常用的钩子:

函数名 执行线程 触发时机
SetupViewFamily Game Thread 初始化阶段,用于设置 ViewFamily 的属性。
PreRenderViewFamily_RenderThread Render Thread 渲染开始前,可以修改渲染标志位、更计算后续渲染需要的数据。
PreRenderView_RenderThread Render Thread 针对单个 View 进行设置(多 View 场景下多次触发)。
PostRenderBasePass_RenderThread Render Thread 在 Base Pass(不透明物体渲染)完成后调用。
SubscribeToPostProcessingPass Render Thread 允许你在特定的后期处理节点(如 ToneMapping)插入逻辑。
更多请查看 ISceneViewExtension 的定义

使用基本流程

继承接口

需要创建一个类,继承自 FSceneViewExtensionBase(它是 ISceneViewExtension 的默认实现,处理了引用计数)。

CPP
#include "SceneViewExtension.h"

class FMyCustomViewExtension : public FSceneViewExtensionBase
{
public:
    FMyCustomViewExtension(const FAutoRegister& AutoRegister) : FSceneViewExtensionBase(AutoRegister) {}
    // 即使什么都不做,也必须提供空实现
	virtual void SetupViewFamily(FSceneViewFamily& InViewFamily) override {}
	virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override {}
	virtual void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override {}

    // 实现你需要的钩子
    void PreRenderViewFamily_RenderThread(FRDGBuilder& GraphBuilder, FSceneViewFamily& InViewFamily) override
    {
        // 这里的逻辑运行在渲染线程
    }
};
点击展开查看更多

注册扩展

你可以通过两种方式注册:

  1. 自动注册: 使用 FSceneViewExtensions::NewExtension 注册,下面演示在 Module 中注册:
CPP
class FMyProjectModule : public IModuleInterface
public:
    virtual void StartupModule() override {
	    // 此时 CEngine 可能未完全初始化,需要延迟到 OnPostEngineInit 再执行
        FCoreDelegates::OnPostEngineInit.AddLambda([](FMyProjectModule* ModulePtr) {
            if (ModulePtr) ModulePtr->ViewExtension = FSceneViewExtensions::NewExtension<FMySceneViewExtension>();
        }, this);
    }
    
    virtual void ShutdownModule() override {
        ViewExtension.Reset();
    }
private:
    // 存储对象,以便传输数据
    TSharedPtr<FMySceneViewExtension, ESPMode::ThreadSafe> ViewExtension;
}
点击展开查看更多
  1. 手动注册: 使用 GEngine->ViewExtensions->Add(MyExtensionInstance)

一些技巧和注意事项

版权声明

作者: Cheyne Xie

链接: https://chaim.eu.org/posts/9dfb4aaf/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键