threejs 用cubeCamera实现地面反射效果

背景:

Three.js 中,地面反射效果可以通过多种方式实现,常见的有 SSR(屏幕空间反射)、ReflectorCubeCamera。每种方法都有各自的优缺点,下面是它们的介绍和对比:

1. SSR (Screen Space Reflection, 屏幕空间反射)

  • 简介: SSR 是一种基于屏幕空间的反射技术,它通过追踪屏幕上可见像素的路径来实现反射。这意味着它只反射屏幕中已经渲染的部分,能在复杂的场景中生成实时反射效果。
  • 优点:
    • 计算效率相对较高,不需要额外的镜头或几何体。
    • 能产生动态反射,实时反映场景中物体的变化。
    • 适用于复杂几何形状和不规则表面。
    • 适合大规模的动态场景,不需要额外的摄像头来更新反射贴图。
  • 缺点:
    • 只能反射屏幕上可见的物体,超出屏幕边界的内容无法被反射。
    • 反射的物体可能存在失真或错误(尤其是边缘区域)。
    • 不适合处理镜头外的反射效果,比如在场景边缘的反射可能缺失。
    • 依赖屏幕分辨率,因此高分辨率下可能对性能有较大影响。

2. Reflector

  • 简介: ReflectorThree.js 内置的一种镜面效果实现,它通过在场景中创建一个虚拟的镜子对象,并根据摄像机的视角实时渲染该对象的反射。
  • 优点:
    • 实现简单,内置于 Three.js,只需添加 Reflector 对象即可。
    • 能生成精确的反射,包括屏幕外的物体,也可以在场景边缘有良好的反射效果。
    • 适合平面或规则几何体的反射,比如地面、水面、墙壁等。
    • 在特定情况下,能高效地提供高质量的反射。
  • 缺点:
    • 仅适用于平面反射,对于复杂的几何形状或不规则表面难以使用。
    • 需要对反射平面进行单独渲染,因此会增加一定的性能开销。
    • 不适合动态场景中的高频率反射,因为每次视角变化都需要重新渲染反射内容。

3. CubeCamera

  • 简介: CubeCamera 是一种通过六个方向同时渲染场景并生成立方体贴图的方式。它捕捉整个场景并生成一个立方体贴图,可以用于反射和环境映射。
  • 优点:
    • 可以捕捉整个 360° 场景,因此适合处理复杂环境反射,比如球体反射、汽车反射等。
    • 可以反射屏幕外的所有物体,反射内容较为全面。
    • 生成的反射贴图可以用于多种效果(例如环境贴图)。
  • 缺点:
    • 每次反射更新时,摄像机需要渲染六个方向,性能开销较大,尤其是在复杂场景中可能导致帧率下降。
    • 实时反射性能开销高,适合静态或少量更新的场景(例如汽车在静态场景中的反射)。
    • 对于实时动态反射,CubeCamera 的开销远大于 SSR 和 Reflector,实时更新立方体贴图在性能上会有较大影响。

总结:以上都是gpt搜的,可以了解下,下面直接上干货,以下是本人逐项测试后的心得,建议。

想实现地面镜面反射:Reflector

想实现地面渐变模糊,细节反射:SSR (官方demo案例:webgl_postprocessing_ssr)

想实现地面color纹理,渐变模糊,反射等多种复合效果的:CubeCamera

原因:对于美术来说,CubeCamera是作为反射贴图贴入到PBR材质上,所以材质的其他属性都可以混合使用,不需要开发shader或者基于封装好的插件,就可以实现达到想要的效果,简单粗暴。性能来说,静态场景目前测试是以上中最低的,不管帧率和cpu占用都是首选。

CubeCamera具体应用:

	const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(1024, {
		format: THREE.RGBFormat,
		generateMipmaps: true,
		minFilter: THREE.LinearMipmapLinearFilter,
	});
	cubeCamera = new THREE.CubeCamera(0.01, 1000, cubeRenderTarget);
	cubeCamera.lookAt(0, 0, 0);
	scene.add(cubeCamera);
	console.log(cubeCamera, cubeRenderTarget);
	// 渲染循环中添加以下代码
    let tPos = camera.position;
	// 数字部分必须设置反射平面的位置
	cubeCamera.position.set(tPos.x, -0.724 - (tPos.y + 0.724), tPos.z);
	cubeCamera.update(renderer, scene);

踩坑

代码很简单,但是实际应用会有很多坑,小白如果不懂的话,直接复制,改参数,重要是听劝会少走很多弯路

1.cubeCamera.position 的设定的位置一定要用这个计算,只需要找到反射面的模型,取出世界坐标的位置即可,一般是模型师提供,如果自己会三维软件的话可以自己动手获取。一旦这个不对,整个反射上去也对应不上实际场景。

2.平面反射材质,用MeshPhongMaterial,如果用MeshPhysicalMaterial会不清晰,出现模糊,而且这种情况是提高参数不能改善的。以下是本人案例中的,仅供参考。

var plane1_MA = new THREE.TextureLoader().load("./textures/plane2_color.jpg");
var plane1_M = new THREE.MeshPhongMaterial({
  color: 0xffffff,
  map: plane1_MA,
  shininess: 0,
  emissive: 0xffffff,
  emissiveIntensity: 0.1,
  reflectivity: 0.08,
  refractionRatio: 0.98,
  blending: 1,
  blendEquation: 1,
  depthFunc: 3,
  opacity: 1,
  transparent: true,
});

3.材质参数上,如果以上添加好了,还没有看到反射,那需要调试参数,reflectivity 反射度开到1,

envMapIntensity开高,1-5之间测试,正常情况都是可以看到反射效果。

地面反射效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值