Трассировка пути на GPU, часть 1

Железо и рендеринг
Наиболее популярные, на сегодняшний день, архитектуры процессоров — x86-64. Их относят к CISC. Они обладают огромным набором команд, что привело к большой площади ядра на кристалле. Это, в свою очередь, повлекло за собой сложность в реализации нескольких ядер на чипе. Процессоры x86 не идеальны для многопоточных вычислений, где требуются многократное выполнение небольшого набора команд (RISC).
В свою очередь, рендеринг — алгоритм, который отлично распараллеливается практически на неограниченное количество ядер.

Unbiased renders
В виду того, что производительность железа неуклонно растет — технические вопросы (например семплинг отражений материалов в V-Ray, количество биасов при антиалиасинге, размытии в движении, глубине резкости, мягких тенях) все больше переходят на плечи железа. Так, несколько лет назад появился первый коммерческий рендер «без допущений» (unbiased render) — Maxwell Render.
Основным его преимуществом было качество финальной картинки, минимум настроек, всевозможных «биасов». С течением времени качество картинки приближается к «идеальному». А недостатком было и есть — время рендеринга. Ждать, пока шум сойдет, приходилось очень долго, и многие люди после нескольких проб сразу от него отказались. Еще хуже обстояли дела с анимацией (по понятным причинам).

image

Алгоритм
1. Луч (начальная точка, соответствующая определенному пикселю на экране) выпускается из камеры.
2. Проверить, пересек ли луч один из элементов геометрии. Если нет, то перейти к п.1.
3. Определить ближайшую к камере точку пересечения луча и геометрии.
4. Выпустить из точки пересечения новый луч по направлении к источнику света.
5. Если есть препятствие у луча между точкой пересечения и источником света, то перейти к п.7
6. Закрасить пиксель цветом (упрощенно, цветом поверхности в данной точке, умноженной на интенсивность источника света в точке соприкосновения с лучем)
7. Выпустить из точки пересечения новый луч в произвольном направлении, перейти к п.2, пока не достигнуто максимальное количество отражений (в большинстве случаев 4-8, если в сцене много отражений или преломлений — то надо увеличить это число).

image
Пример «шумной» картинки.

Количество выборок на пиксель для достижения хорошего качества может измеряться тысячами. К примеру, 10 тысяч (зависит от сцены)
Количество лучей на изображение FullHD 2мпикс*10тыс — 20 млрд.
Существуют несколько видов оптимизации трассировки пути: Bi-Directional Path Tracing, Metropolis Light Transport, Energy Redistribution Path Tracing, призванные пускать лучи «куда надо». Большинство рендеров на CPU используют для этой цели алгоритм MLT (Maxwell, Fry, Lux)

Роль GPU
В алгоритме многократно используются операции с плавающей точкой, и многопоточность для этого алгоритма жизненно необходима. Поэтому эту задачу постепенно принимается себя GPU.
Существующие технологии: CUDA, FireStream, OpenCL, DirectCompute, а также есть возможность написания программ непосредственно на шейдерах.

image

Ситуация обстоит так:
CUDA – пишут все, кому не лень (iRay, Octane Render, Arion Render, Cycles, etc).
FireStream – вообще ничего не видно.
OpenCL – SmallLuxGPU, Cycles, Indigo Render. Похоже, никто всерьез не принимает.
DirectCompute – ничего не видно.
Шейдеры — только один пример. WebGL реализация трассировки пути на шейдерах.

Сравнение рендеров будет в части 2.
Поделиться публикацией

