Unity三角形全屏着色的方式

看到HDRP源码中通过DrawProcedural绘制一个三角形来实现全屏绘制,代码是这样的:

m_CommandBuffer.DrawProcedural(Matrix4x4.identity, m_SharedMaterial, 1, MeshTopology.Triangles, 3, 1, null);
v2f vert(appdata v)
{
   v2f o;
   o.vertex = GetFullScreenTriangleVertexPosition(v.vertexID);
   o.uv = GetFullScreenTriangleTexCoord(v.vertexID);
   return o;
}
开始有点懵逼,后来计算了一下发现是用三角形内部的一个正方形来实现屏幕着色。
			// 顶点位置转换到裁剪空间位置
			// 只考虑xy,通过第一行代码得到,
			// 索引0, x: 0<<1=00, 00&10=00 y: 00&10=0,所以0号位对应坐标为0,0
			// 索引1, x: 1<<1=10, 10&10=10 y: 01&10=0, 所以1号位对应坐标为2,0
			// 索引2, x: 2<<1=100, 100&010=000 y:10&10=10,所以2号位对应坐标为0,2
			// *2-1映射后,顶点的坐标为
			// v0:-1,-1
			// v1:3,-1
			// v2:-1,3
			float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE)
			{
			    float2 uv = float2((vertexID << 1) & 2, vertexID & 2);
			    return float4(uv * 2.0 - 1.0, z, 1.0);
			}
			// UV坐标为:
			// 索引0, x: 0<<1=00, 00&10=00 y: 00&10=0,所以0号位对应UV坐标为0,0
			// 索引1, x: 1<<1=10, 10&10=10 y: 01&10=0, 所以1号位对应UV坐标为2,0
			// 索引2, x: 2<<1=100, 100&010=000 y:10&10=10,所以2号位对应UV坐标为0,2
			float2 GetFullScreenTriangleTexCoord(uint vertexID)
			{
			#if UNITY_UV_STARTS_AT_TOP
			    return float2((vertexID << 1) & 2, 1.0 - (vertexID & 2));
			#else
			    return float2((vertexID << 1) & 2, vertexID & 2);
			#endif
			}

三个顶点在裁剪空间坐标:

v0:-1,1

v1:3,-1

v2:-1,3

三个顶点的UV坐标:

uv0:0,0

uv1:2,0

uv2:0,2

因为裁剪空间中进行齐次除法(w分量为1)后的值域范围是-1,1,所以在这个范围上的UV坐标为:

(0,0) (1,0) (1,1) (0,1),是标准的屏幕UV值域,就可以正常的对屏幕上的各种buffer采样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值