Firemonkey делает странные, странные вещи с Альфой
Работа с Delphi / Firemonkey XE8. В последнее время у него была приличная удача, хотя вам нужно черт побери, чтобы заставить его делать то, что вы хотите. Мой текущий проект заключается в оценке его низкоуровневых 3D-возможностей, чтобы посмотреть, смогу ли я использовать их в качестве отправной точки для игрового проекта. Я также достаточно хорошо знаю Unity3D и собираюсь использовать вместо него Unity3D, но я полагаю, что Delphi / Firemonkey может дать мне некоторую дополнительную гибкость в моем игровом дизайне, потому что он настолько минимален.
Поэтому я решил углубиться в образец, поставляемый Embarcadero... в частности, образец LowLevel3D. Это кроссплатформенный пример, который показывает вам, как ничего не делать, кроме как нарисовать вращающийся квадрат на экране с помощью некоторых пользовательских шейдеров по вашему выбору, и сделать так, чтобы он выглядел одинаково на всех платформах (хотя на самом деле он не работает ВСЕ то же самое на всех платформах... но мы не будем вдаваться в это).
Embc не предоставляет исходные не скомпилированные шейдеры для проекта (который я мог бы добавить, действительно хромает), и требует, чтобы вы поставили свои собственные совместимые шейдеры (некоторые скомпилированные, некоторые нет) для различных платформ, на которые вы нацелены (также хром).... так что моей первой работой было создание шейдера, который работал бы с существующим образцом, который делал бы что-то ДРУГОЕ, чем тот, что уже делал образец. В частности, если я создаю 2D-игру, я хотел убедиться, что я могу делать спрайты с альфа-прозрачностью, базовыми вещами... если я смогу заставить это работать, мне, вероятно, никогда не придется писать еще один шейдер для вся игра
После долгих часов выдергивания волос у меня появился маленький шейдер, который работает с теми же параметрами, что и демонстрационная версия.
Texture2D mytex0: register(t0);
Texture2D mytex1: register(t1);
float4 cccc : register(v0) ;
struct PixelShaderInput
{
float4 Pos: COLOR;
float2 Tex: TEXCOORDS;
};
SamplerState g_samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
RasterizerState MyCull {
FrontCounterClockwise = FALSE;
};
float4 main(PixelShaderInput pIn): SV_TARGET
{
float4 cc,c;
float4 ci = mytex1.Sample(g_samLinear, pIn.Tex.xy);
c = ci;
c.a = 0;//<----- DOES NOT actually SET ALPHA TO ZERO ... THIS IS A PROBLEM
cc = c;
return cc;
}
Не берите в голову, что это фактически не имеет большого значения с параметрами, но проверьте строку, где я установил ALPHA выхода на 0. Ну... Я обнаружил, что это на самом деле не имеет никакого эффекта!
Но это становится пугающим, чем это. Я обнаружил, что включение CULLING в приложении Delphi решило эту проблему. Так что я думаю... ничего страшного, я просто нарисую обе стороны спрайта вручную, верно? Нету! Когда я вручную нарисовал двухсторонний спрайт... проблема вернулась!
Проверьте это изображение: шейдер игнорирует альфа =0, когда двусторонний
На картинке выше очевидно, что альфа подчиняется, потому что облака не окружены черным ящиком, однако само облако является слишком насыщенным (я считаю, что если я умножу rgb * a, то цвета получатся примерно правильными, но я Я не собираюсь делать это в реальной жизни по понятным причинам.
Я новичок в концепции написания пользовательских шейдеров. Любое понимание приветствуется.