Three.js: 立方体纹理方向

创建于 2019-04-25  ·  31评论  ·  资料来源: mrdoob/three.js

在我的应用程序中,我想将定义场景背景和环境贴图反射的 CubeTexture 沿垂直 y 轴旋转 180°。
我的旋转由关于背景场的 VRML 和 X3D 规范定义。

我试图修改几个参数,如mappingflipYrotation纹理字段。 但是我没有找到任何好的方法来做到这一点。

  • 有什么明显的方法可以让我错过吗?
  • 有机会在three.js看到这个吗?
  • 如果我想实现它,您希望看到哪些参数(例如Texture.flipXCubeTexture.flipZ )? 你会对这个功能感兴趣吗?
Enhancement

最有用的评论

你的意思是能够旋转scene.background ? 如果是这样......是的,绝对有兴趣。

不过,我们可能需要一个新的 API...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

所有31条评论

你的意思是能够旋转scene.background ? 如果是这样......是的,绝对有兴趣。

不过,我们可能需要一个新的 API...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

我现在正在为此而苦苦挣扎。 试图让烘焙的地面阴影与立方体贴图中的太阳方向相匹配。
我的立方体贴图似乎在某个地方翻转了 180 度。 如果我能在这里解决这个问题,而不是多次重新渲染我的立方体贴图并试图找出发生这种情况的地方,那就太好了。

@fabienrohrer试试

scene.rotation.y = Math.PI;

如果这不起作用,请提供一个活生生的例子来准确地展示你在做什么。

哦,那行得通吗? 😮 相机必须是现场的孩子吗?

相机必须是场景的孩子吗?

我认为这不重要。

@mrdoob这正是我需要的 :-)

@WestLangley

旋转整个场景是过度的,可能会在我的应用程序中导致许多副作用。

我希望只能旋转背景,当然,环境贴图应该以相同的方式工作。

无法进行现场演示,因为缺少 API。 采取任何具有背景立方体贴图的示例(例如 https://threejs.org/examples/#webgl_materials_cubemap)并且能够仅围绕 y 轴旋转背景都是很重要的。 或者更一般地,将任何旋转应用于背景。

能够将自定义旋转矩阵/四元数应用于任何立方体贴图对我来说似乎是最通用的解决方案。

Three.js 小心地确保材质反射与材质envMap一致,材质

为什么不在您的应用程序中创建正确的世界空间立方体贴图?

相机必须是场景的孩子吗?

我认为这不重要。

我尝试在webgl_materials_standard的控制台中执行scene.rotation.y ++并且枪旋转。 然后我尝试做scene.add( camera )然后如果我做scene.rotation.y ++它会做我们想要的,但随后相机控制变得一团糟😁

如果我们引入一个THREE.Background对象,我们可以添加 API 来处理这个,另外在渲染器中我们还可以引入以下想法:

var envMap = material.envMap;
if ( scene.background && scene.background.isBackground && envMap === null ) {
    envMap = scene.background.texture;
}

我说

试试scene.rotation.y = Math.PI; 如果这不起作用,...

这意味着它可能不起作用。 :-)

这取决于用例。 我尝试使用OrbitControls并且效果很好。

无关: webgl_materials_standard示例应该使用轨道控制,无论如何 IMO。

你的意思是能够旋转scene.background? 如果是这样......是的,绝对有兴趣。

在纹理级别执行此操作更有意义,否则我认为任何 IBL 照明都不会与背景匹配。

我们允许旋转普通纹理,有什么理由不想对立方体纹理做同样的事情吗? 实施起来是否太复杂?

为什么不在您的应用程序中创建正确的世界空间立方体贴图?

这是非常耗时的。 在过去的几天里,我一直致力于生成立方体贴图,进行更改然后重新渲染立方体贴图每次更改大约需要 15-20 分钟。

另一个潜在的有趣用例是您可以实时更改环境照明的方向。 我目前正在将 PMREM 环境贴图与实时阴影的定向光相结合,并将该贴图用作天空盒,从而提供相当不错的日光效果。
显然,在不更改环境贴图颜色的情况下,您可以执行的操作是有限的,但是您可以通过在调整.envMapIntensity同时旋转与定向光同步的贴图来模拟至少几个小时的日光通过.

我还关心性能。 目前我实现了一个关于旋转顶部和底部纹理并交换其他纹理的技巧。 在JS中旋转一个1024x1024的纹理大约需要10ms。

或者,是否有可能只有两个 CubeTexture 方向选项,一个是您当前拥有的选项,另一个是(具有 180 度旋转),该选项与主要用于 3D 格式(X3D、VRML 等)的其他标准友好.) 我们可以轻松地调整与材质反射的一致性来处理这两种格式吗?

这听起来很熟悉#11103

如果我要实现CubeMap.rotation = matrix3 ,你会在 r105 中合并吗?

我还关心性能。 目前我实现了一个关于旋转顶部和底部纹理并交换其他纹理的技巧。 在JS中旋转一个1024x1024的纹理大约需要10ms。

您在应用程序中执行此操作的频率如何?

@WestLangley我只是在这里给你一个详细的答案: https :

您在应用程序中执行此操作的频率如何?

