You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js加载场景背景图片时如何避免显示灰暗?

问题:Three.js场景背景图片显示灰暗

尝试用TextureLoader加载图片作为Three.js场景背景,但图片始终显示灰暗。按教程操作、克隆教程仓库代码都无法解决,排查了浏览器、图片路径,尝试设置renderer.alpha = true也没用。

完整代码如下:

import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
import * as dat from 'dat.gui'

import nebula from '../img/nebula.jpg'
import stars from '../img/stars.jpg'

const renderer = new THREE.WebGLRenderer();

renderer.shadowMap.enabled = true

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

document.body.appendChild(renderer.domElement)

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
)

const orbit = new OrbitControls(camera, renderer.domElement)

const axesHelper = new THREE.AxesHelper(3)
scene.add(axesHelper)

camera.position.set(30,30,30)
orbit.update()

//Box
//First Phase
const boxGeometry = new THREE.BoxGeometry()
//Second Phase
const boxMaterial = new THREE.MeshBasicMaterial({color:0x00FF00})
//Third Phase
const box = new THREE.Mesh(boxGeometry,boxMaterial)
scene.add(box)

//Plane
const planeGeometry = new THREE.PlaneGeometry(30,30)
const planeMaterial = new THREE.MeshStandardMaterial({
    color: 0xFFFFFF,
    side: THREE.DoubleSide
})
const plane = new THREE.Mesh(planeGeometry,planeMaterial)
scene.add(plane)
plane.rotation.x = Math.PI * -0.5
plane.receiveShadow = true

//Grid Helper
const gridHelper = new THREE.GridHelper(30)
scene.add(gridHelper)

//Sphere
const sphereGeometry = new THREE.SphereGeometry(4,50,50)
const sphereMaterial = new THREE.MeshStandardMaterial({
    color: 0x0000FF,
    wireframe: false
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
scene.add(sphere)
sphere.position.set(-10,10,0)
sphere.castShadow = true

//Ambient Light
const ambientLight = new THREE.AmbientLight(0x333333)
scene.add(ambientLight)

//Directional Light
// const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 0.8)
// scene.add(directionalLight)
// directionalLight.position.set(-30,50,0)
// directionalLight.castShadow = true
// directionalLight.shadow.camera.bottom = -12

// const dLightHelper = new THREE.DirectionalLightHelper(directionalLight,5)
// scene.add(dLightHelper)

// const dLightShadowHelper = new THREE.CameraHelper(directionalLight.shadow.camera)
// scene.add(dLightShadowHelper)

//Spotlight
const spotLight = new THREE.SpotLight(0xFFFFFF)
scene.add(spotLight)
spotLight.position.set(-100,100,0)
spotLight.castShadow = true
spotLight.angle = 0.2

const sLightHelper = new THREE.SpotLightHelper(spotLight)
scene.add(sLightHelper)

//FOG
//scene.fog = new THREE.Fog(0xFFFFFF, 0, 200)

// scene.fog = new THREE.FogExp2(0xFFFFFF, 0.01)
// renderer.setClearColor(0xFFEA00)

//Texture
const textureLoader = new THREE.TextureLoader()
scene.background = textureLoader.load(stars)

// const cubeTextureLoader = new THREE.CubeTextureLoader()
// scene.background = cubeTextureLoader.load([
//     nebula,
//     nebula,
//     stars,
//     stars,
//     stars,
//     stars
// ])

//GUI
const gui = new dat.GUI()
const options = {
    sphereColor : '#ffea00',
    wireframe: false,
    speed: 0.01,
    angle: 0.2,
    penumbra: 0,
    intensity: 1
}

// color gui
gui.addColor(options, 'sphereColor').onChange(function(e){
    sphere.material.color.set(e)
})

// wireframe gui
gui.add(options, 'wireframe').onChange(function(e){
    sphere.material.wireframe = e
})

// speed gui
gui.add(options, 'speed', 0, 0.1)

gui.add(options, 'angle', 0, 0.1)
gui.add(options, 'penumbra', 0, 0.1)
gui.add(options, 'intensity', 0, 1)



//Animation
let step = 0



function animate(time) {
    box.rotation.x = time/1000
    box.rotation.y = time/1000

    step += options.speed 
    sphere.position.y = 10* Math.abs(Math.sin(step))
    
    spotLight.angle = options.angle
    spotLight.penumbra = options.penumbra
    spotLight.intensity = options.intensity
    sLightHelper.update()
    
    renderer.render(scene, camera)

}

renderer.setAnimationLoop(animate)

解决方案

问题出在Three.js版本迭代后的颜色空间处理逻辑,旧教程代码未适配新的颜色空间配置,导致sRGB格式的图片被错误解析为线性颜色空间,最终显示灰暗。以下是具体修复:

1. 为背景纹理设置sRGB颜色空间

普通JPG/PNG图片属于sRGB颜色空间,需显式指定纹理的colorSpace属性:

// 修改Texture加载代码
const textureLoader = new THREE.TextureLoader()
const starsTexture = textureLoader.load(stars)
// 新增颜色空间配置
starsTexture.colorSpace = THREE.SRGBColorSpace
scene.background = starsTexture

2. 配置渲染器输出颜色空间

确保渲染器输出与纹理颜色空间匹配,避免颜色转换偏差:

// 修改渲染器初始化代码
const renderer = new THREE.WebGLRenderer();
// 新增输出颜色空间配置
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.shadowMap.enabled = true

3. 排除其他无效操作

  • 无需设置renderer.alpha = true:该配置用于透明背景,与当前背景纹理显示问题无关
  • 你的代码已注释雾效果,无需额外调整
  • 确认图片路径正确:可通过浏览器控制台网络面板检查图片是否正常加载(状态码200)

内容的提问来源于stack exchange,提问作者Azzumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:02:53