View Full Version : دیزاین متریال
pswin.pooya
شنبه 07 آذر 1388, 01:21 صبح
سلام
من برای گیم انجین خودم (D-Engine) میخوام یه دیزاین متریال بزنم. به نظر شما متریالها باید داخل یه گیم انجین به چه شکلی ساخته بشن که بتونن انواع شیدرها رو ساپورت کنن (مثلا شیدرهای چند پاسه) و انعطاف کامل رو داشته باشن.
انجین من به صورت دیفریدشیدینگ کار میکنه و میخوام مثل OGRE متریالها رو به صورت اسکریپت پیاده سازی کنم. فقط اگر در مورد متریالها من رو راهنمایی کنید کافیه (مثلا هر متریلا از یکسری تکنیک و هر تکنیک از یکسری از پاسها تشکیل شده و ... )
kochol
دوشنبه 09 آذر 1388, 17:02 عصر
سلام
اتفاقا من هم در حال ساخت دیزاین جدیدی هستم برای متریال های موتورم و مخصوصا تمرکزم روی شیدرها است.
یه سری کارهایی هم انجام دادم البته اول راه هستم.
دیزاینی که من طراحی کردم اینه که سیستم شیدر به صورت اسکریپتی است که اسکریپت اش هم بسیار شبیه HLSL است و فقط چندتا دستور و سینتکس اضافه داره.
خصوصیاتی هم که داره اینه که اولا بیشتر تمرکز روی pixel shader است و کدهای مربوط به vertex shader بر اساس نیازهای داخل پیکسل شیدر ها ورتکس شیدرها به صورت اتوماتیک ساخته می شن.
دومی خاصیتی که داره اینه که کدهای مربوط به شیدر مستقل از تعداد نور هستند یعنی تو اسکریپت شما تعریف می کنید که چه طوری با نورها کار بشه و کد برای یه نور رو میزنید و کامپایلر بر اساس تعداد نور درخواستی کد را می سازد.
نمونه اسکریپت هم به این شکل است
float4 r = float4(0,0,0,0);
for each light
{
r += saturate(light.NdotL);
}
البته این کد خیلی کاملی نیست و فقط برای نمونه است.
اصل دیزاین هم این طوری است که تمام اسکریپت های شیدر بصورت چندتا تابع است که با چسباندن آنها به یکدیگر می تونی یه شیدر جدید بسازی.
خوبی این دیزاین اینه که مثلا می تونی برای post process ها به شیدرها بگی که اطلاعاتی را که لازم دارند را بدهند چون شیدرها رو خودت generate می کنی پس می تونی به اونها کد کم و زیاد کنی.
این کل دیزاین شیدر من بود البته ساخت یه چنین چیزی بدون باگ خیلی سخت است ولی ارزششو داره من اول می خواستم یه کامپیلر هم برای شیدر اسکریپتم بنویسم ولی بعد دیدم سخته گفتم فعلا همینطوری کد ها رو به HLSL تبدیل کنم تا بعد اگه نیاز شد کامپایلر یا همون Interpreter هم بسازم ولی اگه لازم نشد هم که نمی سازم.
pswin.pooya
دوشنبه 09 آذر 1388, 21:01 عصر
به نظر من اینکار اشتباه باشه. من پیشنهاد میکنم یه زبان اسکریپت طراحی کنی. و کنترل شیدرها رو از داخل متریال انجام بدی (این شکلی منطقی تر به نظر میرسه)
jack
سه شنبه 10 آذر 1388, 14:05 عصر
سلام
الان باب شده که متریال ها در یک متریال ادیتور جداگانه ساخته بشه و خیلی از موتورها هم این کار رو انجام می دن و من به هیچ عنوان این کار رو رد نمی کنم و به نظر می رسه که علت استفاده از این ابزار جلوگیری از درگیری با کدهای hlsl باشه ولی من فکر نمی کنم در بهترین بازی هم حتی از 20 الی 30 شیدر مختلف استفاده بشه
و در کل به نظر من اگه یک برنامه نویس کد شیدرها رو بنویسه بهتر از اینه که کلی زمان صرف ساخت چنین ابزاری بکنه (حالا از کامپایلر و ... بگذریم) الان در 3dsmax هم که قابلیت استفاده از شیدر فراهم شده شما اسم فایل fx رو به عنوان اسم متریال وارد می کنید . و با اینکه 3dsmax در زمینه استفاده از انواع ادیتور های مختلف حرف اول رو می زنه در زمینه شیدرها ابزاری رو ارایه نمی کنه .
مثلا الان چند نوع تکنیک بامپ وجود داره ؟ کلا پارالاکس و ریلایف و استیپ و ... که قطعا شما از همه این تکنیکها استفاده نمی کنید و برای یک بازی که قراره به فروش برسه فکر نکنم بیشتر از 10 تا 15 شیدر استفاده بشه .
دوست دارم با هم به روشهای جدیدی در هر زمینه دست پیدا کنیم من همانطور که ابتدا گفتم این قابلیت رو رد نمی کنم ولی زیاد هم با اون موافق نیستم
ممنون
kochol
سه شنبه 10 آذر 1388, 16:16 عصر
به نظر من اینکار اشتباه باشه. من پیشنهاد میکنم یه زبان اسکریپت طراحی کنی. و کنترل شیدرها رو از داخل متریال انجام بدی (این شکلی منطقی تر به نظر میرسه)
اگر که به نظرت اشتباه است بگو چرا؟ دلیلتو بگو
ولی به نظرم این روش خیلی هم خوب است
شما می تونید با این کار متریال ها رو LOD کنی مثلا نرمال مپ رو در فاصله دور برداری و یا نور پردازی رو per vertex کنی.
سپول
چهارشنبه 18 آذر 1388, 14:10 عصر
این کل دیزاین شیدر من بود البته ساخت یه چنین چیزی بدون باگ خیلی سخت است ولی ارزششو داره من اول می خواستم یه کامپیلر هم برای شیدر اسکریپتم بنویسم ولی بعد دیدم سخته گفتم فعلا همینطوری کد ها رو به HLSL تبدیل کنم تا بعد اگه نیاز شد کامپایلر یا همون Interpreter هم بسازم ولی اگه لازم نشد هم که نمی سازم.
آره زمانی که می بره برات زیاد خواهد بود، ولی خیلی هم فکر نکن ارزششو داره، lol
اولاً دیزاینی که می گی یه سری مزایا داره، اصلی ترینش هم قابلیت multi-platform بودنش هست، ولی اشکالاتش اینه که اولا کلی وقت ات رو می گیره، بعد هم بهینه کردن کد شیدر در همچین دیزاینی تقریباً غیر ممکن یا خیلی سخته، شیدر ها از اونجا که میلیون ها بار تکرار می شن، باید خیلی بهینه باشن که این قضیه با auto-generate کردن vertex shader و سیستم کلا ماجولار جور در نمیاد.
دیزاینی که من پیاده کرده بودم همونطور که می دونی شبیه همین بود منتها کاملا به جای اسکرییپت با گراف شیدر رو می ساختی که الان از رو تجربه ای که داشتم از اون هم راضی نیستم.
چون اولا این سوسول بازی های گراف و این چیزهارو موتور هایی مثل unreal پیاده می کنند برای artist friendly بودن و راحتی ساختن متریال، ولی به نظر من کلا شیدر باید توسط برنامه نویس ساخته بشه و دستی بهینه بشه، در اسکریپت هم اگه همین دیزاین رو ادامه بدی خواهی دید که آخر سر فرق زیادی با Hlsl نمی کنه و عملا همون کارهاری به شکل دیگه انجام می دی با فرق اینکه یک کامپایلر چاق نوشتی که manage کردن و چیز بهش اضافه کردن هم دهنت رو سرویس می کنه.
مثلا به جای for each light تو hlsl می نویسی if( light == LIGHT_SPOT) و ... به قول jack گیم ها دیگه 500 جور متریال ندارند.
به نظر من اینکار اشتباه باشه. من پیشنهاد میکنم یه زبان اسکریپت طراحی کنی. و کنترل شیدرها رو از داخل متریال انجام بدی (این شکلی منطقی تر به نظر میرسه)
این هم یک راهش هست، ولی بازم خیلی research می خواد، شیدر ها رو اگه با اسکریپت کنترل کنی باید ببینی اصلاً چه مزایایی داره، که چی بشه مثلاً ؟ این قضیه شاید فقط به درد متریال های پیچیده مثل آب بخوره که باید توی چند pass صحنه رو رندر کنی و افکت های مختلف رو پیاده کنی که باز هم می شه با hard code سریعتر تو انجین انجامش داد، مگر اینکه خیال داشته باشی 100 جور از انواع آب و اینجور چیزها پیاده کنی.
چون شیدر های معمولی یک سری پارامترهای ثابت می گیرن، که میشه به راحتی تعریف کرد و توی فایلی مثل xml گذاشت و موقع runtime این ها رو وارد کنه.
و در کل به نظر من اگه یک برنامه نویس کد شیدرها رو بنویسه بهتر از اینه که کلی زمان صرف ساخت چنین ابزاری بکنه (حالا از کامپایلر و ... بگذریم) الان در 3dsmax هم که قابلیت استفاده از شیدر فراهم شده شما اسم فایل fx رو به عنوان اسم متریال وارد می کنید . و با اینکه 3dsmax در زمینه استفاده از انواع ادیتور های مختلف حرف اول رو می زنه در زمینه شیدرها ابزاری رو ارایه نمی کنه .
مثلا الان چند نوع تکنیک بامپ وجود داره ؟ کلا پارالاکس و ریلایف و استیپ و ... که قطعا شما از همه این تکنیکها استفاده نمی کنید و برای یک بازی که قراره به فروش برسه فکر نکنم بیشتر از 10 تا 15 شیدر استفاده بشه .
این موضوع که گفتی تنوع اونقدر نیست، درسته، ولی قضیه ترکیدن شیدر ها رو در نظر نگرفتی، فرض کن یک متریال phong همراه با bump داری، حالا این برای هر نوع منبع نور یک شیدر می شه، یعنی تا اینجا مثلا 4 تا. برای سایه زدن یا نزدن هم دوباره دو برابر می شه، یعنی همه اینها سایه داشته باشن یا نداشته باشن. (8 تا)
حالا فرض کن LOD هم بخوای به همین دیزاین ساده اضافه کنی برای 2 تا LOD می شه 16 تا شیدر برای هر متریال.
واسه fx هم این خیلی چیز خوبیه که آرتیست متریال ها رو عیناً تو max ببینه ولی باز هم اینجا مشکل optimize کردن شیدر برای موتور رو پیدا می کنی، fx ها که در max رندر می شه خیلی جنرال هست، و آرتیست هم مثلا با shaderfx می تونه خودش درست کنه، ولی به نظر من این راه درستش نیست، آرتیست هیچ گونه دخالتی تو تولید کد برای موتور نباید داشته باشه، و سیستم شیدر در موتور باید یک چیز بسته و جدا از آرتیست باشه.
- در کل دیزاینی که kochol نوشته بود به نظر من از بقیه کار درست تر هست، مخصوصاً برای مالتی پلتفرم بودن (یعنی مثلا این قابلیت رو بگذاری که کدهای hlsl تولید نکنه و glsl تولید کنه به فرض) ، ولی اشکالات خودش هم داره و وقت زیادی هم می گیره، خود kochol بعداً می فهمه که هر چیز کوچکی اضافه و کم کردن چه قدر براش دردسر خواهد داشت با این دیزاین. (از اونجا کسی هم تو ایران تجربه کافی روی دیزاین شیدر نداره)
من هم در حال طراحی یک دیزاین ترکیبی ساده هستم که بعداً می گم، الان زوده.
- سپول
http://www.hmrengine.com
jack
شنبه 21 آذر 1388, 12:00 عصر
با سلام
من در اینترنت دیدم که با استفاده از گراف سعی کردن که یک موتور شیدر بسازند ولی به نتایج مطلوبی نرسیدند . شاید دلیلش این باشه که هر چیزی رو نمی شه به شکل یک گراف در بیاریم . مثلا به نظر من بهتره که بحث سایه ها و نور ها و مه رو از قسمت طراحی جدا کرده و در قسمت pixel shader به عنوان یک قطعه کد از پیش ساخته به کد نهایی hlsl اضافه کنیم . و به طور کلی بهتره یک سری کدهای پیچیده رو به صورت یک تابع وارد برنامه کنیم . مثلا فرض کنید کد hlsl یک water به همراه reflection و refraction ساختیم . قطعا پیاده سازی این شیدر با یک گراف خیلی کار پیچیده ای هستش . و فرض کنید گرافیست بخواد یک تغییر در این آب ایجاد کنه بعید نیست کاری کنه که همون اب قبلی هم کار نکنه ولی اگه ما یک برنامه داشته باشیم که یک سری کارهای ثابت مثل نور و سایه و مه که اجزای محیطی هستند از قسمت طراحی ماده جدا بشه و به صورت یک تابع در انتهای hlsl تولید شده اضافه بشه بهتره .
ممنون
kochol
یک شنبه 06 دی 1388, 10:46 صبح
سلام
بعد از کلی فکر کردن راجب به حرف های شما و خودم به این نتیجه رسیدم که سپهر راست می گه و این دیزاین من بیشتر به درد artist می خوره و از اون جایی که فکر نمی کنم موتور من بتونه خیلی جنرال بشه (در نهایت فقط خودم باید باهاش کار کنم lol) دیدم که این همه کار فایده ای نداره
پس رفتم ببینم که برای موتور من چه چیزی خوب است.
تمام چیزهایی که لازم دارم رو دیدم که این effect فایل ها ساپورت می کنن ولی از این effect فایل ها خوشم نمی یاد چون مدیریت اون ها دست من نیست.
فرض کن من 10 تا effect دارم که هر کدوم 5 تا تکنیک دارند می شه 50 تا پیکسل و 50 تا ورتکس شیدر در صورتی که این 50 تا پیکسل شیدر من فقط به یه vertex شیدر لازم دارند و این جا اولا 49 تا ورتکس شیدر اضافی دارم که حافظه گرفتند و از اون بدتر الکی سوییچ می شن.
می دونید که switch شیدر یکی از کند ترین کارهاست.
پس تصمیم گرفتم که یه چیزی شبیه اون ها رو خودم بسازم که مدیریتشون دست خودم باشه این طوری خیالم راحتتره و برای راحتی هم از xml استفاده می کنم.
4 تا چیز می شه تو این xml ها تعریف کرد.
1. pixel shader
2. vertex shader
3. توابع عمومی شیدر ها
4. material
این متریال ها همون مثل تکنیک ها عمل می کنن با این تفاوت که منابع اون ها مدیریت می شه.
این هم یه نمونه از xml ای که نوشتم.
<?xml version="1.0" encoding="UTF-8" ?>
<Shader name="SimpleVertex" description="This is a simple vertex shader" type="vertex">
<Input>
<Param name="matWorldViewProjection" type="matrix" autovalue="WorldViewProjection" />
<Param name="inPosition" type="float4" usage="POSITION0"/>
<Param name="inTexcoord" type="float2" usage="TEXCOORD0"/>
</Input>
<Output>
<Out name="outPosition" type="float4" usage="POSITION0"/>
<Out name="outTexcoord" type="float2" usage="TEXCOORD0"/>
</Output>
<Code name="main">
<![CDATA[
void main()
{
outPosition = mul( inPosition, matViewProjection );
outTexcoord = inTexcoord;
} // main
]]>
</Code>
</Shader>
این هم کدی که ساخته شده.
float4x4 matWorldViewProjection;
void SimpleVertex_main(in float4 inPosition : POSITION0,in float2 inTexcoord : T
EXCOORD0,out float4 outPosition : POSITION0,out float2 outTexcoord : TEXCOORD0)
{
outPosition = mul( inPosition, matViewProjection );
outTexcoord = inTexcoord;
} // main
البته این کد خیلی ساده است و یه سری کار هایی دیگه ای هم این دیزاین باید انجام بده که هنوز ننوشتم.
pswin.pooya
یک شنبه 06 دی 1388, 20:02 عصر
کم کم دارم سر درد میگیرم.
دیزاین موتور داره منو خفه میکنه. تازه متوجه شدم که خیلی از قسمتهای موتورم درست طراحی نشدن که بدتر از همه Scene و ... هستش. کلا میخوام کدها رو پاک کنم و از اول شروع به طراحی انجین بکنم. تازه متوجه شدم که چقدر اشتباه توی طراحیم داشتم.
کوچول و سپول عزیز، بابت راهنمایهاتون تشکر میکنم.
فکر کنم برای یه دیزاین خوب، اول از همه باید ببینیم که برای متریال چه چیزهایی لازم هستش. بعد از اون در مورد اینکه اونها رو به چه شکل بدیزاینم بحث کنیم.
jack
یک شنبه 13 دی 1388, 13:00 عصر
سلام خدمت دوستان
@kochol
فرض کن من 10 تا effect دارم که هر کدوم 5 تا تکنیک دارند می شه 50 تا پیکسل و 50 تا ورتکس شیدر در صورتی که این 50 تا پیکسل شیدر من فقط به یه vertex شیدر لازم دارند و این جا اولا 49 تا ورتکس شیدر اضافی دارم که حافظه گرفتند و از اون بدتر الکی سوییچ می شن.
می دونید که switch شیدر یکی از کند ترین کارهاست.
----
اولا تبريک بابت terrain engine که در سمينار بازي سازي تبريز نمايش داديد . در مورد نکته اي که فرموديد ببين هر vertex shader به صورت يک تابع هستش که در يک تکنيک فراخوني مي شه . کلا تکنيک يک فراخواني به يک تابع ورتکس شيدر و يک تابع پيکسل شيدر هستش . حالا لازم نيست که براي 10 تا افکت 10 تا ورتکس شيدر بنويسي مي توني توي يک فايل ديگه ورتکس شيدر رو بنويسي و توي افکت ان را include کني .
kochol
سه شنبه 22 دی 1388, 18:21 عصر
سلام خدمت دوستان
@kochol
فرض کن من 10 تا effect دارم که هر کدوم 5 تا تکنیک دارند می شه 50 تا پیکسل و 50 تا ورتکس شیدر در صورتی که این 50 تا پیکسل شیدر من فقط به یه vertex شیدر لازم دارند و این جا اولا 49 تا ورتکس شیدر اضافی دارم که حافظه گرفتند و از اون بدتر الکی سوییچ می شن.
می دونید که switch شیدر یکی از کند ترین کارهاست.
----
اولا تبریک بابت terrain engine که در سمینار بازی سازی تبریز نمایش دادید . در مورد نکته ای که فرمودید ببین هر vertex shader به صورت یک تابع هستش که در یک تکنیک فراخونی می شه . کلا تکنیک یک فراخوانی به یک تابع ورتکس شیدر و یک تابع پیکسل شیدر هستش . حالا لازم نیست که برای 10 تا افکت 10 تا ورتکس شیدر بنویسی می تونی توی یک فایل دیگه ورتکس شیدر رو بنویسی و توی افکت ان را include کنی .
سلام
ممنون
مگه شما هم تبریز اومده بودید.
شما منظور من را متوجه نشدید مشکل من این نیست که بخوام کد بنویسم مشکل من با کامپایل d3dx است.
من کد افکت زیر رو با PIX تست کردم با وجود اینکه هر دو تکنیک یک pixel shader دارن ولی دو تا pixel shader کامپایل می شه و همین طور دوتا هم pixel shader ست می شه که می دونی SetPixelShader از کند ترین دستور ها است.
// Global variables
//-----------------------------------------------------------------------------
matrix W : WORLD;
matrix WVP : WORLDVIEWPROJECTION;
void RenderSceneVS0( in float4 vPos : POSITION,
in float2 vTex : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTex : TEXCOORD0)
{
oPos = mul( vPos, WVP );
oTex = vTex;
}
void RenderSceneVS1( in float4 vPos : POSITION,
in float2 vTex : TEXCOORD0,
out float4 oPos : POSITION,
out float2 oTex : TEXCOORD0)
{
oPos = mul( vPos + 0.5, WVP );
oTex = vTex * 4;
}
// Texture samplers
//-----------------------------------------------------------------------------
texture MeshTex: MESHTEXTURE;
sampler2D MeshTextureSampler : register(s0);
//-----------------------------------------------------------------------------
shared float4 RenderScenePS0( float2 Tex : TEXCOORD0 ) : COLOR
{
float4 c = tex2D(MeshTextureSampler, Tex) ;
return c;
}
//-----------------------------------------------------------------------------
technique RenderScene
{
pass P0
{
VertexShader = compile vs_2_0 RenderSceneVS0();
PixelShader = compile ps_2_0 RenderScenePS0();
CullMode = NONE;
}
}
technique test
{
pass P0
{
VertexShader = compile vs_2_0 RenderSceneVS1();
PixelShader = compile ps_2_0 RenderScenePS0();
CullMode = NONE;
}
}
سپول
چهارشنبه 23 دی 1388, 16:20 عصر
خوب واسه کاری که گفتی کدت اشتباهه
الان خیلی وقته با d3dxeffect کار نکردم یادم نیست ولی واسه اینکه یکبار کامپایل بشه یه همچین دستوری بود
VertexShader myVS = compile vs_2_0 MainVS();
technique ... {
VertexShader = (myVS)
}
برای اینکه چرا چند بار VS یا PS در تکنیک های مختلف set میشه فکر نکنم چیز عجیبی باشه، مگر اینکه چندتا pass داشته باشی که باز هم برای خود من پیش نمیاد
برای چندتا technique هم خیلی چیزی نیست که روی این مساله سخت بگیری معمولا هر متریال یک تکنیک داره یا اگه چندتا تکنیک داشته باشه shader هاشون متفاوت هست.
kochol
چهارشنبه 23 دی 1388, 17:34 عصر
سلام
من این دیزاین xml رو پیاده کردم و الان از روی اون xml کد شیدر می سازه ولی تو مدیریت اون و ترکیب اون با متریال ها موندم (مثل خر تو گل گیر کردم)
مثلا کامپایلر شیدر من برای هر نور یک کد مجزا تولید می کنه و من براساس اینکه تو صحنه چه خبره باید شیدر های متریال رو ست کنم بعد هم هر شیدر یک سری constant ها داره که باید به صورت خودکار ست بشن.
کلاس هایی که تا الان دارم
ShaderCompiler
ShaderScript
ShaderManager
MaterialScript
Technique
Pass
Material
Shader
حالا دیزاینی که دارم و البته کامل نیست این طوری که یه SubMaterial دارم به ازای هر یکی از شیدر هام که برای هر نور ساخته شده است و شیدرهای هر pass داخل این است و مسول ست کردن value های شیدر است.
jack
یک شنبه 27 دی 1388, 12:46 عصر
@kochol
سلام
ممنون
مگه شما هم تبریز اومده بودید.
شما منظور من را متوجه نشدید مشکل من این نیست که بخوام کد بنویسم مشکل من با کامپایل d3dx است.
من کد افکت زیر رو با PIX تست کردم با وجود اینکه هر دو تکنیک یک pixel shader دارن ولی دو تا pixel shader کامپایل می شه و همین طور دوتا هم pixel shader ست می شه که می دونی SetPixelShader از کند ترین دستور ها است.
---------------
سلام دوست عزيز
نه متاسفانه من تبریز نیومدم . امیدوارم مشکل شما با توضیحاتی که آقا سپهر دادن حل بشه .
سپول
یک شنبه 27 دی 1388, 20:26 عصر
من این دیزاین xml رو پیاده کردم و الان از روی اون xml کد شیدر می سازه ولی تو مدیریت اون و ترکیب اون با متریال ها موندم (مثل خر تو گل گیر کردم)
اولاً دیزاین xml به نظر من جالب نیست، من خودم حال نمی کنم یک شیدر رو شروع کنم از بیخ با xml بنویسم. اگه ادیتور داشته باشی قابل قبوله ولی بدون ادیتور چیز جالبی در نمیاد. معمولا آدم این چیزهایی که کد نویسی داره رو دوست داره با یک زبانی بنویسه که حالت سورس های دیگه رو داشته باشه نه xml.
من هم که xml زده بودن شیدر هام رو در واقع فقط واسه تغییرات کوچک یا دیدن فایل و فهمیدن کارکرد شیدر بوده، و خود xml در واقع با ادیتور گرافی درست می شد.
در مورد ترکیب با متریال، شیدر می تونه جدا باشه و فقط variable هایی که قراره به شیدر بدی رو در یک بافر در متریال ذخیره و آدرس دهی می کنی، که هر متریال هم به یک شیدر bind می شه و موقع آپدیت شدن اون متغیرهای درون بافر خودش رو به شیدر می ده.
دیگه نکته دیگه ای رو که مشکل باشه نمی دونم چیه و کجاش گیر کردی.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.