답변:
당신은 것입니다 어떤 점에서 두 번 개체를 렌더링해야합니다. 당신은 일단 카메라를 향한 얼굴과 마주 얼굴 렌더링 멀리 얻을 수 있습니다 멀리 한 번 카메라를, 그러나 그것의 장단점이있다.
가장 간단한 공통 솔루션은 객체를 동일한 패스에서 두 번 렌더링하여 수행됩니다.
이것은 텍스쳐 렌더링 트릭을 구축하고 구현하고 피할 수있을만큼 간단하지만 몇 가지 눈에 띄는 단점이 있습니다.
이러한 쉐이더의 기본 아이디어는 다음과 같습니다 (Cg, Unity의 경우-코드는 약간 수정 된 툰 쉐이더입니다. 어딘가에서 찾은 소스는 기록하지 않았으므로 준비보다 개념을 잘못 작성했습니다. 사용 셰이더) :
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"
}
다른 일반적인 방법은 객체를 두 번 렌더링하지만 정점 셰이더를 완전히 피합니다. 반면에 단일 패스로는 쉽게 수행 할 수 없으며 렌더 투 텍스쳐가 필요합니다. "평평한"외곽선 색 조각 쉐이더로 오브젝트를 한 번 렌더링하고이 렌더에서 (가중) 흐림 효과를 사용하십시오. 화면 공간 을 설정 한 다음 평소와 같이 객체를 렌더링하십시오.
방법을 구현하는 세 번째 방법과 가장 쉬운 방법이 있지만 GPU에 약간의 세금을 부과하고 아티스트가 쉽게 생성하지 않는 한 아티스트가 수면에서 살인하기를 원할 것입니다. 항상 투명하게 만들거나 필요할 때까지 보이지 않는 곳 (지하 깊은 곳)으로 이동하십시오.
Martin Sojkas의 답변 외에도 정적 객체 (또는 스프라이트)의 경우 더 간단한 것으로 벗어날 수 있습니다.
동일한 스프라이트를 개요를 사용하여 텍스처 아틀라스 또는 다른 텍스처에 완전히 저장할 수 있으므로 전환이 쉽습니다. 또한 시각적으로 더 매력적이거나 다르게 보이는 사용자 정의 개요를 수행 할 수 있습니다.
다른 방법은 스프라이트를 약간 더 큰 단색으로 저장하고 스프라이트 자체가 렌더링되기 직전에 렌더링하는 것입니다. 그러면 선택 색상을 쉽게 변경할 수 있으며 방법 # 1을 사용하여 윤곽 스프라이트가 필요한만큼 다른 색상 모양이 필요하지 않을 수 있습니다.
둘 다 메모리 공간을 늘릴 것입니다.
Martin Sojka의 답변에 대한 의견에서 지적했듯이 FlipCode의 Max McGuire가 자세히 설명한 것처럼 스텐실 또는 깊이 버퍼를 사용하여 비슷한 효과를 얻을 수도 있습니다.
http://www.flipcode.com/archives/Object_Outlining.shtml
스텐실 버퍼를 일정한 값으로 설정하는 동안 기본적으로 원하는 선폭을 사용하여 선 너비를 늘리고 (또는 D3D에서와 같이 선에 카메라 방향 쿼드를 사용하는 것이 불가능한 경우) 와이어 프레임 버전을 그리는 것입니다.
이 접근 방식은 오늘날의 OpenGL을 사용하여 약간 날짜가 지났으며 객체 개요 애플 러가 흐리게 표시되도록하려면 텍스처로 렌더링해야합니다.