# Shader-calculated normals

**URL:** <https://discourse.threejs.org/t/shader-calculated-normals/72108>\
**Category:** Questions\
**Created:** [September 29, 2024, 2:48pm UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108 "2024-09-29T14:48:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![carstenmell](https://avatars.discourse-cdn.com/v4/letter/c/41988e/32.png) [@carstenmell](https://discourse.threejs.org/u/carstenmell)\
**Post date:** [September 29, 2024, 2:48pm UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108/1 "2024-09-29T14:48:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Arthur](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/arthur/32/22954_2.png) [@Arthur](https://discourse.threejs.org/u/Arthur)\
**Post date:** [September 29, 2024, 5:02pm UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108/2 "2024-09-29T17:02:46Z")

</div>

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](https://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/)

---

<div class="post-metadata">

**Author:** ![Arthur](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/arthur/32/22954_2.png) [@Arthur](https://discourse.threejs.org/u/Arthur)\
**Post date:** [September 29, 2024, 5:06pm UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108/3 "2024-09-29T17:06:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![carstenmell](https://avatars.discourse-cdn.com/v4/letter/c/41988e/32.png) [@carstenmell](https://discourse.threejs.org/u/carstenmell)\
**Post date:** [September 29, 2024, 8:08pm UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108/4 "2024-09-29T20:08:03Z")

</div>

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.36](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/8/081ba9b5ae6c7a073007c713679193b44dab0bcb.jpeg)  
 ![Bildschirmfoto 2024-09-29 um 22.05.26](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/9/a/9a660d47eb707d858519fdc1973d8cee746a71ae.png)

---

<div class="post-metadata">

**Author:** ![Arthur](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/arthur/32/22954_2.png) [@Arthur](https://discourse.threejs.org/u/Arthur)\
**Post date:** [September 30, 2024, 9:28am UTC](https://discourse.threejs.org/t/shader-calculated-normals/72108/5 "2024-09-30T09:28:20Z")

</div>

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?
