Оглавление

threejsfundamentals.org

Fix, Fork, Contribute

Отладка Three.js - GLSL

Этот сайт пока не учит GLSL так же, как не учит JavaScript. Это действительно большие темы. Если вы хотите изучать GLSL, рассмотрите эти статьи в качестве отправной точки.

Если вы уже знаете GLSL, вот несколько советов по отладке.

Когда я делаю новый шейдер GLSL, и вообще ничего не появляется, первое, что я делаю, это изменяю фрагментный шейдер, чтобы он возвращал сплошной цвет. Например, в самом низу шейдера я мог бы поставить

void main() {

  ...

  gl_FragColor = vec4(1, 0, 0, 1);  // red
}

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

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

gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1);

Нормали переходят от -1 к +1, поэтому, умножив на 0,5 и добавив 0,5, мы получим значения, которые идут от 0,0 до 1,0, что делает их полезными для цветов.

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

Точно так же, если мы используем текстуры, будут координаты текстуры, и мы можем нарисовать их чем-то вроде

gl_FragColor = vec4(fract(vUv), 0, 1);

fract есть в случае, если мы используем текстурные координаты, которые выходят за пределы диапазона от 0 до 1. Это часто встречается, если для texture.repeat установлено значение больше 1.

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

Чтобы проверить текстуры, попробуйте CanvasTexture или DataTexture, которые, как вы знаете, работают.

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

Я бы сначала посмотрел на матрицы. Я мог бы поставить точку останова сразу после моего вызова renderer.render(scene, camera), а затем начать расширять объекты в инспекторе. Матрица мира и проекционная матрица камеры, по крайней мере, не полны NaN? Расширяя сцену и глядя на ее children, я бы проверил, что мировые матрицы выглядят разумно (без NaN) и последние 4 значения каждой матрицы выглядят разумно для моей сцены. Если я ожидаю, что моя сцена будет иметь размеры 50x50x50 единиц, а некоторые матрицы показывают 552352623.123, то явно что-то не так.

Как и в случае с фрагментным шейдером, мы также можем рисовать значения из вершинного шейдера, передавая их фрагментному шейдеру. Объявите переменные в обоих и передайте значение, которое вы не уверены, правильно. Фактически, если мой шейдер использует нормали, я изменю фрагментный шейдер так, чтобы он отображался так, как указано выше, а затем просто установите для vNormal значение, которое я хочу отобразить, но масштабировать, чтобы значения изменялись от 0,0 до 1,0. Затем я смотрю на результаты и проверяю, соответствуют ли они моим ожиданиям.

Еще одна полезная вещь - использовать более простой шейдер. Можете ли вы нарисовать свои данные с помощью MeshBasicMaterial? Если вы можете тогда попробуйте и убедитесь, что он показывает, как ожидалось.

Если нет, то какой самый простой вершинный шейдер, который позволит вам визуализировать вашу геометрию? Обычно это так же просто, как

gl_Position = projection * modelView * vec4(position.xyz, 1);

Если это работает, начните добавлять изменения постепенно.

Еще одна вещь, которую вы можете сделать, это использовать расширение Shader Editor для Chrome или аналогичное для других браузеров. Это отличный способ посмотреть, как работают другие шейдеры. Это также хорошо, поскольку вы можете внести некоторые из предложенных выше изменений во время работы кода.

Нашли ошибку? Создайте issue на github.
comments powered by Disqus