一行代码解决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> ...
随机推荐
- Oracle和达梦:连接多行查询结果
Oracle和达梦:LISTAGG连接查询结果 LISTAGG介绍 使用LISTAGG函数,您可以将多行数据连接成一个字符串,并指定分隔符进行分隔.这在需要将多行数据合并为单个字符串的情况下非常有用, ...
- [ARC143B] Counting Grids 题解
Counting Grids 题目大意 将 \(1\sim n^2\) 填入 \(n\times n\) 的网格 \(A\) 中,对于每个格子满足以下条件之一: 该列中存在大于它的数. 该行中存在小于 ...
- CF1610B [Kalindrome Array]
Problem 题目简述 给你一个数列 \(a\),有这两种情况,这个数列是「可爱的」. 它本身就是回文的. 定义变量 \(x\),满足:序列 \(a\) 中所有值等于 \(x\) 的元素删除之后,它 ...
- Kubernetes: kube-apiserver 之认证
kubernetes:kube-apiserver 系列文章: Kubernetes:kube-apiserver 之 scheme(一) Kubernetes:kube-apiserver 之 sc ...
- Redis项目搭建
Redis项目搭建 Redis下载 搭建redis首先需要下载Redis,可是Redis官方并没有Windows安装,好在网上从不缺大牛,Github上可以找到Redis的Windows版 下载地址: ...
- 持续集成指南:GitHubAction 自动构建+部署AspNetCore项目
前言 之前研究了使用 GitHub Action 自动构建和发布 nuget 包:开发现代化的.NetCore控制台程序:(4)使用GithubAction自动构建以及发布nuget包 现在更进一步, ...
- .NET8 Blazor新特性 流式渲染
什么是SSR Blazor中的流式渲染结合了SSR(服务端渲染),服务端将HTML拼好返回给前端,有点像我们熟知的Razor Pages 或 MVC . 当已经有了 Razor Pages 或 MVC ...
- Vue02-小案例(购物车功能)
效果图 主要代码 index.html <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 【结对作业】第一周 | 学习体会day06
初步做了app的页面 change作为mysql的关键字,不可以作为命名,否则报错 做了两条线路的中转 初步学习了frame标签,打算明天实现页面的部分切换
- springboot的缓存和redis缓存,入门级别教程
一.springboot(如果没有配置)默认使用的是jvm缓存 1.Spring框架支持向应用程序透明地添加缓存.抽象的核心是将缓存应用于方法,从而根据缓存中可用的信息减少执行次数.缓存逻辑是透明地应 ...