আমি কীভাবে একটি "দেয়ালের পিছনে দেখুন" প্রভাব তৈরি করতে পারি?


103

ডিভিনিটি: আসল সিন 2 এ একটি সুন্দর ভিউ-থ্রো সিস্টেম রয়েছে। আমি যখন দেয়ালের পিছনে যাব, তখন একটি স্প্ল্যাশ মুখোশ উপস্থিত হবে এবং যখন আমি গেমটি ঘুরে দেখি তখন এটি পরিবর্তন হয়। এটি দ্রবীভূত শেডারের মতো এবং এর একটি মেটাবলের প্রভাব রয়েছে।

খেলোয়াড়রা যখন দেয়ালের পিছনে যায় তখন আমি কীভাবে এই প্রভাবটির প্রতিলিপি তৈরি করতে পারি?

আপনি এই ইউটিউব ভিডিওটির মাধ্যমে গতিতে পছন্দসই প্রভাব দেখতে পারেন ।

ভাবমূর্তি


3
হাই, মনে হচ্ছে আপনি এর বাইরে অতিরিক্ত জিনিসগুলির অনুরোধ করে আপনার প্রশ্নে স্ক্রপ ক্রিপ যুক্ত করেছেন। এই পর্যায়ে - বিশেষত এটির একটি পূর্ণ উত্তর পাওয়ার পরে, যা অতিরিক্ত আচরণের জন্য আপনার অনুরোধের দ্বারা কার্যকরভাবে আংশিকভাবে অকার্যকর হয়ে পড়েছে - আপনার প্রয়োজনীয়তা প্রসারিত করার পরিবর্তে আপনি একটি নতুন প্রশ্ন জিজ্ঞাসা করা ভাল better যদি অনুগ্রহটি সেই বিবরণগুলির জন্য ছিল, আপনি নতুন প্রশ্ন জিজ্ঞাসা করে, আপনার সমস্যাটি বর্ণনা করে, অনুগ্রহ করে ফেরতের জন্য অনুরোধ করার জন্য এই প্রশ্নটিকে মডারেটরের মনোযোগের জন্য পতাকাঙ্কিত করে এবং নতুন প্রশ্নে অনুগ্রহটি পোস্ট করে ভাল করবেন।
ডপপেলগ্র্রেনার

2
স্কোপ ক্রাইপের কারণে আমি এই প্রশ্নটিকে আগের অবস্থায় ফিরিয়ে দিয়েছি। অনুগ্রহ যোগ করার সময় এবং সম্পাদনের মধ্যে একটি সুযোগ পরিবর্তনের অন্তর্ভুক্ত সময় দেওয়া, আমি ধরে নিয়েছি আপনি এই প্রশ্নের বিভিন্ন উত্তর পেতে চেয়েছিলেন, তাই আমি অনুগ্রহ ছেড়ে দেব। @ ডপপেলগ্র্রাইনার পরামর্শ অনুসারে, আমি আপনাকে নতুন নতুন প্রয়োজনীয়তা সহ আরও একটি প্রশ্ন জিজ্ঞাসা করার পরামর্শ দিচ্ছি।
আলেকজান্দ্রে ভায়ল্যানকোর্ট

উহু @AlexandreVaillancourt দুঃখিত আমি এটা, আমি শুধু একটি বিকল্প আমার প্রশ্নের কারণ আমি পরিবর্তন করার জন্য শৃঙ্খল questions.thanks পছন্দ করি না যোগ জানেন না ...
সাঈদ Morteza Kamali

উত্তর:


163

কাচ

এই প্রভাবটি তৈরি করতে, আপনি স্টেনসিল বাফার ব্যবহার করে অবজেক্টগুলি মাস্ক করতে পারেন।

স্টেনসিল বাফার হ'ল একটি সাধারণ উদ্দেশ্য বাফার যা আপনাকে স্ক্রিনে আঁকানো প্রতিটি পিক্সেলের জন্য অতিরিক্ত 8 বিট ইন্টিজার (অর্থাত্ 0-255 এর মান) সঞ্চয় করতে দেয়। শেডাররা যেমন স্ক্রিনে পিক্সেলের রঙ নির্ধারণ করতে আরজিবি মান এবং ডিপথ বাফারে আঁকা সেই পিক্সেলের গভীরতার জন্য z মানগুলি গণনা করে, তারা সেই পিক্সেলের প্রতিটিটির জন্য স্টেনসিল বাফারে একটি স্বেচ্ছাসেবক মানও লিখতে পারে। এই স্টেনসিল মানগুলি তখন পিক্সেলগুলি কীভাবে স্ক্রিনে সংমিশ্রণ করা উচিত তা নির্ধারণ করতে পরবর্তী শেডার পাসগুলির সাথে অনুসন্ধান এবং তুলনা করা যেতে পারে।

https://docs.unity3d.com/Manual/SL-Stencil.html

https://alastaira.wordpress.com/2014/12/27/using-the-stencil-buffer-in-unity-free/

