Трёхмерная графика с нуля. часть 1: трассировка лучей

Суперсэмплинг

квадрата

Псевдокод трассировщика лучей

CanvasToViewport(x, y) {
    return (x*Vw/Cw, y*Vh/Ch, d)
}


ReflectRay(R, N) {
    return 2*N*dot(N, R) - R;
}


ComputeLighting(P, N, V, s) {
    i = 0.0
    for light in scene.Lights {
        if light.type == ambient {
            i += light.intensity
        } else {
            if light.type == point {
                L = light.position - P
                t_max = 1
            } else {
                L = light.direction
                t_max = inf
            }

            # Проверка теней
            shadow_sphere, shadow_t = ClosestIntersection(P, L, 0.001, t_max)
            if shadow_sphere != NULL
                continue

            # Диффузность
            n_dot_l = dot(N, L)
            if n_dot_l > 0
                i += light.intensity*n_dot_l/(length(N)*length(L))

            # Блеск
            if s != -1 {
                R = ReflectRay(L, N)
                r_dot_v = dot(R, V)
                if r_dot_v > 0
                    i += light.intensity*pow(r_dot_v/(length(R)*length(V)), s)
            }
        }
    }
    return i
}


ClosestIntersection(O, D, t_min, t_max) {
    closest_t = inf
    closest_sphere = NULL
    for sphere in scene.Spheres {
        t1, t2 = IntersectRaySphere(O, D, sphere)
        if t1 in  and t1 < closest_t
            closest_t = t1
            closest_sphere = sphere
        if t2 in  and t2 < closest_t
            closest_t = t2
            closest_sphere = sphere
    }
    return closest_sphere, closest_t
}


TraceRay(O, D, t_min, t_max, depth) {
    closest_sphere, closest_t = ClosestIntersection(O, D, t_min, t_max)

    if closest_sphere == NULL
        return BACKGROUND_COLOR

    # Вычисление локального цвета
    P = O + closest_t*D  # Вычисление точки пересечения
    N = P - closest_sphere.center  # Вычисление нормали сферы в точке пересечения
    N = N / length(N)
    local_color = closest_sphere.color*ComputeLighting(P, N, -D, sphere.specular)

    # Если мы достигли предела рекурсии или объект не отражающий, то мы закончили
    r = closest_sphere.reflective
    if depth <= 0 or r <= 0:
        return local_color

    # Вычисление отражённого цвета
    R = ReflectRay(-D, N)
    reflected_color = TraceRay(P, R, 0.001, inf, depth - 1)

    return local_color*(1 - r) + reflected_color*r
}


for x in [-Cw/2, Cw/2] {
    for y in [-Ch/2, Ch/2] {
        D = camera.rotation * CanvasToViewport(x, y)
        color = TraceRay(camera.position, D, 1, inf)
        canvas.PutPixel(x, y, color)
    }
}
viewport_size = 1 x 1
projection_plane_d = 1

sphere {
    center = (0, -1, 3)
    radius = 1
    color = (255, 0, 0)  # Красный
    specular = 500  # Блестящий
    reflective = 0.2  # Немного отражающий
}
sphere {
    center = (-2, 1, 3)
    radius = 1
    color = (0, 0, 255)  # Синий
    specular = 500  # Блестящий
    reflective = 0.3  # Немного более отражающий
}
sphere {
    center = (2, 1, 3)
    radius = 1
    color = (0, 255, 0)  # Зелёный
    specular = 10  # Немного блестящий
    reflective = 0.4  # Ещё более отражающий
}
sphere {
    color = (255, 255, 0)  # Жёлтый
    center = (0, -5001, 0)
    radius = 5000
    specular = 1000  # Очень блестящий
    reflective = 0.5  # Наполовину отражающий
}


light {
    type = ambient
    intensity = 0.2
}
light {
    type = point
    intensity = 0.6
    position = (2, 1, 0)
}
light {
    type = directional
    intensity = 0.2
    direction = (1, 4, 4)
}

Ответы

  1. См. рис.
  2. См. рис.
  3. Если экран расположен от фигуры на расстоянии, большем h tg α (где α — угол падения солнечных лучей), длина тени будет 2h. Если экран расположен ближе, длина тени будет меньше.

  4. Чтобы собрать на рассматриваемый препарат больше света.
  5. См. рис.
  6. Изображение — мнимое.
  7. См. рис. Источник находится в точке S1, если изображение действительное, и в S2, если изображение мнимое.
  8. См. рис.
  9. См. рис.
  10. Один из вариантов построения приведен на рисунке.
  11. Да. В этом случае объектив фотоаппарата действует подобно глазному хрусталику.
  12. Источник света должен быть к линзе ближе, чем двойной фокус, иначе образуются области, из которых источник и изображение видны одновременно (заштрихованные на рис.).
  13. См., например, рис.
  14. См. рис.
  15. В космосе нет поглощения света атмосферой, меньше яркость неба, отсутствует атмосферное дрожание, а длительность экспозиции не ограничена только ночным временем — т.е. снижено или исключено влияние факторов, мешающих получать на Земле изображение слабых звезд.

