الوحدة كيفية إنشاء تظليل

Shader هو برنامج نصي صغير يحتوي على حسابات رياضية وخوارزميات لحساب لون كل بكسل معروض، بناءً على مدخلات الإضاءة وتكوين المادة.

Unity يستخدم Shaders المكتوبة باللغات التالية:

  • يتم استخدام لغة برمجة تسمى HLSL لكتابة برامج التظليل نفسها.
  • يتم استخدام لغة خاصة بـ Unity تسمى ShaderLab لتعريف كائن Shader، الذي يعمل كحاوية لبرامج التظليل.

لإنشاء تظليل في Unity اتبع الخطوات التالية:

إنشاء شادر

  • انقر بزر الماوس الأيمن على عرض المشروع -> 'Create' -> 'Shader'

اعتمادًا على إصدار Unity الذي تستخدمه، قد تختلف خيارات Shader، ولكن إليك ما يعنيه كل خيار من الخيارات:

  1. 'Standard Surface Shader': تم تصميم هذا التظليل للعمل مع نظام العرض الفعلي (PBR) Unity's. فهو يسمح للمطورين بإنشاء مواد تستجيب لظروف الإضاءة بشكل واقعي. وهو يدعم ميزات العرض المختلفة مثل التعيين العادي والإبرازات المرآوية والانعكاسات. إنه تظليل متعدد الاستخدامات يوفر توازنًا جيدًا بين الواقعية والأداء.
  2. 'Unlit Shader': كما يوحي الاسم، التظليل غير المضاء لا يأخذ في الاعتبار ظروف الإضاءة. يتم استخدامه غالبًا لعرض التأثيرات التي لا تحتاج إلى إضاءة واقعية، مثل عناصر واجهة المستخدم أو أنظمة الجسيمات أو التأثيرات الخاصة. عادةً ما تكون التظليلات غير المضاءة أكثر كفاءة ويمكن أن تكون مفيدة في المواقف التي تتطلب التحكم الكامل في مظهر الكائن دون أي حسابات للإضاءة.
  3. 'Image Effect Shader': يتم استخدام تظليل image Effect لتطبيق تأثيرات ما بعد المعالجة على الشاشة بأكملها أو أهداف عرض محددة. إنها تسمح للمطورين بتعديل الصورة النهائية المقدمة بعد اكتمال العرض الرئيسي. تتضمن أمثلة تأثيرات الصورة التمويه أو تدرج الألوان أو التشويه أو المرشحات المنمقة. يمكن استخدامها لتحسين الجودة المرئية أو إنشاء تأثيرات فنية محددة.
  4. 'Compute Shader': التظليل الحسابي هو نوع من التظليل الذي يتم تشغيله على وحدة معالجة الرسومات ولكنه لا يعمل على وحدات البكسل مباشرة. يتم استخدامه لإجراء العمليات الحسابية للأغراض العامة على البيانات المتوازية، مما يسمح للمطورين بإجراء حسابات معقدة أو عمليات محاكاة بكفاءة. تُستخدم التظليلات الحسابية بشكل شائع في مهام مثل المحاكاة الفيزيائية أو إنشاء الإجراءات أو معالجة البيانات.
  5. 'Ray Tracing Shader': تستخدم تظليلات تتبع الشعاع تقنية تتبع الشعاع، التي تحاكي سلوك الضوء بشكل أكثر دقة مقارنة بتقنيات التنقيط التقليدية. تُستخدم تظليلات تتبع الشعاع عادةً لتحقيق إضاءة وانعكاسات وظلال واقعية للغاية في التطبيقات في الوقت الفعلي. إنها تتطلب أجهزة قوية وغالبًا ما يتم استخدامها في مجالات الرسومات المكثفة مثل الألعاب أو التصور المعماري.
  • بعد تحديد التظليل، اكتب أي اسم واضغط على Enter

تم إنشاء Shader الجديد ويمكن فتحه في أي محرر نصوص وتعديله ليناسب احتياجاتك.

الافتراضي 'Standard Surface Shader':

Shader "Custom/NewSurfaceShader"
{
    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
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        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;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        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"
}

الافتراضي 'Unlit Shader':

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

الافتراضي 'Image Effect Shader':

Shader "Hidden/NewImageEffectShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        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;
            };

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

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                col.rgb = 1 - col.rgb;
                return col;
            }
            ENDCG
        }
    }
}

الافتراضي 'Compute Shader':

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float4> Result;

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!

    Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
}

الافتراضي 'Ray Tracing Shader':

RWTexture2D<float4> RenderTarget;

#pragma max_recursion_depth 1

[shader("raygeneration")]
void MyRaygenShader()
{
    uint2 dispatchIdx = DispatchRaysIndex().xy;
   
    RenderTarget[dispatchIdx] = float4(dispatchIdx.x & dispatchIdx.y, (dispatchIdx.x & 15)/15.0, (dispatchIdx.y & 15)/15.0, 0.0);
}

خاتمة

كل نوع من أنواع التظليل له نقاط القوة والاستخدامات الخاصة به. من المهم اختيار التظليل المناسب بناءً على متطلباتك المحددة والمؤثرات المرئية التي تهدف إلى تحقيقها في مشروعك.

المقالات المقترحة
إنشاء نظام جرد وصياغة العناصر في الوحدة
إنشاء تأثير وقت الرصاصة في الوحدة
إنشاء محاكي حركة المرور في الوحدة
إنشاء تأثير اهتزاز الكاميرا في الوحدة
كيفية إضافة تأثير نطاق القناص في الوحدة
إنشاء بازوكا في الوحدة
إنشاء طفرات ثنائية الأبعاد في الوحدة