Hello friends, I have created a .glb file using point cloud data and now I am using it to render a model on my website. No matter what I do, and how many lights I add the scene and object remains dark, it is barely visible. I am attaching my code in case anyone wants to have a look. Anything would be helpful!
import * as THREE from 'three';
import { OrbitControls } from 'three-stdlib';
import React, { useRef, useEffect } from 'react';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { Box } from '@mui/material';
interface GLTFViewerProps {
modelPath: string; // Path to the GLTF/GLB file
texturePath: string; // Path to the orthophoto texture (e.g., .jpg or .png)
}
const GLTFViewer: React.FC<GLTFViewerProps> = ({ modelPath, texturePath }) => {
const containerRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
// Initialize Three.js scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.toneMapping = THREE.NoToneMapping; // Disable tone mapping for full brightness
renderer.toneMappingExposure = 2; // Increase exposure for vivid brightness
// Append the renderer canvas to the DOM
if (containerRef.current && !containerRef.current.contains(renderer.domElement)) {
containerRef.current.appendChild(renderer.domElement);
}
// OrbitControls for camera movement
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.screenSpacePanning = false;
const ambientLight = new THREE.AmbientLight(0xffffff, 20); // Brighter ambient light
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 30); // Stronger directional light
directionalLight.position.set(10, 20, 15);
directionalLight.castShadow = true; // Enable shadows if needed
scene.add(directionalLight);
// Add a spotlight to highlight the model
const spotLight = new THREE.SpotLight(0xffffff, 50); // Spotlight with high intensity
spotLight.position.set(15, 30, 10);
spotLight.target.position.set(0, 0, 0); // Point it at the model's center
scene.add(spotLight);
scene.add(spotLight.target);
// Multiple point lights for illumination from all sides
const pointLightPositions = [
[10, 10, 10], // Front-top-right
[-10, 10, 10], // Front-top-left
[10, -10, 10], // Front-bottom-right
[-10, -10, 10], // Front-bottom-left
[0, 10, -10], // Back-top
[0, -10, -10], // Back-bottom
];
pointLightPositions.forEach(([x, y, z]) => {
const pointLight = new THREE.PointLight(0xffffff, 2, 10); // Adjust intensity
pointLight.position.set(x, y, z);
scene.add(pointLight);
});
const hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 10); // Extra bright hemisphere light
scene.add(hemisphereLight);
// Load texture asynchronously
const textureLoader = new THREE.TextureLoader();
textureLoader.load(
texturePath,
(texture) => {
console.log('Texture loaded successfully');
// Load GLTF model once texture is ready
const loader = new GLTFLoader();
fetch(modelPath)
.then((response) => {
if (!response.ok) throw new Error(`Failed to load model: ${response.statusText}`);
return response.arrayBuffer();
})
.then((data) => {
loader.parse(data, '', (gltf) => {
if (gltf.scene) {
gltf.scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
if (child.material instanceof THREE.MeshStandardMaterial) {
child.material.metalness = 0.1; // Slightly metallic
child.material.roughness = 0.8; // More diffuse reflection
child.material.map = texture; // Apply texture
child.material.emissive = new THREE.Color(0x222222); // Add emissive property
child.material.emissiveIntensity = 0.5; // Control emissive intensity
child.material.needsUpdate = true;
}
}
});
gltf.scene.scale.set(0.1, 0.1, 0.1);
const box = new THREE.Box3().setFromObject(gltf.scene);
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.sub(center);
scene.add(gltf.scene);
}
});
})
.catch((error) => console.error('Error loading GLTF model:', error));
},
undefined,
(error) => {
console.error('Error loading texture:', error);
}
);
// Camera position
camera.position.set(0, 0, 10);
(renderer as any).outputEncoding = 3001;
renderer.toneMapping = THREE.ReinhardToneMapping; // Use Reinhard or another tone mapping
renderer.toneMappingExposure = 1.5; // Adjust exposure
// Render loop
const animate = () => {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
// Handle resizing
const onWindowResize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
window.addEventListener('resize', onWindowResize);
// Cleanup
return () => {
window.removeEventListener('resize', onWindowResize);
renderer.dispose();
controls.dispose();
};
}, [modelPath, texturePath]);
return (
<Box
sx={{
width: '100%',
height: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div ref={containerRef} style={{ width: '100%', height: '100%' }} />
</Box>
);
};
export default GLTFViewer;