- Home /
Outline/Silhouette shader does not work correctly when ported to mobile.
I have been developing a game for PC and am trying to port it to mobile devices. I have been using this shader to create an outline around my characters and objects:
http://wiki.unity3d.com/index.php?title=Silhouette-Outlined_Diffuse
This works fine on PC, but when I create a build and test it on my Android device, the size of the outline explodes and it takes up a huge area around my character instead of just a thin outline. I am very new to shaders, usually only tweaking them slightly when I need to. I'm just not really sure how it works.
Here is an example of how it is suppose to look (PC version):
And here is an example of how it looks when ported (Android version):
Does anyone know why this would change so drastically from one platform to another? Or perhaps just offer some insight into how this shader works that would let me change my values accordingly. Thanks in advance.
EDIT: Images added and rephrasing.
i'll just let this here: http://xroft666.blogspot.de/2015/07/glow-highlighting-in-unity.html because there are to few good outline effects, and this one is not well known enough
Answer by SBull · Apr 01, 2016 at 06:28 PM
After much trial and error I FINALLY figured out how to edit the outline shader I had to work on Android. I'll post the final shader below just in case anyone else has the same issue later on. The outline amount may need to be tweaked (at least it did in my case), but it should give a nice smooth outline on the Android port now.
Shader "Outlined/Silhouetted Bumped Mobile" {
Properties {
_Color ("Main Color", Color) = (.5,.5,.5,1)
_OutlineColor ("Outline Color", Color) = (0,0,0,1)
_Outline ("Outline width", Float) = 4
_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) {
////////////////////////////////REPLACE THIS SECTION WITH.../////////////////////////////
// // 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;
/////////////////////////////////////////////...THIS PART///////////////////////////
v2f o;
o.pos = v.vertex;
o.pos.xyz += v.normal.xyz *_Outline*0.01;
o.pos = mul(UNITY_MATRIX_MVP, o.pos);
o.color = _OutlineColor;
return o;
}
ENDCG
SubShader {
Tags { "Queue" = "Transparent" }
// 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 //This is what allows the outline to be seen through other objects
// 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
}
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
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
Cull Front
ZWrite Off
//ZTest Always
Offset 15,15
// 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 exclude_renderers gles xbox360 ps3
ENDCG
SetTexture [_MainTex] { combine primary }
}
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
}
Fallback "Outlined/Silhouetted Diffuse"
}
This Shader code worked perfectly for me. Thanks @SBull.... :)
Thanks for the new shader, it works! Can you explain why this fix works?
Sorry , i cannot get this shader working, its required to use bumpmap?
It works! Unfortunately, it takes away shadows... but still it looks good.
Answer by Ramsdal · Nov 06, 2015 at 07:46 PM
Well the value of 5 is a still a very big outline area... Try with something like:
_Outline ("Outline width", Range (.002, 0.03)) = .015
Your answer
Follow this Question
Related Questions
Is there's any benefit when using mobile shader vs normal shader? - TextMeshPro 1 Answer
How to decrease Android build time and bypass "Compiling Shader Variants" when adding a new scene 0 Answers
Outlined Shader Shadows 1 Answer
Mobile Bumped Diffuse - weird dark surfaces and not enough bump? 1 Answer
Outline Shader with objects inside 0 Answers