level 3
fby825
楼主
Flax Engine 提供了非常广泛的自定义功能,可以扩展渲染管道。其中之一是使用自定义摄像机直接渲染场景到渲染目标。然后将其显示在对象表面上。
在本教程中,您将学习如何实现画中画效果:

创建材质
第一步是为 TV 对象创建专用材质。它将用于在表面上显示渲染的场景图片,以便玩家可以看到它。为此,请按照以下简单步骤作:
创建一个新的空材质并为其命名 TV Material (请参阅 Materials Basics 页面以了解如何作)
在 Material Editor 中打开它(双击资源)

在 Properties Panel(属性面板)中向下滚动,从底部下拉菜单中选择 GPU Texture (GPU 纹理) 选项,然后按 Add parameter (添加参数) 按钮

右键单击新创建的 New 参数,选择选项 Rename 并将其名称设置为 Image
右键单击 Surface 背景并创建 Get Parameter 节点(要了解有关创建节点的更多信息,请参见 Material Editor 页面)

从该节点的下拉菜单中选择 Image 参数,并将其 Color 框与 Material Emissive 输入连接起来。

保存材质资源
创建脚本
现在,您可以编写一个简单的脚本,该脚本将使用摄像机并将其渲染到纹理(也称为渲染目标)。
导航到项目的 Source/Game 目录,并创建名为 CameraTV 的新 C# 脚本

