THREE.js中物体透明度随滚轮变化时阴影无法同步淡化的问题求助
THREE.js中物体透明度随滚轮变化时阴影无法同步淡化的问题求助
大家好,我刚接触THREE.js不久,现在遇到一个头疼的问题想请教各位大佬:
我写了一个函数,能根据鼠标滚轮的位置,改变加载的.glb模型中除指定物体外所有网格的透明度,整体功能跑起来都正常,但有个特别违和的问题——被淡化的物体投射的阴影依然清晰可见。也就是说,物体本身能跟着滚轮正常淡入淡出,但它在下方物体上的阴影却一直留在那里,看起来特别奇怪。
我试了半天也没头绪,因为好像没法直接控制阴影的透明度,只能设置castShadow为true或false。有没有人能给点思路?
下面是我目前的代码:
function lerp(x, y, a) { return (1 - a) * x + a * y; } function scalePercent(start, end, scrollPosY) { return (scrollPosY - start) / (end - start); } export function lerpChangeAllTransparency(name, el, startPer, endPer) { return { frame: name, // 动画所在的关键帧名称 command: el.command, // 动画类型 start: startPer, // 动画开始的滚动百分比 end: endPer, // 动画结束的滚动百分比 target: el.target, // 不受透明度影响的目标物体 alphaFrom: el.alphaFrom, // 起始透明度 alphaTo: el.alphaTo, // 结束透明度 // 动画播放时调用的函数 func: (loadedObject, scrollPercent, target, from, to) => { const percent = scalePercent(startPer, endPer, scrollPercent); const currentAlpha = lerp(from, to, percent); const targetArray = target.split(','); loadedObject.traverse((child) => { if (child.isMesh && child.material) { // 跳过不需要改变透明度的目标物体 if (targetArray.includes(child.name)) return; // 仅克隆一次材质并开启透明属性 if (!child.userData.hasTransparentMaterial) { const cloned = child.material.clone(); cloned.transparent = true; child.material = cloned; child.userData.hasTransparentMaterial = true; } // 应用插值后的透明度 child.material.opacity = currentAlpha; } }); }, }; }
我自己琢磨的几个方向,但不确定对不对:
- 阴影是否和材质的额外属性绑定? 我只修改了
opacity,会不会阴影还受alphaTest或者depthWrite这类属性影响? - 有没有办法让阴影同步响应透明度变化? 难道只能在透明度降到很低的时候直接关闭
castShadow?但这样就没有渐变效果了,显得很突兀。
尝试过的修改思路(还没成功):
我试着在修改opacity的地方加了child.material.needsUpdate = true;,但阴影还是没变化。有没有大佬知道问题出在哪?或者有更优雅的解决方式?
内容来源于stack exchange
相关产品推荐
相关产品推荐

