Unity - шейдерный альфа не работает только на iOS - PullRequest
1 голос
/ 04 апреля 2019

У меня проблема с моим шейдером, но только при сборке на iOS.Я пытаюсь сделать скриншот на экране.Я узнал, что метод получения правильной прозрачности на скриншоте состоит в том, чтобы сделать один скриншот с черным фоном и один с белым фоном, а затем использовать формулу для корректировки цветов.Я создал шейдер с двумя дополнительными свойствами текстуры, чтобы содержать эти черно-белые скриншоты.Суть его в следующем:

        fixed4 frag(v2f IN) : SV_Target
        {
            half4 blackColor = tex2D(_BlackTex, IN.texcoord);
            half4 whiteColor = tex2D(_WhiteTex, IN.texcoord);
            float alphaMultiplier = 1 + blackColor.r - whiteColor.r;
            half4 color = half4(1, 1, 1, 0);

            color.r = blackColor.r / alphaMultiplier;
            color.g = blackColor.g / alphaMultiplier;
            color.b = blackColor.b / alphaMultiplier;
            color.a = alphaMultiplier;


            #ifdef UNITY_UI_CLIP_RECT
            color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
            #endif

            #ifdef UNITY_UI_ALPHACLIP
            clip (color.a - 0.004);
            #endif

            return color;
        }

Это работает в Android, а также в редакторе на моем ПК и Mac.Однако на iOS части скриншота, которые являются полностью прозрачными, показывают как полностью непрозрачные (и черный, черный бит должен ожидаться).

            color.r = alphaMultiplier;
            color.g = alphaMultiplier;
            color.b = alphaMultiplier;
            color.a = 1;

Изменение шейдера, чтобы определить цвет скриншотаиз-за непрозрачности непрозрачные части изображения должны отображаться белым цветом, а прозрачные части изображения - черным.В случае, когда прозрачные области показаны черным в моей сборке, я ожидал, что весь скриншот будет белым.Не былоПравильные части изображения были черно-белыми.

            color.r = alphaMultiplier;
            color.g = alphaMultiplier;
            color.b = alphaMultiplier;
            color.a = 0;

Затем я попытался жестко закодировать альфа в 0 для всех пикселей, чтобы посмотреть, способна ли сборка iOS показать настоящую прозрачность вообще.Это было, изображение было невидимым.

            color.r = blackColor.r; // 0, 0
            color.g = whiteColor.r; // 255, 1
            color.b = alphaMultiplier; // 0, 0
            color.a = 1;

Наконец я попытался установить значения rgb пикселей для черно-белых текстур.Шейдеры сложно отлаживать, поэтому я хотел открыть скриншот сборки в редакторе изображений, чтобы «отладить» их значения.Эти значения, взятые из раздела полной прозрачности, показаны выше.Они точно такие, какими они должны быть для правильной работы шейдера.

Я действительно не знаю, что делать отсюда.Все три моих теста показали, как шейдер в идеальном мире, я не вижу в них вины.Однако, несмотря на все доказательства обратного, он все еще не работает должным образом вне испытаний.Каждый частично прозрачный пиксель отрисовывается идеально, это только полностью прозрачные пиксели, которые не работают, и только в сборках iOS.Единственное, что я могу подумать, что я не проверял, это то, что альфа была жестко запрограммирована во всех моих тестах.Я не понимаю, как это должно иметь значение.Все мои тесты показали, что все должно быть правильно.Пожалуйста, помогите мне.

            color.r = blackColor.r / alphaMultiplier;
            color.g = blackColor.g / alphaMultiplier;
            color.b = blackColor.b / alphaMultiplier;
            color.a = min(max(blackColor.r, 0.25), 0.5);

РЕДАКТИРОВАТЬ: В качестве одного финального теста я использовал свой основной код для rgb и для альфа я использовал переменную, которую я мин / макс в диапазоне от 0,25 до 0,5.Нормальные области экрана полупрозрачны, но области, которые должны быть полностью прозрачными, снова непрозрачны.Я официально понятия не имею.Любая помощь будет действительно, ДЕЙСТВИТЕЛЬНО оценена.

...