- Home /
can you make a surface shader be drawn before or after a certain pass?
I'm trying to make a bumped silhouette outline shader based on the Silhouette-Outlined Diffuse shader, but Unity requires me to use surface shaders, and the problem is, the outline gets drawn after the surface shader so the object can't be seen. How do I control when the surface shader gets drawn?
Shader "Outlined/Silhouetted Bumped Diffuse" {
Properties {
_Color ("Main Color", Color) = (.5,.5,.5,1)
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
_Outline ("Outline width", Range (0.0, 0.03)) = .005
_MainTex ("Base (RGB)", 2D) = "white" { }
_BumpMap ("Bumpmap", 2D) = "bump" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : POSITION;
float4 color : COLOR;
};
uniform float _Outline;
uniform float4 _OutlineColor;
v2f vert(appdata v) {
// just make a copy of incoming vertex data but scaled according to normal direction
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
float2 offset = TransformViewToProjection(norm.xy);
o.pos.xy += offset * o.pos.z * _Outline;
o.color = _OutlineColor;
return o;
}
ENDCG
SubShader {
Tags { "Queue" = "Transparent" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
sampler2D _MainTex;
sampler2D _BumpMap;
uniform float3 _Color;
void surf(Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * _Color;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
// note that a vertex shader is specified here but its using the one above
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
Cull Off
ZWrite Off
ZTest Always
// you can choose what kind of blending mode you want for the outline
Blend SrcAlpha OneMinusSrcAlpha // Normal
//Blend One One // Additive
//Blend One OneMinusDstColor // Soft Additive
//Blend DstColor Zero // Multiplicative
//Blend DstColor SrcColor // 2x Multiplicative
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag(v2f i) : COLOR {
return i.color;
}
ENDCG
}
}
Fallback "Diffuse"
}
Answer by AnomalusUndrdog · Jul 12, 2011 at 10:50 PM
Ok, guys I found the answer, turns out you can reorder when the surface shader gets drawn by cutting-pasting its CGPROGRAM block before or after the pass block. You can also have more than one surface shader and order them however you like.
http://forum.unity3d.com/threads/96393-Achieving-a-multi-pass-effect-with-a-Surface-Shader
Your answer
Follow this Question
Related Questions
Mobile Bumped Diffuse problem 1 Answer
Two bump map shader 0 Answers
Silhouette Toon Shader 0 Answers
Object outline component 0 Answers
Normal mapping mirrored UVs? 2 Answers