개요 객체 효과


26

League of Legends 또는 Diablo III에서와 유사한 개요 효과를 어떻게 얻을 수 있습니까?

리그 오브 레전드 개요 리그 오브 레전드 개요 디아블로 III 개요

쉐이더를 사용합니까? 방법?
특정 엔진에 국한되지 않고 내가 작업중 인 엔진에 적응할 수있는 답변을 선호합니다.

답변:


19

당신은 것입니다 어떤 점에서 두 번 개체를 렌더링해야합니다. 당신은 일단 카메라를 향한 얼굴과 마주 얼굴 렌더링 멀리 얻을 수 있습니다 멀리 한 번 카메라를, 그러나 그것의 장단점이있다.

가장 간단한 공통 솔루션은 객체를 동일한 패스에서 두 번 렌더링하여 수행됩니다.

  • 꼭짓점 셰이더를 사용하여 객체의 법선을 반전시키고 윤곽선의 크기로 "블로우 업"하고 조각 쉐이더를 윤곽선 색상으로 렌더링합니다.
  • 해당 아웃 라인 렌더에서 객체를 정상적으로 렌더링합니다. z- 차수는 일반적으로 개체의 "뒤"에있는면에 의해 윤곽이 만들어 지지만 그림 자체는 카메라를 향한면으로 구성되기 때문에 일반적으로 다소간 자동으로 적절합니다.

이것은 텍스쳐 렌더링 트릭을 구축하고 구현하고 피할 수있을만큼 간단하지만 몇 가지 눈에 띄는 단점이 있습니다.

  • 윤곽선 크기는 카메라와의 거리에 따라 크기를 조정하지 않으면 달라집니다. 멀리있는 물체는 주변 물체보다 윤곽이 더 작습니다. 물론 이것은 실제로 원하는 것일 수 있습니다 .
  • "blow up"버텍스 쉐이더는 예제에서 뼈대와 같은 복잡한 오브젝트에 대해 잘 작동하지 않으므로 z-fighting 아티팩트를 렌더링에 쉽게 도입 할 수 있습니다. 수정하면 오브젝트를 두 번의 패스로 렌더링해야하지만 법선을 반전시키지 않아도됩니다.
  • 다른 물체가 같은 공간을 차지할 때 윤곽선과 물체가 잘 작동하지 않을 수 있으며 일반적으로 반사 및 굴절 쉐이더와 결합 할 때 올바르게 처리하기가 어렵습니다.

이러한 쉐이더의 기본 아이디어는 다음과 같습니다 (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에 약간의 세금을 부과하고 아티스트가 쉽게 생성하지 않는 한 아티스트가 수면에서 살인하기를 원할 것입니다. 항상 투명하게 만들거나 필요할 때까지 보이지 않는 곳 (지하 깊은 곳)으로 이동하십시오.


여기서 스텐실 버퍼는 일반적으로 사용되는 방법이 아닙니까?
edA-qa mort-ora-y

1
@ edA-qamort-ora-y : 이것도 효과가있을 수 있지만, 그 접근법을 시도한 적이 없으므로 그것에 대해 언급 할 수 없습니다. :) 작동 알고리즘을 염두에두면이 방법을 다른 답변으로 자유롭게 추가하십시오.
Martin Sojka

나는 그것에 대해 더 많이 모른다. 스텐실 버퍼와 관련하여 개요가 자주 언급된다. :) 첫 번째 방법의 더 많은 하드웨어 기반 버전 일 수 있습니다 (두 단계, 첫 번째 단계).
edA-qa mort-ora-y

스텐실 버퍼 방식은 스텐실 버퍼를 업데이트하고 지우는 데 더 많은 대역폭을 사용할 수 있으며 여러 번 통과해야합니다. Martin이 제시 한 접근 방식은 일부 경우에 한 번만 수행 할 수 있으며 최대 2 번이며 최소 대역폭 오버 헤드가 필요합니다.
Sean Middleditch

이 접근 방식 (법선을 따라 크기가 확대됨)은 큐브와 같은 객체 (특히 직교 카메라)에서는 작동하지 않습니다. 그것에 대한 해결책이 있습니까?
NPS

4

Martin Sojkas의 답변 외에도 정적 객체 (또는 스프라이트)의 경우 더 간단한 것으로 벗어날 수 있습니다.

동일한 스프라이트를 개요를 사용하여 텍스처 아틀라스 또는 다른 텍스처에 완전히 저장할 수 있으므로 전환이 쉽습니다. 또한 시각적으로 더 매력적이거나 다르게 보이는 사용자 정의 개요를 수행 할 수 있습니다.

다른 방법은 스프라이트를 약간 더 큰 단색으로 저장하고 스프라이트 자체가 렌더링되기 직전에 렌더링하는 것입니다. 그러면 선택 색상을 쉽게 변경할 수 있으며 방법 # 1을 사용하여 윤곽 스프라이트가 필요한만큼 다른 색상 모양이 필요하지 않을 수 있습니다.

둘 다 메모리 공간을 늘릴 것입니다.


4

Martin Sojka의 답변에 대한 의견에서 지적했듯이 FlipCode의 Max McGuire가 자세히 설명한 것처럼 스텐실 또는 깊이 버퍼를 사용하여 비슷한 효과를 얻을 수도 있습니다.

http://www.flipcode.com/archives/Object_Outlining.shtml

스텐실 버퍼를 일정한 값으로 설정하는 동안 기본적으로 원하는 선폭을 사용하여 선 너비를 늘리고 (또는 D3D에서와 같이 선에 카메라 방향 쿼드를 사용하는 것이 불가능한 경우) 와이어 프레임 버전을 그리는 것입니다.

이 접근 방식은 오늘날의 OpenGL을 사용하여 약간 날짜가 지났으며 객체 개요 애플 러가 흐리게 표시되도록하려면 텍스처로 렌더링해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.