一行代码解决Three.js中只能在一侧看到物体的问题
项目场景:
因为该项目比较复杂庞大,在此就简单介绍一下:
通过Three.js创建若干个物体进行了组装,从而形成了一个类似眼球模拟模型的项目,用户可以通过拖动鼠标来达到控制视角(摄像机)的目的,以此来观察整个眼球状态。

Image1 Three.js眼球模型
注:下面所说的正视为从红线正轴往瞳孔(黑色圆形)看去的视角,左视为从蓝线正轴往负轴看去,右视则与其相反
问题描述
左视该眼球可以看到红色的圆形平面,但是左视则发现红色平面消失。

Image2 左视可以正常看到红色的圆形

Image3 右视发现红色圆形消失
创建外部白色球体、内部蓝色不规则球体、红色平面代码:
createSphere() {
const radius = 2.2;
const outerGeometry = new THREE.SphereGeometry(radius, 120, 120);
const outerMaterial = new THREE.MeshPhongMaterial({
color: 0xffffff, // 定义外部的球为白色
transparent: true,
opacity: 0.6, // 降低不透明度以减少反射
metalness: 0.5,
roughness: 0.3,
});
const outerSphere = new THREE.Mesh(outerGeometry, outerMaterial);
// 创建一个具有水平曲面的不完全球体
const waterSurfaceGeometry = new THREE.CircleGeometry(radius - 0.1)
const innerGeometry = new THREE.SphereGeometry(
radius - 0.1,
240,
240,
0,
2 * Math.PI,
Math.PI,
Math.PI / 2
);
const innerMaterial = new THREE.MeshPhongMaterial({
color: 0x02c0f5, // 定义内部的球体为蓝色
opacity: 1,
metalness: 0.5,
roughness: 0.3,
});
const waterSurfaceMaterial = new THREE.MeshPhongMaterial({
color: 0xf60404, // 定义去曲面水面为红色
opacity: 1,
transparent:false, // 设置成不透明
metalness: 0.5,
roughness: 0.3,
});
const innerSphere = new THREE.Mesh(innerGeometry, innerMaterial);
const waterSurface = new THREE.Mesh(waterSurfaceGeometry, waterSurfaceMaterial)
innerSphere.scale.set(1, 1, 1);
innerSphere.add(waterSurface)
this.outerSphere = outerSphere;
this.innerSphere = innerSphere;
const sphereGroup = new THREE.Group();
sphereGroup.add(outerSphere);
sphereGroup.add(innerSphere);
this.sphere = sphereGroup;
this.innerSphere = innerSphere;
return sphereGroup;
},
原因分析:
- 材质透明度问题:通过调整内部圆形的材质透明度,使其更透明,这样可以确保在摄像机视角不理想的情况下仍然能够看到内部。
- 光照效果:通过调整光照效果,可以改变内部圆形的明暗度,使其更加清晰可见。
- 内部圆形的尺寸:通过调整内部圆形的尺寸,使其在不同视角下都能够完整显示。
- 摄像机位置:确保摄像机的位置不会完全遮挡要显示的内容。可以尝试将摄像机向后移动或调整其位置,使其不会完全遮挡内部的圆形。
很明显,上面四种解决方案都不可行,首先红色平面的transparent属性为false,并且不透明度也为1;其次肯定不是光照问题,因为白色外部球体和蓝色内部球体都能正常显示;最后更不是摄像机位置问题,无论怎么调整方位都不能显示出红色圆形。
解决方案:
因此我们需要使用双面渲染,双面渲染能够确保从内部看到外部的表面。默认情况下,Three.js 只会渲染面的正面,通过启用 side: THREE.DoubleSide 可以使其渲染双面。
所以我们只需要在上面的代码中添加一行就能解决这个问题。
const waterSurfaceMaterial = new THREE.MeshPhongMaterial({
color: 0xf60404, // 定义去曲面水面为红色
opacity: 1,
transparent:false, // 设置成不透明
metalness: 0.5,
roughness: 0.3,
side: THREE.DoubleSide // 允许双面渲染
});
最后我们来看看效果!!

