Contabilización de ondas al hacer reflexiones planas

13

He estado estudiando los ejemplos de Nvidia del SDK, en particular el proyecto Island11 y he encontrado algo curioso sobre un fragmento de código HLSL que corrige los reflejos hacia arriba y hacia abajo según el estado de la altura de la ola.

Naturalmente, después de examinar el breve párrafo del código:

// calculating correction that shifts reflection up/down according to water wave Y position
float4 projected_waveheight = mul(float4(input.positionWS.x,input.positionWS.y,input.positionWS.z,1),g_ModelViewProjectionMatrix);
float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;
projected_waveheight = mul(float4(input.positionWS.x,-0.8,input.positionWS.z,1),g_ModelViewProjectionMatrix);
waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;
reflection_disturbance.y=max(-0.15,waveheight_correction+reflection_disturbance.y);

Mi primera suposición fue que compensa la reflexión plana cuando se somete a una perturbación vertical (las ondas), desplazando la geometría reflejada a un punto donde no hay nada y el agua se representa como si no hubiera nada allí o solo el cielo:

ingrese la descripción de la imagen aquí

Ahora, ese es el cielo que se refleja donde deberíamos ver el reflejo verde / gris / amarillento del terreno con la línea de base del agua. Mi problema ahora es que realmente no puedo determinar cuál es la lógica detrás de esto. Proyectando la posición real del espacio mundial de un punto de la geometría de onda / agua y luego multiplicándolo por -.5f, solo para tomar otra proyección del mismo punto, esta vez con su coordenada y cambiada a -0.8 (¿por qué -0.8?).

Las pistas en el código parecen indicar que se obtuvo con prueba y error porque hay redundancia. Por ejemplo, el autor toma la mitad negativa de la coordenada y proyectada (después de la división w):

float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;

Y luego hace lo mismo para el segundo punto (solo positivo, para obtener una diferencia de algún tipo, supongo) y los combina:

waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;

Al eliminar la división entre 2, no veo diferencia en la mejora de la calidad (si alguien se preocupa por corregirme, por favor hágalo). El quid de la cuestión parece ser la diferencia en la y proyectada, ¿por qué es eso? Esta redundancia y la selección aparentemente arbitraria de -.8f y -0.15f me llevan a concluir que esto podría ser una combinación de heurística / trabajo de conjetura. ¿Hay una base lógica para esto o es solo un truco desesperado?

Aquí hay una exageración del problema inicial que corrige el fragmento de código, que se observa en el nivel de teselación más bajo. Con suerte, podría provocar una idea que me estoy perdiendo. El -.8f podría ser una altura de referencia a partir de la cual deducir cuánto perturbar el muestreo de coordenadas de textura del renderizado de la geometría plana reflejada y -.15f podría ser el límite inferior, una medida de seguridad.

ingrese la descripción de la imagen aquí

CloseReflector
fuente

Respuestas:

1

Es probable que esta técnica tenga este artefacto, y es por eso que la mayoría de las veces cuando se usa, aplicamos un desplazamiento vertical en la búsqueda para hacer como si el plano de reflexión real estuviera medio metro por encima de su posición real. Sí, tiene el inconveniente de no tener un reflejo que coincida perfectamente, pero es preferible a los agujeros.

v.oddou
fuente
2
¿Puedes elaborar más?