http://www.codingwithunity.com/2016/01/stencil-buffer-shader-for-special.html

ভাবমূর্তি

মুখোশ স্টেনসিল:

Stencil 
{
    Ref 1 // ReferenceValue = 1
    Comp NotEqual // Only render pixels whose reference value differs from the value in the buffer.
}

ওয়াল স্টেনসিল:

Stencil
{
    Ref 1 // ReferenceValue = 1
    Comp Always // Comparison Function - Make the stencil test always pass.
    Pass Replace // Write the reference value into the buffer.
}

চলুন কার্যকর করা যাক।

এটি মাস্ক হিসাবে ব্যবহার করুন:

Shader "Custom/SimpleMask"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _CutOff("CutOff", Range(0,1)) = 0
    }
    SubShader
    {
        LOD 100
        Blend One OneMinusSrcAlpha
        Tags { "Queue" = "Geometry-1" }  // Write to the stencil buffer before drawing any geometry to the screen
        ColorMask 0 // Don't write to any colour channels
        ZWrite Off // Don't write to the Depth buffer
        // Write the value 1 to the stencil buffer
        Stencil
        {
            Ref 1
            Comp Always
            Pass Replace
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _CutOff;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                float dissolve = step(col, _CutOff);
                clip(_CutOff-dissolve);
                return float4(1,1,1,1)*dissolve;
            }
            ENDCG
        }
    }
}

প্রাচীর হিসাবে এটি ব্যবহার করুন:

Shader "Custom/Wall" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Blend SrcAlpha OneMinusSrcAlpha
        Tags { "RenderType"="Opaque" }
        LOD 200

        Stencil {
            Ref 1
            Comp NotEqual
        }

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

প্রভাব বিশ্লেষণ

আপনি যদি একটি পদ্ধতিগত টেক্সচার পেতে চান তবে আপনার কিছু গোলমাল দরকার।

ভাবমূর্তি আপনি এই শেডারটি শেদারটয়টিতে দেখতে পাবেন ।

এই প্রভাবটি তৈরি করতে, ইউভি স্থানাঙ্কগুলি ব্যবহার করার পরিবর্তে, পোলার কোঅর্ডিনেট ব্যবহার করুন এবং তারপরে শব্দটি জমিনে সেট করুন।

ইউভিগুলি সাধারণত ফ্যাশনের মতো গ্রিডে পিক্সেল না স্ক্রিনের মতো (এক্স = প্রস্থ, ওয়াই = উচ্চতা) আউট করা হয়। পোলার স্থানাঙ্কগুলি তবে এক্স এবং ই কিছুটা আলাদাভাবে ব্যবহার করুন। আপনার প্রয়োজনের উপর ভিত্তি করে একটি নির্ধারণ করে যে এটি বৃত্তের কেন্দ্র থেকে কত দূরে এবং অপরটি 0-1 রেঞ্জ থেকে ডিগ্রিগুলি ডিটারিজ করে।

1600px-sf_radialuvs

Shader "Smkgames/NoisyMask" {
    Properties {
        _MainTex ("MainTex", 2D) = "white" {}
        _Thickness ("Thickness", Range(0, 1)) = 0.25
        _NoiseRadius ("Noise Radius", Range(0, 1)) = 1
        _CircleRadius("Circle Radius", Range(0, 1)) = 0.5
        _Speed("Speed", Float) = 0.5
    }
    SubShader {
        Tags {"Queue"="Transparent" "IgnoreProjector"="true" "RenderType"="Transparent"}
        ZWrite Off 
        Blend SrcAlpha OneMinusSrcAlpha 
        Cull Off

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma target 3.0
            uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
            uniform float _Thickness,_NoiseRadius,_CircleRadius,_Speed;

            struct VertexInput {
                float4 vertex : POSITION;
                float2 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;
                float4 posWorld : TEXCOORD1;

            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;

                o.pos = UnityObjectToClipPos(v.vertex);
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }
            float4 frag(VertexOutput i, float facing : VFACE) : COLOR {

                float2 uv = (i.uv0*2.0+-1.0); // Remapping uv from [0,1] to [-1,1]
                float circleMask = step(length(uv),_NoiseRadius); // Making circle by LENGTH of the vector from the pixel to the center
                float circleMiddle = step(length(uv),_CircleRadius); // Making circle by LENGTH of the vector from the pixel to the center
                float2 polaruv = float2(length(uv),((atan2(uv.g,uv.r)/6.283185)+0.5)); // Making Polar
                polaruv += _Time.y*_Speed/10;
                float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(polaruv, _MainTex)); // BackGround Noise
                float Noise = (circleMask*step(_MainTex_var.r,_Thickness)); // Masking Background Noise
                float3 finalColor = float3(Noise,Noise,Noise);
                return fixed4(finalColor+circleMiddle,(finalColor+circleMiddle).r);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

আরেকটি সমাধান হ'ল ওয়ার্লির শব্দটি:

2018-01-05_8-16-16

আপনি এই শেডারটি শেদারটয়টিতে দেখতে পাবেন


Metaball

তারপরে আমি এই নিবন্ধটি থেকে মেটাবলের প্রভাবটি যুক্ত করব : চিত্র


বিল বোর্ডিং

আরও আছে ...

আপনি যদি আপনার মুখোশটি ঘোরান, আপনার ক্যামেরায় দেখতে চান তবে আপনি বিল বোর্ডটি ব্যবহার করতে পারেন :

 output.pos = mul(UNITY_MATRIX_P, 
              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
              + float4(input.vertex.x, input.vertex.y, 0.0, 0.0));

এটি বিল বোর্ডিংয়ের মুখোশটি:

Shader "Custom/Mask/SimpleMaskBillBoard"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _CutOff("CutOff", Range(0,1)) = 0
        _Radius("Radius", Range(0,1)) = 0.2
        _Speed("speed", Float) = 1
        _ScaleX ("Scale X", Float) = 1.0
        _ScaleY ("Scale Y", Float) = 1.0
    }
    SubShader
    {
        LOD 100
        Blend One OneMinusSrcAlpha
        Tags { "Queue" = "Geometry-1" }  // Write to the stencil buffer before drawing any geometry to the screen
        ColorMask 0 // Don't write to any colour channels
        ZWrite Off // Don't write to the Depth buffer

        // Write the value 1 to the stencil buffer
        Stencil
        {
            Ref 1
            Comp Always
            Pass Replace
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _CutOff;
            float _Speed;
            float _Radius;
            float _ScaleX,_ScaleY;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_P, 
                    mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
                    + float4(v.vertex.x, v.vertex.y, 0.0, 0.0)
                    * float4(_ScaleX, _ScaleY, 1.0, 1.0));

                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                float dissolve = step(col, _CutOff);
                clip(_CutOff-dissolve);
                return dissolve;
            }
            ENDCG
        }
    }
}

