You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Three Fiber:如何仅高亮对象数组中选中的模型

React Three Fiber 单模型高亮解决方案

核心问题分析

你当前的实现思路错误在于:postprocessing的enabled属性是控制整个效果的全局开关,无法实现局部模型过滤。要仅高亮选中模型,必须通过掩码渲染分层或模型材质动态修改两种方式实现。


方案一:基于MaskPass的后期处理高亮(推荐)

利用Three.js的掩码通道,仅对选中模型区域应用高亮效果:

1. 给模型标记选中状态与图层

确保每个模型有唯一ID,绑定选中事件并设置专属图层:

import { cloneElement } from 'react';
import { useStore } from './your-zustand-store';

function ModelRenderer() {
  const { activeModules, selectedModule, setSelectedModule } = useStore();

  return (
    <>
      {activeModules.map((module) => {
        const isSelected = selectedModule?.id === module.id;
        return cloneElement(module.jsx, {
          // 选中模型放到图层1,其余在默认图层0
          layers: isSelected ? 1 : 0,
          // 绑定交互事件
          onPointerOver: () => setSelectedModule(module),
          onContextMenu: (e) => {
            e.preventDefault();
            setSelectedModule(module);
          },
        });
      })}
    </>
  );
}

2. 配置EffectComposer的分层渲染通道

import { useThree, useFrame } from '@react-three/fiber';
import { EffectComposer, RenderPass, MaskPass, ClearMaskPass, UnrealBloomPass } from 'postprocessing';
import { useRef, useEffect } from 'react';
import { useStore } from './your-zustand-store';

function CustomPostProcessing() {
  const { gl, scene, camera } = useThree();
  const composer = useRef(null);
  const { selectedModule } = useStore();

  useEffect(() => {
    // 初始化 composer
    composer.current = new EffectComposer(gl);
    
    // 第一步:渲染背景和非选中模型(默认图层0)
    const baseRenderPass = new RenderPass(scene, camera);
    composer.current.addPass(baseRenderPass);

    if (selectedModule) {
      // 第二步:设置掩码,仅渲染选中模型(图层1)
      camera.layers.set(1);
      const maskPass = new MaskPass(scene, camera);
      composer.current.addPass(maskPass);
      camera.layers.set(0); // 切回默认图层

      // 第三步:对掩码区域应用高亮效果(可替换为其他高亮效果)
      const bloomPass = new UnrealBloomPass();
      bloomPass.strength = 1.8;
      bloomPass.radius = 0.5;
      composer.current.addPass(bloomPass);

      // 第四步:清除掩码,恢复全局渲染
      composer.current.addPass(new ClearMaskPass());
    }

    // 清理资源
    return () => composer.current?.dispose();
  }, [gl, scene, camera, selectedModule]);

  // 替换默认渲染流程
  useFrame((_, delta) => composer.current?.render(delta), 1);
  return null;
}

方案二:动态修改模型材质实现高亮

如果后期处理配置复杂,可直接给选中模型修改材质属性:

{activeModules.map((module) => {
  const isSelected = selectedModule?.id === module.id;
  return cloneElement(module.jsx, {
    // 保留原材质的同时添加 emissive 高亮效果
    onBeforeRender: (_, mesh) => {
      if (isSelected) {
        mesh.material.emissive.set(0xffff00); // 黄色高亮
        mesh.material.emissiveIntensity = 0.8;
      } else {
        mesh.material.emissive.set(0x000000);
        mesh.material.emissiveIntensity = 0;
      }
    },
  });
})}

排查要点

  • 检查selectedModule.id与模型ID的类型是否一致(避免字符串和数字混用)
  • 用MaskPass方案时,确保相机图层切换正确,否则掩码区域为空
  • 若使用postprocessing库,确认版本与R3F兼容(建议用postprocessing@6.x系列)

内容的提问来源于stack exchange,提问作者Rix11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 06:35:40