Микроопыт

В результате двойного отражения ваше изображение не будет «переворачиваться» слева направо. Если комната прямоугольной формы, вы увидите себя в зеркале из любой ее точки.

Материал подготовил А.Леонович

Рендеринг с тенями

ClosestIntersection(O, D, t_min, t_max) {
    closest_t = inf
    closest_sphere = NULL
    for sphere in scene.Spheres {
        t1, t2 = IntersectRaySphere(O, D, sphere)
        if t1 in  and t1 < closest_t
            closest_t = t1
            closest_sphere = sphere
        if t2 in  and t2 < closest_t
            closest_t = t2
            closest_sphere = sphere
    }
    return closest_sphere, closest_t
}
TraceRay(O, D, t_min, t_max) {
    closest_sphere, closest_t = ClosestIntersection(O, D, t_min, t_max)

    if closest_sphere == NULL
        return BACKGROUND_COLOR

    P = O + closest_t*D  # Compute intersection
    N = P - closest_sphere.center  # Compute sphere normal at intersection
    N = N / length(N)
    return closest_sphere.color*ComputeLighting(P, N, -D, sphere.specular)
}
ComputeLighting(P, N, V, s) {
    i = 0.0
    for light in scene.Lights {
        if light.type == ambient {
            i += light.intensity
        } else {
            if light.type == point {
                L = light.position - P
                t_max = 1
            } else {
                L = light.direction
                t_max = inf
            }

            # Проверка тени
            shadow_sphere, shadow_t = ClosestIntersection(P, L, 0.001, t_max)
            if shadow_sphere != NULL
                continue

            # Диффузность
            n_dot_l = dot(N, L)
            if n_dot_l > 0
                i += light.intensity*n_dot_l/(length(N)*length(L))

            # Зеркальность
            if s != -1 {
                R = 2*N*dot(N, L) - L
                r_dot_v = dot(R, V)
                if r_dot_v > 0
                    i += light.intensity*pow(r_dot_v/(length(R)*length(V)), s)
            }
        }
    }
    return i
}

Исходный код и рабочее демо >>Теперь

Любопытно, что…

…даже в эпоху позднего Возрождения зрение и оптические явления считались подозрительными феноменами. Возможно поэтому один из крупных ученых-оптиков Франческо Мавролик долго не осмеливался опубликовать свой основной труд, и тот увидел свет лишь в год его смерти — 1575.

…впервые безупречное с научной точки зрения построение хода лучей в глазу удалось выполнить в начале XVII века великому астроному Иоганну Кеплеру. Ему же принадлежат разработка теории построения изображений в оптических приборах, введение понятий «фокус» и «оптическая ось», применяемые по сей день.

…к телескопу, изобретенному Галилеем, относились как к чуду — народ толпами спешил в него заглянуть. А после того как Галилей преподнес экземпляр телескопа в подарок венецианскому сенату, его жалованье удвоилось.

…простому микроскопу, состоящему из лупы, снабженной штативом, со временем пришел на смену сложный микроскоп, представляющий собой уже систему линз. Придуман он был почти одновременно с изобретением зрительной трубы — в XVII веке, и заслуги в его создании принадлежат, по-видимому, также голландцам. Однако конкурировать с лупой такой микроскоп смог лишь в XIX веке — при появлении составных объективов.

…пытаясь усовершенствовать линзовый телескоп, Ньютон самостоятельно сконструировал и построил прибор, «применяя вместо объективного стекла вогнутый металл», т.е. зеркало. Именно за создание такого — отражательного — телескопа он был избран членом Лондонского Королевского общества в 1672 году.

…как и немало выдающихся ученых, Фуко сам изобретал оригинальные инструменты, в том числе и для астрономических наблюдений. Им, например, был разработан очень важный метод серебрения стекла для отражательных телескопов.

…старинное изобретение «камера-обскура» — черный ящик с маленьким отверстием — при всей своей простоте порой может соперничать даже с современной специальной фотоаппаратурой. Так, с ее помощью делают превосходные цветные снимки без каких-либо искажений.

…телескопы XVIII века имели невероятную длину. Причина в том, что составных объективов, компенсирующих искажения, тогда делать не умели, а однолинзовый объектив давал неокрашенное изображение, лишь если его фокусное расстояние достигало 40 метров!

