编写脚本电脑怎么编写界面_可编写脚本的渲染管道概述

编写脚本电脑怎么编写界面_可编写脚本的渲染管道概述

编写脚本电脑怎么编写界面

The Scriptable Render Pipeline (SRP), introduced in 2018.1 beta, is a way of configuring and performing rendering in Unity that is controlled from a C# script. Before writing a custom render pipeline it’s important to understand what exactly we mean when we say render pipeline.

2018.1 Beta中引入的可脚本渲染管道(SRP)是一种在Unity中配置和执行渲染的方法,该方法由C#脚本控制。 在编写自定义渲染管道之前,重要的是要理解我们所说的渲染管道的确切含义。

什么是渲染管道 (What is a Render Pipeline)

“Render Pipeline” is an umbrella term for a number of techniques used to get objects onto the screen. It encompasses, at a very high level:

“渲染管道”是用于将对象放置到屏幕上的多种技术的总称。 它包括一个非常高的层次:

  • Culling

    剔除
  • Rendering Objects

    渲染对象
  • Post processing

    后期处理

In addition to these high level concepts each responsibility can be broken down further depending on how you want to execute them. For example rendering objects could be performed using:

除了这些高级概念之外,还可以根据您要执行它们的方式进一步分解每个责任。 例如,可以使用以下命令执行渲染对象:

  • Multi-pass rendering

    多遍渲染

    • one pass per object per light

      每个物体每个灯光一次通过
  • Single-pass

    单程

    • one pass per object

      每个对象一次通过
  • Deferred

    递延

    • Render surface properties to a g-buffer, perform screen space lighting

      将表面属性渲染到g缓冲区,执行屏幕空间照明

When writing a custom SRP, these are the kind of decisions that you need to make. Each technique has a number of tradeoffs that you should consider.

在编写自定义SRP时,您需要做出这些决定。 每种技术都有许多您应该考虑的权衡。

示范项目 (Demo Project)

All the features discussed in this post are covered in a demo project located on GitHub

这篇文章中讨论的所有功能都 位于GitHub上的演示项目中

渲染入口点 (The Rendering entry point)

When using SRP you need to define a class that controls rendering; this is the Render Pipeline you will be creating. The entry point is a call to “Render” which takes the render context (described below) and a list of cameras to render.

使用SRP时,您需要定义一个控制渲染的类。 这是您将要创建的渲染管线。 入口点是对“渲染”的调用,该调用获取渲染上下文(如下所述)和要渲染的摄像机列表。

1
2
3
4
public class BasicPipeInstance : RenderPipeline
{
   public override void Render(ScriptableRenderContext context, Camera[] cameras){}
}
1
2
3
4
public class BasicPipeInstance : RenderPipeline
{
   public override void Render ( ScriptableRenderContext context , Camera [ ] cameras ) { }
}

渲染管道上下文 (The Render Pipeline Context)

SRP renders using the concept of delayed execution. As a user you build up a list of commands and then execute them. The object that you use to build up these commands is called the ‘ScriptableRenderContext’. When you have populated the context with operations, then you can call ‘Submit’ to submit all the queued up draw calls.

SRP使用延迟执行的概念进行渲染。 以用户身份建立命令列表,然后执行它们。 用于构建这些命令的对象称为'ScriptableRenderContext' 。 用操作填充上下文后,可以调用“提交”以提交所有排队的绘制调用。

An example of this is clearing a render target using a command buffer that is executed by the render context:

一个示例是使用由渲染上下文执行的命令缓冲区清除渲染目标:

1
2
3
4
5
6
7
8
9
// Create a new command buffer that can be used
// to issue commands to the render context
var cmd = new CommandBuffer();
// issue a clear render target command
cmd.ClearRenderTarget(true, false, Color.green);
// queue the command buffer
context.ExecuteCommandBuffer(cmd);
1
2
3
4
5
6
7
8
9
// Create a new command buffer that can be used
// to issue commands to the render context
var cmd = new CommandBuffer ( ) ;
// issue a clear render target command
cmd . ClearRenderTarget ( true , false , Color . green ) ;
// queue the command buffer
context . ExecuteCommandBuffer ( cmd ) ;
编写脚本电脑怎么编写界面_可编写脚本的渲染管道概述

