2015-01-13 3 views
2

Я создаю ландшафт с несколькими текстурами, который включает в себя плавные переходы между текстурами, основанные на высоте каждого фрагмента. Вот мой пиксельный шейдер:Опорная текстура мерцания при использовании с mix()

#version 430 

uniform sampler2D tex[3]; 

uniform float renderHeight; 

in vec3 fsVertex; 
in vec2 fsTexCoords; 

out vec4 color; 

void main() 
{ 
    float height = fsVertex.y/renderHeight; 

    const float range1 = 0.2; 
    const float range2 = 0.35; 
    const float range3 = 0.7; 
    const float range4 = 0.85; 

    if(height < range1) 
     color = texture(tex[0], fsTexCoords); 
    else if(height < range2) //smooth transition 
     color = mix(texture(tex[0], fsTexCoords), texture(tex[1], fsTexCoords), (height - range1)/(range2 - range1)); 
    else if(height < range3) 
     color = texture(tex[1], fsTexCoords); 
    else if(height < range4) //smooth transition 
     color = mix(texture(tex[1], fsTexCoords), texture(tex[2], fsTexCoords), (height - range3)/(range4 - range3)); 
    else 
     color = texture(tex[2], fsTexCoords); 
} 

'высота' всегда будет находиться в диапазоне [0,1].

Вот странное мерцание, которое я получаю. Из того, что я вижу, они происходят, когда «высота» равна одной из переменных диапазона N при использовании mix().

flickering

Contours highlighted

Что может быть причиной этого? Я также пытался играть с добавлением и вычитанием переменной «смещения» в некоторых вычислениях, но не повезло.


+0

Я уверен, что оба артефакта происходят на равномерной высоте – Pilpel

+0

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

+0

Спасибо. Можете ли вы представить, что может быть причиной этого? Я все еще не могу понять это ... – Pilpel

ответ

1

Ваша проблема non-uniform flow control. В принципе, вы не можете вызвать texture() внутри if.

Два решения:

  • делают все вызовы текстуры() сначала затем смесь результатов со смесью()
  • вычислить частные производные от координат текстуры (с dFdx & со, есть. пример в ссылке выше) и используйте textureGrad() вместо текстуры()

В очень простых случаях первое решение может быть немного быстрее. Второй - это способ пойти, если вы хотите иметь много текстур (обычные карты и т. Д.). Но не верьте мне на слово, измерьте.