…отчетливое изображение в глазу рыб возникает подобно настройке на резкость в фотоаппарате. Шарообразный хрусталик не изменяет своей кривизны, как у человека, а перемещается мышцами «вперед-назад».

…чтобы улучшить качество изображения, объективы современных фотоаппаратов составляют из нескольких линз, изготовленных из разных сортов стекла. Конструкция настолько сложна, что проектирование объективов «поручают» компьютерам. Чисто геометрические построения, однако, не могут учесть всех потерь, которые испытывает световой поток при многократных отражениях на поверхностях линз.

…в последнее время неизмеримо возрос поток астрономической информации — во многом благодаря началу работы рекордного по размерам десятиметрового зеркального телескопа имени Кека на Гавайях и запуску на околоземную орбиту космического телескопа Хаббла с зеркалом диаметром 2,4 метра.

Построение изображения в рассеивающей линзе

Чтобы построить изображение предмета в рассеивающей линзе, нужно определить положения точек изображения, соответствующих верхней и нижней точкам предмета. Вот как определить положение точки изображения для верхней точки предмета:

  1. Нужно пустить луч, перпендикулярный главной оптической оси. Этот луч после преломления отклонится. Но его продолжение обязательно пересечет главный фокус линзы.
  2. Нужно пустить луч от верхней точки предмета через оптический центр линзы (построить побочную оптическую ось).
  3. Точку пересечения продолжения луча, полученного в шаге 1, с побочной оптической осью, нужно обозначить за изображение верхней точки предмета (на рисунке это точка А´).

Точно такие же действия нужно выполнить для нижней точки предмета. В результате получится точка пересечения, соответствующая изображению нижней точки предмета (на рисунке это точка А´´).

Внимание! Независимо от расположения предмета относительно рассеивающей линзы, изображение всегда получается прямым, уменьшенным, мнимым. Пример №3

Построить изображение предмета в рассеивающей линзе

Пример №3. Построить изображение предмета в рассеивающей линзе.

Чтобы построить изображение, пустим от верхней точки предмета побочную оптическую ось через оптический центр и проведем перпендикуляр к линзе. Затем из точки главного фокуса проведем луч через точку пересечения линзы с перпендикуляром. Пересечение этого луча с побочной оптической осью есть изображение верхней точки предмета. Теперь проведем от нее перпендикуляр к главной оптической оси. Это и будет являться изображением предмета. Оно является мнимым, уменьшенным и прямым.

Зачем читать эту статью?

  1. Шейдеры. В первых видеопроцессорах алгоритмы были жёстко заданы в «железе», но в современных программист должен писать собственные шейдеры. Другими словами, вам всё равно нужно реализовывать большие фрагменты ПО рендеринга, только теперь оно выполняется в видеопроцессоре.
  2. Понимание. Вне зависимости от того, используете ли вы готовый конвейер или пишете свои шейдеры, понимание того, что происходит за кулисами позволит вам оптимальнее использовать готовый конвейер и писать шейдеры лучше.
  3. Интересность. Немногие области информатики могут похвастаться возможностью мгновенного получения видимых результатов, которые даёт нам компьютерная графика. Чувство гордости после запуска выполнения первого запроса SQL несравнимо с тем, что вы чувствуете в первый раз, когда удастся правильно оттрассировать отражения. Я преподавал компьютерную графику в университете в течение пяти лет. Меня часто удивляло, как мне удавалось семестр за семестром получать удовольствие: в конце концов мои усилия оправдывали себя радостью студентов от того, что они могли использовать свои первые рендеры в качестве обоев рабочего стола.

Сцена

сцену

Часть I: трассировка лучей

обязаныШвейцарский ландшафтГрубая аппроксимация ландшафта

Для каждого пикселя холста
    Закрасить его нужным цветом
Разместить глаз и рамку в нужных местах
Для каждого пикселя холста
    Определить квадрат сетки, соответствующий этому пикселю
    Определить цвет, видимый сквозь этот квадрат
    Закрасить пиксель этим цветом

Основы трассировки лучей

сейчасположением камерыокном просмотра (viewport)областью видимости (field of view)

Разместить глаз и рамку в нужных местах (1)
Для каждого пикселя холста
    Определить квадрат сетки, соответствующий этому пикселю (2)
    Определить цвет, видимый сквозь этот квадрат (3)
    Закрасить пиксель этим цветом (4)

Построение изображения в собирающей линзе

Предметы схематично изображаются в виде стрелки. Чтобы построить изображение предмета в собирающей линзе, нужно найти положение верхней и нижней точки этого изображения. Сначала находят положение точки изображения, соответствующей верхней точки предмета (точки А). Для этого из этой точки нужно пустить два луча:

Два вида лучей при построении изображений в линзе

Первый луч проходит из верхней точки предмета (точки А) параллельно главной оптической оси. На линзе (в точке С) луч преломляется и проходит через точку фокуса (точку F).

