three.js如何为球体对象添加外发光效果?

33
我正在使用three.js构建某种行星系统,并花了几个小时寻找一个合适的解决方案来给一个带有纹理的球体对象添加外发光效果。
我发现了这个例子http://stemkoski.github.io/Three.js/Selective-Glow.html,它似乎可以解决问题,但问题是——这种发光效果也会影响主要的3D对象,导致颜色改变(如该网页中所示)。
另一个不错的发光例子可以在这里找到http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html,但同样它会让整个区域都发光,而不只是“外部”物体。
我一直在阅读 GitHub 上关于“overrideMaterial”属性的讨论线程,但这似乎是实验性的、未被使用和未记录的……甚至不确定这是否能解决我的问题。
请分享您的想法,谢谢!

请问您能否发布“overrideMaterial”讨论串的链接? - Stemkoski
由于我是新用户,它不允许我发布超过2个链接。 :) https://github.com/mrdoob/three.js/issues/265 - Kyeno
1
请参考以下相关问题:https://dev59.com/iGkv5IYBdhLWcg3w_Vqn - WestLangley
非常感谢@WestLangley!我并不是一个很擅长GLSL编程的人,但这似乎是一个立即可用的解决方案,明天将会仔细分析一下。 :) http://data-arts.appspot.com/globe/ - Kyeno
1
开源,下载链接在这里:https://code.google.com/p/webgl-globe/ - Kyeno
有趣的是,那个代码似乎有一个着色器可以完全实现你想要的功能。现在的问题是如何提取它... - Stemkoski
2个回答

56

我已经开始着手将WebGL Globe代码中产生大气效果的部分分离出来。初步的工作版本在这里:

http://stemkoski.github.io/Three.js/Atmosphere.html

据我所知,原始代码中有一些有趣的事情可以创建大气效果。首先,发光纹理被放置在另一个球体上 - 让我们称之为Atmo Sphere :) - 它环绕着带有地球图像的球体。大气材料被翻转,使得正面不渲染,只有背面,因此它不会遮挡地球球体,尽管它环绕着它。其次,梯度照明效果是通过使用片段着色器而不是纹理实现的。然而,如果你放大或缩小,大气层的外观会改变;这在WebGL Globe实验中并不明显,因为缩放被禁用了。
[更新于4月30日]
接下来,与源代码类似

http://stemkoski.github.io/Three.js/Selective-Glow.html

将带有渐变照明纹理的球体(以及另一个黑色纹理的球体)放置在第二个场景中,然后使用添加混合器将该场景的结果与原始场景组合。为了让您可以尝试用于创建发光效果的参数,我包括了一些滑块,以便您更改值并查看不同的发光效果。

希望这可以帮助您入门。祝你好运!

[更新于6月11日]

我有一个新的示例,以一种更简单的方式实现相同的效果,而不是使用后处理和两个场景的加法混合,我只是更改了自定义材料的一些参数。(回想起来似乎很明显。)请查看更新后的示例:

http://stemkoski.github.io/Three.js/Shader-Halo.html

尚未解决缩放/平移问题。

[更新于7月24日]

我解决了缩放/平移问题。这需要使用着色器;有关复杂性的详细信息,请参见相关问题Three.js - shader code for halo effect, normals need transformation,最终工作示例请参见:

http://stemkoski.github.io/Three.js/Shader-Glow.html

我对最终结果感到非常满意,因此不再更新此答案 :)


1
李,干得好!看起来非常有趣!真不敢相信你花了这么多时间解决这个问题,非常感谢!我现在就去看看。我欠你一个人情 :) - Kyeno
1
如果我可以建议您一件事(这也是我自己需要实现的东西),那就是您的浏览器调整大小事件无法处理Atmo Sphere。 :) 这对于示例或任何内容都不是必要的。 - Kyeno
1
这是一个有趣的问题,我一直想要解决这个项目。你说得对,浏览器调整大小确实是个问题,我使用<code>THREEx.WindowResize(renderer, camera)</code>来处理它,并需要为具有发光效果的次要场景设置类似的东西。如果你觉得你“欠我一个人情”,你可以通过帮助其他使用three.js标签提问的人来回报。而且,没有什么比点赞更能表达“谢谢”了:D - Stemkoski
1
完全同意Dmitry的观点。这很酷,但与所有新的threejs代码不兼容。 - Starfs
1
@LeeStemkoski 你好,这个例子似乎在新的three.js版本中无法工作。你能否更新一下呢?非常感谢。 - dyh333
显示剩余3条评论

1
在你所提到的例子中,我使用了加法混合的蓝色发光效果--如果你使用白色代替,也许会产生你想要的效果。

谢谢回复!我已经尝试过了-白色仍然会影响原始图像。我马上会发布我的代码。 - Kyeno
1
好的,第一个例子是我只渲染主渲染器的单通道渲染: http://matt.prayam.com/private/planet3d/第二个例子是我使用了你的方法,使用合成器进行多通道渲染: http://matt.prayam.com/private/planet3d/white.html唯一的区别在于 onRenderLoop 回调函数中。 - Kyeno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接