Альфа-маска в DirectX

#c #directx

#c #directx

Вопрос:

Я искал везде, и я не могу найти ответ, который работает.

Я пытаюсь проделать дыру в текстуре, "sheet.png" будучи текстурой и "hole.png" будучи альфа-маской. Это белое изображение с черным кругом, в котором я хочу, чтобы на листе было отверстие.

Как мне это сделать? Это то, что у меня есть до сих пор, но все, что он делает, это рисует две текстуры друг поверх друга

 md3dDev->SetTexture(0, gTexture);
md3dDev->SetTexture(1, holeTexture);

md3dDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
md3dDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);  

md3dDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
md3dDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);

md3dDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE );
md3dDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
md3dDev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );

md3dDev->SetRenderState( D3DRS_ALPHABLENDENABLE, true);
md3dDev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);//alpha
md3dDev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);//alpha
  

Спасибо за вашу помощь

Ответ №1:

Первое правило: COLOROP сочетается с COLORARG, ALPHAOP — с ALPHAARG, не смешивайте их.

Невозможно передать информацию о цвете в alphachannel в конвейере фиксированной функции. Ближайший подход, который я могу придумать, — это подготовить текстуру отверстия так, чтобы информация размещалась в alphachannel. Тогда вы можете использовать что-то вроде этого:

   // multiply colorchannel from colortexture with diffuse lighting
  d3dSetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE);   
  d3dSetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  d3dSetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  // ignore alpha from colortexture
  d3dSetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1); 
  d3dSetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CURRENT);

  // ignoring colorchannel from alphatexture
  d3dSetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1); 
  d3dSetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
  // get alpha from alphatexture
  d3dSetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1); 
  d3dSetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  

Однако в наши дни это довольно устаревшее. Используйте шейдеры! 🙂

Ответ №2:

Если вы пишете свои собственные шейдеры, просто перемножьте альфа-символы вместе.

 Output = tex2d(Texture[0], uv)
Output.A *= tex2d(Texture[1], uv).A
  

если вы используете его фиксированный конвейер / эмуляцию, то я не уверен, извините.

Комментарии:

1. Я не использую никаких пользовательских шейдеров. Ты думаешь, это то, что я должен сделать?

2. @robev Да, именно так я бы и поступил. Для начала в них может быть немного сложно разобраться. Хороший учебник, который я нашел, был riemers.net/eng/Tutorials/DirectX/Csharp/series3.php , по общему признанию, это не для C , но в любом случае это скорее шейдерная сторона того, чему он учит.