Disclosure: cross-posted on Unreal Answers, thought was sufficiently general for GameDev.SE
I am currently rendering a displacement texture and, separately, a normal texture for my ocean. Is there a clever way where I can actually just compute the normal in the final material. I.E. the un-displaced normal is (0, 0, 1) then by using perhaps ddx/ddy work out the real normal? It seems like this question is trying a similar thing. I don't really understand the ddx/ddy nodes/functions but they seem at least related.
Using the ddx, ddy nodes what I tried was computing for each given point:
dx = ddx(WorldPosition.x)
dy = ddy(WorldPosition.y)
dz/dx = ddx(height) / dx
dz/dy = ddy(height) / dy
Then I used these values to rotate my base normal of (0, 0, 1) to the final normal. It kinda looks like I'm on the right track but I not 100% calculation at a couple of points. Further, it isn't quite right as the normal appears to change as I move the camera around (using the world normal buffer visualisation).
Calculation:
let Tan(theta) = dz / dx
let Tan(phi) = dz / dy
Then plugging these values into the rotation matrix R_theta, R_phi:
\$R_\theta=\begin{pmatrix} 1 & 0 & 0 \\ 0 & cos(\theta) & -sin(\theta) \\ 0 & sin(\theta) & cos(\theta) \\ \end{pmatrix} R_\phi=\begin{pmatrix} cos(\phi) & 0 & sin(\phi) \\ 0 & 1 & 0 \\ -sin(\phi) & 0 & cos(\phi) \\ \end{pmatrix}\$
I compute theta and phi by applying atan to dz/dx and dz/dy respectively.
Finally multiplying R_thea * R_phi * n to get:
sin(phi)
-sin(theta)cos(phi)
cos(theta)cos(phi)
Is what I am trying to do possible and what am I doing wrong? Specifically:
- Am I using the ddx, ddy nodes correctly to compute the change in height over x and y
- How come the normal appears to change as I move the camera
- Does the fact there is horizontal displacement in my ocean matter