A not very exciting example of a render pipeline :)

渲染管道的一个不太令人兴奋的示例:)

Here’s a complete render pipeline that simply clears the screen.

这是一个完整的渲染管道,可以简单地清除屏幕。

剔除 (Culling)

Culling is the process of figuring out what to render on the the screen.

剔除是弄清楚要在屏幕上渲染的内容的过程。

In Unity Culling encompasses:

在Unity中,Culling包括:

  • Frustum culling: Calculating the objects that exist between the camera near and far plane.

    视锥剔除:计算相机*面和远平面之间存在的对象。
  • Occlusion culling: Calculating which objects are hidden behind other objects and excluding them from rendering. For more information see the Occlusion Culling docs.

    遮挡剔除:计算哪些对象隐藏在其他对象后面,并将其从渲染中排除。 有关更多信息,请参见遮挡剔除文档

When rendering starts, the first thing that needs to be calculated is what to render. This involves taking the camera and performing a cull operation from the perspective of the camera. The cull operation returns a list of objects and lights that are valid to render for the camera. These object are then used later in the render pipeline.

渲染开始时,首先需要计算的是渲染内容。 这涉及拿起相机并从相机的角度执行剔除操作。 剔除操作将返回可用于摄像机渲染的对象和光源的列表。 这些对象随后将在渲染管道中使用。

选择SRP (Culling in SRP)

In SRP, you generally perform object rendering from the perspective of a Camera. This is the same camera object that Unity uses for built-in rendering. SRP provides a number of API’s to begin culling with. Generally the flow looks as follows:

在SRP中,通常从“摄影机”的角度执行对象渲染。 这是Unity用于内置渲染的相机对象。 SRP提供了许多开始使用的API。 通常,流程如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Create an structure to hold the culling paramaters
ScriptableCullingParameters cullingParams;
//Populate the culling paramaters from the camera
if (!CullResults.GetCullingParameters(camera, stereoEnabled, out cullingParams))
    continue;
// if you like you can modify the culling paramaters here
cullingParams.isOrthographic = true;
// Create a structure to hold the cull results
CullResults cullResults = new CullResults();
// Perform the culling operation
CullResults.Cull(ref cullingParams, context, ref cullResults);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Create an structure to hold the culling paramaters
ScriptableCullingParameters cullingParams ;
//Populate the culling paramaters from the camera
if ( ! CullResults . GetCullingParameters ( camera , stereoEnabled , out cullingParams ) )
    continue ;
// if you like you can modify the culling paramaters here
cullingParams . isOrthographic = true ;
// Create a structure to hold the cull results
CullResults cullResults = new CullResults ( ) ;
// Perform the culling operation
CullResults . Cull ( ref cullingParams , context , ref cullResults ) ;

The cull results that get populated can now be used to perform rendering.

现在,可以使用填充的剔除结果执行渲染。

画画 (Drawing)

Now that we have a set of cull results, we can render them to the screen.

现在我们有了一组剔除结果,我们可以将它们渲染到屏幕上。

But there are so many ways that things can be configured, so a number of decisions need to be made up front. Many of these decisions will be driven by:

但是,可以通过多种方式配置事物,因此需要预先制定许多决策。 其中许多决定将由以下因素驱动:

  • The hardware you are targeting the render pipeline to

    您要将渲染管道定位到的硬件
  • The specific look and feel you wish to achieve

    您希望达到的特定外观
  • The type of project you are making

    您正在制作的项目类型

For example, think of a mobile 2D sidescroller game vs a PC high end first person game. These games have vastly different constraints so will have vastly different render pipelines. Some concrete examples of real decisions that may be made:

