assignFinalMaterial method
void
assignFinalMaterial(
- Object3D mesh
Assigns final material to a Mesh, Line, or Points instance. The instance already has a material (generated from the glTF material options alone) but reuse of the same glTF material may require multiple threejs materials to accomodate different primitive types, defines, etc. New materials will be created if necessary, and reused from a cache. @param {Object3D} mesh Mesh, Line, or Points instance.
Implementation
void assignFinalMaterial(Object3D mesh) {
final geometry = mesh.geometry;
Material material = mesh.material!;
bool useVertexTangents = geometry?.attributes["tangent"] != null;
bool useVertexColors = geometry?.attributes["color"] != null;
bool useFlatShading = geometry?.attributes["normal"] == null;
if (mesh is Points) {
final cacheKey = 'PointsMaterial:${material.uuid}';
PointsMaterial? pointsMaterial = cache.get(cacheKey);
if (pointsMaterial == null) {
pointsMaterial = PointsMaterial();
pointsMaterial.copy(material);
pointsMaterial.color.setFrom(material.color);
pointsMaterial.map = material.map;
pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
cache.add(cacheKey, pointsMaterial);
}
material = pointsMaterial;
}
else if (mesh is Line) {
final cacheKey = 'LineBasicMaterial:${material.uuid}';
LineBasicMaterial? lineMaterial = cache.get(cacheKey);
if (lineMaterial == null) {
lineMaterial = LineBasicMaterial();
lineMaterial.copy(material);
lineMaterial.color.setFrom(material.color);
cache.add(cacheKey, lineMaterial);
}
material = lineMaterial;
}
// Clone the material if it will be modified
if (useVertexTangents || useVertexColors || useFlatShading) {
String cacheKey = 'ClonedMaterial:${material.uuid}:';
if (material.type == "GLTFSpecularGlossinessMaterial"){
cacheKey += 'specular-glossiness:';
}
if (useVertexTangents) cacheKey += 'vertex-tangents:';
if (useVertexColors) cacheKey += 'vertex-colors:';
if (useFlatShading) cacheKey += 'flat-shading:';
Material? cachedMaterial = cache.get(cacheKey);
if (cachedMaterial == null) {
cachedMaterial = material.clone();
if (useVertexTangents) cachedMaterial.vertexTangents = true;
if (useVertexColors) cachedMaterial.vertexColors = true;
if (useFlatShading) cachedMaterial.flatShading = true;
cache.add(cacheKey, cachedMaterial);
associations[cachedMaterial] = associations[material];
}
material = cachedMaterial;
}
// workarounds for mesh and geometry
if (material.aoMap != null &&
geometry?.attributes["uv2"] == null &&
geometry?.attributes["uv"] != null) {
geometry?.setAttributeFromString('uv2', geometry.attributes["uv"]);
}
// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
if (material.normalScale != null && !useVertexTangents) {
material.normalScale!.y = -material.normalScale!.y;
}
if (material.clearcoatNormalScale != null && !useVertexTangents) {
material.clearcoatNormalScale!.y = -material.clearcoatNormalScale!.y;
}
mesh.material = material;
}