FPro Sensei
از همون تابع داخلی refraction استفاده میکنه و مقدایر (V, PositionWS, N, ior, thickness) میده به اون تا اون برام یک مدل RefractionModelBox برگشت بده و اما کار این تابع چیست : بردار دید (V) را با نرمال سطح (N) و IOR شکست میدهد — refract(-V, N, 1/IOR) — یعنی…
اگر بازم متوجه نشدید که RefractionModelBox چیه با این تصویر کاملا متوجه میشید همون رابطه اسنل رو داره
🔥1
FPro Sensei
float2 hitNDC = ComputeNormalizedDeviceCoordinates(
refraction.positionWS, GetWorldToHClipMatrix());
این خط نقطهٔ خروج پرتوی شکستهشده (که یک مختصات سهبعدی در فضای جهانی است) را به یک مختصات دوبعدی روی صفحهٔ نمایش (UV بین ۰ تا ۱) تبدیل میکند — یعنی «این نقطه از دنیای سهبعدی، دقیقاً کجای تصویر رندرشده قرار میگیرد؟» اما سوال این هست که چرا لازمه ؟
refraction.positionWS که از RefractionModelBox گرفتیم یک نقطه در فضای ۳بعدی جهان است (مثلاً «ته آب، ۲۰ سانتیمتر پایینتر و کمی به یک طرف کجشده»). اما برای نمونهبرداری از _ColorPyramidTexture (که یک تصویر ۲بعدی رندرشده از دوربین است) نیاز داریم بدانیم این نقطه در پیکسلبندی تصویر کجا میافتد. ❗️
FPro Sensei
float hitDeviceDepth = SampleCameraDepth(hitNDC);
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
float surfaceLinearDepth = LinearEyeDepth(PositionWS, GetWorldToViewMatrix());
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
float surfaceLinearDepth = LinearEyeDepth(PositionWS, GetWorldToViewMatrix());
خط اول:
در همان UV که از مرحلهٔ قبل (
خط دوم:
عمق خام غیرخطی (device depth) را به یک عدد خطی بهمتر تبدیل میکند. بافر عمق در GPU معمولاً غیرخطی ذخیره میشود (دقت بیشتر نزدیک دوربین، کمتر دور) و برای مقایسهٔ مستقیم فاصلهها باید خطیاش کنیم. نتیجه:
خط سوم:
این یکی overload متفاوتی از
SampleCameraDepth(hitNDC)در همان UV که از مرحلهٔ قبل (
hitNDC) بهدست آمد، بهجای رنگ، مقدار عمق را از بافر عمق دوربین میخواند. خروجیاش یک عدد خام است (device depth، معمولاً بین ۰ و ۱، غیرخطی) — یعنی «چیزی که همین الان روی صفحه در این پیکسل رندر شده، چقدر از دوربین فاصله دارد؟»خط دوم:
LinearEyeDepth(hitDeviceDepth, _ZBufferParams)عمق خام غیرخطی (device depth) را به یک عدد خطی بهمتر تبدیل میکند. بافر عمق در GPU معمولاً غیرخطی ذخیره میشود (دقت بیشتر نزدیک دوربین، کمتر دور) و برای مقایسهٔ مستقیم فاصلهها باید خطیاش کنیم. نتیجه:
hitLinearDepth = «فاصلهٔ واقعی (متر) چیزی که در آن UV روی صفحه دیده میشود، از دوربین.»خط سوم:
LinearEyeDepth(PositionWS, GetWorldToViewMatrix())این یکی overload متفاوتی از
LinearEyeDepth است — بهجای گرفتن device depth، مستقیم یک موقعیت world را میگیرد و با ماتریس world-to-view فاصلهٔ آن نقطه از دوربین را حساب میکند. اینجا PositionWS موقعیت خود سطح آب است (نه نقطهٔ شکستهشده). نتیجه: surfaceLinearDepth = «سطح آب خودش چقدر از دوربین فاصله دارد؟»
FPro Sensei
float offsetMultiplier = (hitLinearDepth > surfaceLinearDepth) ? 1.0 : 0.0;
float2 samplingNDC = lerp(ScreenPosition.xy, hitNDC, offsetMultiplier);
float2 samplingNDC = lerp(ScreenPosition.xy, hitNDC, offsetMultiplier);
خط اول:
یک سوییچ صفر/یک میسازد:
اگر
در غیر این صورت (چیزی که آنجاست جلوتر از آب است — یعنی یک جسم مثل پای کاراکتر جلوی آب ایستاده) →
خط دوم:
بر اساس آن سوییچ، بین دو UV انتخاب میکند:
وقتی
وقتی
چون
offsetMultiplierیک سوییچ صفر/یک میسازد:
اگر
hitLinearDepth > surfaceLinearDepth (چیزی که پشت UV شکستهشده هست، از خود سطح آب دورتر است — یعنی واقعاً «پشت آب» است) → offsetMultiplier = 1.0در غیر این صورت (چیزی که آنجاست جلوتر از آب است — یعنی یک جسم مثل پای کاراکتر جلوی آب ایستاده) →
offsetMultiplier = 0.0خط دوم:
lerp(ScreenPosition.xy, hitNDC, offsetMultiplier)بر اساس آن سوییچ، بین دو UV انتخاب میکند:
وقتی
offsetMultiplier = 1.0 → نتیجه دقیقاً hitNDC میشود (همان UV شکستهشده که از RefractionModelBox + پروجکشن بهدست آمد) — یعنی رفرکشن واقعی اعمال میشود.وقتی
offsetMultiplier = 0.0 → نتیجه دقیقاً ScreenPosition.xy میشود (UV خودِ پیکسل سطح آب، بدون هیچ آفستی) — یعنی رفرکشن خاموش میشود و همانجایی که هستیم را میخوانیم.چون
lerp با ضریب دقیقاً ۰ یا ۱ است (نه یک عدد میانی)، این عملاً یک if است نوشتهشده بهشکل بدون شاخه (branchless) — روی GPU این معمولاً سریعتر از if واقعی اجرا میشود.🔥1
FPro Sensei
float mipLevel = PositivePow(saturate(Roughness), 1.3)
* max((float)_ColorPyramidLodCount - 1.0, 0.0);
float3 color = SampleCameraColor(samplingNDC, mipLevel);
color *= GetInverseCurrentExposureMultiplier();
خط اول: محاسبهٔ
نتیجه: هرچه سطح زبرتر (Roughness بالاتر)،
خط سوم:
از
خط چهارم:
پیرامید رنگ، رنگها را بهشکل pre-exposed ذخیره میکند — یعنی مقدار auto-exposure صحنه از قبل در آن ضرب شده.
mipLevel_ColorPyramidTexture فقط یک تصویر ساده نیست — یک mip chain است: نسخهٔ کاملرزولوشن (mip 0)، بعد نصفرزولوشن (mip 1)، ربع (mip 2)، و همینطور تا آخر. هر مرحلهٔ پایینتر عملاً یک نسخهٔ تارتر و کوچکتر از تصویر است نتیجه: هرچه سطح زبرتر (Roughness بالاتر)،
mipLevel بزرگتر میشود → از سطح تارتر پیرامید نمونه گرفته میشود → رفرکشن محو/تار بهنظر میرسد. سطح صاف/براق (Roughness=0) → mipLevel=0 → کاملاً واضح.خط سوم:
SampleCameraColor(samplingNDC, mipLevel)از
_ColorPyramidTexture در مختصات samplingNDC (همان UV نهایی که با گارد عمق تعیین شد) و در سطح mip محاسبهشده، رنگ را میخواند. این تابع wrapper است که خودش _ColorPyramidUvScaleAndLimitCurrentFrame را هم داخلش اعمال میکند (چون پیرامید رنگ همیشه دقیقاً هماندازهٔ کل صفحه نیست، یک بخش کوچکش padding/unused است، و این ضریب scale/limit جلوی خواندن از آن ناحیهٔ نامعتبر را میگیرد).خط چهارم:
color *= GetInverseCurrentExposureMultiplier()پیرامید رنگ، رنگها را بهشکل pre-exposed ذخیره میکند — یعنی مقدار auto-exposure صحنه از قبل در آن ضرب شده.
🔥1
FPro Sensei
float3 absorption = exp(-max(AbsorptionColor, 0.0)
* max(AbsorptionStrength, 0.0)
* refraction.dist);
color *= absorption;
float2 coordCS = samplingNDC * 2.0 - 1.0;
float2 t = Remap10(abs(coordCS),
_SSRefractionInvScreenWeightDistance,
_SSRefractionInvScreenWeightDistance);
float edgeFade = Smoothstep01(t.x) * Smoothstep01(t.y);
بخش اول: جذب (Absorption) — قانون Beer-Lambert
هرچه
نتیجه: این نسخه از عمق واقعی مسیر نوری (
absorption = exp(-AbsorptionColor * AbsorptionStrength * refraction.dist)
color *= absorption
هرچه
refraction.dist بزرگتر باشد (پرتو مسیر طولانیتری داخل آب طی کرده — یعنی آب عمیقتر)، exp(-...) کوچکتر میشود → رنگ بیشتر جذب/تیره میشود.AbsorptionColor به هر کانال رنگ اجازه میدهد با نرخ متفاوت جذب شود — مثلاً آب معمولاً قرمز را سریعتر از آبی جذب میکند، برای همین آب عمیق آبی/سبز بهنظر میرسد.AbsorptionStrength یک ضریب کلی برای شدت این افکت است.نتیجه: این نسخه از عمق واقعی مسیر نوری (
refraction.dist) استفاده میکند — پس با عمق واقعی آب (نه فقط یک پارامتر ثابت) هماهنگ میشود.🔥1
FPro Sensei
float2 coordCS = samplingNDC * 2.0 - 1.0;
float2 t = Remap10(abs(coordCS),
_SSRefractionInvScreenWeightDistance,
_SSRefractionInvScreenWeightDistance);
float edgeFade = Smoothstep01(t.x) * Smoothstep01(t.y);
RefractedColor = max(color, 0.0);
Weight = saturate(edgeFade);
float2 t = Remap10(abs(coordCS),
_SSRefractionInvScreenWeightDistance,
_SSRefractionInvScreenWeightDistance);
float edgeFade = Smoothstep01(t.x) * Smoothstep01(t.y);
RefractedColor = max(color, 0.0);
Weight = saturate(edgeFade);
محاسبهٔ
UV نمونهبرداری را به بازهٔ
رنگ نهایی محاسبهشده (بعد از نمونهبرداری از پیرامید، اصلاح exposure، و جذب) را در خروجی میگذارد.
مقدار fade را بین ۰ و ۱ محدود میکند و بهعنوان خروجی دوم تابع (
edgeFadeUV نمونهبرداری را به بازهٔ
[-1,1] میبرد، فاصله تا نزدیکترین لبهٔ صفحه را حساب میکند، و با Smoothstep01 یک مقدار نرم بین ۰ (دقیقاً روی لبه) تا ۱ (دور از لبه، وسط صفحه) میسازد. ضرب t.x * t.y یعنی اگر از هر جهت (افقی یا عمودی) به لبه نزدیک شویم، فید کم میشود.RefractedColor = max(color, 0.0)رنگ نهایی محاسبهشده (بعد از نمونهبرداری از پیرامید، اصلاح exposure، و جذب) را در خروجی میگذارد.
max(..., 0.0) فقط یک گارد ایمنی است — جلوی مقادیر منفی احتمالی (که در محاسبات نوری گاهی از خطای عددی float پیش میآید و در HDR/رندر بعدی مشکل ایجاد میکند) را میگیرد.Weight = saturate(edgeFade)مقدار fade را بین ۰ و ۱ محدود میکند و بهعنوان خروجی دوم تابع (
Weight) برمیگرداند.🔥1👏1
در نهایت با ساخت و تعریف ورودی های نود میتوانید از این توی شیدر آبتون استفاده کنید آموزش تخصصی بود از جانب FPro Sensei ❗️
🔥1🥰1
FPro Sensei
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Refraction.hlsl"
جالب اینجاست که این com.unity.render-pipelines.core کتابخانه SRP هست یعنی مشترک بین URP و HDRP پس توی هر دو تاش میتونید استفاده کنید ولی URP فرق داره
🔥1🥰1
ویلبرورد اسنلیوس و کشف قانون شکست نور 🔍✨
که بود: ریاضیدان هلندی (۱۵۸۰–۱۶۲۶)، استاد دانشگاه لیدن، معروف به کار مثلثبندی برای اندازهگیری زمین 🌍📐.
کشف: با استفاده از تخصصش در زاویه و مثلثات، زاویهٔ تابش و شکست نور را در عبور از هوا به شیشه/آب اندازه گرفت 📏💧 و در سال ۱۶۲۱ فهمید نسبت سینوس این دو زاویه همیشه ثابت است — همان قانون امروزی:
n₁ sinθ₁ = n₂ sinθ₂ 📝
سرنوشت عجیب: خودش آن را منتشر نکرد 🤐. در ۱۶۲۶ درگذشت 🪦، دکارت در ۱۶۳۷ همین قانون را منتشر کرد 📢، و سالها بعد هویگنس با بررسی دستنوشتههایش ثابت کرد اسنلیوس زودتر به آن رسیده بود 🕵️♂️ — برای همین قانون به نام او ماند 🏆.
نکته تاریخی: او هم اولین کاشف نبود؛ ابن سهل (ایرانی، حدود ۹۸۴ میلادی) 🇮🇷 و توماس هریوت هم پیشتر و مستقل به رابطههای مشابه رسیده بودند، ولی کارشان منتشر نشد 📜❌.
در نهایت تو در کار شیدر نویسی از این قانون دانشمند استفاده میکنی 👓
#دانستنی
که بود: ریاضیدان هلندی (۱۵۸۰–۱۶۲۶)، استاد دانشگاه لیدن، معروف به کار مثلثبندی برای اندازهگیری زمین 🌍📐.
کشف: با استفاده از تخصصش در زاویه و مثلثات، زاویهٔ تابش و شکست نور را در عبور از هوا به شیشه/آب اندازه گرفت 📏💧 و در سال ۱۶۲۱ فهمید نسبت سینوس این دو زاویه همیشه ثابت است — همان قانون امروزی:
n₁ sinθ₁ = n₂ sinθ₂ 📝
سرنوشت عجیب: خودش آن را منتشر نکرد 🤐. در ۱۶۲۶ درگذشت 🪦، دکارت در ۱۶۳۷ همین قانون را منتشر کرد 📢، و سالها بعد هویگنس با بررسی دستنوشتههایش ثابت کرد اسنلیوس زودتر به آن رسیده بود 🕵️♂️ — برای همین قانون به نام او ماند 🏆.
نکته تاریخی: او هم اولین کاشف نبود؛ ابن سهل (ایرانی، حدود ۹۸۴ میلادی) 🇮🇷 و توماس هریوت هم پیشتر و مستقل به رابطههای مشابه رسیده بودند، ولی کارشان منتشر نشد 📜❌.
در نهایت تو در کار شیدر نویسی از این قانون دانشمند استفاده میکنی 👓
#دانستنی
🔥1🥰1
الان میدونم همه از هوش مصنوعی استفاده میکنن ولی بعضی ها استفاده بشدت خیلی جو میدن و خودشون دست بالا گرفتن ولی باید بگم براشون خبر بدی دارم چون کلادی که تو استفاده میکنی مخفیانه توی کد های واتر مارک های مخفی میزاره که حتا روحت هم خبر نداره چه برسه به ذهنت ❗️
یک نمونه :
حالا فرض کن بین بعضی کاراکترهای کد، Zero-Width Space (
اینجا بعد از
ولی چشم تو تقریباً این را میبیند:
یک نمونه :
#ifndef ANITOON_WATER_INCLUDED
#define ANITOON_WATER_INCLUDED
void Water_float(float3 PositionWS, out float3 Output)
{
float3 color = float3(0.0, 0.5, 1.0);
// این تابع کاملاً عادی به نظر میرسد.
Output = color;
}
#endif
حالا فرض کن بین بعضی کاراکترهای کد، Zero-Width Space (
U+200B) جاسازی شده باشد:#ifndef ANITOON_WATER_INCLUDED
#define ANITOON_WATER_INCLUDED
void Water_float(float3 PositionWS, out float3 Output)
{
float3 color = float3(0.0, 0.5, 1.0);
// این تابع کاملاً عادی به نظر میرسد.
Output = color;
}
#endif
اینجا بعد از
float3 یک کاراکتر نامرئی وجود دارد:
float3[U+200B] PositionWS
ولی چشم تو تقریباً این را میبیند:
float3 PositionWS
👍1👏1
FPro Sensei
الان میدونم همه از هوش مصنوعی استفاده میکنن ولی بعضی ها استفاده بشدت خیلی جو میدن و خودشون دست بالا گرفتن ولی باید بگم براشون خبر بدی دارم چون کلادی که تو استفاده میکنی مخفیانه توی کد های واتر مارک های مخفی میزاره که حتا روحت هم خبر نداره چه برسه به ذهنت ❗️…
روش های واتر مارک های مخفی :
۱. کاراکترهای Zero-Width :
ظاهر :
ولی ممکن است بین حروف کاراکترهای نامرئی باشد:
چشم تقریباً هیچ تفاوتی نمیبیند.
۲. BOM یا کاراکتر نامرئی ابتدای فایل:
۴. داده داخل کامنت :
و انتهای یکی از کامنتها دادهای نامرئی قرار گرفته باشد:
و دیگر روش های پنهان که اصلا روحتون خبر نداره ❗️❗️
۱. کاراکترهای Zero-Width :
ظاهر :
float3 PositionWS;
float3 Normal;
ولی ممکن است بین حروف کاراکترهای نامرئی باشد:
float3[U+200B]PositionWS;
float3[U+200C]Normal;
چشم تقریباً هیچ تفاوتی نمیبیند.
۲. BOM یا کاراکتر نامرئی ابتدای فایل:
#ifndef ANITOON_WATER_INCLUDED
[U+FEFF]#ifndef ANITOON_WATER_INCLUDED
۴. داده داخل کامنت :
// Water calculation
// normal = geometric normal
// reflection = SSR
و انتهای یکی از کامنتها دادهای نامرئی قرار گرفته باشد:
// Water calculation[U+200B][U+200C][U+200C][U+200B]
و دیگر روش های پنهان که اصلا روحتون خبر نداره ❗️❗️
❤1👍1
اگر کسی یک برنامه بسازه و بگه منم ساختم ولی به دورغ بگه و با هوش مصنوعی بسازه مطمعن باشه که راحت من یا دیگر افراد متخصص براحتی میتونه تشخیص بده که کلک زدی یا نه پس در مقابل این اینجور افراد براشون سوپرایز هم دارم پس صادقانه باشید نه دورغین ❗️❗️
👍1
FPro Sensei
اگر کسی یک برنامه بسازه و بگه منم ساختم ولی به دورغ بگه و با هوش مصنوعی بسازه مطمعن باشه که راحت من یا دیگر افراد متخصص براحتی میتونه تشخیص بده که کلک زدی یا نه پس در مقابل این اینجور افراد براشون سوپرایز هم دارم پس صادقانه باشید نه دورغین ❗️❗️
This media is not supported in your browser
VIEW IN TELEGRAM
FPro Sensei
اگر کسی یک برنامه بسازه و بگه منم ساختم ولی به دورغ بگه و با هوش مصنوعی بسازه مطمعن باشه که راحت من یا دیگر افراد متخصص براحتی میتونه تشخیص بده که کلک زدی یا نه پس در مقابل این اینجور افراد براشون سوپرایز هم دارم پس صادقانه باشید نه دورغین ❗️❗️
کارایی که با هوش مصنوعی زده میشه ارزش پایین هست دوست عزیز 🤖💸 برای مثال قراره Assetهایی که توی ساختنشون از هوش مصنوعی استفاده شده بشدت ارزونتر فروخته بشه 📉 همین ویدیوهایی که با هوش زده میشود قطعا ارزش فروختهاشون بشدت کمتر از ویدیوهای واقعی هست 🎥❌
الکی هم نیست هوش ول کنن هر کسی با این چیزی بسازه و بزنه به نام خودش چون قانون DMCA هست که میگه باید حقوق سازنده محفوط باشه ⚖️🛡 یعنی فکر میکنید هوش مصنوعی بی قانونه؟ خیر 🚫 توی اون قانون خاص خودشو داره و گرنه هر کی هرکی میشه برای هر کاری که با اون زده میشه هم واتر مارک نامرئی میزنه 🏷✨
الکی هم نیست هوش ول کنن هر کسی با این چیزی بسازه و بزنه به نام خودش چون قانون DMCA هست که میگه باید حقوق سازنده محفوط باشه ⚖️🛡 یعنی فکر میکنید هوش مصنوعی بی قانونه؟ خیر 🚫 توی اون قانون خاص خودشو داره و گرنه هر کی هرکی میشه برای هر کاری که با اون زده میشه هم واتر مارک نامرئی میزنه 🏷✨
هوش مصنوعی «کلود» روی متنهایش واترمارک نامرئی میگذارد
مدلهای جدید هوش مصنوعی کلود سیگنالهای نامرئی را در خود تعبیه خواهند کرد که میتوانند به شناسایی متن تولید شده توسط این چتبات پس از کپی کردن کمک کنند.
شرکت آنتروپیک از روز دوم ماه اوت سال۲۰۲۶، واترمارکهای قابل خواندن توسط ماشین را به متن تولید شده توسط مدلهای جدید کلود اضافه خواهد کرد.
به نقل از آیای، این اقدام در راستای الزامات شفافیت ذیل ماده ۵۰ قانون هوش مصنوعی اتحادیه اروپا انجام میشود. شرکت آنتروپیک، آییننامه اجرایی اتحادیه اروپا در مورد محتوای تولید شده توسط هوش مصنوعی را امضا کرده است.
مدلهای جدید کلود که از آن تاریخ عرضه میشوند، محتوای تولید شده را در سطح مدل علامتگذاری خواهند کرد. شرکت آنتروپیک میگوید این علامتگذاریها نه تنها برای کاربران اروپایی، بلکه در سراسر جهان اعمال خواهد شد.
این سیستم از روشهای مختلفی برای متن و فایلهای پشتیبانیشده استفاده خواهد کرد. متنها واترمارکهای نامرئی دریافت میکنند
پ.ن : در کل میگه یعنی کسی که تا الان با هوش مصنوعی پز میداد دیگه داره تموم میشه
مدلهای جدید هوش مصنوعی کلود سیگنالهای نامرئی را در خود تعبیه خواهند کرد که میتوانند به شناسایی متن تولید شده توسط این چتبات پس از کپی کردن کمک کنند.
شرکت آنتروپیک از روز دوم ماه اوت سال۲۰۲۶، واترمارکهای قابل خواندن توسط ماشین را به متن تولید شده توسط مدلهای جدید کلود اضافه خواهد کرد.
به نقل از آیای، این اقدام در راستای الزامات شفافیت ذیل ماده ۵۰ قانون هوش مصنوعی اتحادیه اروپا انجام میشود. شرکت آنتروپیک، آییننامه اجرایی اتحادیه اروپا در مورد محتوای تولید شده توسط هوش مصنوعی را امضا کرده است.
مدلهای جدید کلود که از آن تاریخ عرضه میشوند، محتوای تولید شده را در سطح مدل علامتگذاری خواهند کرد. شرکت آنتروپیک میگوید این علامتگذاریها نه تنها برای کاربران اروپایی، بلکه در سراسر جهان اعمال خواهد شد.
این سیستم از روشهای مختلفی برای متن و فایلهای پشتیبانیشده استفاده خواهد کرد. متنها واترمارکهای نامرئی دریافت میکنند
پ.ن : در کل میگه یعنی کسی که تا الان با هوش مصنوعی پز میداد دیگه داره تموم میشه
👍1