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
FPro Sensei
+ آموزش باندل : اگر یک شیدر نویس حرفه ای باشید باید خوب دقت کرده باشید که هر شیدری که در یونیتی پکیج میشه و فروخته میشه همشون UI دارن که با استفاده از C# میان اون شیدر که به زبان HLSL نوشتن رو کنترل میکنن ولی چطوری :
Custom Shader GUI (تغییر ظاهر Inspector)
این اسکریپت را با نام ShaderUI در یک پوشه به نام Editor (حتماً نام پوشه Editor باشد) ذخیره کنید:
نکته مهم: برای اینکه شیدر از این اسکریپت استفاده کند، باید خط آخر شیدر خود را (قبل از بستن آخرین آکوالاد) به این صورت تغییر دهید:
این اسکریپت را با نام 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 - ابرو و مژه و چشم فقط بصورت خط دیده میشه
1 - ابرو و مژه و چشم بطور کامل دیده میشه
2 - ابرو و مژه و چشم بصورت نیمه شفاف دیده میشه
3 - ابرو و مژه و چشم فقط بصورت خط دیده میشه
❤3
چرا انیمیشن 3D همانند 2D فریم به فریم نیست و بر خلاف 2D انیمیشن نرم تری داره و ایا راهی هست که بشه همان افکت انیمیت 2d را در 3d پیاده سازی کرد ؟
برای پیدا کردن جواب به ریشه ساختار این دو می پردازیم :
#نکته_انیمت
برای پیدا کردن جواب به ریشه ساختار این دو می پردازیم :
#نکته_انیمت
FPro Sensei
چرا انیمیشن 3D همانند 2D فریم به فریم نیست و بر خلاف 2D انیمیشن نرم تری داره و ایا راهی هست که بشه همان افکت انیمیت 2d را در 3d پیاده سازی کرد ؟ برای پیدا کردن جواب به ریشه ساختار این دو می پردازیم : #نکته_انیمت
This media is not supported in your browser
VIEW IN TELEGRAM
سایکل قدم زدن یک کاراکتر 2d
FPro Sensei
سایکل قدم زدن یک کاراکتر 2d
This media is not supported in your browser
VIEW IN TELEGRAM
سایکل قدم زدن یک کاراکتر 3d
❤1
اگر این دو گیف بالا را با هم دیگر مقایسه کنیم به این نتیجه میرسید که انیمیشن 3d بدون پرش فریم هست و حتا 0.1 ثانیه از فریمش انیمت شده ولی 2d کمی انیمیشن داری پرش فریم هست چون فریم بای فریم و هست و کلا فریم هاش انیمیت نشده و از فریم به فریم پرش داره و سوم دلیل نوع درون یابی و interpolation هست برای بررسی دقیق تر به نحوه ساختارش می پردازیم
FPro Sensei
ساختار و ریشه anime 2d
همان طور که ویدیو مشاهده کردید انیمه بصورت فریم بای فریم ساخته میشود و این پرش فریم و محدود کردن آن به 24 فریم باعث میشود تا اون افکت خاص انیمت را همیشه در انیمه ها ببینیم
FPro Sensei
افکت خاص انیمت
This media is not supported in your browser
VIEW IN TELEGRAM
سایکل قدم زدن در انیمه 2d
This media is not supported in your browser
VIEW IN TELEGRAM
ساختار و ریشه 3d animation
FPro Sensei
ساختار و ریشه 3d animation
همان طور که در ویدیو مشاهده کردیم انیمیشن 3d دارای درون یابی های به نام Bezier و linear هست که یعنی فریم بای فریم نیست و حتا دهم ثاینه از فریم بصورت خودکار انیمت شده همان باعث میشود که بسیار نرم به نظر برسد