使用具有 0 粗糙度的 GLTF 导出的立方体 原则 BSDF 材料在 Three.js 中无法正确显示

Posted

技术标签:

【中文标题】使用具有 0 粗糙度的 GLTF 导出的立方体 原则 BSDF 材料在 Three.js 中无法正确显示【英文标题】:Cube exported using GLTF with 0 roughness Principled BSDF material doesn't display properly in Three.js 【发布时间】:2021-09-04 03:03:50 【问题描述】:

我的 Blender 材质出现在 three.js 中时遇到了问题。我在 SO 和其他地方经常看到的一个重要细节是 GLTF 格式对在 Blender 中导出节点设置的支持有限,最好坚持使用 Principled BSDF 等基础知识。然而,即使使用基本的 Principled BSDF 设置(如下图所示),创建一个粗糙度为 0 的灰色反射立方体,我在 three.js 中也看不到任何反射(也如图所示)。

这是我的 three.js 场景:

import * as THREE from "three"
import GLTFLoader from "three/examples/jsm/loaders/GLTFLoader.js"
import OrbitControls from "three/examples/jsm/controls/OrbitControls.js"

(async () => 
    const gScene = new THREE.Scene()
    const canvas = document.querySelector("#c")
    const gRenderer = new THREE.WebGLRenderer(canvas)
    const gCamera = new THREE.PerspectiveCamera(50, canvas.clientWidth/canvas.clientHeight, 0.1, 1000)
    gCamera.position.x = 0
    gCamera.position.Y = 100
    gCamera.position.z = 20

    const controls = new OrbitControls(gCamera, canvas)
    controls.target.set(0,5,0)
    controls.update()

    const ambientLight = new THREE.AmbientLight(0xffffff, 40)
    gScene.add(ambientLight)

    const gltfLoader = new GLTFLoader()

    let scene = await new Promise((resolve, reject) => 
        gltfLoader.load('./scene.glb', (loadedGLB) => 
            resolve(loadedGLB.scene)
        )
    )
    gScene.add(scene)

    function resizeRendererToDisplaySize(renderer)
        const canvas = renderer.domElement
        const pixelRatio = window.devicePixelRatio
        const width = canvas.clientWidth * pixelRatio | 0
        const height = canvas.clientHeight * pixelRatio | 0 
        const needResize = canvas.width !== width || canvas.height !== height 
        if (needResize)
            renderer.setSize(width, height, false)
        
        return needResize
    
    function render()
        if(resizeRendererToDisplaySize(gRenderer))
            let canvas = gRenderer.domElement
            gCamera.aspect = canvas.clientWidth/ canvas.clientHeight
            gCamera.updateProjectionMatrix()
        
        gRenderer.render(gScene,gCamera)

        requestAnimationFrame(render)
    
    requestAnimationFrame(render)
)()

混合文件:https://drive.google.com/file/d/1rJXmlKuZsNXl3zRt8YqaB7nUamOfKRw3/view?usp=sharing

【问题讨论】:

【参考方案1】:

您可以通过将 HDR 环境贴图添加到场景中来实现您想要的效果。这个想法是加载相应的纹理,例如通过RGBELoader,使用PMREMGenerator对其进行预处理,然后将其应用于Scene.environment。通过这样做,纹理被设置为场景中所有 PBR 材质的环境贴图。

我建议您查看存储库中的基本 glTF 示例以了解更多详细信息。还要确保使用相同的渲染器配置(意味着确保在 sRGB 颜色空间中工作并使用色调映射)。

https://threejs.org/examples/webgl_loader_gltf

【讨论】:

以上是关于使用具有 0 粗糙度的 GLTF 导出的立方体 原则 BSDF 材料在 Three.js 中无法正确显示的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将 gltf 转换为 dae?

将伪造查看器场景导出到 GLTF

如何在 react-three-fiber 中使用 GLTFExporter 导出多个不同的 3d 场景

Blender 2.79 材料导出到 gltf 失去光泽

处理具有多种顶点格式的 GLTF 节点

dae 到 gltf pbr 导出不导出纹理不是 base64