Основываясь на опубликованном вами коде шейдера, вы не интерполируете UV-координаты из вершин - скорее всего, вы интерполируете трехмерную позицию (fragVert
), а затем вычисляете UV-координаты путем преобразования в сферические координаты.
Ваш анализ верен в том, что наименьшее значение mipmap выбирается при наличии разрыва, поскольку выбор mipmap основан на производных, которые оцениваются численно по UV, используемым в соседних пикселях. Когда один пиксель имеет u = 0, а другой - u = 1, вы получите очень большую производную. Ваша попытка исправить имеет ту же проблему в том, что большие производные встречаются вокруг u = 0,01 и u = 0,99, поэтому два шва появляются по обе стороны от того места, где был первоначальный шов.
Относительно простой подход к решению проблемы состоит в том, чтобы решить, какой уровень MIP использовать самостоятельно, и вызвать textureLod
его напрямую. Если планета всегда будет находиться достаточно близко к камере, вы можете просто жестко закодировать уровень мипа в 0 (или, если уж на то пошло, вообще не включать уровни мипа в текстуру). В противном случае это может быть основано на log2 расстояния точки от камеры, масштабируемого некоторыми подходящими факторами. Обратите внимание, что это эффективно отключит анизотропную фильтрацию.
Более «правильный» подход заключается в расчете некоторых более качественных производных. Вместо использования dFdx
и dFdy
на ультрафиолетовых лучах, которые имеют разрывы из-за atan2
, вы можете применить dFdx
и dFdy
к fragVert
(который будет непрерывным на всем протяжении сферы), затем использовать некоторое исчисление (правило цепочки), чтобы найти формулу для получения производных УФ с позиции производных. Это будет более сложным и медленным, но имеет то преимущество, что анизотропная фильтрация должна работать.
Наконец, поскольку вы новичок в OpenGL, я просто отмечу, что, хотя вычисление UV по сферическим координатам является совершенно правильным способом текстурирования сферы, это не «обычный» способ, который выбирает большинство людей. Чаще всего строят сферическую сетку, в которой для каждой вершины заданы значения UV и просто передаются из вершинного шейдера в пиксельный шейдер (линейно интерполируемый по каждому треугольнику). Вершины располагаются вдоль шва, таким образом , что есть две копии каждой вершины, в точно таких же положениях, но половина с u = 0 соединена с треугольниками на одной стороне, а другая половина с u = 1 соединена с треугольники на другой стороне. Это устраняет любой видимый шов и не требует никаких хитростей в пиксельном шейдере.