Комментарии 19

    +6
    Статья, к сожалению, вызывает недоумение, и даже обещание второй части не…

    Ну я думаю вы поняли мысль, как это выглядит. Мысль буквально обрывается на середине.
      +2
      Однако, раз это вызвало такие эмоции, осмелюсь предположить что автор преподносит материал интересно.

      Вторую часть жду Я тоже.
        +1
        Ну автор преподносит мысль «пока непонятно». Материала мало, и он обрывается ровно на том месте, где логично было бы не обрывать. Это же не сериал, а статья, пусть и в нескольких частях.
      +5
      Смутная надежда, — что автор просто вместо «предпросмотр» случайно нажал самую большую «опубликовать» — остается.
        +1
        Очень хотелось поделиться. Признаю, мысль выглядит оборваной.
        У меня уже есть большая часть текста, но нужно провести много тестов. Вот в Cycles нету поддержки физического неба, поэтому сделанные мной тесты «под открытым солнцем» не подходят.
          +1
          Я бы посоветовал писать статью в том стиле, будто бы вам в журнал писать. То есть статья отдельно должна быть цельной, если есть необходимость разделать по частям, то каждая часть — наскольо это возможно — самостоятельная. Вот сейчас есть отличная статья про xneur habrahabr.ru/blogs/linux/132851/, и она по частям, что логично.
            0
            И я честно говоря не понял к чему там картинка приведена? Она как то с текстом не особо вяжется, никак не выделена.

            Я думаю стоит пока убрать, дописать до какого то логического завершения и дать паре людей вычитать. Тогда будет всё ок. Если что, я готов помочь и посоветовать.
        +1
        Концовка статьи немного озадачила:

        CUDA – пишут все, кому не лень (iRay, Octane Render, Arion Render, Cycles, etc).

        Здесь упомянуты 4 производителя, что наталкивает вас на вывод, что «пишут все, кому не лень»

        OpenCL – SmallLuxGPU, Cycles, Indigo Render. Похоже, никто всерьез не принимает.

        Здесь же, наоборот, 3 производителя приводят вас к выводу, что «никто всерьез не принимает».
        Поясните, пожалуйста этот момент.
          0
          Попробую так:

          OpenCL продвигается Intel & AMD
          CUDA только компанией nVidia

          Карты от nV поддерживают OpenCL & CUDA
          Карты от AMD (Intel пропускаю ибо не имел возможности потрогать GPU в Sandy Bridge) поддерживают OpenCL.

          А теперь фокус:

          Шейдерные процессоры в картах nV отлично работают в float, но никакие с integer.
          Stream процессоры от AMD наоборот — для bitcoin mining хорошо, а вот работа с float послабее.

          А т.к для нашей задачи нужны операции с float сильнее то и выбирают язык той конторы, чьи карты шустрее в задачах.
            +1
            Но ведь OpenCL в nVidia реализован поверх CUDA, т.е. практически нет разницы, на чем писать (проигрыш в производительности около 10%, что не критично), всё равно под капотом это будут вызовы CUDA.

            А теперь такой момент: теоретически вы можете переносить код на OpenCL на любые устройства, его поддерживающие (т.к. компиляция kernel в нативный код устройства происходит в рантайме), т.е. если вы пишете рендер на OpenCL, то вы не ограничены каким либо железом (не знаю, как оно на практике).

            Вопрос к знатокам: раз OpenCL — это спецификация, и большинство производителей имеют реализацию этой спецификации, то возможно ли часть работы (в данном случае рендеринга, но это не принципиально) отдавать другим устройствам? Т.е. параллелить работу не только между ядрами GPU, но и между CPU и GPU? Иначе говоря, можно ли в рантайме подсовывать разные реализации OpenCL, на которых будут исполняться kernel'ы?
              0
              На OpenCL не спешат писать из-за сложности этого языка. CUDA намного проще и понятнее. Да и код получается значительно короче.
              В общем, если сравнивать CUDA и OpenCL, то OpenCL — это как реализация многопоточных вычислений с использованием pthreads, а CUDA — с использованием openmp (аналогия, признаюсь, хреновая, но, надеюсь, смысл переносит).
                0
                Да, возможно — тот же самый Cycles от Blender так делает. Только сыровато всё еще.
                0
                >OpenCL продвигается Intel & AMD
                OpenCL продвигается Intel, AMD, NVIDIA. Только фокус последняя делает больше на CUDA, чем на OpenCL. И это именно продвигает, а не поддерживает, т.к. у них довольно быстро появляется поддержка последних стандартов.

                0
                SmallLuxGPU, Cycles — опен сорс, находятся на ранней стадии разработки, и множества нужных функций в них нет. Например в Cycles нету физического неба, свойственного практически всем анбиасам.
                Indigo — коммерческий рендер, однако от его «GPU-ускорения» ни тепло, ни холодно. Прирост скорости очень малозначительный.
                К тому же существует множество CUDA рендеров от любителей, например «шутер от первого лица» в реальном времени.
                Nvidia продвигает свою технологию CUDA. А OpenCL либо не оптимизирован до конца, либо умышленно урезается в производительности.
                Основное направление деятельности ATI — игры. И при большем количестве шейдерных ядер по сравнению с карточками Nvidia (в той же ценовой категории) абсолютно не использует возможность занять рынок вычислений, не связанных с шейдерами для OpenGL или DirectX.
                  0
                  >Nvidia продвигает свою технологию CUDA. А OpenCL либо не оптимизирован до конца, либо умышленно урезается в производительности
                  Ваша неправда. OpenCL — это стандарт, а CUDA собственная разработка — поэтому там проще получить перф, чем через OpenCL.
                +2
                Мда, кармы маловато, ничего больше опубликовать не могу.
                  0
                  Ну держи, ждем продолжения.

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

                Самое читаемое