UnityChan(Channel)
403 subscribers
1.79K photos
62 videos
13 files
41 links
کانال آموزش و نکات UnityChan

گروه یونیتی https://t.me/UnityChan
Download Telegram
توضیح کد و نحوه کارکرد آن :

در این شما شیدر و ویژگی آن را تعریف میکنید که در این مسیر میتوانید شیدر خود را بروی متریال انتخاب کنید


Shader "Custom/StylizedURPShader_FProSensei"


ویژگی‌ها: این بخش شامل ویژگی‌های قابل تنظیم شیدر است که در ادیتور یونیتی قابل مشاهده‌ هست. هر ویژگی یک نام، نوع و مقدار پیش‌فرض داره (دقیقا مثل ورودی میمومه مثل این که شما داری public int تعریف میکین که مقدارشو توی ادیتور یونیتی تنظیم کنی)


Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
_NormalMap ("Normal Map", 2D) = "bump" {}
_HeightMap ("Height Map", 2D) = "white" {}
_TranslucencyColor ("Translucency Color", Color) = (1,1,1,1)
_TranslucencyIntensity ("Translucency Intensity", Range(0, 1)) = 0.5
_RimColor ("Rim Color", Color) = (1,1,1,1)
_RimPower ("Rim Power", Range(1, 10)) = 3
_EmissionColor ("Emission Color", Color) = (1,1,1,1)
_EmissionIntensity ("Emission Intensity", Range(0, 10)) = 1
_Alpha ("Alpha", Range(0, 1)) = 1
_SpecularColor ("Specular Color", Color) = (1,1,1,1)
_SpecularIntensity ("Specular Intensity", Range(0, 1)) = 0.5
_Metallic ("Metallic", Range(0, 1)) = 0.0
_Smoothness ("Smoothness", Range(0, 1)) = 0.5
_TransmissionColor ("Transmission Color", Color) = (1, 1, 1, 1)
_TransmissionIntensity ("Transmission Intensity", Range(0, 1)) = 0.5
_OutlineColor ("Outline Color", Color) = (0, 0, 0, 1)
_OutlineThickness ("Outline Thickness", Range(0.01, 0.1)) = 0.05
_StylizedColor ("Stylized Color", Color) = (1, 0.5, 0.5, 1)
_StylizedIntensity ("Stylized Intensity", Range(0, 2)) = 1.0
}


SubShader: این بخش شامل مراحل رندرینگ است یعنی کل pass ها در این بخش قرار میگیره.
Tags: نوع رندرینگ را مشخص می‌کند (در اینجا چون از ترنسپرنت استفاده کردم شفاف).
Blend: نحوه ترکیب رنگ‌ها را در حالت شفافیت مشخص می‌کند.
ZWrite: تعیین می‌کند که آیا باید عمق پیکسل‌ها نوشته شود یا نه.
ZTest: نوع تست عمق را مشخص می‌کند.


