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