Необходимо рисовать HTML в Direct3D. HTML рисуется движком IE на DC полученном от Direct3D Surface или в Bitmap в памяти без проблем. Из всего этого получается текстура, которая рисуется где угодно.
Нет также проблем когда для HTML (в нем самом) задан цвет фона — т.е. когда нет никаких прозрачных участков — все ОК. Но есть так же задача отображать HTML с прозрачностью. Самый простой вариант — просто некий форматированный текст на произвольном фоне в Direct3D сцене. Получить от IE bitmap с альфа каналом невозможно. Возможно захватить часть изображения из буфера Direct3D и подсунуть его IE, чтобы он нарисовал HTML поверх него, потом взять его и вернуть обратно в Direct3D, но это ужасно неэффективно, поскольку HTML обычно статичный, а сцена под ним меняется постоянно. Хочется получить текстуру с альфаканалом, которая обновляется, только когда обновляется HTML. Пока придумал такой подход — рисовать HTML несколько раз на черном и на белом фоне, потом на основании двух изображений вычислить третье с альфа каналом. В теории все прекрасно. На практике есть проблема — IE сглаживает шрифты и контуры символов выглядят неправильно. Понятно, что цвета на сглаженных контурах на черном и белом фоне отличаются, поэтому для итоговой картинки необходимо вычислить некий цвет и альфа, так чтоб при наложении на произвольный цвет, контур также выглядел сглаженным.
Возможно, я неправильно вычисляю альфаканал и цвета точек в итоговой картинке. Но у меня есть сомнение — а возможно ли это в принципе?
Может имеет смысл порыть в направлении отключения сглаживания шрифтов в IE и сгглаживать картинку уже на последнем этапе в Direct3D. Но что то мне подсказывает, что результат будет хуже.
Конечно можно. Я буду везде считать цвет пикселей от 0 (черный) до 1(белый).
Допустим, у вас есть цвет пикселя C, который блендится с фоном с коэффициентом λ. Тогда на черном фоне у вас будет цвет B=λC, а на белом цвет W=λC+(1-λ).
Тогда W=B+(1-λ), откуда λ = B-W+1, а изначальный цвет C = B/λ.
Правда я уверен, что рендерить HTML 2 раза на черном и белом фоне будет оптимальным решением вашей задачи. Может вам и не нужен альфа канал на самом деле? Вы не особо то и описали что вы делаете.
Я именно так и делаю — и получается по контуру символов не то что хотелось бы. Т.е. для черных символов или белых все хорошо. А вот для других цветов выходит или слишком яркий или слишком темный контур. Дело в том что алгоритм сглаживания IE не знает наших формул. Т.е. он может для темного фона применять не такой коэффициент, как для светлого. Ну это грубо говоря.
Естественно. Сглаживание — это блендинг не с фоном, а с соседними пикселами. Да еще и неизвестным алгоритмом. Расскажите для чего вам альфа. Почему не рендерить HTML сразу на нужном фоне?
Для скорости. Если фон меняется на каждом кадре — а там может быть и видео или анимация, то придется получать DC фона и на каждом кадре просить IE туда отрисовать HTML — это будет очень медленно. Кроме того мне кажется Direct3D не даст мне DC для RenderTarget surface и придется картинки гонять из видео-памяти в системную — а это очень медленно. Отрисовка же заготовленной текстуры с альфаканлом вообще практически бесплатна с точки зрения производительности.
Дело в том, что я очень сомневаюсь в полезности HTML на фоне, который меняется каждый кадр. У вас нормально получается читать такой HTML? У меня бы глаза вылезли на лоб :) Подумайте, действительно ли вам нужен так часто меняющийся фон у HTML страницы, да еще и не однотонный небось. HTML же должен быть читаемым!
Какой фон решать не мне, а дизайнеру. Я должен обеспечить возможность вывода с прозрачным фоном. Кроме того, динамичный фон может вполне себе обеспечивать читаемость, если его: 1. размыть. 2. наложить на него однотонную заливку, но с прозрачностью. Еще прозрачность позволит добавить эффекты, которые не пересекаются с самим текстом, но пересекаются с прямоугольной областью в которой рисуется текст.