2015-03-17 3 views
0

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

Я пытаюсь достичь простого направленного освещения. Вот как это выглядит:

enter image description here

Вот что код вершинного шейдера:

gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition.xyz, 1.0);  
vNormal = vec3(uNMatrix * vec4(aVertexNormal.xyz, 1.0)); 
vColor = aVertexMaterialColor; 

А вот фрагмент кода шейдера:

vec3 light = normalize(vec3(0.5, 0.2, 1.0)); 
float amount = max(dot(vNormal, light), 0.0); 
vec4 finalColor = vColor; 
finalColor.rgb *= amount; 

Проблема заключается в том, что стена с окнами имеет различную полосу, где отдельные треугольники кажутся темнее других. Я не могу контролировать геометрию, которую я получаю, но я верю, что треугольники определены нормально, как и нормали.

uPMatrix - проекционная матрица, uMVMatrix - матрица вида модели, а uNMatrix - нормальная матрица. Вот как нормальная матрица создается (GL-матрица):

var mvMatrix = this.getModelViewMatrix(); 
var nMatrix = this.nMatrix; 

mat4.copy(nMatrix, mvMatrix); 
mat4.invert(nMatrix, nMatrix); 
mat4.transpose(nMatrix, nMatrix); 

Любые идеи, что я могу делать неправильно, или как я могу сделать всю стену плавно затененных?

+0

Похоже на классические артефакты освещения вершин, если вы «* не можете управлять геометрией», вы должны обязательно использовать [для фрагментного освещения] (http://learningwebgl.com/blog/?p=1523) –

+0

Спасибо за ответ. Я посмотрю на ссылку ... – superqd

ответ

0
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition.xyz, 1.0);  
vNormal = vec3(uNMatrix * vec4(aVertexNormal.xyz, 1.0)); 
vColor = aVertexMaterialColor; 
vec3 light = normalize(vec3(0.5, 0.2, 1.0)); 
float amount = max(dot(vNormal, light), 0.0); 
vec4 finalColor = vColor; 
finalColor.rgb *= amount; 

Для того, чтобы треугольник, чтобы иметь некоторое изменение цвета на его поверхности, там должны быть некоторые изменения входного сигнала (ну, или gl_FragCoord, но это в то время как другая вещь), что на самом деле меняется. Так как ваши два varyings vNormal и vColor зависят от двух атрибутов, один из следующих должно быть правдой:

  • aVertexMaterialColor не одинакова для всех трех вершин.
  • aVertexNormal не то же самое для всех трех вершин.

Скорее всего, это нормали; предполагая, что ваша геометрия исходит из файла, либо вы неправильно загрузили нормали (последовательно), либо не указали правильному инструменту моделирования для создания плоских затененных нормалей.

Вот отладки трюк:

finalColor.rgb = vNormal * 0.5 + vec3(0.5); 

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

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

+0

Я очень ценю ваш ответ. Я попробовал технику отладки и получил следующее: http://imgur.com/ftV9MMg Я предполагаю, что «не плоские нормали» означает, что нормали для стены не все указывают в одном направлении? Это означает, что нормали для 3 верт - это не одно и то же ... вы знаете, просто думая об этом вслух (как вы это сформулировали), я думаю, что знаю, где я должен сейчас искать потенциальную проблему (код, который вычисляет нормали, которые I * может * контролировать). – superqd

+0

@superqd Отредактировано немного, чтобы уточнить. –

+0

Я вернулся к коду, который вычисляет нормали, и нашел ошибку. К сожалению, я использую уникальные вершины. Код, который вычислял нормали, был итерированием по индексам и захватом треугольников verts из этого. Но поскольку вершины не дублируются, это означает, что одна и та же вершина может использоваться в более чем одном треугольнике. Это означало, что нормальная для этой вершины изменялась каждый раз. Я сохраняю вершины уникально, чтобы сэкономить место, но мне любопытно, что такое «обычное» решение для этого. Люди обычно просто живут с дублированными вершинами и, как правило, не имеют этой проблемы? – superqd

 Смежные вопросы

  • Нет связанных вопросов^_^