2015-05-26 4 views
-1

Iam пытается создать процедурный водяной лужи в webGL с «водяной рябью» по смещению вершин. Проблема, с которой я сталкиваюсь, заключается в том, что я получаю шум, который я не могу объяснить.WebGL Нормальные вычисления из положения текстуры

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

void main()   {   
      float damping = 0.5; 
      vNormal = normal; 

      // wave radius 
      float timemod = 0.55; 
      float ttime = mod(time , timemod); 

      float frequency = 2.0*PI/waveWidth; 
      float phase = frequency * 0.21; 

      vec4 v = vec4(position,1.0); 
      // Loop through array of start positions 
      for(int i = 0; i < 200; i++){ 

       float cCenterX = ripplePos[i].x; 
       float cCenterY = ripplePos[i].y; 
       vec2 center = vec2(cCenterX, cCenterY) ; 

       if(center.x == 0.0 && center.y == 0.0) 
        center = normalize(center); 

       // wave width 
       float tolerance = 0.005; 

       radius = sqrt(pow(uv.x - center.x , 2.0) + pow(uv.y -center.y, 2.0)); 
       // Creating a ripple 
       float w_height = (tolerance - (min(tolerance,pow(ripplePos[i].z-radius*10.0,2.0)))) * (1.0-ripplePos[i].z/timemod) *5.82; 

       // -2.07 in the end to keep plane at right height. Trial and error solution 
       v.z += waveHeight*(1.0+w_height/tolerance)/2.0 - 2.07; 

       vNormal = normal+v.z; 
      } 
      vPosition = v.xyz; 

      gl_Position = projectionMatrix * modelViewMatrix * v; 
     } 

И первый проход пиксельный шейдер, который пишет в текстуре:

 void main() 
     { 
      vec3 p = normalize(vPosition); 

      p.x = (p.x+1.0)*0.5; 
      p.y = (p.y+1.0)*0.5; 


      gl_FragColor = vec4( normalize(p), 1.0); 
     } 

Вторая вершинного шейдера является стандартным Passthrough.

Второй фрагмент fragmentshader - это то место, где я пытаюсь вычислить нормали, которые будут использоваться для расчета света.

void main() { 

      float w = 1.0/200.0; 
      float h = 1.0/200.0; 

      // Nearest Nieghbours 
      vec3 p0 = texture2D(rttTexture, vUV).xyz; 
      vec3 p1 = texture2D(rttTexture, vUV + vec2(-w, 0)).xyz; 
      vec3 p2 = texture2D(rttTexture, vUV + vec2(w, 0)).xyz; 
      vec3 p3 = texture2D(rttTexture, vUV + vec2(0, h)).xyz; 
      vec3 p4 = texture2D(rttTexture, vUV + vec2(0, -h)).xyz; 

      vec3 nVec1 = p2 - p0; 
      vec3 nVec2 = p3 - p0; 

      vec3 vNormal = cross(nVec1, nVec2); 

      vec3 N = normalize(vNormal); 

      float theZ = texture2D(rttTexture, vUV).r; 
      //gl_FragColor = vec4(1.,.0,1.,1.); 
      //gl_FragColor = texture2D(tDiffuse, vUV); 
      gl_FragColor = vec4(vec3(N), 1.0); 
     } 

Результат таков:

enter image description here

Изображение показывает нормалей и шум я ссылаюсь на это несоответствие синего.

Вот живая демонстрация: http://oskarhavsvik.se/jonasgerling_water_ripple/waterRTT-clean.html

Я ценю любые советы и указатели, не только исправление этой проблемы. Но код в родословной, я здесь, чтобы учиться.

ответ

1

После краткого просмотра кажется, что ваша проблема заключается в хранении позиций x/y.

gl_FragColor = vec4(vec3(p0*0.5+0.5), 1.0); 

enter image description here

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

vec3 p2 = vec3(1, 0, texture2D(rttTexture, vUV + vec2(w, 0)).z); 

Вместо 1, 0 вы хотите использовать шкалу, соответствующую размеру вашего отображаемого четырехъядерных по отношению к высоте волны. В любом случае, результат теперь выглядит следующим образом.

enter image description here

Высота/z кажется, масштабируется по расстоянию от центра, так что я отправился на поиски normalize() и удалить его ...

  vec3 p = vPosition; 
      gl_FragColor = vec4(p*0.5+0.5, 1.0); 

Нормаль выглядеть следующим образом. ..

enter image description here

+0

Ok, спасибо большое за ваше время, то есть именно то, что я искал. Ты спасатель жизни :) Я действительно объясняю объяснение. –

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

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