打开脚本
编写以下代码并保存
using System;using FlaxEngine;public class CameraTV : Script{ public Camera Cam; public MaterialBase Material; [Limit(1, 2000)] public Float2 Resolution { get => _resolution; set { value = Float2.Clamp(value, new Float2(1), new Float2(2000)); if (_resolution != value) { _resolution = value; if (_output) { // Resize backbuffer UpdateOutput(); } } } } public float ViewDistance = 2000; private Float2 _resolution = new Float2(640, 374); private GPUTexture _output; private SceneRenderTask _task; private MaterialInstance _material; private void UpdateOutput() { var desc = GPUTextureDescription.New2D( (int)_resolution.X, (int)_resolution.Y, PixelFormat.R8G8B8A8_UNorm); _output.Init(ref desc); } public override void OnEnable() { // Create backbuffer if (_output == null) _output = new GPUTexture(); UpdateOutput(); // Create rendering task if (_task == null) _task = new SceneRenderTask(); _task.Order = -100; _task.Camera = Cam; _task.Output = _output; _task.ViewFlags = ViewFlags.Reflections | ViewFlags.Decals | ViewFlags.AO | ViewFlags.GI | ViewFlags.DirectionalLights | ViewFlags.PointLights | ViewFlags.SpotLights | ViewFlags.SkyLights | ViewFlags.Sky | ViewFlags.Shadows | ViewFlags.SpecularLight | ViewFlags.CustomPostProcess | ViewFlags.ToneMapping; _task.Enabled = false; if (Material && _material == null) { // Use dynamic material instance if (Material.WaitForLoaded()) throw new Exception("Failed to load material."); _material = Material.CreateVirtualInstance(); // Set render task output to draw on model _material.SetParameterValue("Image", _output); // Bind material to parent model if (Actor is StaticModel staticModel && staticModel.Model) { staticModel.Model.WaitForLoaded(); staticModel.SetMaterial(0, _material); } } _task.Enabled = true; } public override void OnUpdate() { // Optimize by disabling rendering if main game view is far too far var mainView = MainRenderTask.Instance.View; _task.Enabled = Vector3.Distance(Actor.Position, mainView.Origin + mainView.Position) <= ViewDistance; } public override void OnDisable() { // Unbind temporary material if (Actor is StaticModel staticModel && staticModel.Model && staticModel.Model.IsLoaded) staticModel.SetMaterial(0, Material); // Ensure to cleanup resources Destroy(ref _task); Destroy(ref _output); Destroy(ref _material); }}准备对象
最后一步是设置一个场景并将所有这些东西链接在一起。
创建新的 Camera 对象并将其放置在场景中
添加将呈现相机图像的对象。您可以从 Toolbox (工具箱) 窗口中使用 Cube 模型

选择生成的对象,然后只需拖动它即可将 CameraTV 脚本添加到其中

为脚本属性 Cam 和 Material 设置对摄像机和材质的引用。您还可以调整分辨率(以像素为单位)。

点击播放并查看结果!

2025年03月27日 11点03分
1
在本教程中,您将学习如何实现画中画效果:

创建材质第一步是为 TV 对象创建专用材质。它将用于在表面上显示渲染的场景图片,以便玩家可以看到它。为此,请按照以下简单步骤作:
创建一个新的空材质并为其命名 TV Material (请参阅 Materials Basics 页面以了解如何作)
在 Material Editor 中打开它(双击资源)

在 Properties Panel(属性面板)中向下滚动,从底部下拉菜单中选择 GPU Texture (GPU 纹理) 选项,然后按 Add parameter (添加参数) 按钮
右键单击新创建的 New 参数,选择选项 Rename 并将其名称设置为 Image右键单击 Surface 背景并创建 Get Parameter 节点(要了解有关创建节点的更多信息,请参见 Material Editor 页面)

从该节点的下拉菜单中选择 Image 参数,并将其 Color 框与 Material Emissive 输入连接起来。
保存材质资源创建脚本
现在,您可以编写一个简单的脚本,该脚本将使用摄像机并将其渲染到纹理(也称为渲染目标)。
导航到项目的 Source/Game 目录,并创建名为 CameraTV 的新 C# 脚本

打开脚本编写以下代码并保存
using System;using FlaxEngine;public class CameraTV : Script{ public Camera Cam; public MaterialBase Material; [Limit(1, 2000)] public Float2 Resolution { get => _resolution; set { value = Float2.Clamp(value, new Float2(1), new Float2(2000)); if (_resolution != value) { _resolution = value; if (_output) { // Resize backbuffer UpdateOutput(); } } } } public float ViewDistance = 2000; private Float2 _resolution = new Float2(640, 374); private GPUTexture _output; private SceneRenderTask _task; private MaterialInstance _material; private void UpdateOutput() { var desc = GPUTextureDescription.New2D( (int)_resolution.X, (int)_resolution.Y, PixelFormat.R8G8B8A8_UNorm); _output.Init(ref desc); } public override void OnEnable() { // Create backbuffer if (_output == null) _output = new GPUTexture(); UpdateOutput(); // Create rendering task if (_task == null) _task = new SceneRenderTask(); _task.Order = -100; _task.Camera = Cam; _task.Output = _output; _task.ViewFlags = ViewFlags.Reflections | ViewFlags.Decals | ViewFlags.AO | ViewFlags.GI | ViewFlags.DirectionalLights | ViewFlags.PointLights | ViewFlags.SpotLights | ViewFlags.SkyLights | ViewFlags.Sky | ViewFlags.Shadows | ViewFlags.SpecularLight | ViewFlags.CustomPostProcess | ViewFlags.ToneMapping; _task.Enabled = false; if (Material && _material == null) { // Use dynamic material instance if (Material.WaitForLoaded()) throw new Exception("Failed to load material."); _material = Material.CreateVirtualInstance(); // Set render task output to draw on model _material.SetParameterValue("Image", _output); // Bind material to parent model if (Actor is StaticModel staticModel && staticModel.Model) { staticModel.Model.WaitForLoaded(); staticModel.SetMaterial(0, _material); } } _task.Enabled = true; } public override void OnUpdate() { // Optimize by disabling rendering if main game view is far too far var mainView = MainRenderTask.Instance.View; _task.Enabled = Vector3.Distance(Actor.Position, mainView.Origin + mainView.Position) <= ViewDistance; } public override void OnDisable() { // Unbind temporary material if (Actor is StaticModel staticModel && staticModel.Model && staticModel.Model.IsLoaded) staticModel.SetMaterial(0, Material); // Ensure to cleanup resources Destroy(ref _task); Destroy(ref _output); Destroy(ref _material); }}准备对象
最后一步是设置一个场景并将所有这些东西链接在一起。
创建新的 Camera 对象并将其放置在场景中
添加将呈现相机图像的对象。您可以从 Toolbox (工具箱) 窗口中使用 Cube 模型

选择生成的对象,然后只需拖动它即可将 CameraTV 脚本添加到其中
为脚本属性 Cam 和 Material 设置对摄像机和材质的引用。您还可以调整分辨率(以像素为单位)。
点击播放并查看结果!