वस्तु प्रभाव


26

मैं लीग ऑफ लीजेंड्स या डियाब्लो III में पाए गए लोगों के समान एक रूपरेखा प्रभाव कैसे प्राप्त कर सकता हूं?

लीग ऑफ लीजेंड्स की रूपरेखा लीग ऑफ लीजेंड्स की रूपरेखा डियाब्लो III की रूपरेखा

यह एक shader का उपयोग किया जाता है? कैसे?
मैं उन उत्तरों को पसंद करूंगा जो किसी विशेष इंजन से बंधे नहीं हैं, लेकिन एक यह कि मैं जिस भी इंजन पर काम कर रहा हूं, उसके अनुकूल हो सकता हूं।

जवाबों:


19

आपको किसी बिंदु पर वस्तु को दो बार प्रस्तुत करना होगाआप केवल एक बार कैमरे का सामना करने वाले चेहरों और एक बार कैमरे से दूर होने वाले चेहरों को प्रस्तुत करने के साथ दूर हो सकते हैं , लेकिन इसका व्यापार बंद है।

सबसे सरल सामान्य समाधान वस्तु को एक ही पास में दो बार रेंडर करके किया जाता है:

  • आप ऑब्जेक्ट के मानदंड को उलटने के लिए एक वर्टेक्स शेडर का उपयोग करते हैं और आउटलाइन के रंग में इसे रेंडर करने के लिए आउटलाइन के आकार और टुकड़े टुकड़े के द्वारा "इसे उड़ा दें"।
  • उस रूपरेखा को प्रस्तुत करने पर, आप सामान्य रूप से वस्तु को प्रस्तुत करते हैं। जेड-ऑर्डर आमतौर पर स्वचालित रूप से सही, अधिक या कम होता है, क्योंकि रूपरेखा उन चेहरों द्वारा बनाई जाती है जो ऑब्जेक्ट के "बैक" में होते हैं, जबकि आंकड़ा खुद कैमरे का सामना करने वाले चेहरे से बना होता है।

यह किसी भी रेंडर-टू-टेक्सचर ट्रिक्स को बनाने और कार्यान्वित करने और उससे बचने के लिए काफी सरल है, लेकिन इसमें कुछ उल्लेखनीय कमियां हैं:

  • बाह्यरेखा आकार, यदि आप इसे कैमरे से दूरी से मापते नहीं हैं, तो यह अलग-अलग होगा। आगे की वस्तुओं के पास पास की तुलना में एक छोटी रूपरेखा होगी। बेशक, यह वही हो सकता है जो आप वास्तव में चाहते हैं
  • "ब्लो अप" वर्टेक्स शेडर जटिल वस्तुओं के लिए बहुत अच्छी तरह से काम नहीं करता है जैसे कि आप उदाहरण के लिए कंकाल, आसानी से रेंडर करने के लिए ज़ेड-फाइटिंग आर्टिफैक्ट्स शुरू करते हैं। इसे ठीक करने से आपको ऑब्जेक्ट को दो पास में प्रस्तुत करने की आवश्यकता होती है, लेकिन आपको मानदंडों को उलटने से बचाता है।
  • रूपरेखा और वस्तु बहुत अच्छी तरह से काम नहीं कर सकते हैं जब अन्य वस्तुओं एक ही स्थान पर कब्जा कर रहे हैं और सामान्य रूप से प्रतिबिंब और अपवर्तन रंगों के साथ संयुक्त होने पर सही होने के लिए एक दर्द है।

इस तरह के एक shader के लिए मूल विचार इस तरह दिखता है (Cg, Unity के लिए - कोड एक थोड़ा संशोधित toon shader है जो मैंने कहीं पाया और स्रोत को नोट नहीं किया, इसलिए यह एक तैयार की तुलना में अधिक बुरी तरह से लिखित सबूत-की-अवधारणा है। उपयोग करने के लिए shader):

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 को थोड़ा अधिक कर देता है और आपके कलाकारों को आपकी नींद में हत्या करना चाहता है जब तक कि आप उन्हें उत्पन्न करना आसान नहीं बनाते हैं: क्या वस्तुओं की रूपरेखा अलग है हर समय जाल, बस पूरी तरह से पारदर्शी या कहीं चले गए जहां यह (गहरी भूमिगत की तरह) नहीं देखा जाता है जब तक कि आपको इसकी आवश्यकता न हो


