【问题标题】:Transparent object behind outline object轮廓对象后面的透明对象
【发布时间】:2025-12-19 08:30:16
【问题描述】:

我有一个轮廓的对象。

在它后面我想画一个透明的物体。我的问题是轮廓与透明对象混合。

我怎样才能画出轮廓,这样它就不会被混合?

# PLANE
geo1 = new THREE.PlaneGeometry 500, 500
mat1 = new THREE.MeshPhongMaterial({color: 0x00ff00, transparent: true, opacity: 0.5})
plane = new THREE.Mesh geo1, mat1
plane.position.z = -100
scene.add plane

# SHADED MODEL
torusKnotGeo = new THREE.TorusKnotGeometry 50, 10, 128, 16
phongMat2 = new THREE.MeshPhongMaterial 0xffffff
torusKnot = new THREE.Mesh torusKnotGeo, phongMat2
scene.add torusKnot

# OUTLINE
uniforms = offset:
    type: "f"
    value: 2
shader = shader['outline']
shaderMat = new THREE.ShaderMaterial
    uniforms: uniforms,
    vertexShader: shader.vertex_shader,
    fragmentShader: shader.fragment_shader,
torusKnotOutline = new THREE.Mesh torusKnotGeo, shaderMat
torusKnotOutline.material.depthWrite = false
outScene.add torusKnotOutline

jsfiddle(基于https://*.com/a/23198184/2785396

【问题讨论】:

  • 透明对象在不透明对象之后渲染。重写你的程序,首先渲染飞机。
  • 我尝试将 sortObjects 设置为 false 并先添加平面,但没有成功。我错过了什么吗? jsfiddle.net/ckra27s1。我会试试阿德里安说的。
  • 正如我所说,透明对象在不透明对象之后渲染。您必须将其放在单独的渲染通道中。

标签: three.js


【解决方案1】:

我不能评论(没有足够的代表),所以我会发布一个答案。

您从原始 JS fiddle 中获取示例:http://jsfiddle.net/Eskel/g593q/5/ 并删除了作曲家。作曲家在渲染过程中添加了一些额外的操作。

composer.addPass normal
composer.addPass mask
composer.addPass outline
composer.addPass clearMask
composer.addPass copyPass
  • 首先渲染物体场景、轮廓场景和蒙版场景。
  • 然后它制作一个在其上渲染轮廓的蒙版,然后清除该蒙版。这部分创建你的大纲,这是一个非常重要的步骤。为什么?因为如果我使用您的代码并添加一个额外的对象,您会看到轮廓被两个对象遮挡。无论第二个对象是在场景的前面还是后面,都会发生这种情况,我相信你不希望发生这种情况。示例:http://jsfiddle.net/adrian_moisa/84470k4n/1/
  • 最后,它将轮廓复制到渲染的场景。

我的建议是分叉原始示例并保持作曲家完好无损。如果您没有让它工作,请记住包含原始示例中的以下脚本。如果其中任何一个在操作中丢失,您的作曲家就会损坏,这意味着您的页面将无法呈现。

  • ShaderPass.js
  • RenderPass.js
  • MaskPass.js
  • EffectComposer.js
  • CopyShader.js
  • AdditiveBlendShader.js

【讨论】: