animationTextureNormal

@three-blocks/coreWebGPUWebGL
animationTextureNormal(textureNode : Node, frameIndex : Node<int>, framesCount : Node<int>, timeInterpolation : Node<float>, textureOffset : Node<int>, idIndex : Node<int>) : Node<vec3>

Sample transformed normal from a baked animation texture. Correctly handles non-uniform scaling by normalizing the basis vectors.

Algorithm

  • Retrieves transformation matrix via {@link animationTextureMatrix}
  • Extracts 3×3 rotation/scale basis from mat4
  • Computes per-axis scale factors via dot products
  • Divides normal by scale factors before matrix multiplication
  • Returns properly transformed normal vector

Technical Details

  • Handles non-uniform scaling correctly (unlike naive normal transformation)
  • Renormalization prevents lighting artifacts on scaled geometries
  • Compatible with both VAT (vertex normals) and OAT (instance normals)
Parameters
textureNodeNode
Baked animation texture.
frameIndexNode<int>
Current frame index.
framesCountNode<int>
Total frame count.
timeInterpolationoptionalNode<float>
Interpolation factor [0..1].
Default is 0.
textureOffsetoptionalNode<int>
Offset in the texture for packed animations.
Default is 0.
idIndexoptionalNode<int>
Vertex or instance index.
Default is vertexIndex.
Returns
Node<vec3> — Transformed normal.
See also
Example
import { AnimationBakeMixer, animationTextureNormal } from '@three-blocks/core';
import { MeshStandardNodeMaterial, instanceIndex } from 'three/tsl';

// Using AnimationBakeMixer (recommended - sets both position and normal)
const mixer = new AnimationBakeMixer(texture, { mode: 'object', fps: 60 });
mixer.registerMaterial(material);

// Manual node material setup
const material = new MeshStandardNodeMaterial();
material.normalNode = animationTextureNormal(
  texture,
  frameUniform,
  framesCountUniform,
  interpolationUniform,
  textureOffsetUniform,
  instanceIndex  // Use instanceIndex for OAT, vertexIndex for VAT
);