Подтвердить что ты не робот

Three.js: Что такое точное различие между Ламбертом и Фонгом?

Я понимаю разницу между Ламбертом и Фонгом в общей компьютерной графике. Я также понимаю, как мы можем изменить и создать свои собственные материалы, используя three.js. Но я не могу разобраться в различии между MeshLambertMaterial и MeshPhongMaterial в их состояниях по умолчанию.

Я попытался переключить их на сцену с одним направленным источником света и 125 сферами, я не вижу никаких различий. Three.js используется в главе моей книги, поэтому мне нужно убедиться, что все данные точны и точны.

Спасибо, Шейн

4b9b3361

Ответ 1

Я предполагаю, что вам нужна точная разница между MeshLambertMaterial и MeshPhongMaterial, как реализовано в three.js.

Вы должны различать модель затенения и модель освещения. Three.js не реализует "чистые" модели Фонга или Ламберта.

Для MeshLambertMaterial расчет освещенности выполняется в каждой вершине, и полученный цвет интерполируется по поверхности многоугольника. (Зашивка Гуро, (обобщенная) модель освещения Ламберта)

Для MeshPhongMaterial, нормали вершин интерполируются по поверхности многоугольника, а расчет освещенности выполняется на каждом текселе. (Фондовая затенение (обобщенная) модель освещения фонтанов)

Вы увидите явное различие, если у вас есть pointLight, который близок к лицу - особенно если расстояние затухания света меньше расстояния до вершин лица.

Для обоих материалов, в случае FlatShading, нормальная поверхность заменяет каждую нормальную вершину.

three.js.r.66

Ответ 2

Шейн, это не твоя вина, что ты запутался.

Ламберт - это модель освещения (с физической основой) для отраженного от поверхности света, выраженного через входящее направление освещения относительно нормали поверхности в точке падения.

Phong - более тонкая модель затенения (хотя и более хакерская), которая гласит, что свет состоит из окружающих + диффузных + зеркальных компонентов. Он обрабатывает окружающий компонент как постоянный везде (взломать!), Диффузный компонент, используя вышеприведенную модель Ламберта, и зеркальную составляющую с использованием степенного спада (что является умным взломом, примерно приближающим фактические BRDF).

Слово "Phong" также является методом интерполяции (при использовании в контексте современных конвейеров рендеринга на основе треугольника). При расчете освещения в пикселе внутри треугольника у вас есть два варианта:

  • Зарисовка гуру: вычислить цвет в трех вершинах и интерполировать внутри, используя барицентрические координаты или

  • Затенение фонга: используя нормаль в трех вершинах, интерполируйте нормаль внутри и вычисляйте затенение, используя эту интерполированную нормаль на каждом пикселе.

Вот почему (как отметил @RayToal), если ваше зеркальное "выделение" попадает внутрь треугольника, ни одна из вершин не будет яркой, но затенение Фонга будет интерполировать нормальное положение, и будет яркое пятно в интерьере вашего отображаемого треугольника.

Ответ 3

В компьютерной графике очень часто путают модель отражения Phong с затенением Фонга. В то время как первая является моделью локального освещения таких точек, как Ламбертиан, более поздним является метод интерполяции, подобный зашиванию Гуро. Если вам трудно различать их, вот список подробных статей по каждой из этих тем. http://en.wikipedia.org/wiki/List_of_common_shading_algorithms

Ответ 4

Если вы знаете немного GLSL, я думаю, что лучше всего для вас - посмотреть на шейдеры вершин/фрагментов, сгенерированные в обоих случаях, и искать различия. Вы можете использовать http://benvanik.github.com/WebGL-Inspector/, чтобы получить код программ, или поместите console.log() в нужное место в трех источниках js (ищите buildProgram, вы должны вывести prefix_fragment + fragmentShader и prefix_vertex + vertexShader, чтобы увидеть программный код).

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

Ламберт: https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js#L2036 Фонг: https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js#L2157

Это может быть более читаемым, чем просмотр исходного кода программы.