pmndrs / gltfjsx

🎮 Turns GLTFs into JSX components
https://gltf.pmnd.rs
MIT License
4.41k stars 290 forks source link

Expose materials attributes/properties / Explode materials #251

Open jo-chemla opened 3 months ago

jo-chemla commented 3 months ago

Hi there, I've tested gltfjsx hoping it would let me do some kind of Level of Detail LOD on my mesh geometries & textures - by chaining multiple Suspense with gradually higher geometry polycount or texture resolution.

My glb scenes are pretty simple, often a single mesh with one or two materials referencing one diffuse/emissive colormap (usually 3d-scan data used as shadeless). Current export therefore looks like below. Since I'd like to load a low-res texture first, then mid-res, then high res async, I think one way to do it would be to declaratively create a meshStandardMaterial which would reference the map as a texture - see the commented-out portions below. To do this, I would edit the component JSX tree myself in order to create that material and set its map by copying the glb material map.

Rather than doing it myself, would it make sense for gltfjsx itself to export the materials within the component tree this way rather than simply exporting nodes and materials? For example via a CLI flag the user could explicitly ask to explode materials and expose material attributes/properties (type/class like meshStandardMaterial or emissive, maps, params etc). Thanks for the feedback!

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.16 input_500k_1x16k_optimized_draco_ktx2.glb -k -m -s 
*/

import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'
// import { TextureLoader } from 'three/src/loaders/TextureLoader'
// import { useLoader } from '@react-three/fiber'

export function Model(props) {
  const { nodes, materials } = useGLTF('/input_500k_1x16k_optimized_draco_ktx2.glb')
  // const colorMap = useLoader(TextureLoader, 'PavingStones092_1K_Color.jpg');
  return (
    <group {...props} dispose={null}>
      <mesh name="Mesh_0_Part_0" castShadow receiveShadow geometry={nodes.Mesh_0_Part_0.geometry} material={materials.default_tex0} />
      // <mesh name="Mesh_0_Part_0" castShadow receiveShadow geometry={nodes.Mesh_0_Part_0.geometry}   >
      //   <meshStandardMaterial map={colorMap} />
      // </mesh>
    </group>
  )
}

useGLTF.preload('/input_500k_1x16k_optimized_draco_ktx2.glb')