Ho studiato gli esempi di Nvidia dall'SDK , in particolare il progetto Island11 e ho trovato qualcosa di curioso su un pezzo di codice HLSL che corregge i riflessi su e giù a seconda dello stato dell'altezza dell'onda.
Naturalmente, dopo aver esaminato il breve paragrafo del codice:
// 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);
La mia prima ipotesi è stata che compensa la riflessione planare quando è soggetta alla perturbazione verticale (le onde), spostando la geometria riflessa in un punto in cui non c'è nulla e l'acqua viene semplicemente resa come se non ci fosse nulla o solo il cielo:
Ora, quello è il cielo che riflette dove dovremmo vedere il riflesso verde / grigio / giallastro del terreno con la linea di base dell'acqua. Il mio problema è ora che non riesco davvero a individuare quale sia la logica che sta dietro. Proiettando la posizione spaziale mondiale effettiva di un punto della geometria onda / acqua e quindi moltiplicando per -.5f, solo per prendere un'altra proiezione dello stesso punto, questa volta con la sua coordinata y modificata a -0,8 (perché -0,8?).
Indizi nel codice sembrano indicare che è stato derivato con tentativi ed errori a causa della ridondanza. Ad esempio, l'autore prende la metà negativa della coordinata y proiettata (dopo la divisione w):
float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;
E poi fa lo stesso per il secondo punto (solo positivo, per ottenere una differenza di qualche tipo, presumo) e li combina:
waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;
Rimuovendo la divisione per 2, non vedo alcuna differenza nel miglioramento della qualità (se qualcuno si preoccupa di correggermi, per favore fallo). Il punto cruciale sembra essere la differenza nella y proiettata, perché? Questa ridondanza e la selezione apparentemente arbitraria di -.8f e -0.15f mi portano a concludere che questa potrebbe essere una combinazione di euristica / ipotesi di lavoro. C'è una base logica per questo o è solo un hack disperato?
Ecco un'esagerazione del problema iniziale che il frammento di codice risolve, osservando al livello di tassellatura più basso. Spero che possa scatenare un'idea che mi manca. -.8f potrebbe essere un'altezza di riferimento da cui dedurre quanto disturbare la coordinata della trama campionando il rendering della geometria riflessa planare e -.15f potrebbe essere il limite inferiore, una misura di sicurezza.