В OpenGL 2.1 я передаю позицию и вектор нормали в свой вершинный шейдер. Затем вершинный шейдер устанавливает varying
вектору нормали, так что теоретически он линейно интерполирует нормали по каждому треугольнику. (Что, как я понимаю, является основой затенения Фонга.)
Во фрагментном шейдере я использую нормаль с законом Ламберта для расчета диффузного отражения. Это работает, как и ожидалось, за исключением того, что интерполяция между вершинами выглядит забавно. В частности, я наблюдаю эффект звездообразования, когда по краям между вершинами есть заметные «горячие точки».
Вот пример, не из моей собственной визуализации, но демонстрирующий точно такой же эффект (см. золотую сферу внизу страницы): http://pages.cpsc.ucalgary.ca/~slongay/pmwiki-2.2.1/pmwiki.php?n=CPSC453W11.Lab12 а>
Википедия говорит, что это проблема с затенением Горо. Но насколько я понимаю, интерполируя нормали и выполняя пофрагментный расчет освещения, я использую модель Фонга, а не Гуро. Это правильно?
Если бы я использовал гораздо более мелкую сетку, я полагаю, что эти звездообразования были бы гораздо менее заметны. Но является ли добавление большего количества треугольников единственным способом решить эту проблему? Я бы подумал, что есть способ получить плавную интерполяцию без эффекта звездообразования. (Я определенно видел идеально гладкое затенение на грубых сетках в других местах, например, в 3d Studio Max. Но, возможно, они делают что-то более сложное, чем просто интерполяция нормалей.)