不多。 每个客户端加载一次,每次更改背景时一次(非常罕见的情况)。 DEFINE 也可以完成这项工作。

我还关心性能……大约需要 10 毫秒。

您在应用程序中执行此操作的频率如何?

不多。 每个客户端加载一次,每次更改背景时一次(非常罕见的情况)。

对不起,我没有遵循那个逻辑。

不幸的是,由于运行时开销(补充 mat3 乘法), @WestLangley不想合并我对 CubeTexture.rotation 的修改。 在这种情况下,我已经没有想法在 Threejs 中彻底解决这个问题了。
如果threejs贡献者不能解决这个问题,请关闭这个问题。

我等待这个功能的实现。

@FishOrBear不幸的是, threejs维护者决定不实现这一点。 如果你想在你的项目中使用这个未合并的补丁,你可以在 fork 中应用这个未合并的补丁:

https://github.com/mrdoob/three.js/pull/16507

@mrdoob也许我们可以在 #18157 中重新考虑此功能请求?

我是用threejs做一个类似AutoCAD的应用,所以我们用xy来坐飞机。

当前的 CubeTexture 与我们的有点冲突。

顺便说一句:使用 Babylon.js,至少可以围绕 y 轴旋转天空盒:

https://www.babylonjs-playground.com/#UU7RQ #447

引擎通过转换片段着色器中的反射向量来支持这一点。 正是在#16507 中没有接受的方法。 Babylon.js 片段着色器中的代码:

https://github.com/BabylonJS/Babylon.js/blob/1c4627141f83c08fe4a7e30e2621c916b4e6c9c9/src/Shaders/ShadersInclude/reflectionFunction.fx#L114 -L117

@mrdoob我认为我们应该实现这个功能。 论坛里还有一个要求:

https://discourse.threejs.org/t/rotate-a-scenes-background-skybox-texture/12199

我怀疑每个片段的单个额外矩阵/向量乘法会显着影响性能。

我的应用程序中仍然存在同样的问题,解决它的黑客很丑陋而且成本很高......我也建议接受这种改进。

我也很乐意看到添加此功能。

看起来拦截器可能会降低性能,但这应该很容易测试。 我们可以尝试添加它,如果出现无法接受的性能下降,我们可以再次删除它。

同样在这里,可以使用此功能而不是重新实现我的后台渲染:)

我不确定是否会关注性能问题。 没有什么可以阻止我们直接在顶点着色器中生成光线方向? 那么它的成本将与任何其他modelMatrix转换一样多。

就我而言,我可以使用此功能,因为我正在渲染由相机捕获并由用户上传的立方体贴图。 照片并不总是正确地朝北,因此上传后需要手动更正。

我这样做的一种方法是将旋转存储为变量,在渲染之前将其应用于场景,然后在渲染之后将场景的旋转重置为恒等式。

这会导致对我所有场景对象的世界矩阵进行两次不必要的更新。 这也意味着我无法在 onBeforeRender 中进行任何位置更新。 但否则它会将场景保持在正常状态。

顺便说一句(因为没有人提到它),似乎可以使用 6 种材料的阵列来制作一个“经典”的天空盒。

像这样:

const urls = [
  '/assets/skybox/right.png',
  '/assets/skybox/left.png',
  '/assets/skybox/top.png',
  '/assets/skybox/bottom.png',
  '/assets/skybox/front.png',
  '/assets/skybox/back.png',
];

const materials = urls.map((url) => {
  const texture = new THREE.TextureLoader().load(url);

  return new THREE.MeshBasicMaterial({
    map: texture,
    side: THREE.BackSide,
    fog: false,
    depthWrite: false,
  });
});

const skybox = new THREE.Mesh( new THREE.BoxBufferGeometry(10000, 10000, 10000), materials );
scene.add(skybox);

skybox.rotation.y = Math.PI / 2;

如此处所示: https :

@wmcmurray你必须用相机移动这个天空盒以使其正常工作,你必须确保你的盒子尺寸 X < Math.sqrt(0.75 * camera.far * camera.far) 所以角落总是适合视图,但这似乎比我旋转/不旋转场景的技巧更容易。

我们应该为此重新打开 PR 吗? 有两个用例,如果我们不想影响性能,我们可以使用着色器定义:

  • 用例 1:环境预先计算一次,不需要在着色器中旋转。 这可以由用户在 CPU 上完成,如果他愿意,甚至可以在 GPU 上完成
  • 用例 2:在查看器上工作时,使用鼠标实时旋转背景是很常见的。

为了防止用例 1的用户受到矩阵乘法的影响,也许我们可以简单地添加一个标志,如:

renderer.dynamicBackground = true;

并相应地编译背景着色器?

同时

正如@wmcmurray@capnmidnight 所指出的,您基本上可以重新编码自己的背景渲染,这并不难。 只是要格外小心观察平面(近和远值)。

除了使用MeshBasicMaterial ,您还可以直接创建自己的着色器扩展ShaderMaterial并对立方体贴图进行采样。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

filharvey picture filharvey  ·  3评论

clawconduce picture clawconduce  ·  3评论

fuzihaofzh picture fuzihaofzh  ·  3评论

donmccurdy picture donmccurdy  ·  3评论

konijn picture konijn  ·  3评论