例如,考虑一下移动2D横屏游戏与PC高端第一人称游戏。 这些游戏的约束条件差异很大,因此渲染管线也将差异很大。 可能做出的实际决策的一些具体示例:

  • HDR vs LDR

    HDR与LDR
  • Linear vs Gamma

    线性与伽玛
  • MSAA vs Post Process AA

    MSAA与后期处理AA
  • PBR Materials vs Simple Materials

    PBR材料与简单材料
  • Lighting vs No Lighting

    照明与不照明
  • Lighting Technique

    照明技术
  • Shadowing Technique

    遮蔽技术

Making these decisions when writing a render pipeline will help you determine many of the constraints that are placed when authoring it.

在编写渲染管线时做出这些决定将有助于您确定创作管线时所施加的许多约束。

For now, we’re going to demonstrate a simple renderer with no lights that can render some of the objects opaque.

现在,我们将演示一个没有光源的简单渲染器,该渲染器可以使某些对象不透明。

过滤:渲染桶和图层 (Filtering: Render Buckets and Layers)

Generally, when rendering object has a specific classification, they are opaque, transparent, sub surface, or any number of other categories. Unity uses a concept of queues for representing when an object should be rendered, these queues form buckets that objects will be placed into (sourced from the material on the object). When rendering is called from SRP, you specify which range of buckets to use.

通常,当渲染对象具有特定的分类时,它们是不透明的,透明的,子表面或任意数量的其他类别。 Unity使用队列的概念来表示何时应渲染对象,这些队列形成了将要放置对象的存储桶(来自对象上的材料)。 从SRP调用渲染时,您可以指定要使用的存储桶范围。

In addition to buckets, standard Unity layers can also be used for filtering.

除存储桶外,标准Unity层也可用于过滤。

This provides the ability for additional filtering when drawing objects via SRP.

通过SRP绘制对象时,这提供了附加过滤的功能。

1
2
3
4
5
6
7
8
9
10
11
12
// Get the opaque rendering filter settings
var opaqueRange = new FilterRenderersSettings();
//Set the range to be the opaque queues
opaqueRange.renderQueueRange = new RenderQueueRange()
{
    min = 0,
    max = (int)UnityEngine.Rendering.RenderQueue.GeometryLast,
};
//Include all layers
opaqueRange.layerMask = ~0;
1
2
3
4
5
6
7
8
9
10
11
12
// Get the opaque rendering filter settings
var opaqueRange = new FilterRenderersSettings ( ) ;
//Set the range to be the opaque queues
opaqueRange . renderQueueRange = new RenderQueueRange ( )
{
    min = 0 ,
    max = ( int ) UnityEngine . Rendering . RenderQueue . GeometryLast ,
} ;
//Include all layers
opaqueRange . layerMask = ~ 0 ;

绘制设置:应如何绘制事物 (Draw Settings: How things should be drawn)

Using filtering and culling determines what should be rendered, but then we need to determine how it should be rendered. SRP provides a variety of options to configure how your objects that pass filtering should be rendered. The structure used to configure this data is the ‘DrawRenderSettings’ structure. This structure allows for a number of things to be configured:

使用过滤和剔除可以确定应呈现的内容,但随后我们需要确定应如何呈现。 SRP提供了多种选项来配置应如何呈现通过过滤的对象。 用于配置此数据的结构是“ DrawRenderSettings”结构。 这种结构允许配置许多东西:

  • Sorting – The order in which objects should be rendered, examples include back to front and front to back.

    排序–对象的渲染顺序,示例包括从前到后和从前到后。
  • Per Renderer flags – What ‘built in’ settings should be passed from Unity to the shader, this includes per object light probes, per object light maps, and similar.

    Per Renderer标志–应将什么“内置”设置从Unity传递到着色器,其中包括每个对象的光照探测器,每个对象的光照贴图等。
  • Rendering flags – What algorithm should be used for batching, instancing vs non-instancing.

    渲染标志–批处理,实例化与非实例化应使用哪种算法。
  • Shader Pass – Which shader pass should be used for the current draw call.

    着色器通道–当前的绘制调用应使用哪个着色器通道。
