Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
VBDUnit
0 / 0 / 1
Регистрация: 02.02.2014
Сообщений: 52
1

SharpDX 2D и наложение с альфа-каналом

07.07.2018, 12:02. Просмотров 454. Ответов 3

Привет всем! Столкнулся с проблемой. Рисую одно изображение на другом через SharpDX.Direct2D:

C#
1
2
3
4
5
void drawImage(SharpDX.Direct2D1.DeviceContext canvas, SharpDX.Direct2D1.Bitmap1 bitmap)
{
      canvas.PrimitiveBlend = SharpDX.Direct2D1.PrimitiveBlend.SourceOver;
      canvas.DrawBitmap(bitmap, rctTo, 1f, quality, rctFrom, null);
}
Проблема в том, что результат выглядит как будто используется сложение цветов, т.е. PrimitiveBlend.Add, а не PrimitiveBlend.SourceOver. Другие режимы
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  
//
    // Сводка:
    //     Used to specify the geometric blend mode for all Direct2D primitives.
    public enum PrimitiveBlend
    {
        //
        // Сводка:
        //     The standard source-over-destination blend mode.
        SourceOver = 0,
        //
        // Сводка:
        //     The source is copied to the destination; the destination pixels are ignored.
        Copy = 1,
        //
        // Сводка:
        //     The resulting pixel values use the minimum of the source and destination pixel
        //     values. Available in Windows?8 and later.
        Minimum = 2,
        //
        // Сводка:
        //     The resulting pixel values are the sum of the source and destination pixel values.
        //     Available in Windows?8 and later.
        Add = 3,
        //
        // Сводка:
        //     No documentation.
        Maximum = 4
    }
пробую - картина меняется, а вот SourceOver выглядит 1 в 1 как Add. Кто-нибудь сталкивался с таким? Как это можно решить?

Добавлено через 15 минут
UPD: Обновил SharpDX до последней версии, ситуация не изменилась.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2018, 12:02
Ответы с готовыми решениями:

Graphics: как рисовать Альфа каналом
собственно вопрос такой как рисовать именно прозрочностью то есть например я кистью нарисовал...

Использование фона формы с альфа-каналом
Здравствуйте. Есть некоторые сложности с обработкой бекграунд-изображения программы. На данный...

Почему изображение с альфа каналом не наслаивается на изображение?
Собственно в моей программе взрыв должен происходить над машиной. Но вот незадача: почему взрыв...

