-
Notifications
You must be signed in to change notification settings - Fork 41
Hello
zilch edited this page Mar 8, 2021
·
2 revisions
这个系列是从0开始,使用Unity的SRP(Scriptable Render Pipeline)来实现各种渲染功能。某些地方可能会在一开始有理解不到位的地方,后面如果发现了就会返回过来修改。
作为开篇,先定一个小目标,使用SRP绘制一个Cube。
SRP中实现自定义RP,需要按以下步骤来:
- 继承
RenderPipelineAsset
,实现自己的RPAsset
- 继承
RenderPipeline
,实现自己的RP
- 在
RPAsset
的CreatePipeline
函数中返回自己实现的RP
用c#代码来实现,非常简单:
[CreateAssetMenu(menuName = "SRPLearn/XRendererPipelineAsset")]
public class XRendererPipelineAsset : RenderPipelineAsset
{
protected override RenderPipeline CreatePipeline()
{
return new XRenderPipeline();
}
}
public class XRenderPipeline : RenderPipeline
{
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
}
}
然后右键->Create->SRPLearn->XRendererPipelineAsset
,创建一个XRendererPipelineAsset
资源文件,配置到Edit/ProjectSetting/Graphic
。
这样我们就完成了项目中自定义渲染管线的配置。但目前这条渲染管线什么都没做,所以场景中是一片漆黑,即使创建了Cube,也是看不到的。
渲染管线的绘制入口为RenderPipeline.Render
函数,Render
函数有两个参数,分别是ScriptableRenderContext
与Camera[]
数组。Camera数组包含了GameView中玩家创建的所有摄像机,以及SceneView中的编辑器摄像机。
我们需要对每个摄像机,做单独的渲染操作。这里暂不区分SceneView与GameView
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
//遍历摄像机,进行渲染
foreach(var camera in cameras){
RenderPerCamera(context,camera);
}
//提交渲染命令
context.Submit();
}
RenderPerCamera实现:
private void RenderPerCamera(ScriptableRenderContext context,Camera camera){
//将camera相关参数,设置到渲染管线中
context.SetupCameraProperties(camera);
//对场景进行裁剪
camera.TryGetCullingParameters( out var cullingParams);
var cullingResults = context.Cull(ref cullingParams);
//相关参数,用来计算物体渲染时的排序
var sortingSetting = new SortingSettings(camera);
var drawSetting = new DrawingSettings(_shaderTag,sortingSetting);
//相关参数,用来过滤需要渲染的物体
var filterSetting = new FilteringSettings(RenderQueueRange.all);
//绘制物体
context.DrawRenderers(cullingResults,ref drawSetting,ref filterSetting);
}
其中_shaderTag
定义如下:
private ShaderTagId _shaderTag = new ShaderTagId("ForwardBase");
这表示,我们只会绘制Shader的LightMode
为ForwardBase
的物体。(因为目前创建的Cube,默认使用Builtin的Standard材质,其LightMode为ForwardBase)
这样,场景中就能正常显示创建的Cube了。
但是你会发现Directional Light
无论如何调整,都不起效果。 那是因为我们还没在渲染管线中加入灯光控制。