فهرست مستندات
تنظیم حالوهوا و نور zoneهای پارک#
این یک دفترچهٔ عملی برای درجهبندیٔ مجدد دو zone منتشرشدهٔ پارک است —
شکوفهزار مرجانی (coral-bloom) و ایوان ابر (cloud-terrace) — با روش
آزمونوخطا: کدام دستگیره در کدام فایل است، بصری چه میکند و برای کدام حس
به کدام سمت باید بردش. فرض بر این است که
تکنیکهای سهبعدی zoneهای پارک را برای
معماری رندرینگ خواندهاید؛ اینجا فقط مقادیر جهت هنری را دست میزنیم، هرگز
ساختار را نه. هر مقداری که در ادامه نقل میشود مقدار فعلی منتشرشده است تا
بتوانید ویرایشتان را با یک مبنای مشخص مقایسه کنید.
پنل تنظیم حالوهوا (فقط توسعه)#
سریعترین راه پیداکردن مقادیر اصلاً ویرایش فایل نیست. پارک یک پنل تنظیم حالوهوای مخصوص توسعه دارد و همان چرخهٔ ترجیحی کاوش است:
- سرور توسعه را بالا بیاورید (
pnpm --filter park dev) و zoneای را که درجهبندی میکنید باز کنید. - کلید
Mرا بزنید. یک پنل DOM با اسلایدرها و انتخابگرهای رنگ برای مه، نور خورشید و نیمکره، پالت آسمان، قرص خورشید، ابرها (پوشش، مقیاس، سرعت، روشنایی) و post (bloom و exposure) متعلق به zone فعال باز میشود. - بکشید و فریم را ببینید — هر تغییر یک نوشتن uniform زنده یا یک بهروزرسانی ارزان prop است، هرگز بازسازی pipeline یا گراف shader نه. پیشنویس در localStorage بین reloadها میماند.
- وقتی حالوهوا درست خوانده شد، «کپی JSON» را بزنید. خروجی برای پختن در فایلها شکل گرفته است:
{
"zone": "coral-bloom",
"skyModel": { "fogFar": 300, "palette": { "zenithColor": "#1b5fd7" } },
"registryPost": { "bloom": { "strength": 0.55 }, "exposure": 1.12 }
}
- مقادیر را در فایلهای authored بپزید — دستی یا با یک دستیار هوش مصنوعی:
skyModelدر*-sky-model.tsمربوط به zone وregistryPostدر ورودیart.postهمان zone درsrc/zones/registry.ts. - نزدیکترین تستها را اجرا کنید و مثل همیشه روی هر دو backend درجهبندی کنید.
پنل با import.meta.env.DEV گیره شده، پس Vite آن را کاملاً از build محصول
حذف میکند. مقادیر ساختاری build-time میمانند و قابلتنظیم نیستند:
octaves/detail ابر، اندازه و بسط نقشهٔ سایه، و اندازهٔ زاویهای قرص
خورشید (discInnerCos/discOuterCos). نقشهٔ دستگیرههای زیر همچنان مرجع
این است که هر مقدار سرانجام کجا زندگی میکند — و برای دستگیرههایی که پنل
عمداً در معرض نمیگذارد.
کار روزمره با پنل#
- هر کنترل از روی مقدار authored زون شروع میشود و نشان «· پیشفرض» دارد؛ با دستکاری، نشان پاک میشود، پس diff فعلی همیشه دیده میشود.
- «بازنشانی» همهٔ overrideها را به حالوهوای authored برمیگرداند و پیشنویس localStorage را هم همراهش پاک میکند.
- جعبهٔ import («وارد کردن JSON» + «اعمال») یک خروجی الصاقشده را برمیگرداند — همان اعتبارسنجی ویرایش محلی اجرا میشود، پس ورودی نامعتبر با پیام رد میشود.
- پیشنویس سراسری است نه per-zone: یک zone را تنظیم کنید، JSON را کپی
کنید، بازنشانی کنید، بعد سراغ zone بعدی بروید. فیلد
zoneخروجی پاکتها را از هم جدا نگه میدارد. - برای درجهبندی با هنرمندی که checkout ندارد، سرور توسعه را روی شبکهٔ محلی بالا بیاورید و لینک بدهید — پنل روی هر صفحهٔ سروشدهٔ dev کار میکند.
انتقال پنل به یک محیط دیگر#
پنل امروز عمداً محلیِ پارک است — generic کردنش پیش از وجود مصرفکنندهٔ دوم همان اشتباه تکمصرفکنندهای را تکرار میکند که ADR-0060 بازنشستهاش کرد. درزها از قبل تمیزند، پس وقتی وقتش برسد انتقال ارزان است:
- بدون تغییر قابل استفادهٔ مجدد: مکانیک store، نگهبان کلید
M، پوستهٔ پنل، و چرخهٔ export/import. - مخصوص هر محیط: تایپ override و کاتالوگ خودش، یک مدل merge/serialize روی تایپ sky-spec خودش، و نگاشت handle زنده برای کامپوننت آسمان خودش.
- پیشنیاز: محیط باید از قبل art direction را به صورت داده (فایلهای model) نگه دارد و از طریق prop و نوشتن uniform زنده مصرف کند — همان الگویی که این سند شرح میدهد. نورهای هاردکد در JSX اول به همان ریفکتور نیاز دارند.
- وقتی محیط دوم واقعاً پنل را به کار گرفت، هستهٔ generic به جای کپیشدن به یک ماژول مشترک منتقل میشود.
چرخهٔ تکرار#
- سرور توسعه را با
pnpm --filter park devبالا بیاورید. Vite روی پورت 4800 سرو میکند (باAL_AMR_DEV_PARK_PORTقابل تغییر است). - zoneای را که درجهبندی میکنید باز کنید:
/zones/coral-bloomیا/zones/cloud-terrace(مسیر/قلب باغ است). - هر مقدار زیر را ویرایش و ذخیره کنید — همهٔ تغییرات hot-reload میشوند؛ نه build، نه restart، نه پاککردن کش.
- بدانید کدام سطح کیفیت را قضاوت میکنید. نشست با
standardشروع میشود و بعد از فریمهای کند پایدار (دو پنجرهٔ متوالی با p95 بالای ۲۴ میلیثانیه) بهصورت خودکار بهcompatibleتنزل میکند و هرگز برنمیگردد.compatibleاکتاوها و جزئیات ابر، پاس bloom و سایههای پوشش گیاهی را حذف میکند — تصویری ذاتاً تختتر.enhancedهرگز خودکار انتخاب نمیشود. اگر وسط نشست فریم ناگهان بیروحتر شد، احتمالاً سطح جابهجا شده، نه ویرایش شما. - backend دوم را عمداً ببینید: renderer اول WebGPU را ترجیح میدهد و به
WebGL2 برمیگردد؛ با افزودن
?al-amr-rendering=force-webgl2به URL، مسیر WebGL2 را اجباری کنید. روی هر دو درجهبندی کنید. - قبل از آزمایش پشتیبان بگیرید. سورسهای
cloud-terraceممکن است در worktree شما commit نشده باشند، پسgit checkout --آنها را برنمیگرداند — اول فایل را کپی کنید (cp cloud-terrace-sky-model.ts /tmp/backup/) یا مبنایتان را commit کنید.
سه لایهٔ حالوهوا#
حالوهوا از سه لایه میآید، به ترتیب اهرمبری:
- مدل آسمان zone —
coral-bloom-sky-model.tsیاcloud-terrace-sky-model.ts. این تقریباً ۹۰٪ حالوهواست: پالت آسمان، مه، نور خورشید و نیمکره، بودجهٔ ابر. همیشه از اینجا شروع کنید. - overrideهای post در zone — ورودی
art.postدرenvironments/park/src/zones/registry.ts. فقط دو دستگیره وجود دارد:bloom.strength(در بازهٔ[0, 8]گیره میشود) وexposure(در بازهٔ[0.1, 8]گیره میشود و بهصورت جهش uniform زنده رویrenderer.toneMappingExposureنوشته میشود — هرگز بازسازی pipeline نه). روشنایی و درخشش سراسری، نه چیز دیگر. - رنگهای مواد در کامپوننتهای
.tsx— سبزهای چمنزار، رنگ بدنهٔ آب، tintهای پوشش گیاهی. چاشنی نهایی بعد از آنکه نور درست شد.
قاعدهٔ سرانگشتی: اول نور را درست کنید، بعد مواد را. صحنهای که زیر نور غلط بد به نظر میرسد، زیر نور درست به شکل متفاوتی بد به نظر خواهد رسید.
پارامترهای پالت آسمان#
هر دو zone همان ساختار ParkSkySpec را از
environments/park/src/scenes/sky/park-sky-model.ts resolve میکنند. پالت،
گرادیان گنبد و ابرها را رنگ میکند؛ هیچ سطحی را نور نمیکند.
| پارامتر | شکوفهزار مرجانی | ایوان ابر | اثر بصری |
|---|---|---|---|
zenithColor | #1b5fd7 | #4aa8e8 | آسمان درست بالای سر. برای روز آبیتر و صافتر عمیقتر کنید؛ برای بهشت high-key به سمت فیروزهای روشن کنید. |
midColor | #6fb2f0 | #8ecbf4 | رنگ میانی آسمان بین سماوی و افق. همراه zenithColor حرکتش دهید وگرنه گرادیان باند میشود. |
horizonColor | #dff0ff | #f4fbff | افق سمت خورشید که با جملهٔ خورشید گرم میشود. برای مه سفیدتر، برای هوای شفاف اشباعتر کنید. |
horizonAwayColor | #cfe4f8 | #e6f3fc | افق روبهروی خورشید. کمی سردتر/تیرهتر از horizonColor نگهش دارید وگرنه آسمان جهتش را از دست میدهد. |
hazeColor | #e4f1fd | #eef7fd | هالهٔ زیرافق — و رنگ مه خطی (دامها را ببینید). |
sunDiscColor | #fffef8 | #ffffff | رنگ قرص خورشید. برای ساعت طلایی گرمتر، برای ظهر سفیدتر کنید. |
sunHaloColor | #fff3d4 | #fff6e2 | هالهٔ تنگ دور قرص. مهمترین سرنخ «خورشید گرم». |
cloudLitColor | #ffffff | #ffffff | وجههای آفتابی ابر. |
cloudShadeColor | #b6c6dd | #c2d2e4 | سایهٔ ابر. تیرهتر = ابر دراماتیکتر؛ روشنتر = بهشت پنبهای. |
برای آسمان آبیتر و صافتر: zenithColor و midColor را عمیقتر کنید، دو
رنگ افق را کمی به آبی بکشید و cloudShadeColor را روشنتر کنید. برای آسمان
نرمتر و رؤیاییتر: همهچیز را به سمت سفید ببرید، از افق شروع کنید.
پارامترهای بصری خورشید#
اینها خورشید را داخل گنبد شکل میدهند. discInnerCos/discOuterCos
اندازهٔ زاویهای قرص را تعیین میکنند (کسینوس نیمزاویهٔ هسته و لبه — مقدار
منتشرشده 0.99972/0.99912 یعنی حدود ۱٫۳۵/۲٫۴ درجه، در هر دو zone یکسان؛
هر چه به ۱ نزدیکتر، قرص کوچکتر). قرص و هاله به attachment امیسیو
میرسند، پس آنها همان چیزی هستند که پاس انتخابی bloom واقعاً میبیند.
| پارامتر | شکوفهزار مرجانی | ایوان ابر | اثر بصری |
|---|---|---|---|
discIntensity | 4.2 | 3.8 | روشنایی HDR قرص؛ قویترین تغذیهٔ bloom. برای خورشید آرامتر کمتر، برای جرقه بیشتر کنید. |
haloIntensity | 2.1 | 1.6 | هالهٔ طلایی تنگ (هم HDR؛ نرم bloom میگیرد). |
glowIntensity | 0.55 | 0.6 | درخشش گرم پهن، فقط پاس زیبایی (زیر آستانهٔ bloom). |
washIntensity | 0.2 | 0.22 | رنگمایهٔ گرم بسیار پهن روی آسمانی سمت خورشید. |
نور، مه و سایهٔ resolveشده#
این فیلدهای خروجی resolve*Sky رگ نور واقعی را میرانند — تنها عددهایی که
روشنایی سطوح را عوض میکنند.
| پارامتر | شکوفهزار مرجانی | ایوان ابر | اثر بصری |
|---|---|---|---|
sunColor | #fff2dc | #fff6e8 | رنگ نور جهتدار. گرمتر = عصر دیرتر. |
sunIntensity | 1 | 1.5 | قدرت نور جهتدار: آفتاب مستقیم، هایلایتها و کنتراست سایه. دستگیرهٔ مدلسازی فرم. |
hemisphereSkyColor | #93c4f2 | #93c4f2 | نور محیطی از بالا. آبیتر = سایههای سردتر. |
hemisphereGroundColor | #c0a075 | #c0a075 | بازتاب محیطی از پایین. لحن خاک گرمتر/تیرهتر، زیر سطوح را گرم میکند. |
hemisphereIntensity | 2 | 3 | قدرت نور پرکنندهٔ محیطی: چقدر همهچیز از هر زاویه خوانا است. |
skyBrightness | 1.42 | 1.55 | ضریب HDR فقط روی گرادیان گنبد — هیچ چیز را نور نمیکند، اما تعیین میکند خود آسمان از میان ACES چقدر درخشان خوانده شود. |
fogNear / fogFar | 96 / 260 | 110 / 300 | کجا مه چشمانداز شروع و کجا تمام میشود، بر حسب متر. fogFar کوتاهتر = جهان صمیمیتر و مهآلودتر. |
shadowExtent | 92 | 104 | نیمبسط سایهٔ ارتوگرافیک؛ باید کل دیسک zone را بپوشاند (با تست پین شده). |
shadowMapSize | 1024 (در enhanced برابر 2048) | مانند هم | رزولوشن سایه؛ برای کار حالوهوا دست نزنید. |
بودجهٔ ابر#
شیء clouds در هر مدل آسمان دو بار ظاهر میشود — یک بار برای شاخهٔ
compatible و یک بار برای بقیه — پس هر دو را ویرایش کنید وگرنه سطحها
ناسازگار میشوند. مقادیر فعلی داخل هر zone بین شاخهها یکسان است.
| پارامتر | شکوفهزار مرجانی | ایوان ابر | اثر بصری |
|---|---|---|---|
octaves | 5 (در enhanced برابر 6، در compatible برابر 3) | مانند هم | جزئیات FBM؛ دستگیرهٔ هزینهٔ واقعی fragment است، نه دستگیرهٔ حالوهوا. |
detail | true (در compatible برابر false) | مانند هم | روشن/خاموشبودن لایهٔ جزئیات billow. |
coverage | 0.5 | 0.62 | چقدر آسمان ابری است. واضحترین صفحهکلید «هوا». |
scale | 0.5 | 0.5 | اندازهٔ عارضههای ابر. کمتر = تودههای بزرگتر و نرمتر. |
speed | 0.008 | 0.008 | سرعت رانش روی ساعت TSL. |
brightness | 1.8 | 1.9 | ضریب HDR روی رنگ آفتابی ابر؛ در مقادیر بالا bloom را تغذیه میکند. |
نسبت، خودِ حالوهواست#
روشنایی سطح تقریباً برابر است با رنگ ماده × (خورشید جهتدار + محیطی نیمکره). هیچکدام از این دو عدد بهتنهایی معنا ندارند — نسبت بینشان معنا
دارد:
- حس تابستان سوزان:
sunIntensityبالا،hemisphereIntensityپایین — سایههای عمیق، مدلسازی قوی، روشنایی خیرهکننده روی وجههای آفتابی. - حس نرم و روشن:
sunIntensityپایینتر،hemisphereIntensityبالا — سایههای کمعمق، همهچیز خوانا، با بهای کمی تختشدن.
ایوان ابر دقیقاً از طریق همین نسبت نرمتر و روشنتر از شکوفهزار مرجانی
منتشر شده (خورشید ۱٫۵ / نیمکره ۳ در برابر خورشید ۱ / نیمکره ۲ — نور پرکنندهٔ
ایوان کاملاً غالب است). مواد پوشش گیاهی گرافهای MeshStandardNodeMaterial
بدون جملهٔ امیسیو هستند، پس یک گل روی زمین که روبهخورشید دیده میشود تقریباً
فقط با نور پرکنندهٔ نیمکره روشن میشود: اگر گلها از بعضی زاویهها مثل
کاغذرنگی تیره خوانده میشوند، محیطی را بالا ببرید، نه خورشید را.
دستور: باغ آفتابیتر که خوانا میماند#
یک قبل/بعد مشخص روی شکوفهزار مرجانی — مدلسازی و جرقهٔ خورشید بیشتر بدون
ازدستدادن چمنزار روشن و خوانا. در coral-bloom-sky-model.ts:
sunColor: "#fff2dc",
sunIntensity: 1,
sunColor: "#fff2dc",
sunIntensity: 1.7,
hemisphereSkyColor: "#93c4f2",
hemisphereGroundColor: "#c0a075",
hemisphereIntensity: 2,
hemisphereSkyColor: "#93c4f2",
hemisphereGroundColor: "#c0a075",
hemisphereIntensity: 1.7,
و در environments/park/src/zones/registry.ts:
art: Object.freeze({
resolveSky: resolveCoralBloomSky,
post: Object.freeze({ bloom: Object.freeze({ strength: 0.62 }) }),
}),
art: Object.freeze({
resolveSky: resolveCoralBloomSky,
post: Object.freeze({ bloom: Object.freeze({ strength: 0.55 }), exposure: 1.12 }),
}),
دلیل: بالابردن خورشید از ۱ به ۱٫۷ فرم سایه و جرقهٔ سقفها را برمیگرداند؛
نیمکره از ۲ به ۱٫۷ پایین میآید تا نور پرکننده، مدلسازیای را که خورشید تازه
افزوده تخت نکند؛ exposure برابر ۱٫۱۲ کل فریم را به روشنایی ادراکی قبلی
برمیگرداند؛ و bloom شل میشود تا برقهای خورشید قویتر هاله نگیرند. در این
دو zone بازهٔ شیرین sunIntensity تقریباً بین ۱٫۲ تا ۱٫۸ است — پایینتر از آن
سایهها شست میشوند و بالاتر از آن خورشید مشترک اواخر ظهر با پالتهای تازهٔ
روز میجنگد. برای ایوان ابر همین حرکت از مبنای ۱٫۵ کار میکند، اما نیمکره را
غالب نگه دارید (همین است که ایوان را بهشت میخواند).
اهرمهای خوانایی گل#
وقتی نور درست شد، کنتراست گیاهان زمینی در سطح ماده تنظیم میشود، همه داخل
environments/park/src/scenes/coral-bloom/:
- رنگمایهٔ گلبرگ زمین —
CoralBloomTerrain.tsx. لکهٔ صورتی زیر باغ با گلها رقابت میکند. برای کنتراست کمش کنید:
const blushed = mix(crest, petalBlush, blushMask.mul(0.32));
const blushed = mix(crest, petalBlush, blushMask.mul(0.15));
- روشنایی per نمونهٔ گلها —
CoralBloomFlora.tsx(درFlowerInstances). کف0.85تعیین میکند تیرهترین گل چقدر روشن است؛ بالا ببریدش تا همهٔ سرها بلند شوند (سیستم گلبرگهای لانه با0.85 + 0.3 * petal.tintهم همینطور پاسخ میدهد):
mesh.setColorAt(index, color.copy(hue).multiplyScalar(0.85 + 0.3 * flower.tint));
mesh.setColorAt(index, color.copy(hue).multiplyScalar(1.0 + 0.3 * flower.tint));
- اشباع پالت گلبرگ —
CORAL_PETAL_PALETTEدرcoral-bloom-model.tsهم گلها را تغذیه میکند هم گلبرگهای لانه را؛ برای پاستلی کماشباع کنید، برای جشن پراشباع. - چگالی و اندازهٔ سر — تعداد گلها per سطح و
headScale: 0.75 + random() * 0.6درcoral-bloom-model.ts. سرهای بزرگتر از دور بهتر خوانده میشوند؛ تعداد، بودجههای رندر را جابهجا میکند، پس مقیاس را ترجیح دهید.
پروتکل آزمایش#
به این ترتیب کار کنید؛ هر قدم یک چرخهٔ ذخیره-ونگاه است:
- از مبنای دستنخورده اسکرینشات بگیرید (نمای spawn بهعلاوهٔ یک نمای روبهخورشید) تا «بهتر» صادق بماند.
- اول
sunIntensityرا حرکت دهید — مدلسازیای را تعریف میکند که بقیه به آن واکنش نشان میدهند. hemisphereIntensityرا برای عمق سایه و خوانایی گلها تنظیم کنید.exposureرا در رجیستری برای روشنایی سراسری اضافه یا تنظیم کنید.fogFar(و همراهشfogNear) را برای عمق و صمیمیت تنظیم کنید.- رنگها را آخر از همه ریزتنظیم کنید: پالت، رنگهای نیمکره، tint مواد.
- روی هر دو backend راستیآزمایی کنید (با و بدون
?al-amr-rendering=force-webgl2) و یادتان باشدcompatibleچه چیزهایی را حذف میکند: bloom، جزئیات ابر، سایههای پوشش گیاهی. اگر رویcompatibleمنتشر میکنید، رویcompatibleدرجهبندی کنید.
دامها و نامتغیرها#
fogColorباید همیشه باhazeColorپالت برابر باشد — مه همان هالهٔ زیرافق گنبد است و هر ناهماهنگی لبهٔ جهان را با آسمان درز میکند. پالت را ویرایش کنید، نه خط مه را.clouds.coverage(و خواهربرادرهایش) در هر مدل آسمان دو بار ظاهر میشود — شاخهٔcompatibleو بقیه. هر دو را عوض کنید وگرنه سطحها هوای متفاوت نشان میدهند.fogNear < fogFarرا حفظ کنید وshadowExtentرا برابر یا بالاتر از شعاع zone نگه دارید: ثابتهای guardrail به نام*_SHADOW_COVERS_*با تستهای آسمان پین شدهاند و مجموعهٔ تست را قرمز میکنند.- تغییر رنگ و نور هیچ تست و هیچ بودجهٔ رندری را نمیشکند. افزودن مش، نمونه یا attribute نمونه میشکند — بودجهها per zone per مسیر اندازه میشوند، پس در سمت تنظیم مقادیر بمانید مگر آنکه قصد بودجهبندی مجدد دارید.
octavesوcoverageابر هزینهٔ واقعی fragment را per سطح عوض میکنند. کارایی را روی سطحی قضاوت کنید که منتشر میکنید، نه رویenhanced.- overrideهای post جهش uniform هستند، پس جابهجاکردنشان ارزان است — اما per
تعویض zone اعمال میشوند و مقدار خارج از بازه بیصدا گیره میشود
(
bloom.strengthبه[0, 8]وexposureبه[0.1, 8]). اگر یک ویرایش افراطی «هیچ کاری نکرد»، احتمالاً روی گیره نشستهاید.
برای معماری پشت همهٔ این دستگیرهها — گنبد، pipeline پسپردازش، سیاست سطحها — تکنیکهای سهبعدی zoneهای پارک را ببینید.