Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   псевдо 3D - как сделать освещение? (http://www.flasher.ru/forum/showthread.php?t=123087)

DRAGOnoid 24.03.2009 15:57

псевдо 3D - как сделать освещение?
 
здравствуйте ещё раз. Развивая тему 3Д решил попробовать сделать ещё освещение.
как я полагаю делается за счёт поиска угла между вектором нормали к плоскости и вектором самого света...

посему вопрос - как найти нормаль к плоскости в пространсвте?

единственное до чего додумался это что можно получить гломальную матрицу с помощью getRelativeMatrix3D
а что дальше с ней делать - ума не приложу :(
ведь чтобы получить хотя бы нормаль с помощью Vector3D.crossProduct - надо знать 2 вектора лежащие на плоскости.

а может вообще есть способ по проще, организовать затемнение или засветление объекта?

Alex Lexcuk 24.03.2009 17:08

>>Развивая тему 3Д решил попробовать сделать ещё освещение.
Правильно.
Делать можно так: Брать желательно среднюю точку грани, или если объект разбит на мелкие грани любую точку грани. В общем
Код:

var грань:Vector3D = new Vector3D(100,100,100);
var солнышко:Vector3D = new Vector3D(1000,1000,1000);
var свет:Number = Vector3D.distance(грань,солнышко);

Если солнышко будет далеко, то эффекта 0. Если близко то тоже 0;
Суммируя выше сказанное эффект 0, отсюда следует, что данный способ не подходит. Легче всего не напрячь процессор и получить красиво задумманое это просто сделать интервал дистанци для каждого объекта в отдельности и нафик этот свет, если он так далеко, то можно сделаь свет слева, свет справа или свет спереди или сзади.
В общем вот пример простого самодельного света. (свет спереди нагрузка на проц минимум)
http://www.murmadillo.tut.su/html/4cube.html

>>посему вопрос - как найти нормаль к плоскости в пространсвте?
>>ведь чтобы получить хотя бы нормаль с помощью Vector3D.crossProduct - надо знать 2 вектора лежащие на плоскости.

Ну так вы их знаете первый вектор это ваш свет, а второй это ваша плоскость.

DRAGOnoid 24.03.2009 17:28

сслка что то у меня неработает
на самом деле всё что я имею это Matrix3D объекта
и вот как используя её получить вектор нормали плоскости, чтобы потом получить угол между этой нормали и вектором падения света - тогда по углу можно ставить коэфициент освещения.

в общем всё сводится к тому - как найти вектор нормали к плоскости по её Matrix3D.

Alex Lexcuk 24.03.2009 17:35

Вложений: 2
>>в общем всё сводится к тому - как найти вектор нормали к плоскости по её Matrix3D.

Никак. Matrix3D - это просто преобразования к плоскости можно и к вектору матрицу применить.

сслка что то у меня неработает

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

_dm 24.03.2009 18:13

Цитата:

Ну так вы их знаете первый вектор это ваш свет, а второй это ваша плоскость.
Как это плоскость может быть вектором? О_о
Да и вектор, который свет, не подходит, потому что он не лежит на освещаемой плоскости.

DRAGOnoid
А зачем тебе плоскость освещать? Треугольников у тебя разве нету?

Цитата:

в общем всё сводится к тому - как найти вектор нормали к плоскости по её Matrix3D.
это смотря как плоскость размещена БЕЗ трансформации. Если, допустим, это XZ, ZY, ZX плоскость, то можно. Нормалью будет один из столбцов(строк) матрицы.

А вобще данных мало... Откуда у тебя плоскость, если ты не знаешь её нормали. И как ты применяешь трансформации к плоскости если у тебя, опять же, нету её нормали? Это ж невозможно =)

Alex Lexcuk 24.03.2009 18:45

>>Как это плоскость может быть вектором? О_о

А почему плоскости не быть вектором. Вы ж представляете себе плоскость. Это такая плоская здоровенная штуковина которая может лежать на трех точках одновременно. У первой точки могут быть координаты (100,0,0) у второй (0,100,0) и третья (0,0,100). Те. это вектор (100,100,100). Таким образом можно одним вектором описать любую плоскость. И найти методом
Код:

crossProduct(a:Vector3D):Vector3D
Возвращает новый объект Vector3D, который расположен перпендикулярно (под прямым углом) к текущему и второму объекту Vector3D.

Перпендикуляр к этим плоскостям.

DRAGOnoid 24.03.2009 18:50

плоскость я вращаю за счёт встроенных вращений во флеше типа rotationY

как применить к Vector3D - Matrix3D ?

litebox 24.03.2009 19:09

Есть такое понятие: плоскость, и есть такое понятие: вектор; вектор != плоскость, это факт :)
По поводу самодельных трехмерных движков, есть такая книга http://www.ozon.ru/context/detail/id/1692806/ - вариант для C, но там очень много теоретического материала по созданию, освещению и текстурированию 3d моделей - автор свое дело знает :)

