From 060dbdc7ba63f721e15fcc08c7bac0b8ef17e68c Mon Sep 17 00:00:00 2001
From: Robert Long <robert@robertlong.me>
Date: Wed, 5 Sep 2018 16:27:06 -0700
Subject: [PATCH] Initial pass at MobileStandardMaterial

---
 src/components/gltf-model-plus.js       |  11 ++-
 src/materials/MobileStandardMaterial.js | 110 ++++++++++++++++++++++++
 2 files changed, 118 insertions(+), 3 deletions(-)
 create mode 100644 src/materials/MobileStandardMaterial.js

diff --git a/src/components/gltf-model-plus.js b/src/components/gltf-model-plus.js
index e898bf82a..d3c8b56c0 100644
--- a/src/components/gltf-model-plus.js
+++ b/src/components/gltf-model-plus.js
@@ -1,4 +1,5 @@
 import SketchfabZipWorker from "../workers/sketchfab-zip.worker.js";
+import MobileStandardMaterial from "../materials/MobileStandardMaterial";
 import cubeMapPosX from "../assets/images/cubemap/posx.jpg";
 import cubeMapNegX from "../assets/images/cubemap/negx.jpg";
 import cubeMapPosY from "../assets/images/cubemap/posy.jpg";
@@ -76,7 +77,7 @@ function cloneGltf(gltf) {
 
     cloneSkinnedMesh.bind(new THREE.Skeleton(orderedCloneBones, skeleton.boneInverses), cloneSkinnedMesh.matrixWorld);
 
-    cloneSkinnedMesh.material = skinnedMesh.material.clone();
+    // cloneSkinnedMesh.material = skinnedMesh.material.clone();
   }
 
   return clone;
@@ -256,8 +257,12 @@ async function loadGLTF(src, contentType, preferredTechnique, onProgress) {
 
   gltf.scene.traverse(object => {
     if (object.material && object.material.type === "MeshStandardMaterial") {
-      object.material.envMap = envMap;
-      object.material.needsUpdate = true;
+      if (preferredTechnique === "KHR_materials_unlit") {
+        object.material = MobileStandardMaterial.fromStandardMaterial(object.material);
+      } else {
+        object.material.envMap = envMap;
+        object.material.needsUpdate = true;
+      }
     }
   });
 
diff --git a/src/materials/MobileStandardMaterial.js b/src/materials/MobileStandardMaterial.js
new file mode 100644
index 000000000..1666f8827
--- /dev/null
+++ b/src/materials/MobileStandardMaterial.js
@@ -0,0 +1,110 @@
+const VERTEX_SHADER = `
+#include <common>
+#include <uv_pars_vertex>
+#include <uv2_pars_vertex>
+#include <color_pars_vertex>
+#include <fog_pars_vertex>
+#include <morphtarget_pars_vertex>
+#include <skinning_pars_vertex>
+#include <logdepthbuf_pars_vertex>
+#include <clipping_planes_pars_vertex>
+
+void main() {
+  #include <uv_vertex>
+  #include <uv2_vertex>
+  #include <color_vertex>
+	#include <skinbase_vertex>
+
+  #include <begin_vertex>
+	#include <morphtarget_vertex>
+	#include <skinning_vertex>
+	#include <project_vertex>
+	#include <logdepthbuf_vertex>
+
+	#include <worldpos_vertex>
+	#include <clipping_planes_vertex>
+	#include <fog_vertex>
+}
+`;
+
+const FRAGMENT_SHADER = `
+uniform vec3 diffuse;
+uniform vec3 emissive;
+uniform float opacity;
+
+#include <common>
+#include <color_pars_fragment>
+#include <uv_pars_fragment>
+#include <uv2_pars_fragment>
+#include <map_pars_fragment>
+#include <aomap_pars_fragment>
+#include <emissivemap_pars_fragment>
+#include <fog_pars_fragment>
+#include <logdepthbuf_pars_fragment>
+#include <clipping_planes_pars_fragment>
+
+void main() {
+  #include <clipping_planes_fragment>
+
+  vec4 diffuseColor = vec4(diffuse, opacity);
+  ReflectedLight reflectedLight = ReflectedLight(vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
+  vec3 totalEmissiveRadiance = emissive;
+
+  #include <logdepthbuf_fragment>
+  #include <map_fragment>
+  #include <color_fragment>
+  #include <alphatest_fragment>
+  #include <emissivemap_fragment>
+
+  reflectedLight.indirectDiffuse += vec3(1.0);
+
+  #include <aomap_fragment>
+
+  reflectedLight.indirectDiffuse *= diffuseColor.rgb;
+
+  vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
+
+  gl_FragColor = vec4(outgoingLight, diffuseColor.a);
+
+  #include <premultiplied_alpha_fragment>
+  #include <tonemapping_fragment>
+  #include <encodings_fragment>
+  #include <fog_fragment>
+}
+`;
+
+export default class MobileStandardMaterial extends THREE.ShaderMaterial {
+  static fromStandardMaterial(material) {
+    const parameters = {
+      vertexShader: VERTEX_SHADER,
+      fragmentShader: FRAGMENT_SHADER,
+      uniforms: {
+        uvTransform: { value: new THREE.Matrix3() },
+        diffuse: { value: material.color },
+        opacity: { value: material.opacity },
+        map: { value: material.map },
+        aoMapIntensity: { value: material.aoMapIntensity },
+        aoMap: { value: material.aoMap },
+        emissive: { value: material.emissive },
+        emissiveMap: { value: material.emissiveMap }
+      },
+      fog: true,
+      lights: false,
+      opacity: material.opacity,
+      transparent: material.transparent,
+      skinning: material.skinning,
+      morphTargets: material.morphTargets
+    };
+
+    const mobileMaterial = new MobileStandardMaterial(parameters);
+
+    mobileMaterial.color = material.color;
+    mobileMaterial.map = material.map;
+    mobileMaterial.aoMap = material.aoMap;
+    mobileMaterial.aoMapIntensity = material.aoMapIntensity;
+    mobileMaterial.emissive = material.emissive;
+    mobileMaterial.emissiveMap = material.emissiveMap;
+
+    return mobileMaterial;
+  }
+}
-- 
GitLab