По сути, я хочу (в DirectX) взять два частично прозрачных изображения и смешать их вместе. Это прекрасно работает при смешивании по умолчанию, поскольку они оба отображаются как перекрывающиеся и т. Д. Однако проблема в том, что непрозрачность заметно возрастает там, где они пересекаются. Это вызывает все больше проблем, поскольку спрайты перекрываются. То, что я хотел бы сделать, это сохранить смешивание одинаковым, за исключением сохранения общей непрозрачности для всех этих смешиваемых спрайтов, независимо от того, как они перекрываются.
Похоже, для этого была бы настройка рендеринга (все эти спрайты одни в своем пакете спрайтов, что облегчает эту часть), но если это так, я этого не знаю. Прямо сейчас я стреляю в темноте, и я пробовал много разных вещей, и ни одна из них не выглядела правильно. Я знаю, что мне, вероятно, нужен какой-то вариант D3DBLENDOP, но я просто не знаю, какие настройки там мне действительно нужны (я много чего пробовал, но на этом этапе все догадывается).
Вот скриншот того, что на самом деле происходит со стандартным смешиванием (лучшее, что я могу получить): http://arcengames.com/share/FFActual.png Вот скриншот с макетом того, как бы я хотел, чтобы смешивание получилось (силовые поля были добавлены в тот же слой в Photoshop, а затем получили общее альфа-значение): http://arcengames.com/share/FFMockup.png
Вот как я это сделал в Photoshop:
1. Возьмите два изображения и удалите всю прозрачность (за исключением полностью прозрачных пикселей).
2. Объедините их в один слой, который смешивает цвет, но не имеет никакой частичной альфа.
3. Теперь установите глобальную прозрачность для этого слоя, скажем, 40%.
В результате получается что-то, что выглядит немного смешанным по цвету, но не имеет увеличения непрозрачности на перекрывающихся участках.
ОБНОВЛЕНИЕ: Хорошо, большое спасибо Гозу ниже, который предложил использовать Z-Buffer. Это работает! Смешивание, по большому счету, идеально и именно то, что я хотел бы. Единственная оставшаяся проблема? Используя этот новый метод, вокруг края изображения силового поля появляется огромный артефакт, который отображается последним. Смотрите это: http://www.arcengames.com/share/FFZBuffer.png
ОБНОВЛЕНИЕ: Ниже приведено окончательное решение в C # (SlimDX)
- Очистка ZBuffer до черного, прозрачного или белого цвета один раз за кадр имеет одинаковый эффект (это происходит перед вызовом BeginScene)
Direct3DWrapper.ClearDevice (SlimDX.Direct3D9.ClearFlags.ZBuffer, Color.Transparent, 0);
- Все остальные спрайты отрисовываются с Z = 1, для них ZBuffer отключен:
device.SetRenderState (RenderState.ZEnable, ZBufferType.DontUseZBuffer);
- Спрайты силового поля рисуются при Z = 2, с включенным ZBuffer, включенным ZWrite и ZFunc как Less:
device.SetRenderState (RenderState.ZEnable, ZBufferType.UseZBuffer);
device.SetRenderState (RenderState.ZWriteEnable, true);
device.SetRenderState (RenderState.ZFunc, Compare.Less);
- В это время также установлены следующие флаги, чтобы предотвратить обнаружение артефакта черной границы:
device.SetRenderState (RenderState.AlphaTestEnable, true);
device.SetRenderState (RenderState.AlphaFunc, Compare.GreaterEqual);
device.SetRenderState (RenderState.AlphaRef, 55);
Обратите внимание, что AlphaRef находится на 55 из-за альфа-уровней, установленных в конкретном исходном изображении, которое я использовал. Если бы мое исходное изображение имело более высокое альфа-значение, то AlphaRef также должен был бы быть выше.