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

在Babylon.js中能否实现物体透明度随观测视角动态变化?

在Babylon.js中实现基于视角的面透明度变化效果

可以实现,核心思路是通过自定义材质着色器计算每个面与相机的夹角,动态调整透明度。下面是具体实现步骤:

实现步骤

  • 创建基础场景与立方体
    先搭建Babylon.js的基础场景,包括引擎、相机、灯光和立方体:

    const canvas = document.getElementById("renderCanvas");
    const engine = new BABYLON.Engine(canvas, true);
    const createScene = function () {
        const scene = new BABYLON.Scene(engine);
        scene.clearColor = new BABYLON.Color4(0.1, 0.1, 0.1, 1);
        
        const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI/2, Math.PI/2, 5, BABYLON.Vector3.Zero(), scene);
        camera.attachControl(canvas, true);
        
        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);
        light.intensity = 0.7;
        
        const cube = BABYLON.MeshBuilder.CreateBox("cube", {size: 2}, scene);
        return scene;
    };
    const scene = createScene();
    engine.runRenderLoop(() => { scene.render(); });
    window.addEventListener("resize", () => { engine.resize(); });
    
  • 自定义材质与着色器逻辑
    使用PBRMaterial(或StandardMaterial),通过自定义片段着色器修改透明度。核心是计算面的法向量与相机视线方向的夹角:

    1. 首先创建材质,启用透明度:
      const material = new BABYLON.PBRMaterial("customMat", scene);
      material.alpha = 1;
      material.enableAlphaMode = true;
      material.alphaMode = BABYLON.Engine.ALPHA_BLEND;
      cube.material = material;
      
    2. 注入自定义着色器代码,在片段着色器中计算夹角并调整透明度:
      material.onBindObservable.add(() => {
          const effect = material.getEffect();
          // 传递相机位置给着色器
          effect.setVector3("cameraPosition", scene.activeCamera.position);
      });
      
      // 自定义片段着色器代码
      material.fragmentShader = `
          #define CUSTOM_FRAGMENT_BEGIN
          // 计算视线方向(相机到顶点的方向)
          vec3 viewDir = normalize(vPositionW - cameraPosition);
          // 顶点法向量(已转换到世界空间)
          vec3 normalW = normalize(vNormalW);
          // 计算法向量与视线方向的夹角余弦值
          float dotProduct = dot(normalW, viewDir);
          // 调整透明度:当夹角为0(正对相机)时alpha为0,夹角越大alpha越接近1
          // 这里可以通过pow调整曲线,让变化更自然
          float alpha = pow(1.0 - abs(dotProduct), 2.0);
          diffuseColor.a = alpha;
          #define CUSTOM_FRAGMENT_END
      `;
      
  • 逻辑说明

    • dotProduct是面法向量与视线方向的点积,当面正对相机时,法向量与视线方向完全相反,点积为-1,abs(dotProduct)为1,此时alpha为0,完全透明;
    • 当旋转相机或立方体,夹角增大,abs(dotProduct)减小,alpha逐渐增大,面变得不透明;
    • 通过pow函数可以调整透明度变化的曲线,数值越大,透明到不透明的过渡越平缓。

额外优化

  • 如果需要更细腻的控制,可以调整pow的指数,或者添加阈值,比如当夹角小于某个值时直接设为完全透明;
  • 若使用StandardMaterial,自定义着色器的注入逻辑类似,只需修改材质类型和对应的着色器注入点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:57:20