ورود

View Full Version : مشکل با شیدرهای HLSL



pswin.pooya
دوشنبه 25 بهمن 1389, 17:40 عصر
از کجا میتونم تشخیص بدم که یه متغییر مثلا "in_Color" برای شیدر پیکسل هست یا ورتکس و یا هر دوی اونها؟ و به چه شکلی میتونم تشخیص بدم که یه هندلر مثلا با مقدار 11 برای شیدر پیکسل هست یا اینکه ورتکس و ... . این امکان وجود داره که دو متغییر با اسمهای متفاوت (داخل شیدرهای متفاوت) دارای مقدار handler یکسان باشن؟ مثلا متغییر "in_prjMatrix" داخل ورتکس شیدر دارای یک هندلر عددی یکسان با متغییری به اسم "xyz" داخل شیدر پیکسل باشه؟

راستی میتونم نتغییرهای محیطی تعریف کنم. متغییرهایی که یه بار ست میشن و همه شیدرها از اونها استفاده میکنن. مثلا من داخل OpenGL و GLSL یه متغییر محیطی به اسم in_Time دارم که یه بار زمان شروع به رندر ست میشه و بعد از اون هر شیدری که اون رو تعریف کنه میتونه ازش استفاده کنه. میشه همچین کاری رو داخل HLSL انجام داد؟

من از دایرکت 9 استفاده می کنم

سپول
سه شنبه 26 بهمن 1389, 19:20 عصر
برای مشکل دوم، اگه از D3DX و D3DXEffect استفاده می کنید :

زمان معرفی متغیر در شیدر :


;shared float4x4 worldMat


در برنامه اصلی قبل از لود کردن افکت :


D3DXCreateEffectPool(&g_myPool);


موقع لود کردن افکت (D3DXCreateEffect) پارامتر 7 هم همین g_myPool رو بدهید.
اگه effect هم استفاده نمی کنید که این مورد یک کار high-level هست و هر سیستم شیدر (مثل effect) واسه خودش راهی داره، تحت کنترل API نیست، opengl هم عجیبه که همچین چیزی داره چون باید low-level باشه.

مورد اول هم دقیقا نفهمیدم منظورت چیه . شاید ID3DXEffect::IsParameterUsed منظورته.

pswin.pooya
چهارشنبه 27 بهمن 1389, 00:26 صبح
دیزاین موتور من به شکلی هستش که زمان کامپایل (بعد از کامپایل) فورا تمام متغییرها رو میشماره و داخل یه std::map نگهداریشون میکنه و همچنین بعضی از متغییرهای دیگه رو داخل یه عضو کلاس ذخیره میکنه. حالا مشکل اینجاست که چون پیکسل و ورتکس شیدرها از هم جدا هستن من نمی تونم همچین کاری رو بکنم. مثلا از کجا باید بدونم که متغییری به اسم xyz داخل ورتکس شیدر تعریف شده یا پیکسل شیدر و یا هر دوی اونها از همه بدتر اینه که توابع ست من فقط با uint کار میکنن یعنی شماره متغییر رو میگیرن وستش میکنن نه اسم اون رو. این دیزاین برای OpenGL خوبه اما اینجور که به نظر میاد برای DX چندان مناسب نیستش.

من از افکتها استفاده نمی کنم. بلکه به صورت مستقیم از CreateVertexShader و CreatePixelShader و D3DXCompileShader استفاده میکنم.

سپول
جمعه 29 بهمن 1389, 14:34 عصر
سلام .
دقیق نمی فهمم منظورت رو.
اگه متغیرها رو می خوای که کاری نداره، هر شیدری رو که با D3DXCompileShader کامپایل می کنی ، یک ID3DXConstantTable* هم می ده بهت که کلیه اطلاعات متغیرهای درون اون شیدر از جمله اسم و نوع و رجیستر و همه چی رو می ده.

اگه می خوای مطمئن بشی که متغیر ها یک جور می مونن در چند شیدر باید از دستور register استفاده کنی.