সর্বশেষ ফলাফল:

2018-01-04_20-18-39

উত্স উপলব্ধ: https://github.com/smkplus/Divinity-Origin-Sin-2


দরকারী লিংক

আমি একটি ভাল টিউটোরিয়াল পেয়েছি যা বিশ্বকে দ্রবীভূত করে এই প্রভাবটি কার্যকর করেছে:

Image1

বিশ্বকে দ্রবীভূত করা পর্ব 1

বিশ্ব দ্রবীভূত করা অংশ ২ 2

ভাবমূর্তি

Shader "Custom/DissolveBasedOnViewDistance" {
    Properties{
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Center("Dissolve Center", Vector) = (0,0,0,0)
        _Interpolation("Dissolve Interpolation", Range(0,5)) = 0.8
        _DissTexture("Dissolve Texture", 2D) = "white" {}
    }

        SubShader{
        Tags { "RenderType" = "Opaque" }
        LOD 200


            CGPROGRAM

        #pragma surface surf Standard vertex:vert addshadow

        #pragma target 3.0

        struct Input {
            float2 uv_MainTex;
            float2 uv_DissTexture;
            float3 worldPos;
            float viewDist;
        };



        sampler2D _MainTex;
        sampler2D _DissTexture;
        half _Interpolation;
        float4 _Center;


        // Computes world space view direction
        // inline float3 WorldSpaceViewDir( in float4 v )
        // {
        //     return _WorldSpaceCameraPos.xyz - mul(_Object2World, v).xyz;
        // }


        void vert(inout appdata_full v,out Input o){
            UNITY_INITIALIZE_OUTPUT(Input,o);

         half3 viewDirW = WorldSpaceViewDir(v.vertex);
         o.viewDist = length(viewDirW);

        }

        void surf(Input IN, inout SurfaceOutputStandard o) {


            float l = length(_Center - IN.worldPos.xyz);

            clip(saturate(IN.viewDist - l + (tex2D(_DissTexture, IN.uv_DissTexture) * _Interpolation * saturate(IN.viewDist))) - 0.5);

         o.Albedo = tex2D(_MainTex,IN.uv_MainTex);
        }
        ENDCG
        }
        Fallback "Diffuse"
}

অন্য স্টেনসিল টিউটোরিয়াল:

Left4Dead

স্টেনসিল টিউটোরিয়াল


10
এটি প্লেয়ার চরিত্রের সামনের দিকের দেওয়ালের মুখোমুখি হওয়ার জ্ঞান দিয়ে কীভাবে মুখোশটি করা যায় তার একটি ভাল ব্যাখ্যা, তবে চরিত্রের জ্যামিতির সামনে থাকা দেয়ালগুলিতে স্বয়ংক্রিয়ভাবে এই শেডারটি প্রয়োগ করার কোনও উপায় আছে কি?
ফুলফি

10
@ ফ্লুফি আপনি যখন অক্ষরের দেয়ালগুলির পিছনে থাকেন তখন সনাক্ত করার জন্য রয়কাস্ট ব্যবহার করতে পারেন তখন মাস্ক সক্ষম করুন।
সৈয়দ মুর্তেজা কমালী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.