SharpGLTF 转 Three.js 材质—— emissive 自发光

215 阅读1分钟

先上结论:

SharpGLTF 中,自发光(emissive)的 Vector3 中数值的取值范围为 0 ~ 1,对应的 Three.js 中的自发光的值为 0 ~ 1。GLTF 中的材质无法影响到 three.js 材质中的 emissiveIntensity 值,始终为默认值 1;

Three.js 中 GLTFLoader 的源码

GLTFLoader 中的转化代码

if ( materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial ) {
  materialParams.emissive = new Color().fromArray( materialDef.emissiveFactor );
}

Color.fromArray 的实现

fromArray( array, offset = 0 ) {

  this.r = array[ offset ];
  this.g = array[ offset + 1 ];
  this.b = array[ offset + 2 ];

  return this;

}

emissiveIntensity 为固定值

material.emissiveIntensity = 1.0;

SharpGLTF 设置 Emissive 的效果

实现方式 1

gltfMaterial.WithEmissive(new Vector3(255, 255, 255), 1f);

生成的 gltf 中的数据:

{
  "name":"wall_outer.001",
  "alphaMode":"BLEND",
  "doubleSided":true,
  "emissiveFactor":[
    1,
    1,
    1
  ],
  "pbrMetallicRoughness":{
    "baseColorFactor":[
      1,
      1,
      1,
      0.699999988079071
    ],
    "baseColorTexture":{
      "index":14
    },
    "metallicFactor":0
  }
}

对应的 Three.js 中的数据

mat.emissive = {r: 1, g: 1, b: 1}
mat.emissiveIntensity = 1;

实现方式 2

将 strength 调整到 100

gltfMaterial.WithEmissive(new Vector3(255, 255, 255), 100f);

生成的 gltf 中的数据:

{
  "alphaMode":"BLEND",
  "doubleSided":true,
  "emissiveFactor":[
    1,
    1,
    1
  ],
  "extensions":{
    "KHR_materials_emissive_strength":{
      "emissiveStrength":100
    }
  },
  "name":"wall_outer.002",
  "pbrMetallicRoughness":{
    "baseColorFactor":[
      1,
      1,
      1,
      0.699999988079071
    ],
    "baseColorTexture":{
      "index":14
    },
    "metallicFactor":0
  }
}

对应的 Three.js 中的数据

mat.emissive = {r: 1, g: 1, b: 1}
mat.emissiveIntensity = 1;

实现方式3

gltfMaterial.WithEmissive(new Vector3(0, 0, 0), 1f);

生成的 gltf 中的数据:

{
  "alphaMode":"BLEND",
  "doubleSided":true,
  "name":"wall_outer.003",
  "pbrMetallicRoughness":{
    "baseColorFactor":[
      1,
      1,
      1,
      0.699999988079071
    ],
    "baseColorTexture":{
      "index":14
    },
    "metallicFactor":0
  }
}

对应的 Three.js 中的效果,自发光颜色变为 0;

mat.emissive = {r: 0, g: 0, b: 0}
mat.emissiveIntensity = 1;

实现方案4

gltfMaterial.WithEmissive(new Vector3(1, 1, 1), 1f);

生成的 gltf 中的数据:

{
  "alphaMode":"BLEND",
  "doubleSided":true,
  "emissiveFactor":[
    1,
    1,
    1
  ],
  "name":"wall_outer.004",
  "pbrMetallicRoughness":{
    "baseColorFactor":[
      1,
      1,
      1,
      0.699999988079071
    ],
    "baseColorTexture":{
      "index":14
    },
    "metallicFactor":0
  }
}

对应的 Three.js 中的数据

mat.emissive = {r: 1, g: 1, b: 1}
mat.emissiveIntensity = 1;

实现方案 5

gltfMaterial.WithEmissive(new Vector3(0.5f, 0.3f, 0.9f), 1f);

生成的 gltf 中的数据:

{
  "alphaMode":"BLEND",
  "doubleSided":true,
  "emissiveFactor":[
    0.5,
    0.30000001192092896,
    0.8999999761581421
  ],
  "name":"wall_outer.005",
  "pbrMetallicRoughness":{
    "baseColorFactor":[
      1,
      1,
      1,
      0.699999988079071
    ],
    "baseColorTexture":{
      "index":14
    },
    "metallicFactor":0
  }
}

对应的 Three.js 中的数据

mat.emissive = {r: 0.5, g: 0.3, b: 0.9}
mat.emissiveIntensity = 1;