2014-01-23 7 views
0

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

Это связанная часть моего фрагментарного шейдера. Все вычисления находятся в поле зрения. Я использую направленный солнечный свет.

// samplers 
vec3 normal = texture2D(normals, coord).xyz; 
vec3 position = texture2D(positions, coord).xyz; 
float shininess = texture2D(speculars, coord).x; 

// normalize directional light source 
vec3 source; 
if(directional) source = position + normalize(light); 
else source = light; 

// reflection 
float specular = 0; 
vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 
int power = 5; 
specular = shininess * pow(reflection, power); 

// ... 

// output 
image = color * attenuation * intensity * (fraction + specular); 

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

far highlights are too strong and near highlights disappear

Что я делаю неправильно?

+0

Показать код на стороне клиента, особенно светлые векторы. Убедитесь, что вы не путаете позиции с указаниями. –

+0

Для источников направленного света я рассматриваю положение как направление. Например, солнце имеет положение «0,5, 1,0, 1,5». Это создает проблемы? Тем не менее проблема одинакова для огней направления и точечных огней. – danijar

+1

Недостаточно кода. Покажите, как вы создаете матрицы вида модели. Например, если ваш взгляд на вектор равен x, y, z, 1, это может быть проблема –

ответ

2

Вы вычисляете вектор отражения из положения объекта вместо использования направления инвертированного света (указывающего от объекта к источнику света).

Это как с использованием V вместо L в этой схеме:

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

+0

Спасибо. При использовании 'float reflection = max (0, точка (отражение (нормализация (исходное положение), нормальное), lookat));' больше нет видимых бликов. Когда я умножаю 'specular' на 10, появляется какая-то подсветка, но она по-прежнему дезориентирована. Как я могу еще больше отладить свою проблему? Я знаю, что матрицы правильные, так как диффузное освещение работает с точечными огнями. – danijar

+0

Я думаю, вы должны использовать: specular = pow (отражение, блеск); Кстати, мне также трудно отлаживать шейдеры ... Я обычно делаю «отладку цвета» (то есть: http://en.wikibooks.org/wiki/Cg_Programming/Unity/Debugging_of_Shaders) –

+0

Каким будет диапазон для ' shininess' значит? У меня есть поверхности без зеркального отражения вообще. При установке «блеск» на ноль функция pow станет одной, и она добавится к освещению, а не умножается. Я могу сделать скриншоты отдельных шагов шейдера, напечатанных на экране. Какие этапы были бы полезны? – danijar

1

Я думаю, что имена переменных сбивают вас с толку. Из того, что я читаю (если вы находитесь в пространстве камеры и без Handedness знаний)

vec3 lookat = vec3(0, 0, 1); 
float reflection = max(0, dot(reflect(position, normal), lookat)); 

lookat является направленным светом и position является фактическим lookat.

Удостоверьтесь, что normal (это, вероятно, уже нормализован) и position (lookat) нормализованы.

Менее запутанный код будет:

vec3 light_direction = vec3(0, 0, 1); 
vec3 lookat = normalize(position-vec3(0,0,0)); 
float reflection = max(0, dot(reflect(light_direction, normal), -lookat)); 

Без нормализации position, reflection будет смещен. Уклонение будет сильным, если position находится вдали от камеры vec3(0,0,0)

Отметьте как lookat не является постоянным; он изменяется для каждой позиции. lookat = vec3(0,0,1) смотрит в сторону одного места в пространстве взгляда.

+0

не будет (позиция - vec3 (0, 0,0)) возвращает вектор из «камеры» в точку, когда нам нужен вектор от точки к камере? –

+0

@racarate (position - vec3 (0, 0,0)) - это вектор от камеры к позиции, и это «взгляд». Но вы правы: точка должна находиться между отраженным лучом и вектором от положения, указывающего на камеру (-lookat) –