SubShader
{
Tags { "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
ZWrite On
ZTest LEqual


Pass: یک مرحله رندرینگ را تعریف می کنیم مثلا اوت لاین خودش یک pass داره.
Name: نام مرحله رندرینگ.
Tags: نوع نورپردازی را مشخص می‌کند.


Pass
{
Name "Forward"
Tags { "LightMode"="UniversalForward" }

HLSLPROGRAM: شروع برنامه‌نویسی HLSL.
#pragma target: نسخه هدف HLSL را مشخص می‌کند.
#include: فایل‌های کتابخانه‌ای مربوط به متغیرها و نورپردازی را وارد می‌کند.


HLSLPROGRAM
#pragma target 4.5
#include "UnityShaderVariables.hlsl"
#include "UnityLighting.hlsl"
#include "CoreRP/ShaderLibrary/Core.hlsl"
#include "CoreRP/ShaderLibrary/Lighting.hlsl"


Attributes: ساختاری برای ورودی‌های وکتورهای هندسی که شامل موقعیت، نرمال و UVها است.


struct Attributes
{
float4 positionOS :
float3 normalOS :
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
};


Varyings: ساختاری برای نگهداری مقادیر بین مرحله vertex و fragment.


struct Varyings
{
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float4 positionCS : SV_POSITION;
float3 tangentWS : TEXCOORD3;
};


FragmentInput: ساختاری برای ورودی‌های مرحله fragment.


struct FragmentInput
{
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float3 normalWS : TEXCOORD2;
float3 tangentWS : TEXCOORD3;
};


متغیرهای نمونه‌برداری: این متغیرها برای نگهداری بافت‌ها و ویژگی‌های مختلف مانند رنگ، شدت و غیره استفاده می‌شوند.


sampler2D _MainTex;
sampler2D _NormalMap;
sampler2D _HeightMap;
fixed4 _TranslucencyColor;
float _TranslucencyIntensity;
fixed4 _RimColor;
float _RimPower;
fixed4 _EmissionColor;
float _EmissionIntensity;
float _Alpha;
fixed4 _SpecularColor;
float _SpecularIntensity;
float _Metallic;
float _Smoothness;
fixed4 _TransmissionColor;
float _TransmissionIntensity;
fixed4 _OutlineColor;
float _OutlineThickness;
fixed4 _StylizedColor;
float _StylizedIntensity;
🔥2👍1
FPro Sensei
توضیح کد و نحوه کارکرد آن : در این شما شیدر و ویژگی آن را تعریف میکنید که در این مسیر میتوانید شیدر خود را بروی متریال انتخاب کنید Shader "Custom/StylizedURPShader_FProSensei" ویژگی‌ها: این بخش شامل ویژگی‌های قابل تنظیم شیدر است که در ادیتور یونیتی قابل…
Varyings vert(Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToClip(input.positionOS);
output.uv0 = input.uv0; // UV0
output.uv1 = input.uv1; // UV1
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
output.tangentWS = TransformObjectToWorldTangent(input.normalOS);
return output;
}

vert: تابع vertex که ورودی‌ها را از ساختار Attributes دریافت کرده و خروجی‌ها را به ساختار Varyings تبدیل می‌کند.
TransformObjectToClip: موقعیت شیء را به فضای کلیپ تبدیل می‌کند.
TransformObjectToWorldNormal: نرمال شیء را به فضای جهانی تبدیل می‌کند.
TransformObjectToWorldTangent: تانژانت شیء را به فضای جهانی تبدیل می‌کند.



half4 frag(FragmentInput input) : SV_Target
{
half4 baseColor = tex2D(_MainTex, input.uv0);

// Normal mapping
half3 normalMapValue = tex2D(_NormalMap, input.uv0).rgb * 2.0 - 1.0;
normalMapValue.xy *= half3(0.5, 0.5); // Scale the normal map
half3 normalWS = normalize(input.normalWS + normalMapValue);

frag: تابع fragment که رنگ نهایی پیکسل را محاسبه می‌کند.
tex2D: بافت اصلی را بر اساس UVها دریافت می‌کند.
نرمال مپینگ: نرمال مپ را دریافت کرده و آن را به دامنه [-1, 1] تبدیل می‌کند و سپس به نرمال شیء اضافه می‌کند.


half3 translucency = _TranslucencyColor.rgb * _TranslucencyIntensity;

half rim = pow(1.0 - saturate(dot(normalWS, -_WorldSpaceCameraPos)), _RimPower);
half4 rimColor = rim * _RimColor;

half3 finalLighting = half3(0, 0, 0);

Translucency effect: تأثیر شفافیت را محاسبه می‌کند.
Rim lighting effect: نور حاشیه‌ای را محاسبه کرده و رنگ آن را تعیین می‌کند.
finalLighting: متغیری برای ذخیره نور نهایی.


for (int i = 0; i < MAX_LIGHT_COUNT; i++)
{
half3 lightDir = normalize(_WorldSpaceLightPos[i].xyz);
half3 viewDir = normalize(-_WorldSpaceCameraPos);
half3 reflectionDir = reflect(-lightDir, normalWS);
float specAngle = max(0.0, dot(reflectionDir, viewDir));
float specularTerm = pow(specAngle, 16 * _Smoothness);

// Basic Lambertian diffuse shading with stylization effect
float diffTerm = max(dot(normalWS, lightDir), 0.0);
diffTerm *= (diffTerm * (1 - diffTerm) * _StylizedIntensity);

finalLighting += diffTerm * _LightColor[i].rgb + (_SpecularColor.rgb * specularTerm * _SpecularIntensity);
}

این حلقه برای هر منبع نوری موجود در صحنه اجرا می‌شود.
نورپردازی پایه: با استفاده از فرمول لامبرتین نورپردازی انجام می‌شود و سپس تأثیر استایلایز به آن اضافه می‌شود.



half4 finalColor = baseColor + translucency + rimColor + finalLighting;

finalColor.rgb += (_TransmissionColor.rgb * _TransmissionIntensity);

finalColor.a *= _Alpha;


finalColor += _EmissionColor * _EmissionIntensity;


finalColor.rgb *= lerp(half3(1.0), _StylizedColor.rgb, _StylizedIntensity);

return finalColor;

finalColor: رنگ نهایی ترکیب شده با تأثیرات مختلف محاسبه می‌شود.
لکه‌گذاری رنگ استایلایز: رنگ نهایی با رنگ استایلایز شده ترکیب می‌شود


Pass
{
Name "Outline"
Tags { "LightMode"="UniversalForward" }

Cull Front
ZWrite Off
Blend One One

HLSLPROGRAM

این بخش برای ایجاد یک پاس جدید برای رسم حاشیه (Outline) تعریف شده است.
در اینجا، نوع رندرینگ و تنظیمات مربوط به حاشیه مشخص می‌شود.

تابع vert برای Outline

Varyings vert(Attributes input)
{
Varyings output;

float3 offset = normalize(input.normalOS) * _OutlineThickness;



    output.positionCS = TransformObjectToClip(input.positionOS + float4(offset, 0));

return output;
}

در اینجا موقعیت اشیاء به سمت خارج جابجا می‌شود تا حاشیه ایجاد شود.


half4 frag() : SV_Target
{
return _OutlineColor;
}

رنگ حاشیه را به عنوان خروجی تعیین می‌کند.



ENDHLSL

• پایان برنامه HLSL.



FallBack "Diffuse"

• اگر شیدر نتواند بارگذاری شود، از شیدر پیش‌فرض دیفیوز استفاده خواهد کرد.
🔥2
+ آموزش باندل :
اگر یک شیدر نویس حرفه ای باشید باید خوب دقت کرده باشید که هر شیدری که در یونیتی پکیج میشه و فروخته میشه همشون UI دارن که با استفاده از C# میان اون شیدر که به زبان HLSL نوشتن رو کنترل میکنن ولی چطوری :
1
FPro Sensei
+ آموزش باندل : اگر یک شیدر نویس حرفه ای باشید باید خوب دقت کرده باشید که هر شیدری که در یونیتی پکیج میشه و فروخته میشه همشون UI دارن که با استفاده از C# میان اون شیدر که به زبان HLSL نوشتن رو کنترل میکنن ولی چطوری :
Custom Shader GUI (تغییر ظاهر Inspector)

این اسکریپت را با نام ShaderUI در یک پوشه به نام Editor (حتماً نام پوشه Editor باشد) ذخیره کنید:

using UnityEngine;
using UnityEditor;

public class ShaderUI : ShaderGUI
{
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
Material targetMat = materialEditor.target as Material;

// تیتر اصلی
GUILayout.Label("Arknights Style PBR Settings", EditorStyles.boldLabel);
EditorGUILayout.Space();

// بخش تنظیمات بافت و رنگ
EditorGUILayout.BeginVertical("HelpBox");
GUILayout.Label("Base Maps", EditorStyles.miniBoldLabel);
materialEditor.ShaderProperty(FindProperty("_MainTex", properties), "Albedo (RGB)");
materialEditor.ShaderProperty(FindProperty("_BaseColor", properties), "Color Tint");
materialEditor.ShaderProperty(FindProperty("_NormalMap", properties), "Normal Map");
EditorGUILayout.EndVertical();

// بخش PBR
EditorGUILayout.BeginVertical("HelpBox");
GUILayout.Label("Physical Properties", EditorStyles.miniBoldLabel);
materialEditor.ShaderProperty(FindProperty("_Metallic", properties), "Metallic");
materialEditor.ShaderProperty(FindProperty("_Smoothness", properties), "Smoothness");
EditorGUILayout.EndVertical();

// بخش Stylized (Cel Shading)
EditorGUILayout.BeginVertical("HelpBox");
GUILayout.Label("Stylized Rendering (Cel Shading)", EditorStyles.miniBoldLabel);
materialEditor.ShaderProperty(FindProperty("_StepThreshold", properties), "Shadow Threshold");
materialEditor.ShaderProperty(FindProperty("_StepFeather", properties), "Shadow Softness (Feather)");
materialEditor.ShaderProperty(FindProperty("_RimColor", properties), "Rim Color");
materialEditor.ShaderProperty(FindProperty("_RimPower", properties), "Rim Power");
EditorGUILayout.EndVertical();

// بخش Outline
EditorGUILayout.BeginVertical("HelpBox");
GUILayout.Label("Outline Settings", EditorStyles.miniBoldLabel);
materialEditor.ShaderProperty(FindProperty("_OutlineColor", properties), "Outline Color");
materialEditor.ShaderProperty(FindProperty("_OutlineWidth", properties), "Outline Thickness");
EditorGUILayout.EndVertical();

EditorGUILayout.Space();
materialEditor.RenderQueueField(); // تنظیم ترتیب رندر
}

// متد کمکی برای پیدا کردن پراپرتی‌ها
private MaterialProperty FindProperty(string name, MaterialProperty[] props)
{
return ShaderGUI.FindProperty(name, props);
}
}

نکته مهم: برای اینکه شیدر از این اسکریپت استفاده کند، باید خط آخر شیدر خود را (قبل از بستن آخرین آکوالاد) به این صورت تغییر دهید:
CustomEditor "shaderUI"
2
FPro Sensei
GUILayout.Label("Arknights Style PBR Settings", EditorStyles.boldLabel);
نکته مهم :
اگر بتوانید از این شیدر که نوشتم درست استفاده کنید و اصول نور پردازی pbr هم بلد باشید دقیقا به گرافیک رندر بازی Arknight خواهید رسید ولی نحوه استفاده از شیدر و اصول کامپوزیت به سبک arknight رو به عهده شما میزارم 😏
1
نحوه ساخت شیدر به کدام روش برای شما خفن تر و جذاب تر محسوب میشود ؟ (هر کدوم بگید براش آموزش میاد) :
من که بطور (مداوم انیمه دیدم)بطور کلی به 3 حالت تقسیم کردم :

1 - ابرو و مژه و چشم بطور کامل دیده میشه

2 - ابرو و مژه و چشم بصورت نیمه شفاف دیده میشه

3 - ابرو و مژه و چشم فقط بصورت خط دیده میشه
3
چرا انیمیشن 3D همانند 2D فریم به فریم نیست و بر خلاف 2D انیمیشن نرم تری داره و ایا راهی هست که بشه همان افکت انیمیت 2d را در 3d پیاده سازی کرد ؟

برای پیدا کردن جواب به ریشه ساختار این دو می پردازیم :

#نکته_انیمت
اگر این دو گیف بالا را با هم دیگر مقایسه کنیم به این نتیجه میرسید که انیمیشن 3d بدون پرش فریم هست و حتا 0.1 ثانیه از فریمش انیمت شده ولی 2d کمی انیمیشن داری پرش فریم هست چون فریم بای فریم و هست و کلا فریم هاش انیمیت نشده و از فریم به فریم پرش داره و سوم دلیل نوع درون یابی و interpolation هست برای بررسی دقیق تر به نحوه ساختارش می پردازیم
FPro Sensei
ساختار و ریشه anime 2d
همان طور که ویدیو مشاهده کردید انیمه بصورت فریم بای فریم ساخته میشود و این پرش فریم و محدود کردن آن به 24 فریم باعث میشود تا اون افکت خاص انیمت را همیشه در انیمه ها ببینیم
This media is not supported in your browser
VIEW IN TELEGRAM
ساختار و ریشه 3d animation
FPro Sensei
ساختار و ریشه 3d animation
همان طور که در ویدیو مشاهده کردیم انیمیشن 3d دارای درون یابی های به نام Bezier و linear هست که یعنی فریم بای فریم نیست و حتا دهم ثاینه از فریم بصورت خودکار انیمت شده همان باعث میشود که بسیار نرم به نظر برسد