Какой программой можно видео с альфа каналом - превратить в гиф с альфа-каналом?
Здравствуйте. Помогите советом. Какой программой можно видео с альфа каналом (с прозрачным...

Текстура с альфа каналом
Всем доброго времени суток. Возникла проблема с наложением текстуры с альфа-каналом на примитив....

3
VBDUnit
0 / 0 / 1
Регистрация: 02.02.2014
Сообщений: 52
14.07.2018, 14:31  [ТС] 2
Пытаюсь найти причину. Уже обнаружил, что ошибка происходит только в случае, если накладываемое изображение получено путем применения 2Д шейдера (т.е. эффекта, который Effect<T> where T : CustomEffectBase). Шейдер ошибок не имеет - если картинку сохранить в PNG, то в файле она будет нормальной, если же при этом её загрузить и наложить - результат нормальный. То есть ошибка происходит только в случае, если мы работаем с результатом работы шейдера напрямую.

Помимо этого заметил, что когда я применяю шейдер к битмапу и накладываю результат уже поверх какого-то изображения

C#
1
2
3
4
5
6
7
8
  
//inputBitmap1 - входной битмап
gpuEffect.SetInput(0, inputBitmap1, true);
 
//drawingContext привязан к битмапу, на котором уже что-то есть
drawingContext.DrawImage(gpuEffect, toPlace, InterpolationMode.Linear, CompositeMode.SourceOver);
 
//в результате шейдер отрабатывает, но поверх того, что уже было в drawingContext, отрисовывается так, как будто указан параметр CompositeMode.Add, [B]вне зависимости от того, что мы указываем[/B]
то он никак не реагирует на параметр CompositeMode - всегда результат получается одинаковым.
то есть варианты
C#
1
2
3
drawingContext.DrawImage(gpuEffect, toPlace, InterpolationMode.Linear, CompositeMode.SourceOver);
drawingContext.DrawImage(gpuEffect, toPlace, InterpolationMode.Linear, CompositeMode.Plus);
drawingContext.DrawImage(gpuEffect, toPlace, InterpolationMode.Linear, CompositeMode.Xor);
и другие, что бы мы не подставили, дают одинаковый неправильный результат
0
VBDUnit
0 / 0 / 1
Регистрация: 02.02.2014
Сообщений: 52
16.07.2018, 12:14  [ТС] 3
Провёл эксперименты с шейдером - выяснилось, что оно вообще недекватно работает с альфа-каналом.
Простой 2D шейдер на HLSL:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Texture2D InputTexture : register(t0);
 
SamplerState InputSampler : register(s0);
 
cbuffer constants : register(b0)
{
    float alpha : packoffset(c0.x);
}
 
float4 main(
    float4 pos      : SV_POSITION,
    float4 posScene : SCENE_POSITION,
    float4 uv0 : TEXCOORD0
) : SV_Target
{
    float4 p = InputTexture.Sample(InputSampler, uv0);
    p.a = alpha;
    return p;
}
Просто берем и присваиваем альфа канал. Работать это должно так:
http://www.homacosoft.com/good_compose.png

А получается так:
http://www.homacosoft.com/bad_compose.png

Все текстуры в формате B8G8R8A8_Uniform.
0
Миниатюры
SharpDX 2D и наложение с альфа-каналом   SharpDX 2D и наложение с альфа-каналом  
VBDUnit
0 / 0 / 1
Регистрация: 02.02.2014
Сообщений: 52
21.07.2018, 12:09  [ТС] 4
В общем, я нашел один недочет, который неправильно передавал параметры, однако даже после того, как я его поправил, всё равно наложение осуществляется неправильно. Ниже проиллюстрировал, что происходит.

Пиксельный шейдер вида:
C
1
2
3
4
float4 p = InputTexture.Sample(InputSampler, uv0);
p.a = pow((p.r + p.g + p.b) / 3.0f, 2.0f); //на самом деле тут по другому, но смысл такой же - светлое оставляем, темное убираем
p.r*=1.1f;
return p;
Использую следующим образом:
C#
1
2
effect.SetInput(0, flower);
canvasTree.DrawImage(effect, position, interpolationMode, compositeMode);
В результате получается неправильно. Всегда. Какие бы я не выбирал сочетания InterpolationMode и CompositeMode. Сгенерировал таблицу с вариантами.

Фулсайз: http://homacosoft.com/shader_wtf.jpg

Что это такое? Почему это происходит? Почему при SourceOver оно осветляет это дерево даже там, где альфа равна 0?!

Изменение свойства PrimitiveBlend у DeviceContext ничего не меняет. Как это исправить? Облазил все документации вдоль и поперек, нигде про такое не написано, только сказано, что делай Premultipiled Alpha и правильный CompositeMode и будет тебе счастье.

Кто-нибудь может что-нибудь подсказать?
0
Миниатюры
SharpDX 2D и наложение с альфа-каналом  
21.07.2018, 12:09
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2018, 12:09

QPixmap с альфа-каналом
Помогите пожалуйста. Есть окно (400 на 400 пикселей). Хочу применить к нему setMask(QPixmap). Но...

Загрузка картинки с альфа-каналом
Как загрузить и поставить на фон картинку, имеющий альфа-канал %-) Я хочу чтобы результат был...

Как загрузить картинку с альфа каналом?
Мне нужно загружать изображение с альфа каналом и рисовать это изображение поверх другого, в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru