Vertex normals after world position offset

I’m performing deformation of the mesh with the help of world position offset with recalculation of normals.
If only Z is changing everything is working fine with good lighting as a result.
But if I’m shifting X or Y also, lighting is completely broken.
For my understanding it is because VertexNormalWS positions are not recalculating

wpo

Is it possible to force to recalculate them or some other method to achieve the result?

Is this any use?

Thank you for your answer
I have seen this video and learned a lot from it, but, unfortunately, it covers only part of my need. As I mentioned if I’m transforming only Z, like in this video, everything work fine. Any additional shifting in X,Y keep old normal positions in world space and break lighting.

1 Like

Is it possible? Probably yes. It depends on how you’re deforming the mesh.
If you’re using math functions, the normal of a curve can be found mathematically also.
Here’s a forum post that discusses solving for the normal of a point on a sine wave, for example.
https://gamedev.net/forums/topic/551569-finding-the-normal-of-a-point-on-a-sine-wave/551569/

“Sine curve is parameterized as (x,sin(x)). A unit-length tangent is (1,cos(x))/sqrt(1+(cos(x))^2) = (tx,ty). A unit-length normal is (ty,-tx).”

In other words, it comes down to solving for the functions tangent, and then rotating the tangent 90 degrees.

Thank you, the problem is different.
I’m able to calculate normal vectors and provide it to normal node of material. The upper picture illustrates that everything is good with it. Tricky things start when I’m shifting whole position of plane by X and Y with world position offset. All my recalculated normals are applied to wrong position of final surface.

Shifting the entire plane flat in XY has no impact on normal direction. Think of a closed book on a table. If you slide it from one end to the other, the cover will still facing up.

I’m guessing you’ve just somehow made the normal adjustment out of phase with the physical displacement and need to also offset the function being used to calculate the normal an equal amount.

Will not work also :frowning:
This is synthetic example just for demonstration. Shifting is not only part of future transformation. When I’m adding scaling the result is worse

Recalculated normals are applied only for area where is intersection of source geometry and final geometry. Then seems tiling.
I want new normarls will be applied for new transformed vertices.
It seems pixel shader doesn’t take in consideration WPO result in a good\correct way

There is nothing wrong with how the engine handles WPO. It is performed on the vertex shader, prior to the pixel shader running.

It’s obvious in your screenshot that the frequency of the sine wave in the normal recalculation is not equal to the frequency in the scaled mesh. You need to scale the wave being used for the normal calculation.

This is exactly I want to achieve - recalculate vertices in vertex shader from source mesh and then apply some function (for example sin) to new ones. I don’t need frequency synchronization, only new positions.

This is an example of sin function which is calculated in world space, two planes with different scaling with WPO

Normals have no position themselves, only direction. In vertex shader we are controlling
calculation of WPO and normals. When we shift vertices and rotate normals, normals stay at old positions, and we could see it at mesh page.
Then I could only suppose that lighting calculations take old position of normals and apply it to new surface.
May be I don’t understand fundamentals or it is impossible to achieve what I want in current implementation of pipeline.

hmm. how you do the normal computation? it could be rather easy just computing a coarse delta with 2 lil offset for both x and y. you gotta run the deform function multiple times but you get normals this way. common technique. good old bump mapping trick before normal maps were a thing. and still used in raymarching.
beep

Normal computation is simple for sin function and problem is not here.
If I’m changing only Z position of the mesh, there is no problem.

Here are world normals view for not scaled mesh and scaled one

Mate, if you used the formula I gave you in my very first reply, you’d be done 2 days ago.

2 Likes

Many thanks for your example and your time.

I’m using the same approach in calculations of normals.
It is good to see that scaling is working in some cases.
In you example sin is calculated based on source geometry and then the result is scaling in all directions proportionally.
I need to separate X,Y scaling and surface calculations. This is still not working.

If not possible, may be there is some other method which will allow dynamically change geometry at shader level in a way which I want to achieve.

It seems very old issue which was described in
Instanced Static Meshes Incorrect Normals when Scaled Non-Uniformly

Right, because UVs are my function input, it automatically scales with the mesh. But even when using any arbitrary input, you can use the object scale as a modifier to the frequency of the function input to proportionally scale it manually. You can see me doing something similar to prevent the scale from increasing the amplitude of the wave.

It’s not a matter of it working in some cases but not others. If you do the necessary math, it will work.

The problem has been solved by setting Shader Offsets parameter of Absolute Word Position node to “Excluding Material Shader Offsets”