SRP中的shader

SRP中的shader

在Unity中使用SRP时,我们需要使用HLSL来编写shader。HLSL语法与GLSL类似,在使用HLSL的地方我们需要用HLSLPROGRAMENDHLSL来包裹:

Shader "My Pipeline/Unlit" {
	Properties {}

	SubShader {

		Pass
		{
			HLSLPROGRAM

			#pragma vertex UnlitPassVertex
			#pragma fragment UnlitPassFragment

			#include "Unlit.hlsl"

			ENDHLSL
		}
	}
}

此时,unity_MatrixVPunity_ObjectToWorld这两个矩阵也不能直接使用,需要我们自行声明:

float4x4 unity_MatrixVP;
float4x4 unity_ObjectToWorld;

struct VertexInput {
	float4 pos : POSITION;
};

struct VertexOutput {
	float4 clipPos : SV_POSITION;
};

VertexOutput UnlitPassVertex (VertexInput input) {
	VertexOutput output;
	float4 worldPos = mul(unity_ObjectToWorld, input.pos);
	output.clipPos = mul(unity_MatrixVP, worldPos);
	return output;
}

float4 UnlitPassFragment (VertexOutput input) : SV_TARGET {
	return 1;
}

另外,这两个矩阵的更新频率实际上是不同的,unity_MatrixVP矩阵绘制每一帧画面时只需更新一次,而unity_ObjectToWorld跟绘制的物体还有关系,因此它需要每次绘制时都要更新一次。这样的话,我们可以利用unity提供的cbuffer,使得这两个矩阵可以按照自身需要的频率更新:

CBUFFER_START(UnityPerFrame)
	float4x4 unity_MatrixVP;
CBUFFER_END

CBUFFER_START(UnityPerDraw)
	float4x4 unity_ObjectToWorld;
CBUFFER_END

现在使用该shader的材质,来绘制一些gameobject试试:

SRP中的shader1

接下来,我们希望这些gameobject拥有不同的颜色,显然颜色这个是跟随材质变化的,因此我们要把它放到UnityPerMaterial中:

CBUFFER_START(UnityPerMaterial)
	float4 _Color;
CBUFFER_END

这下gameobject就可以五彩斑斓了:

SRP中的shader2

最后,我们希望在SRP中使用gpu instancing的方式来绘制这些gameobjects。首先在C#中把开关打开:

drawSettings.enableInstancing = true;

然后还要在shader中引入INSTANCING_ON关键字:

#pragma multi_compile_instancing

为了支持instancing,原先放在UnityPerMaterialbuffer中的_Color需要挪到UNITY_INSTANCING_BUFFER中:

UNITY_INSTANCING_BUFFER_START(PerInstance)
	UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_INSTANCING_BUFFER_END(PerInstance)

同时vertex shader和frag shader也要相应地改动:

struct VertexInput {
	float4 pos : POSITION;
	UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct VertexOutput {
	float4 clipPos : SV_POSITION;
	UNITY_VERTEX_INPUT_INSTANCE_ID
};

VertexOutput UnlitPassVertex (VertexInput input) {
	VertexOutput output;
	UNITY_SETUP_INSTANCE_ID(input);
	UNITY_TRANSFER_INSTANCE_ID(input, output);
	float4 worldPos = mul(UNITY_MATRIX_M, float4(input.pos.xyz, 1.0));
	output.clipPos = mul(unity_MatrixVP, worldPos);
	return output;
}

float4 UnlitPassFragment (VertexOutput input) : SV_TARGET {
	UNITY_SETUP_INSTANCE_ID(input);
	return UNITY_ACCESS_INSTANCED_PROP(PerInstance, _Color);
}

这时我们再用frame debug看一下,可以发现draw call大大降低了:

SRP中的shader3

如果你觉得我的文章有帮助,欢迎关注我的微信公众号 我是真的想做游戏啊

Reference

[1] Custom Shaders

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值