هندلر های شیدر کاره ای نیستند و فقط برای نرم افزار احتیاج هست، چیزی که برای hardware اهمیت داره شماره register متغیر ها هست که بین شیدرها باید ثابت باشه.
نرم افزار ادیتور شیدر (http://www.hmrengine.com/img/0.7/shot04.jpg) نسخه قدیمی hmrEngine از همین متد ها استفاده می کرد. با فرق اینکه خودش شیدر رو درست می کرد و مقدار های درست به Register اونها می داد برای اینکه توی همدیگه pack یا share بشوند.سورس اون می تونه کمک کنه، احتمالا سورسش هم داری.

pswin.pooya
جمعه 29 بهمن 1389, 19:23 عصر
سلام
نه سورسش رو ندارم. چه شکلی میتونم شماره ریجیسترهای متغییرهای یه شیدر کامپایل شده رو بگیرم. چون من هم داخل رندرر OpenGL از همین متد استفاده میکنم. یعنی شماره یه ریجیستر که همون هندلر متغییر هست رو میگیرم و توی یه std::map<std::string,int> ذخیره میکنم.

راستی از ایده ریموت انجینت خیلی خوشم اومد. امیدوارم که توی تولید انجینت مثل همیشه موفق باشی

سپول
شنبه 30 بهمن 1389, 02:36 صبح
وقتی شیدر رو با D3DXCompileShader کامپایل کردید یک ID3DXConstantTable می ده.
متد ID3DXConstantTable::GetConstantDesc
متغیر : D3DXCONSTANT_DESC::RegisterCount و D3DXCONSTANT_DESC::RegisterIndex


راستی از ایده ریموت انجینت خیلی خوشم اومد. امیدوارم که توی تولید انجینت مثل همیشه موفق باشی
مرسی.

pswin.pooya
شنبه 14 خرداد 1390, 22:05 عصر
سلام
چه شكلي ميتونم تشخيص بدم كه ورودي هاي شيدر راس چيه؟ مثلا position و color و .... متاسفانه اسم اينها داخل constant tableشيدر راس نيستش.

سپول
دوشنبه 16 خرداد 1390, 11:15 صبح
اونو دیگه نمی دونم چیه.
من اون موقع که shaderEditor رو نوشته بودم، از اونجا که گراف رو خودم درست می کردم می دونستم فرمت Vertex و همه متغیر ها و کد چی هست. از این توابع استفاده نمی کردم

jack
دوشنبه 16 خرداد 1390, 12:27 عصر
من برای حل این مشکل در موتورم از 2 نوع vertex_type استفاده کردم . یک نوع برای ذخیره راس و یک نوع برای نمایش راس .و در نوع ذخیره راس علاوه بر اطلاعات مکان و رنگ و .. نوع راس رو به صورت یک ایندکس تعریف کردم . توی برنامه هم برای هر نوع راس یک ایندکس تعریف کردم . حالا موقع نمایش اول نوع راس را از نوع ذخیره بیرون می کشم و عملیات setvertexdeclaration رو انجام می دهم سپس با نوع راس نمایش صحنه رو نمایش می دهم .

pswin.pooya
دوشنبه 16 خرداد 1390, 17:04 عصر
سلام
من داخل GD سوالم رو مطرح كردم كه جواب زير رو به من دادن.

وروديهاي شيدر راس رو ميشه با دستور D3DXGetShaderInputSemantics گرفت.

اين تكه كد مال انجين من براي گرفتن وردي هاي شيدر راس هست (شايد روزي روزگاري به درد كسي خورد):


uint_t count = 0;
UINT buf_size = 0;
m_vShader->GetFunction(0,&buf_size);
DWORD* vShaderMain = DGE_NEW_ARRAY(DWORD,buf_size);
m_vShader->GetFunction(vShaderMain,&buf_size);
D3DXGetShaderInputSemantics(vShaderMain,0,&count);
D3DXSEMANTIC *sems = DGE_NEW_ARRAY(D3DXSEMANTIC,count);
D3DXGetShaderInputSemantics(vShaderMain,sems,&count);
for (int i = 0; i < count; i++)
{
switch (sems[i].Usage)
{
case D3DDECLUSAGE_POSITION:
vdec.position =1;
case D3DDECLUSAGE_NORMAL:
vdec.normal =1;
case D3DDECLUSAGE_TEXCOORD:
if (sems[i].UsageIndex == 0)
vdec.tex_coord0 =1;
else
vdec.tex_coord1 =1;
case D3DDECLUSAGE_TANGENT:
vdec.tangant =1;
case D3DDECLUSAGE_COLOR:
vdec.color =1;
}
}
DGE_DELETE_ARRAY(vShaderMain);
DGE_DELETE_ARRAY(sems);

كه بعد از گرفتن وروديها vdec مخصوص هر شيدر رو ميسازه و زمان ست كردن متريال. vdec اون شيدر رو هم ست ميكنه. پس ديگه لازم نيست كه هيچ جا مشخص بشه كه بايد چه وروديهاي به شيدر داده بشه چون با توجه به متريال خود اونها ست ميشن.