Image4 右视能够正常看到红色平面
一行代码解决Three.js中只能在一侧看到物体的问题的更多相关文章
- 一行代码解决ie6,7,8,9,10兼容性问题
"浏览器模式"."文档模式"选项的区别如下: 1."浏览器模式"用于切换IE针对该网页的默认文档模式.对不同版本浏览器的条件备注解析.发送给 ...
- 一行代码解决各种IE的兼容问题
一行代码解决各种IE的兼容问题 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 < ...
- 一行代码在 .NET Core 中快速使用 log4net
原文:一行代码在 .NET Core 中快速使用 log4net 1. .NET Core 控制台程序中使用 第一步:添加引用 Install-Package log4net 第二步:将附件 LogH ...
- js一行代码解决各种IE兼容问题
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实 IE给出了解决方案 Google也给出了解决方案 百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 <!Doctype html ...
- 一行代码解决JS数字大于2^53精度错误的问题
服务端使用长整型(Int64)的数字,在浏览器端使用JS的number类型接收时,当这个实际值超过 (2^53-1)时,JS变量的值和实际值就会出现不相等的问题.常见场景比如使用雪花算法生成Id. 在 ...
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 2012-04-25 16:29:04| 分类: 学习 |字号 订阅 在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE ...
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 http://www.jb51.net/css/383986.html
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 复制代码 代码如下: <!Do ...
- 怎么用一行代码解决CSS各种IE各种兼容问题
用一行代码来解决CSS在,IE6,IE7,IE8,IE9,IE10 中的各种兼容性问题. 在网站前端写代码的过程中,很多时间IE各个版本的兼容问题很难整.现在百度与谷歌都有了一行解决这种兼容性的代码了 ...
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10(转)
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 <!Doctype html&g ...
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10(转载)
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 <!Doctype html> ...
随机推荐
- How can I access GPT-4?
How can I access GPT-4? Written by Joshua J.. Updated over a week ago API Access Most users will n ...
- Robert Kiraly Software Developer
Robert KiralySoftware DeveloperCell Phone: 650-600-2520 Freenode: ##venturesSupports text messages P ...
- 一个vuepress配置问题,引发的js递归算法思考
前言 这两天在尝试用语雀+ vuepress + github 搭建个人博客. 小破站地址 :王天的 web 进阶之路 语雀作为编辑器,发布文档推送 github,再自动打包部署,大概流程如下. 问题 ...
- 【luogu题解】T378828 位运算
位运算 题目背景 题目由 daiyulong20120222 创作(me) 并由 QBW1117完善以及数据 . 题目描述 给定两个数\(x,y\) ,在给定一个位运算符号 \(c\). 请你列出 \ ...
- Stable Diffusion扩散模型
人像生成模型 1.模型理论基础 扩散模型(Diffusion Model): 1.1 Diffusion Model 原理 首先,Denoise Model 需要一个起始的噪声图像作为输入.这个噪声图 ...
- MNIST中文手写数字数据识别
MNIST中文手写数字数据识别 实验环境 python=3.7 torch==1.13.1+cu117 torchaudio==0.13.1+cu117 torchvision==0.14.1 数据描 ...
- Quartz核心原理之架构及基本元素介绍
1 什么是Quartz Quartz是一个作业调度框架,它可以与J2EE和J2SE应用相结合,也可以单独使用.它能够创建多个甚至数万个jobs这样复杂的程序,jobs可以做成标准的java组件或EJB ...
- localhost工具:本地代码的远程之路
在日常的开发过程中,本地代码远程调试一直是最理想的开发状态.本文通过介绍京东集团内开发的一个轻量简单的小工具"localhost",从多角度的方案思考,到原理介绍,到最终的方案落地 ...
- vertx的学习总结1
一. vertx是什么? 答:lib工具包 二. 为什么要使用vertx 答: 异步和非阻塞:Vert.x 采用了事件驱动和非阻塞的编程模型,可以处理大量并发请求而不会阻塞线程,提供更好的响应 ...
- 拖.sql文件到cmd中运行
这个非常简单,但是网上说的又不清楚. 第一步cmd中进入数据库 其操作是 mysql -u root - p 密码: 第二步使用数据库 其操作是use 数据库名字: ...