flutter3d
Showcase Changelog 38 packages API reference

Stretched highlights

since 0.8.0 Shading and materials

Brushed steel, a vinyl record and the bottom of a saucepan all have fine grooves running one way. A highlight on them is not a round spot: it smears out into a streak across the grooves. The anisotropy layer gives a material that streak without modelling the grooves.

This is a different thing from anisotropic texture filtering, which keeps a texture sharp at a slant and changes nothing about how the surface reflects light.

Step 1: Two materials #

anisotropyStrength is how far the highlight stretches, from nought to one. anisotropyRotation is which way, in radians, turning from the surface's tangent towards its bitangent. Both live in MaterialExtensions, which only LightingModel.pbrLayered reads. The plain material on the left is the same model without them.

final Material plain = Material(
  name: 'plain',
  lighting: LightingModel.pbrLayered,
  baseColor: Vector4(0.8, 0.05, 0.05, 1.0),
  roughness: 0.3,
);
_brushed = Material(
  name: 'brushed',
  lighting: LightingModel.pbrLayered,
  baseColor: Vector4(0.8, 0.05, 0.05, 1.0),
  roughness: 0.3,
  extensions: MaterialExtensions(
    anisotropyStrength: strength,
    anisotropyRotation: rotation,
  ),
);

Step 2: A mesh with tangents #

The stretch runs along the mesh's tangent, so the mesh needs a tangent that means something. Where the tangent lies along the normal there is no direction left to stretch in, and the renderer draws the highlight round.

// A sphere from `SphereShape` carries a tangent at every vertex, running
// around the sphere along its lines of latitude.
final DeviceMesh ball = DeviceMesh.upload(
  context.device,
  SphereShape(radius: 0.5, segments: 48, rings: 24).build(),
);

Step 3: Turn it while it runs #

MaterialExtensions cannot be changed in place, so the page builds a new one each frame from the sliders.

_brushed.extensions = MaterialExtensions(
  anisotropyStrength: strength,
  anisotropyRotation: rotation,
);

Compare the right sphere with the left one: the round spot on the left is drawn out into a band on the right. Drag Rotation to a quarter turn and the band swings round to cross the sphere the other way. Strength at nought gives back the round spot.

Note. glTF can also carry an anisotropy texture that sets the direction per pixel. The engine keeps it so a file saves back unchanged, but does not draw it: the direction comes from the rotation alone.