Unity-SRP之自定义渲染管线

自定义渲染管线

前置工作

  1. 在PlayerSetting中奖颜色空间Color Space由Gamma空间换成Linear线性空间
  2. 在Window->PackageManager中安装Core RP Library包。这个包由Unity封装了底层C++渲染接口,还包含一些着色器文件,后面会依赖这个包做拓展功能。
    在这里插入图片描述
    在这里插入图片描述

创建管线资产和实例

using UnityEngine;
using UnityEngine.Rendering;

[CreateAssetMenu(menuName = "Rendering/CreateCustomRenderPipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
	protected override RenderPipeline CreatePipeline()
	{
		return new CustomRenderPipeline();
	}
}

using UnityEngine;
using UnityEngine.Rendering;

public class CustomRenderPipeline : RenderPipeline
{
	protected override void Render(ScriptableRenderContext context, Camera[] cameras)
	{

	}
}

在这里插入图片描述
因为替换了新的渲染管线,而新的管线啥也没做,所以Game视图和Scene视图都是黑色的。
在这里插入图片描述

using UnityEngine;
using UnityEngine.Rendering;

public partial class CameraRenderer
{
	private ScriptableRenderContext renderContext;
	private Camera camera;

	const string bufferName = "Render Camera CCC";
	CommandBuffer buffer = new CommandBuffer
	{
		name = bufferName
	};
	// 存储剔除后的结果数据
	CullingResults cullingResults;

	public void Render(ScriptableRenderContext _renderContext, Camera _cam)
	{
		this.renderContext = _renderContext;
		this.camera = _cam;

		//设置命令缓冲区的名字
		PrepareBuffer();

		//在Game视图绘制的几何体也绘制到Scene视图中
		PrepareForSceneWindow();

		if (!Cull())
		{
			return;
		}

		Setup();
		DrawVisibleGeometry();
		//绘制SRP不支持的着色器类型
		DrawUnsupportedShaders();
		DrawGizmos();
		Submit();
	}

	static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
	// 绘制可见物体 绘制顺序须遵循 不透明物体->绘制天空盒->透明物体(减少天空盒绘制像素的数量,透明物体不会进行深度测试)
	private void DrawVisibleGeometry()
	{
		// 设置绘制顺序和指定渲染相机
		var sortingSettings = new SortingSettings(camera)
		{
			criteria = SortingCriteria.CommonOpaque
		};
		//绘制几何体
		var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);
		//设置哪些类型的渲染队列可以被绘制
		var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);

		//1.绘制不透明物体
		renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

		//2.绘制天空盒
		renderContext.DrawSkybox(camera);

		sortingSettings.criteria = SortingCriteria.CommonTransparent;
		drawingSettings.sortingSettings = sortingSettings;
		//只绘制RenderQueue为transparent透明的物体
		filteringSettings.renderQueueRange = RenderQueueRange.transparent;
		//3.绘制透明物体
		renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
	}
	// 提交缓冲区渲染命令
	private void Submit()
	{
		buffer.EndSample(SampleName);
		ExecuteBuffer();
		renderContext.Submit();
	}

	// 设置相机矩阵
	private void Setup()
	{
		renderContext.SetupCameraProperties(camera);
		// 得到相机的clear flags
		CameraClearFlags flags = camera.clearFlags;
		buffer.ClearRenderTarget(flags <= CameraClearFlags.Depth, flags == CameraClearFlags.Color, flags == CameraClearFlags.Color ? camera.backgroundColor.linear : Color.clear);
		buffer.BeginSample(SampleName);
		ExecuteBuffer();
	}

	// 执行并清空缓冲区命令
	private void ExecuteBuffer()
	{
		renderContext.ExecuteCommandBuffer(buffer);
		buffer.Clear();
	}

	// 剔除
	private bool Cull()
	{
		ScriptableCullingParameters p;
		if (camera.TryGetCullingParameters(out p))
		{
			cullingResults = renderContext.Cull(ref p);
			return true;
		}
		return false;
	}
}

using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering;
using UnityEngine.Profiling;

public partial class CameraRenderer
{
	partial void DrawUnsupportedShaders();
	partial void DrawGizmos();
	partial void PrepareForSceneWindow();
	partial void PrepareBuffer();
#if UNITY_EDITOR
	//SRP不支持的着色器标签类型
	static ShaderTagId[] legacyShaderTagIds =
	{
		new ShaderTagId("Always"),
		new ShaderTagId("ForwardBase"),
		new ShaderTagId("PrepassBase"),
		new ShaderTagId("Vertex"),
		new ShaderTagId("VertexLMRGBM"),
		new ShaderTagId("VertexLM")
	};

	//绘制成使用错误材质的粉红颜色
	static Material errorMaterial;
	// 绘制SRP不支持的着色器类型
	partial void DrawUnsupportedShaders()
	{
		if (errorMaterial == null)
		{
			errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
		}
		//数组第一个元素用来构造DrawingSeting对象的时候设置
		var drawingSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera))
		{
			overrideMaterial = errorMaterial
		};
		for (int i = 1; i < legacyShaderTagIds.Length; i++)
		{
			//遍历数组逐个设置着色器的PassName,从i=1开始
			drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
		}
		var filteringSettings = FilteringSettings.defaultValue;
		//绘制不支持的ShaderTag类型的物体
		renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
	}

	//绘制Gizmos
	partial void DrawGizmos()
	{
		if (Handles.ShouldRenderGizmos())
		{
			renderContext.DrawGizmos(camera, GizmoSubset.PreImageEffects);
			renderContext.DrawGizmos(camera, GizmoSubset.PostImageEffects);
		}
	}

	partial void PrepareForSceneWindow()
	{
		if (camera.cameraType == CameraType.SceneView)
		{
			//如果切换到Scene视图,调用此方法完成绘制
			ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
		}
	}

	string SampleName { get; set; }
	partial void PrepareBuffer()
	{
		Profiler.BeginSample("Editor Only");
		SampleName = camera.name;
		buffer.name = SampleName;
		Profiler.EndSample();
	}
#else
	const string SampleName = bufferName;
#endif
}

(未完待续)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cchoop

有用的话请杯肥宅水

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值