Второй луч необходимо направить из верхней точки предмета (точки А) через оптический центр линзы (точку О). Он пройдет, не преломившись.

На пересечении двух лучей обозначаем точку А1. Это и будет изображение верхней точки предмета. Таким же образом нужно поступить с нижней точкой предмета. Но на пересечении вышедших из линзы лучей нужно поставить точку В1. Изображение предмета при этом — А1 В1.

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

Схема построения изображения Расположение предмета относительно линзы + характеристика изображение
Предмет располагается за двойным фокусом. Изображение:
  • уменьшенное;
  • перевернутое;
  • действительное.
Предмет располагается в фокальной плоскости второго фокуса. Изображение:
  • перевернутое;
  • действительное.
Предмет располагается в пространстве между фокусом и двойным фокусом. Изображение:
  • увеличенное;
  • перевернутое;
  • действительное.
Предмет находится в фокальной плоскости. Изображения нет, поскольку лучи идут параллельно друг другу и не пересекаются.
Предмет располагается между линзой и фокусом. Изображение:
  • увеличенное;
  • прямое;
  • мнимое.

Пример №1. Построить изображение предмета, изображенного на рисунке. Определить тип изображения.

Чтобы построить изображение предмета, достаточно определить его положение одной точки — верхней. Поскольку предмет расположен параллельно линзе, для построения изображения, достаточно будет соединить найденную точку изображения для верхней точки предмета перпендикуляром, проведенным к главной оптической оси.

Чтобы построить изображение верхней точки, пустим от нее два луча — побочную оптическую ось через оптический центр и перпендикуляр к линзе. Затем найдем пересечение побочной оптической оси с преломленным лучом. Теперь пустим перпендикуляр к главной оптической оси и получим изображение. Оно является действительным, увеличенным и перевернутым.

Частный случай — построение изображения точки

Положение изображения точки можно найти тем же способом, описанным выше. Нужно лишь построить два луча и найти их пересечение после выхода из линзы (см. рисунок ниже). Так, изображению точки S соответствует точка S´.

Особую сложность составляет случай, когда точка расположена на главной оптической оси. Сложность заключается в том, что все лучи, которые можно построить, будут совпадать с главной оптической осью. Поэтому возникает необходимость в определении хода произвольного луча. Направим луч от точки S (луч SB) к собирающей линзе. Затем построим побочную оптическую ось PQ такую, которая будет параллельна лучу SB. После этого построим фокальную плоскость и найдем точку пересечения (точка С) фокальной плоскости с побочной оптической осью. Теперь соединим полученную точку С с точкой В. Это будет преломленный луч. Продолжим его до пересечения с главной оптической осью. Точка пересечения с ней и будет изображением точки S. В данном случае оно является мнимым.

Пример №2. Построить изображение точки, расположенной на главной оптической оси.

Чтобы построить изображение, пустим произвольный луч к линзе. Затем построим параллельную ему побочную оптическую ось и фокальную плоскость. Из места пересечения этой оси с фокальной плоскостью пустим луч, также проходящий через точку пересечения линзы с произвольным лучом. Построим продолжение луча до получения точки пересечения с главной оптической осью. Отметим точку пересечения — она является действительным изображением точки.

Вопросы по геометрической оптике

Вопрос 1. Сформулируйте закон преломления света.

Ответ. Закон преломления света , или закон Снеллиуса, гласит: падающий и преломлённый лучи и перпендикуляр, проведённый к границе раздела двух сред в точке падения луча, лежат в одной плоскости.

Вопрос 2. Что такое показатель преломления?

Ответ. 

  1. Абсолютный показатель преломления среды показывает, во сколько раз скорость света в данной среде меньше, чем в вакууме.
  2. Отностительный показатель преломления двух сред равен отношению их абсолютных показателей преломления.

Вопрос 3. Какие законы лежат в основе геометрической оптики?

Ответ.

  • закон прямолинейного распространения света;
  • закон независимости световых лучей;
  • закон отражения света;
  • закон преломления света.

Вопрос 4. В чем суть закона независимости световых лучей?

Ответ. Этот закон утверждает, что световые лучи распространяются независимо друг от друга. Другими словами, эффект, производимый отдельным пучком света, не зависит от того, действуют ли одновременно остальные пучки или они устранены.

Вопрос 5. Сформулируйте закон отражения.

Ответ. Закон отражения гласит: отраженный луч лежит в одной плоскости с падающим лучом и перпендикуляром, проведенным к границе раздела двух сред в точке падения, а угол падения равен углу отражения.

Нужна помощь в решении задач? Обращайтесь в профессиональный сервис для студентов в любое время.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
АвтоДиск
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: