天天看点

替换着色器Replacement Shader的用法

方法解释

1.Tags可以自定义。

2.subshader标签的使用:

原本的shader:

Tags { “RenderType”=“Opaque” }

替换的shader:

Tags { “RenderType”=“Opaque” }

Tags { “RenderType”=“SomethingElse” }

标签为"RenderType"=“Opaque"的,会被同样是"RenderType”="Opaque"标签的替换shader所替换。

需要替换的shader,RenderType后面的键值要一样。

官网文档解释:SetReplacementShader将浏览场景中的所有对象,不是使用其常规着色器,而是使用第一个子着色器,该子着色器具有与指定关键帧匹配的值。 其Shader具有Rendertype =“ Opaque”标记的对象将被替换的shader中的第一个具有Rendertype =“ Opaque”的subshader替换,任何具有RenderType =“ SomethingElse”着色器的对象将使用第二个具有RenderType =“ SomethingElse”的替换子着色器,依此类推。 如果着色器的替换着色器中的指定关键帧的着色器没有匹配的标记值,则将不呈现任何对象。

Camera类的RenderWithShader方法和SetReplacementShader方法的区别

1. public void RenderWithShader(Shader shader, string replacementTag);

其中参数shader为要替换为的shader;replacementTag 为shader的Tag标示。

可以使用指定的shader来代替当前物体的shader渲染一帧。当replacementTag为空时会替换视口中所有物体的shader。

2.SetReplacementShader

被替换后每一帧都会用替换的shader来渲染物体,而不是只渲染一帧,结束时要调用**ResetReplacementShader()**恢复原状。

渲染示例

脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
[ExecuteInEditMode]
public class ReplaceShader: MonoBehaviour {

       public Shader ReplacementShader;
 
       void OnEnable() {
              if (ReplacementShader != null) {
                     GetComponent<Camera>().SetReplacementShader(ReplacementShader, "RenderType");
                     //1.GetComponent<Camera>().SetReplacementShader(ReplacementShader, "MyType");
                     //GetComponent<Camera>().camera.RenderWithShader(ReplacementShader, "RenderType");
              }
       }
 
       void OnDisable() {
              GetComponent<Camera>().ResetReplacementShader();
       }
}
           

原本的shader

替换着色器Replacement Shader的用法
Shader "Base/HalfLambert" {
	Properties {
		_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		//2.自定义的Tags,要保证键值一样
		//Tags { "MyType"="Test" }
		Pass { 
			Tags { "LightMode"="ForwardBase" }
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			fixed4 _Diffuse;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);				
				o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				fixed halfLambert = dot(worldNormal, worldLightDir)*0.499+0.5;
				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;
				fixed3 color = diffuse;
				return fixed4(diffuse, 1.0);
			}
			
			ENDCG
		}
	} 
}
           

替换的shader

替换着色器Replacement Shader的用法
Shader "Base/ReplaceLambert" {
	SubShader {
		Tags { "RenderType"="Opaque" }
		//3.自定义的Tags,要保证键值一样
		//Tags { "MyType"="Test" }
		Pass { 
			Tags { "LightMode"="ForwardBase" }
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			struct a2v {
				float4 vertex : POSITION;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				return fixed4(1,0,0,1);
			}
			
			ENDCG
		}
	} 
}
           

使用方法

把脚本挂在相机上,拖入替换的shader。

继续阅读