如何计算照明波的法线?

时间:2015-12-10 18:48:39

标签: directx-11 hlsl

我使用DirectX11对平面进行顶点操作,对于我的照明(具有镜面反射的多点光源)我需要重新计算每个顶点的法线。

我的问题基本上是我用什么方程来得到这个波动方程(在HLSL中)的法线(x& y):

input.position.y = height * sin(input.position.x + time) * sin(input.position.y + time);

1 个答案:

答案 0 :(得分:1)

您需要沿x轴和y轴计算曲面的切线。您可以在顶点着色器中的每个顶点执行此操作。顶点的法线是该顶点处切线向量的叉积。

为了获得切线,您需要计算方程的导数。你的等式是这样的形式:

f(x,y) = a*sin(b*x+t)*sin(c*y+t)

a是波的幅度(或高度),bc是波长或周期,t是波浪相。这种函数的偏导数是:

df/dx = a*b*cos(b*x+t)*sin(c*y+t) // tangent equation along x-axis
df/dy = a*c*sin(b*x+t)*cos(c*y+t) // tangent equation along y-axis

在您的情况下a=heightb=c=1。切线向量为:

tx = [x, y, df/dx] // tangent vector along x-axis at point (x,y)
ty = [x, y, df/dy] // tangent vector along y-axis at point (x,y)

最后,为了计算法线,你可以得到切向量的叉积:

n = cross(tx,ty)

请注意交叉产品的顺序。如果您切换订单,则结果将为-n。评估我们得到的交叉产品:

n = [y*((df/dy)-(df/dx)), x*((df/dx)-(df/dy)), 0]

在上面的向量中替换df/dxdf/dy

k = (a*c*sin(b*x+t)*cos(c*y+t) - a*b*cos(b*x+t)*sin(c*y+t))
n = [y*k, x*(-k), 0]

所以,对于你的等式我们得到:

k = height*(sin(x+t)*cos(y+t) - cos(x+t)*sin(y+t))
n = [y*k, -x*k, 0]

在每个顶点处,当您放入x和y坐标时,您将获得法线向量。由于我的微积分是生锈的,我可能在我的推导中犯了一些错误。但它应该是这些方面的东西。