|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
закраска треугольника (shading), с интерполяцией
Сейчас изучаю возможности Flash 8 по текстурированию и закраске треугольников. В перспективе - идея сделать несложный 3d engine с текстурами и нормальным (не flat, а Gouraud) светом (что отсутствует в большинстве даже продвинутых flash 3d engines).
Кому лениво читать, можно пропустить все кроме выделенного жирным. С текстурированием всё довольно просто, с помощью MovieClip.attachBitmap и MovieClip.transform.matrix а также mask по форме нужного треугольника все неплохо работает, и даже скорость вполне сносная. С освещением сложнее, быстрого и некривого решения пока не нашёл. Итак, сразу сформулирую вопрос: Имеется треугольник с вершинами A (0, 0); B (256, 0); C (0, 256). Для каждой вершины задан свой цвет, например A - красный, B - зелёный, C - синий. Нужно проинтерполировать цвет по всей площади треугольника. То есть закрасить его так чтобы в каждой его точке цвет определялся в зависимости от расстояния от каждой вершины. Другими словами, нужен градиент не linear, а с тремя вершинами. При этом важно чтобы это работало быстро. Какие есть идеи? Теперь варианты как это делал я: 1) Делается BitmapData(256, 256), присоединяется к нужному клипу. for (y = 0; y < 256; ++y) { // линейная интерполяция по катету AC, для r, g, b цвет1_r = цвет_в_А_r * (256 - y) / 256 + цвет_в_C_r * y / 256; ... такая же интерполяция по гипотенузе BC... цвет2_r = ... for (x = 0; x < 256; ++x) { // интерполяция между цвет1 и цвет 2, для r, g, b цвет_r = цвет_1_r * ( 256 - x) / 256 + цвет_2_r * x /256; .. setPixel(x, y, (цвет_r << 16) + (цвет << 8) + цвет_b); } } 2) Делается BitmapData(2, 2). setPixel(0, 0, цветА) setPixel(1, 0, цветB) setPixel(0, 1, цветC) цветD = ... // посчитать средний по компонентам r,g,b цвет между цветB и цветC setPixel(1, 1, цветD) Дальше BitmapData присоединяется к клипу с опцией smoothing = true и клип увеличивается (с помощью MovieClip.transform.matrix) до 256х256. В итоге flash сглаживает картинку и получается приблизительно то что нужно. Правда по качесту далеко не идеально потому что вокруг середины гипотенузы получается пятно от пиксела (1, 1). Хорошо заметно, если цветB=цветC=зелёный (например). По скорости работает очень неплохо. Ещё думал, как бы это реализовать с помощью градиента(нескольких градиентов), но так и не придумал. Можно поиграться с моим кодом: http://heilong.oceanography.ru/flash/lab/ Для наглядности в нём можно закомментировать текстурирование (строка 22), преобразования на плоскости (строка 111) и произвольные цвета вершин (строки 51-59), тогда как раз будет заметно неидеальное качество. Чтобы было лучше видно, можно поставить посильнее увеличение (строка 44). Кто осилил мои "много букв", милости прошу к обсуждению/идеям. |
Часовой пояс GMT +4, время: 01:00. |
|
« Предыдущая тема | Следующая тема » |
|
|