我一直在研究SDK中Nvidia的示例,尤其是Island11项目,并且我发现了一些对HLSL代码感到好奇的东西,该代码根据波高的状态上下校正反射。
自然地,在检查了简短的代码段之后:
// 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);
我的第一个猜测是,当它受到垂直扰动(波浪)时,它会补偿平面反射,将反射的几何图形移动到一个什么都没有的位置,而水只是像没有东西或只有天空一样被渲染:
现在,那是天空在反射,我们应该看到该地形的绿色/灰色/黄色反射与水线基线相关的地方。我的问题是,现在我无法真正查明其背后的逻辑是什么。投影波浪/水几何图形的一个点的实际世界空间位置,然后乘以-.5f,仅进行同一点的另一个投影,这一次其y坐标更改为-0.8(为什么是-0.8?)。
代码中的线索似乎表明它是通过反复试验得出的,因为存在冗余。例如,作者采用投影的y坐标的负一半(在w除后):
float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;
然后对第二点做同样的事情(我想只是为了肯定,为了得到某种区别),并将它们结合起来:
waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;
通过除以2,我看不出质量改善方面有什么区别(如果有人愿意纠正我,请这样做)。问题的症结似乎是预计y的差异,为什么呢?这种冗余以及-.8f和-0.15f的任意选择使我得出结论,这可能是启发式/猜测式工作的组合。是否有逻辑上的依据,或者只是绝望的破解?
这是代码段修复的初始问题的夸张,在最低细分级别上观察到。希望这可能会引发一个我想念的想法。-.8f可能是一个参考高度,从中可以推断出多少扰动纹理坐标以采样平面反射的几何体渲染,而-.15f可能是下限,这是一种安全措施。