1
2
3
4
5
6
7
8
9
10
11
12
// Create the draw render settings
// note that it takes a shader pass name
var drs = new DrawRendererSettings(Camera.current, new ShaderPassName("Opaque"));
// enable instancing for the draw call
drs.flags = DrawRendererFlags.EnableInstancing;
// pass light probe and lightmap data to each renderer
drs.rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps;
// sort the objects like normal opaque objects
drs.sorting.flags = SortFlags.CommonOpaque;
1
2
3
4
5
6
7
8
9
10
11
12
// Create the draw render settings
// note that it takes a shader pass name
var drs = new DrawRendererSettings ( Camera . current , new ShaderPassName ( "Opaque" ) ) ;
// enable instancing for the draw call
drs . flags = DrawRendererFlags . EnableInstancing ;
// pass light probe and lightmap data to each renderer
drs . rendererConfiguration = RendererConfiguration . PerObjectLightProbe | RendererConfiguration . PerObjectLightmaps ;
// sort the objects like normal opaque objects
drs . sorting . flags = SortFlags . CommonOpaque ;

画画 (Drawing)

Now we have the three things we need to issue a draw call:

现在,我们具有发出抽签所需的三件事:

  • Cull results

    剔除结果
  • Filtering rules

    过滤规则
  • Drawing rules

    绘图规则

We can issue a draw call! Like all things in SRP, a draw call is issued as a call into the context. In SRP you normally don’t render individual meshes, instead you issue a call that renders a large number of them in one go. This reduces script execution overhead as well as allows fast jobified execution on the CPU.

我们可以发出抽奖电话! 像SRP中的所有内容一样,绘制调用作为对上下文的调用而发出。 在SRP中,通常不渲染单个网格,而是发出一个可一次性渲染大量网格的调用。 这样可以减少脚本执行的开销,并允许在CPU上快速执行作业。

To issue a draw call we combine the functions that we have been building up.

为了发出抽签通知,我们结合了已经建立的功能。

1
2
3
4
5
6
7
// draw all of the renderers
context.DrawRenderers(cullResults.visibleRenderers, ref drs, opaqueRange);
// submit the context, this will execute all of the queued up commands.
context.Submit();
1
2
3
4
5
6
7
// draw all of the renderers
context . DrawRenderers ( cullResults . visibleRenderers , ref drs , opaqueRange ) ;
// submit the context, this will execute all of the queued up commands.
context . Submit ( ) ;

This will draw the objects into the currently bound render target. You can use a command buffer to switch the render target if you so wish.

这会将对象绘制到当前绑定的渲染目标中。 如果愿意,可以使用命令缓冲区切换渲染目标。

A renderer that renders opaque objects can be found here:

可以在以下位置找到渲染不透明对象的渲染器:

https://github.com/stramit/SRPBlog/blob/master/SRP-Demo/Assets/SRP-Demo/2-OpaqueAssetPipe/OpaqueAssetPipe.cs

https://github.com/stramit/SRPBlog/blob/master/SRP-Demo/Assets/SRP-Demo/2-OpaqueAssetPipe/OpaqueAssetPipe.cs

This example can be further extended to add transparent rendering:

可以进一步扩展此示例以添加透明渲染:

https://github.com/stramit/SRPBlog/blob/master/SRP-Demo/Assets/SRP-Demo/3-TransparentAssetPipe/TransparentAssetPipe.cs

https://github.com/stramit/SRPBlog/blob/master/SRP-Demo/Assets/SRP-Demo/3-TransparentAssetPipe/TransparentAssetPipe.cs

The important thing to note here is that when rendering transparent the rendering order is changed to back to front.

这里要注意的重要一点是,当透明渲染时,渲染顺序更改为从后到前。

We hope that this post will help you get started writing your own custom SRP. Download the 2018.1 beta to get started and let us know what you think on this forum thread!

我们希望这篇文章可以帮助您开始编写自己的自定义SRP。 下载2018.1 beta版以开始使用,并让我们知道您对该论坛主题的看法!

翻译自: https://blogs.unity3d.com/2018/01/31/srp-overview/

编写脚本电脑怎么编写界面