主要参考:
unity, 替换shader渲染(Rendering with Replaced Shaders) : http://www.cnblogs.com/wantnon/p/4528677.html
测试例子:
Test.cs挂到Camera上
using UnityEngine; using System.Collections; public class Test1 : MonoBehaviour { private Camera shaderCamera; private RenderTexture replaceRenderTexture; public void Start() { shaderCamera = new GameObject("Test", typeof(Camera)).GetComponent<Camera>(); Camera origCamera = GetComponent<Camera>(); replaceRenderTexture = new RenderTexture((int)origCamera.pixelWidth, (int)origCamera.pixelHeight, 16, RenderTextureFormat.ARGB32); replaceRenderTexture.wrapMode = TextureWrapMode.Clamp; replaceRenderTexture.useMipMap = false; replaceRenderTexture.filterMode = FilterMode.Bilinear; replaceRenderTexture.Create(); } public void OnPreRender() { Camera origCamera = GetComponent<Camera>(); shaderCamera.CopyFrom(origCamera); //shaderCamera.backgroundColor = Color.clear; shaderCamera.clearFlags = CameraClearFlags.SolidColor; shaderCamera.renderingPath = RenderingPath.Forward; shaderCamera.targetTexture = replaceRenderTexture; shaderCamera.depth = 10; shaderCamera.RenderWithShader(Shader.Find("Unlit/blueSphere"), "RenderType"); } }
redAndGreen.shader
Shader "Unlit/redAndGreenSphere" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader{ Tags { "RenderType"="Green" } LOD 100 Pass { //Tags { "RenderType"="Green" } CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return fixed4(0, 0.5, 0, 1); } ENDCG } } SubShader { Tags { "RenderType"="Red" } LOD 100 Pass { //Tags { "RenderType"="Red" } CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return fixed4(0.5, 0, 0, 1); } ENDCG } } }
blueSphere.shader
Shader "Unlit/blueSphere" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Green" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); //return col; return fixed4(0, 0, 0.5, 1); } ENDCG } } }
结论:
在shaderCamera 中,因为调用了RenderWithShader(Shader.Find("Unlit/blueSphere"), "RenderType");,因为blueSphere的SubShader的 "RenderType"="Green",所以,会在场景中进行寻找 第一个SubShader的"RenderType"="Green" 的物体,用blueSphere的SubShader来代替这些物体就进行渲染。
所以,上面的挂上了redAndGreen材质的球,本来是绿色,会用blueSphere.shader来渲染,渲染为蓝色。