Sen edecek bir noktada iki kez nesneyi işlemek zorunda. Sadece bir kez kameraya bakan yüzleri ve bir kez kameradan bakan yüzleri görüntüleyerek kurtulabilirsiniz , ancak takası değişebilir.
En basit ortak çözüm, nesneyi aynı geçişte iki kez yapmak suretiyle yapılır:
- Nesnenin normlarını ters çevirmek için tepe noktası gölgelendiricisi kullanır ve dış çizginin boyutuna göre "havaya uçurur" ve anahat renginde oluşturmak için bir parça gölgelendirici kullanırsınız
- Bu anahat render üzerinde, nesneyi normal olarak yaratırsınız. Z sırası genellikle otomatik olarak doğru, aşağı yukarı doğrudur, çünkü ana hat, nesnenin "arkasındaki" yüzlerle yapılırken, figürün kendisi kameraya bakan yüzlerden oluşur.
Bu, herhangi bir dokuya dönüştürme püf noktası oluşturmak ve uygulamak ve bunları önlemek için yeterince basittir, ancak dikkat çeken birkaç dezavantajı vardır:
- Anahat boyutu, kamerayla arasındaki mesafeye göre ölçeklendirme yapmazsanız değişkenlik gösterecektir. Uzaktaki nesneler yakındakilerden daha küçük bir taslak olacaktır. Tabii ki, aslında istediğin bu olabilir .
- "Patlatmak" tepe gölgelendiricisi, örneğinizdeki iskelet gibi karmaşık nesneler için çok iyi çalışmaz, z dövüş artefaktlarını işleyiciye kolayca sunar. Bunu düzeltmek, nesneyi iki seferde oluşturmanızı gerektirir, ancak normalleri ters çevirmekten kurtarır.
- Anahat ve nesne, diğer nesneler aynı alanı işgal ettiğinde çok iyi çalışmayabilir ve genel olarak yansıma ve kırılma gölgelendiricileriyle birleştirildiğinde doğru olması gereken bir acıdır.
Böyle bir gölgelendirici için temel fikir şöyle görünür (Birlik için Cg - kod - bir yerde bulduğum ve değiştirdiğim bir gölgelendiricidir, kaynağı not etmedim, bu yüzden hazır bir fikirden daha kötü yazılmış bir kavram kanıtı. kullanımlı gölgelendirici):
Shader "Basic Outline" {
Properties {
_Color ("Main Color", Color) = (.5,.5,.5,1)
_OutlineColor ("Outline Color", Color) = (1,0.5,0,1)
_Outline ("Outline width", Range (0.0, 0.1)) = .05
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
Tags { "RenderType"="Opaque" }
Pass {
Name "OUTLINE"
Tags { "LightMode" = "Always" }
CGPROGRAM
#pragma exclude_renderers gles
#pragma exclude_renderers xbox360
#pragma vertex vert
struct appdata {
float4 vertex;
float3 normal;
};
struct v2f
{
float4 pos : POSITION;
float4 color : COLOR;
float fog : FOGC;
};
float _Outline;
float4 _OutlineColor;
v2f vert(appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float3 norm = mul ((float3x3)UNITY_MATRIX_MV, v.normal);
norm.x *= UNITY_MATRIX_P[0][0];
norm.y *= UNITY_MATRIX_P[1][1];
o.pos.xy += norm.xy * _Outline;
o.fog = o.pos.z;
o.color = _OutlineColor;
return o;
}
ENDCG
Cull Front
ZWrite On
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
SetTexture [_MainTex] { combine primary }
}
Pass {
Name "BASE"
Tags {"LightMode" = "Always"}
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float3 normal : TEXCOORD2;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.normal = v.normal;
o.uv = TRANSFORM_UV(0);
o.viewDir = ObjSpaceViewDir( v.vertex );
return o;
}
uniform float4 _Color;
uniform sampler2D _MainTex;
float4 frag (v2f i) : COLOR
{
half4 texcol = tex2D( _MainTex, i.uv );
half3 ambient = texcol.rgb * (UNITY_LIGHTMODEL_AMBIENT.rgb);
return float4( ambient, texcol.a * _Color.a );
}
ENDCG
}
}
FallBack "Diffuse"
}
Diğer yaygın yöntem nesneyi de iki kez oluşturur, ancak tepe gölgelendiriciyi tamamen önler. Öte yandan, tek bir geçişte kolayca yapılamaz ve dokuya dönüştürülmesi gerekir: Nesneyi bir kez "düz" anahat renkli parça gölgelendirici ile bir kez oluşturun ve bu görüntü üzerinde (ağırlıklı) bir bulanıklık kullanın ekran boşluğundan sonra, nesneyi üzerine her zamanki gibi yerleştirin.
Ayrıca, GPU'ya biraz daha fazla vergi ayırması ve sanatçıların sizi oluşturmasını kolaylaştırmadıkça, uykunuzda sizi öldürmesini istemesine neden olacak olmasına rağmen, bu yöntemi uygulamak için üçüncü ve muhtemelen en kolay olanı var: her zaman ağlayın, sadece tamamen saydam veya görünmeyen bir yere (derin yeraltı gibi) ihtiyacınız olana kadar hareket ettirin