hello,After I used plan to paste the material picture, the color was distorted

the url : previewer

I did use ”textureLoader.colorSpace=THREE.SRGBColorSpace ;“, but it didn’t work. I don’t know why. Sorry to disturb everyone.

<script type="module">
    import * as THREE from 'three';
    import {OrbitControls} from 'three/addons/controls/OrbitControls.js';

    // 初始化场景、相机和渲染器
    const scene = new THREE.Scene();
    scene.background = new THREE.Color('#F3F4F6');

    const camera = new THREE.PerspectiveCamera(
        60,  // 降低视角,移动端更适合
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    );

    const container = document.getElementById('viewerContainer');
    const renderer = new THREE.WebGLRenderer({antialias: true});
    // 关键修改:设置像素比,解决移动端模糊和尺寸问题
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // 限制最大像素比为2
    renderer.setSize(window.innerWidth, window.innerHeight);
    container.appendChild(renderer.domElement);

    // 初始化控制器(优化移动端体验)
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableRotate = false;
    controls.enablePan = false;
    controls.zoomSpeed = 0.5;
    // 关键修改:适配移动端触摸事件
    controls.touches = {
        ONE: THREE.TOUCH.PAN,
        TWO: THREE.TOUCH.DOLLY_PAN
    };
    controls.enableDamping = true; // 增加阻尼,使触摸更流畅
    controls.dampingFactor = 0.1;

    let initialParams = null;

    // 加载图片
    const textureLoader = new THREE.TextureLoader();
    //
    textureLoader.colorSpace=THREE.SRGBColorSpace ;

    textureLoader.load(
        '<?=$img?>',
        (texture) => {
            // 获取图片原始尺寸(关键:使用naturalWidth/naturalHeight获取真实尺寸)
            const imageWidth = texture.image.naturalWidth;
            const imageHeight = texture.image.naturalHeight;
            const imageAspect = imageWidth / imageHeight;
            const windowAspect = window.innerWidth / window.innerHeight;

            // 计算平面尺寸(为移动端增加安全边距)
            const safetyMargin = 0.9; // 90%的屏幕空间,留10%边距
            let planeWidth, planeHeight;

            if (imageAspect > windowAspect) {
                // 图片更宽,按宽度适配
                planeWidth = 20 * safetyMargin;
                planeHeight = planeWidth / imageAspect;
            } else {
                // 图片更高,按高度适配
                planeHeight = 15 * safetyMargin;
                planeWidth = planeHeight * imageAspect;
            }

            // 创建图片平面
            const geometry = new THREE.PlaneGeometry(planeWidth, planeHeight);
            const material = new THREE.MeshBasicMaterial({
                map: texture,
                side: THREE.DoubleSide
            });

            const imagePlane = new THREE.Mesh(geometry, material);
            scene.add(imagePlane);

            // 计算相机位置
            const fovRadians = THREE.MathUtils.degToRad(camera.fov);
            const cameraZ = (planeHeight / 2) / Math.tan(fovRadians / 2);
            camera.position.z = cameraZ;

            // 存储初始参数用于窗口调整
            initialParams = {
                imageAspect,
                planeWidth,
                planeHeight,
                cameraZ,
                fovRadians
            };

            // 渲染循环
            function animate() {
                requestAnimationFrame(animate);
                controls.update();
                renderer.render(scene, camera);
            }

            animate();

            // 窗口大小调整(优化移动端旋转屏幕适配)
            window.addEventListener('resize', () => {
                if (!initialParams) return;

                renderer.setSize(window.innerWidth, window.innerHeight);

                const newWindowAspect = window.innerWidth / window.innerHeight;
                camera.aspect = newWindowAspect;
                camera.updateProjectionMatrix();

                // 重新设置渲染器尺寸和像素比
                renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

                // 重新计算平面尺寸
                let newPlaneWidth, newPlaneHeight;
                if (initialParams.imageAspect > newWindowAspect) {
                    newPlaneWidth = 20 * safetyMargin;
                    newPlaneHeight = newPlaneWidth / initialParams.imageAspect;
                } else {
                    newPlaneHeight = 15 * safetyMargin;
                    newPlaneWidth = newPlaneHeight * initialParams.imageAspect;
                }

                // 更新平面和相机位置
                imagePlane.geometry.dispose();
                imagePlane.geometry = new THREE.PlaneGeometry(newPlaneWidth, newPlaneHeight);
                camera.position.z = (newPlaneHeight / 2) / Math.tan(initialParams.fovRadians / 2);
            });

            // 关键修复:延迟执行一次resize,解决移动端初始加载尺寸问题
            setTimeout(() => {
                window.dispatchEvent(new Event('resize'));
            }, 100);
        },
        undefined,
        (error) => console.error('图片加载失败:', error)
    );
</script>

instead of

textureLoader.colorSpace=THREE.SRGBColorSpace ;

do
`...(texture) => {texture.colorSpace=THREE.SRGBColorSpace ...

thanks, The box I used before didn’t work, but now it’s changed to plan, and ” texture.colorSpace=THREE.SRGBColorSpace “works.