Яски 24.03.2009 19:54

Какая куча бреда в отдельно взятой теме.

Плоскость можно задать многими способами, один из них это нормаль(вектор) и оффсет(число).

Как я понял вы хотите сделать освещение по Ламберту — каждая грань будет освещена равномерна по всей площади, свет имеет направление, но не имеет координаты.
Тогда формула освещенности для каждой грани будет такой:
Код:

  intensity = dot(normal, light) + ambient
    dot — скалярное произведение векторов
    normal — нормаль грани
    light — направление света
    ambient — любое число, значение освещенности "по-умолчанию".

Дальше нам нужно получать нормаль грани. Я, если честно, пока еще не разбирался с работой с 3D в десятке, и, например не знаю, как там расположены оси координат. Вижу пока два способа получения нормали экранного объекта( это вектор перпендикулярный плоскости объекта)
Код AS3:

 //для начала получаем глобальную матрицу
 var matrix:Matrix3D = dsp.getRelativeMatrix3D(stage);
 // Получаем вектор нормали в глобальном пространстве, здесь два варианта — преобразуем из локальных координат одну из осей или получаем компоненты этих векторов прямо из матрицы.
  // По первому способу, передаем локальную ось z (может правильно будет передавать и другую ось, могу ошибаться, это зависит от конкретной реализации, вобщем ось вверх
  var normal:Vector3D = matrix.deltaTransformVector(Vector3D.Z_AXIS);
  // Свет направлен вертикально вниз по оси z
  const light:Vector3D = new Vector3D(0, 0, -1);
  var intensity:Number = light.dotProduct(normal) + 0.1;
  // При использовании этого способа экранный объект нельзя масштабировать, иначе результат будет неправильным. Для учета масштабов есть еще один способ.


Alex Lexcuk 24.03.2009 20:14

>>как применить к Vector3D - Matrix3D ?

Да, мой исходничек не смотрели, ладно, я сейчас сам посмотрю, кстати по свой же ссылке
Код:

_pVec = mat3D.transformVector(_pVec);
И вот так считается свет до камеры (по координате Z) красиво и не дорого (экономия процессора)
Код:

//работает только красный (для примера)
                public function calcColor(_color:uint,_dist:Array,_index:int):uint{
                        var color:uint;
                        len = _dist.length;
                        var dMin:Number = _dist[0][0];
                        var dMax:Number = _dist[len-1][0];
                        var dStep:Number = Math.abs((dMax - dMin)/len);

                        var rMin:uint = 0x00;
                        var rMax:uint = 0xee;
                        var cStep:Number = Math.abs((rMin-rMax)/len);

                        var r:uint;
                        var g:uint = 0x00;
                        var b:uint = 0x00;



                        var ind:Number = (_dist[_index][0]-dMin)/dStep;
                        r = uint(rMax-cStep*ind);
                        color = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
                       
                        return color;
                       
                }

>> вариант для C
Смотрел варианты для С или С++. Флеш им не конкурент. Ибо большая чать, того что мы тут пытаемся сделать внедрена в видуху в виде OpenGl и тени и свет и сортировка граней и многое прочее выполняется в видеокарте, и там ничего химичить не надо - оно идет само собой. Так что С пока пусть полежит в сторонке.


Часовой пояс GMT +4, время: 13:36.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.