Hello friends, can anyone help me little bit.
Free 3D model Peter the Great hairstyle for download as blend, fbx, obj, and gltf on TurboSquid: 3D models for games, architecture, videos. (2092708)
how to show this “peter 3d model” same as its shows, using .obj and textures.
It showing like this
in below child.name material
‘White_Scarf’
‘Red_Collar’
‘EyeLeft’
‘EyeRight’
‘EyeInternal’
'EyeInternal.
‘PeterHead’
‘Button’
‘Green_Jacket’
‘HairSimple’
‘LashesSimple’
‘BrowsSimple’
‘MoustacheSimple’
i have below textures exist
PEyeMatMask.jpg
PEyeOuterTex.jpg
PHead_Color.png
PHead_Height.png
PIris_texture.jpg
Thanks
<script lang="ts" setup>
import { find } from 'lodash'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'
import { TextureLoader } from 'three/src/loaders/TextureLoader'
const projectStore = useProjectStore()
const container: any = ref(null)
const isFetching = ref(false)
const fetchingPercentage = ref(0)
let renderer: any, camera: any, scene: any
let controls: any
const currentProject = computed(() => projectStore.currentProject)
const getSize = () => {
const width = window.innerHeight * 0.93
const height = window.innerHeight * 0.55
return {
width, height,
}
}
const aspectRatio = computed(() => {
return 9
})
const createRenderer = () => {
const { width, height } = getSize()
renderer = new THREE.WebGLRenderer()
renderer.setSize(width, height)
container.value.appendChild(renderer.domElement)
}
const createCamera = () => {
camera = new THREE.PerspectiveCamera(aspectRatio.value, window.innerWidth / window.innerHeight, 0.5, 1000)
camera.position.z = 5
}
const createScene = () => {
scene = new THREE.Scene()
scene.background = new TextureLoader().load(currentProject.value.default_project_background_attachment[0].image)
const ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.5) // Soft white light
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 1)
directionalLight.position.set(3, 3, 3).normalize() // Adjust position as needed
scene.add(directionalLight)
}
const loadTexture = (texturePath: any) => {
return new Promise((resolve, reject) => {
const textureLoader = new TextureLoader()
textureLoader.load(
texturePath.image,
(texture) => {
resolve(texture)
},
undefined,
(error) => {
console.error('An error happened while loading texture', error)
reject(error)
},
)
})
}
const loadObject = async () => {
const objLoader = new OBJLoader()
objLoader.load(
currentProject.value.three_d_asset_file?.url,
async (object) => {
const box = new THREE.Box3().setFromObject(object)
const center = box.getCenter(new THREE.Vector3())
object.position.sub(center)
if (utils.isEmpty(currentProject.value.three_d_asset_textures_attachment)) {
scene.add(object)
isFetching.value = false
return
}
const textures: any = []
for (const texturePath of currentProject.value.three_d_asset_textures_attachment) {
const model = await loadTexture(texturePath)
textures.push({ model, name: texturePath.media.name })
}
const PEyeMatMask = find(textures, txt => txt.name === 'PEyeMatMask.png')?.model
const PEyeOuterTex = find(textures, txt => txt.name === 'PEyeOuterTex.jpg')?.model
const PHead_Color = find(textures, txt => txt.name === 'PHead_Color.png')?.model
const PHead_Height = find(textures, txt => txt.name === 'PHead_Height.png')?.model
const PIris_texture = find(textures, txt => txt.name === 'PIris_texture.png')?.model
object.traverse && object.traverse((child) => {
if (child instanceof THREE.Mesh) {
if (child.name === 'White_Scarf') {
child.material.map = PEyeMatMask
child.material.needsUpdate = true
}
if (child.name === 'Red_Collar') {
child.material.map = PEyeOuterTex
child.material.needsUpdate = true
}
if (child.name === 'EyeLeft') {
child.material.map = PIris_texture
child.material.needsUpdate = true
}
if (child.name === 'EyeRight') {
child.material.map = PIris_texture
child.material.needsUpdate = true
}
if (child.name === 'EyeInternal') {
child.material.map = PIris_texture
child.material.needsUpdate = true
}
if (child.name === 'EyeInternal.001') {
child.material.map = PIris_texture
child.material.needsUpdate = true
}
if (child.name === 'PeterHead') {
child.material.map = PHead_Color
child.material.needsUpdate = true
}
if (child.name === 'Button') {
child.material.map = PEyeMatMask
child.material.needsUpdate = true
}
if (child.name === 'Green_Jacket') {
child.material.map = PHead_Height
child.material.needsUpdate = true
}
if (child.name === 'HairSimple') {
child.material.map = PHead_Height
child.material.needsUpdate = true
}
if (child.name === 'LashesSimple') {
child.material.map = PEyeOuterTex
child.material.needsUpdate = true
}
if (child.name === 'BrowsSimple') {
child.material.map = PHead_Color
child.material.needsUpdate = true
}
if (child.name === 'MoustacheSimple') {
child.material.map = PHead_Color
child.material.needsUpdate = true
}
}
})
scene.add(object)
isFetching.value = false
},
(xhr) => {
fetchingPercentage.value = Math.round((xhr.loaded / xhr.total) * 100)
},
(error) => {
console.error('An error occurred while loading the OBJ file:', error)
},
)
}
const animate = () => {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
const createControls = () => {
controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.25
controls.enableZoom = true
}
function loadInitialData() {
isFetching.value = true
setTimeout(() => {
createRenderer()
createCamera()
createScene()
loadObject()
createControls()
animate()
}, 300)
}
loadInitialData()
</script>
<template>
<div>
<div ref="container" class="rounded-sm overflow-hidden cursor-grab" />
</div>
</template>
Normally you would use OBJ Loader + MTL Loader + Textures, where MTL file is defining materials and textures used (assuming this MTL file was included with the OBJ file you downloaded).
If you download GLB file of that model and load it in my GLTF Viewer then you can export it to OBJ format which will include MTL file and textures, this way you can inspect the MTL file and see how it’s structured.
You might be better off trying to use GLB file instead of dealing with OBJ. This since GLB file should already include textures and would probably reduce your code by 50%.
1 Like
@KomelAbbas if you decide to stick with OBJ format then try to figure out whether all textures are intended for the map
slot and not individually maybe for metalnessMap
or normalMap
or any other.
Any child material can possibly be using multiple textures in different slots.
1 Like
Thanks @GitHubDragonFly i will try this.
GitHubDragonFly:
GLB
Thank you for the replay
I have tried glb format and look like it resolve most of problem.
but can you let me know why it not showing same as it original form.
const loadObject = async () => {
const loader = new GLTFLoader()
loader.load(
currentProject.value.three_d_asset_file?.url,
(gltf) => {
const box = new THREE.Box3().setFromObject(gltf.scene)
const center = box.getCenter(new THREE.Vector3())
gltf.scene.position.sub(center)
scene.add(gltf.scene)
isFetching.value = false
},
(xhr) => {
fetchingPercentage.value = Math.round((xhr.loaded / xhr.total) * 100)
},
(error) => {
console.error('An error occurred while loading the model:', error)
},
)
}
@KomelAbbas you should try loading that model in my GLTF Viewer to see how it shows there. The viewer has some light, tone mapping and environment controls so try adjusting those to achieve the best look possible.
Also try using other online GLTF Viewers to see if they do a better job in showing that model.
You might just need to add some lights to your code to improve the visual appearance.
1 Like
@KomelAbbas you should also try some other models with your current code.
If any other model shows properly then start questioning the other models.
1 Like
Thank you @GitHubDragonFly and @yesbird
The .glb format works fine after changing some lighting options.
1 Like