क्या स्टैंसिल बफर यहाँ आमतौर पर इस्तेमाल किया दृष्टिकोण नहीं है?
14:49 पर edA-qa मोर्ट-ओर-वाई

1
@ edA-qamort-ora-y: यह भी काम कर सकता है, लेकिन मैंने कभी उस दृष्टिकोण की कोशिश नहीं की, इसलिए इस पर टिप्पणी नहीं कर सकता। :) यदि आपके पास एक कार्यशील एल्गोरिदम है, तो इस विधि को एक और उत्तर के रूप में भी जोड़ने के लिए स्वतंत्र महसूस करें।
मार्टिन सोज्का

मैं खुद इसके बारे में ज्यादा नहीं जानता, केवल यह है कि अक्सर स्टेंसिल बफ़र्स के संदर्भ में उल्लिखित किया जाता है। :) ऐसा लगता है कि यह आपके पहले दृष्टिकोण का एक अधिक हार्डवेयर आधारित संस्करण हो सकता है (दो पास, पहले एक बड़ा)।
eda-qa mort-ora-y

स्टेंसिल बफर दृष्टिकोण अपडेट करने और स्टैंसिल बफ़र्स को साफ़ करने में अधिक बैंडविड्थ का उपयोग कर सकता है, और कई पास की आवश्यकता होती है। मार्टिन लिस्ट में कुछ सीमित मामलों में एक पास में, दो में अधिकतम किया जा सकता है और न्यूनतम बैंडविड्थ ओवरहेड की आवश्यकता होती है।
शॉन मिडिलडाइच

यह दृष्टिकोण (मानदंड के साथ आकार को उड़ाना) क्यूब्स (विशेष रूप से ऑर्थो कैमरा) जैसी वस्तुओं के साथ काम नहीं करता है। इसका कोई हल?
एनपीएस

4

मार्टिन सोजकास जवाब के अलावा, स्थिर वस्तुओं (या स्प्राइट) के लिए आप कुछ सरल के साथ दूर हो सकते हैं।

आप एक ही स्प्राइट को बचा सकते हैं लेकिन पूरी तरह से अपनी बनावट एटलस या किसी अन्य बनावट में रूपरेखा के साथ, जो स्विच करना आसान बनाता है। यह आपको कस्टम रूपरेखा करने की भी अनुमति देगा जो अधिक नेत्रहीन रूप से आकर्षक हैं या बस अलग दिखते हैं।

दूसरी विधि स्प्राइट को एक रंग के आकार के रूप में सहेजना है जो थोड़ा बड़ा होता है और प्रस्तुत करता है कि स्प्राइट से पहले ही इसका प्रतिपादन किया जाता है। यह आपको चयन के रंग को आसानी से बदलने की क्षमता देगा, और आपको विधि # 1 के साथ आउटलाइन स्प्राइट्स की आवश्यकता के रूप में विभिन्न रंगों के आकार की आवश्यकता नहीं होगी।

दोनों हालांकि आपकी मेमोरी फुटप्रिंट को बढ़ाएंगे।


4

जैसा कि मार्टिन सोज्का के जवाब में टिप्पणियों में कहा गया है, स्टैंसिल या डेप्थ बफर का उपयोग करके एक समान प्रभाव भी प्राप्त किया जा सकता है, जैसा कि फ्लिपकोड पर मैक्स मैकगायर द्वारा विस्तृत किया गया है:

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

यह मूल रूप से उस मॉडल के वायरफ्रेम संस्करण को खींच रहा है जिसे आप बढ़ी हुई लाइन चौड़ाई के साथ उल्लिखित करना चाहते हैं (या ऐसा संभव नहीं है, जैसा कि डी 3 डी में है, उदाहरण के लिए, लाइनों के लिए कैमरे का सामना करना पड़ रहा है) स्टैंसिल बफर को स्थिर मान पर सेट करते समय।

यह aproach आज के OpenGL का उपयोग करके थोड़ा दिनांकित हो सकता है और वस्तु की रूपरेखा स्पष्ट होने के लिए, बनावट को प्रस्तुत करना अभी भी आवश्यक होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.