Shader-calculated normals

I have a glb animation of a scroll unrolling. It‘s a point level animation that exported from Cinema4D with morph targets.

If I set the flatshading to true, it is perfect except of course the faceted look that goes with flat shading.

Updating the vertex normals does not work. It just displays the normals from the exported animation in its first state, when the scroll is rolled, not unfolded.

How can I make the smooth shader behave like the flat shader in calculating the normals at each animation frame but with smooth shading?

Updating vertex normals does not work due to morph targets. Asking chatgpt to write custom shader resulted only in errors. Only flatshading:true works fine, but I don‘t like the faceted look.

Assuming your model is oriented sensibly and the scroll unrolls smoothly, you might get decent enough results with something like

vec3 currentNormal = normal * rotationMatrix( axis , angle);

Where:

  • axis is the axis you’re unrolling the scroll around
  • angle is the angle to rotate your normal by. It would be obtained by doing some math using the total amount of times the scroll is rolled on itself, and the animation’s progress (between 0 and 1). Something like float angle = lerp( scrollRollCount, 1., animationProgress ) * PI * 2. ;, but then you also have to account for the point’s vertical position on the scroll.
  • rotationMatrix code can be found here

Or you could try to make your life easier by adding a bunch of nulls to your scroll, and make sure they are all perpendicular to it when it’s unrolled, and they behave as though they are stuck on it when it’s rolled - so they’d be physical representation of your normals.
Then at each animation frame, you can easily get the direction they’re pointing in with Object3D.getWorldDirection() , and feed this to your shader through a buffer attribute. You probably don’t want to create one of these ‘normal objects’ for each point of your scroll as that’s a bit overkill, so you could instead just create a few and interpolate values between them.

I’m afraid it’s a bit more complicated - a cloth simulation crumpling nicely at the bottom… but thank you very much for your answer!


Bildschirmfoto 2024-09-29 um 22.05.26

Hmm yeah if it crumbles there’s no reasonably easy solution. Though from what I remember morph targets in THREE.js support morph normals, maybe there’s a way to export these from C4D?