Three.js r111 THREE.ShaderLib.cube 统一 tCube 到 envMap 问题

Posted

技术标签:

【中文标题】Three.js r111 THREE.ShaderLib.cube 统一 tCube 到 envMap 问题【英文标题】:Three.js r111 THREE.ShaderLib.cube uniforms tCube to envMap issue 【发布时间】:2020-04-14 17:15:56 【问题描述】:

我正在使用 AFrame 制作 360 度全景查看器,并制作了一个自定义组件以使用立方体贴图作为天空。

具有 6 个立方体面的纹理由 THREE.CubeTextureLoader 加载,然后我执行以下代码。

var shader = THREE.ShaderLib['cube'];
shader.uniforms['tCube'].value = texture;

var skyBoxMaterial = new THREE.ShaderMaterial(
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: shader.uniforms,
    depthTest: false,
    side: THREE.BackSide,
    transparent: true
);

var size = 1000;
var skyBoxGeometry = new THREE.CubeGeometry(size, size, size);

return new THREE.Mesh(skyBoxGeometry, skyBoxMaterial);

它通过 setObject3D 函数返回我在实体上使用的对象。

使用 0.9.2 版的 AFrame(使用 v0.102.2 of Three),这段代码可以完美运行,并且我得到了预期的多维数据集。使用 1.0.1 版(使用 v0.111.5)时,我遇到了一个问题,因为 ShaderLib 已被修改,并且统一的 tCube 不再存在。我看到有一个 envMap 制服显然服务于相同的目的,但是当我在这个属性上设置我的纹理时,我在控制台中得到 WebGLProgram 着色器错误

index.js:27291 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog invalid shaders
THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:308: 'envColor' : undeclared identifier
ERROR: 0:308: '=' : dimension mismatch
ERROR: 0:308: 'assign' : cannot convert from 'const highp float' to 'FragColor mediump 4-component vector of float'

有没有人尝试过同样的问题,或者可以帮助我如何解决它?我需要以不同的方式管理我的纹理,还是有其他方法可以替代对立方体贴图使用着色器?

谢谢!

【问题讨论】:

【参考方案1】:

尝试使用这个 sn-p 增强您的代码:

Object.defineProperty( skyBoxMaterial, 'envMap', 

    get: function () 

        return this.uniforms.envMap.value;

    

 );

顺便说一句:如果您需要天空盒,强烈建议使用Scene.background。在你的情况下:

scene.background = texture;

three.js R111

【讨论】:

谢谢@Mugen87!我只需要从您的代码 sn-p 中删除 .material 以使其工作:) 您能解释一下为什么以前的版本不需要此行吗?我知道scene.background,但它不符合我的需求,因为我想管理场景之间的淡入淡出,它需要我加载2个立方体贴图并在另一个淡入时使一个淡出。 对不起,错字。我已经编辑了答案以更正代码。 three.js 重构了 (PBR) 环境映射的实现方式。立方体着色器实际上是供内部使用的,因此migration guide 中没有明确指出更改。 你好@Mugen87,很抱歉带回这个问题,但现在我在升级 aframe 后发现 R116 有点奇怪。在函数中我做 var shader = Object.assign(, THREE.ShaderLib['cube']); shader.uniforms.envMap.value = 纹理;初始化着色器然后设置纹理,效果很好,但我注意到升级后如果我有两个立方体贴图实例(具有不同的 id 和纹理),它们现在共享相同的纹理,这不是之前的情况。是否存在可以解释这种行为的重大变化? envMap 相关代码发生了变化,但我无法告诉您它如何影响自定义天空盒的使用。有没有机会通过一个现场示例jsfiddle.net/6o28xgkq(可能没有框架)来演示这个问题? 好吧,我没有打扰你,我在编写和阅读 ShaderLib 代码时了解了问题所在。这是引用而不是克隆的问题。我把它修好了,它工作得很好:jsfiddle.net/ty85a4Ln 至少我理解了一些新的东西:) 很抱歉打扰你,谢谢你的帮助!干杯

以上是关于Three.js r111 THREE.ShaderLib.cube 统一 tCube 到 envMap 问题的主要内容,如果未能解决你的问题,请参考以下文章

three.js-001

Three.js开发指南---使用three.js的材质(第四章)

three.js(16)-精灵图

three.js源码目录

three.js简介

three.js 入门详解