如何使粒子发光并向周围投射光线?


22

我目前正在尝试在黑暗的森林中制作萤火虫效果。该水平仪的光线非常暗,播放器是少数几个光源之一。为了让玩家更好地看到关卡,我尝试使发光的萤火虫随机出现在地图上。一种方法是使用粒子系统。但是我不能使粒子在周围环境中发光。有没有办法做到这一点?


3
这里的真正问题是“光是昂贵的”。您可能最好放置一些定点光源以充分照亮该区域,将其烘焙为光照贴图,然后使用粒子来说明光源的来源,而不是使用数十种非常昂贵的动态光源。
Draco18s 2015年

@ Draco18s不会有数十只萤火虫。它们只会出现在播放器的视图内。它是自上而下的,因此易于控制。而且在任何给定时间,萤火虫的数量应少于10只。我不认为10个动态点光源昂贵吗?
DarkDestry

默认情况下,Unity一次只允许两个活动的动态光源照亮几何图形(尽管对于2D设置可能有所不同)。当然,您可以增加此值,但请记住,+ 1光源是对绘图调用的x2影响。
Draco18s 2015年

2
@ Draco18s对于正向渲染路径可能是正确的,但是如文档 “在使用“延迟着色”时,可以影响对象的灯光数量没有限制 ”中所述-许多只影响一小部分灯光的小灯光屏幕正是这种用例,延迟的渲染路径擅长高效处理。(通常,每个唯一的光源需要一次绘制调用,而不是像正向渲染那样是乘数)
DMGregory

那是个很好的观点。我大部分时间都忘记了不同的渲染路径。
Draco18s 2015年

Answers:


7

发光粒子现在是5.5中的内置功能。

只需在粒子检查器中启用“灯光”,添加对灯光预制件的引用(点光源和聚光灯都可以使用),并将“比率”更改为1。

在此处输入图片说明

还有voilà,发光的粒子: ![在此处输入图片描述

事实证明,这是一个相当优化的设置,即使在数百个最大灯光下,我的装备也能以1500 + fps的速度运行。

编辑:经过观察,在我看来粒子光在每个片段照明和顶点照明之间切换(大概是为了优化?)。如果将最大光照设置得太高,可能会产生少量的视觉伪影。

Edit2:正如DMGregory指出的那样,工件是前向渲染优化的副产品。延迟照明解决了这个问题。添加了更好的gif


1
那是好消息!:)如果包含一些逐步说明,说明如何使用新的粒子系统功能进行设置,则此答案会更好。
DMGregory

1
您看到的顶点照明行为听起来有点像Unity在向前渲染中应用的一些优化。使用延迟路径时是否看到相同的行为?
DMGregory

你是对的!使用延迟渲染路径时,伪像不再存在。
eclmist

31

当心:

这个答案已经过时了。现在,Unity本机支持点光源粒子。请参阅此答案以获取全部详细信息。

我将在这里留下任何好奇的人,或者使用Unity的旧版本,或者需要比本机方法所提供的更多的手动控制-请注意,本机支持可能比下面介绍的方法更加有效和可扩展。


我不确定为什么这么多答案都认为这是困难或不可能的。对于在PC上运行的现代延迟渲染管线而言,处理几十个动态点光源是非常常规的。

这是我制作的一个简单示例: 萤火虫的例子

我使用此脚本为我的最大粒子动态生成足够的灯光(确保您调整了粒子系统设置,因此最大数值是合理的-默认值1000不会使您的图形卡非常满意),然后更新它们以遵循活动状态粒子:

[RequireComponent(typeof(ParticleSystem))]
public class ParticleLights : MonoBehaviour {

    public Light lightPrefab;

    ParticleSystem _system;
    ParticleSystem.Particle[] _particles;
    Light[] _lights;


    void Start () {
        _system = GetComponent<ParticleSystem>();
        _particles = new ParticleSystem.Particle[_system.maxParticles];

        _lights = new Light[_system.maxParticles];
        for(int i = 0; i < _lights.Length; i++)
        {
            _lights[i] = (Light)Instantiate(lightPrefab);
            _lights[i].transform.parent = transform;
        }
    }

    void Update () {

        int count = _system.GetParticles(_particles);
        for(int i = 0; i < count; i++)
        {
            _lights[i].gameObject.SetActive(true);
            _lights[i].transform.localPosition = _particles[i].position;

            // Looks like the GetCurrentColor function was added in 5.3.
            // You can use other methods in earlier Unity versions.
            _lights[i].color = _particles[i].GetCurrentColor(_system);
        }

        for (int i = count; i < _particles.Length; i++)
        {
            _lights[i].gameObject.SetActive(false);
        }
    }
}

编辑:您可以先创建一个游戏对象(在本例中为创建->灯光->点光源),然后使用所需的名称/参数/脚本/子代进行设置,然后将其从层次结构中拖入,以创建预制件您的项目资源管理器。这会将对象另存为资产,可以在多个场景和脚本之间重复使用,并且具有一定程度的继承性。您可以删除场景中的副本,资产将保留在Assets文件夹中,以便在需要时进行引用。

确保lightPrefab的范围相对较小并且没有阴影投射,以便为场景中发生的一切提供最大的性能扩展空间。您不需要将lightPrefab本身变成绿色(或萤火虫的颜色)-它会从粒子的颜色中拾取它。

如果将每个萤火虫制作成自己的GameObject,并带有广告牌四边形和自定义运动/眨眼脚本的灯,则可能会更好地控制萤火虫的飞行,因为获得令人信服的漂移所花费的粒子系统技艺比我知道。;)


实际上...尽管我说过不要对萤火虫使用阴影投射,但我只是尝试在示例场景中将其打开,并且不会造成任何问题。萤火虫经过物体时,阴影围绕的方式真的很酷,并且会增加幽灵般的气氛。根据场景和目标硬件的复杂程度,您的里程可能会有所不同,因此请确保配置文件正确,但这可能是我过早优化的一种情况。:)
DMGregory

您如何创建轻型预制件?
DarkDestry 2015年

同样,由于某种原因,ParticleSystem.Particle引用旧粒子。没有用于它的GetCurrentColor或GetCurrentSize方法。
DarkDestry 2015年

@DarkDestry我已经在创建预制件的答案中添加了注释。至于缺少的功能,这可能是一个版本问题-我正在5.3中工作,在Unity的早期版本中,您可能会以其他方式执行此操作。让我们使用Hamza Hasan友好创建的会议室在chat中讨论实现细节
DMGregory

因此,轻型预制件与普通预制件相同。被提及为轻型预制件时感到困惑。
DarkDestry

3

几年前,在价格不高的动态灯可以买到之前,我们只需使用带有附加混合功能的2D广告牌粒子效果。它将使场景变白。通过以正确的萤火虫深度绘制它,您将获得几乎正确的排序。与Alpha混合相比,叠加自身时,附加Alpha不需要排序。它不会照亮所有场景,但是会照亮萤火虫周围的区域。然后,如果需要,您可以动态照明并每隔几秒钟选一次萤火虫之一来实际照明场景。

关于发光效果已经存在一个问题和答案如何在Unity 2D游戏中实现这种照明?


0

不幸的是,我对当前版本的Unity并没有太多的经验(很多年前我曾玩弄过它),所以我不确切知道您必须在引擎中使用哪些功能集。

无论如何,无论您使用哪种发动机,都应尽量避免使用动态照明。它们在计算上非常昂贵,并且往往以非常指数的方式增加场景的复杂性。但是,就像大多数3D渲染的日常工作一样,您可以通过多种方法通过作弊来获得相似的效果。

实现类似效果的一种可能方法是将预制的发光纹理映射到萤火虫下方的地形(假设Y =上/下坐标系),其中X和Z位置控制发光在地形上的位置和Y偏移从控制纹理的Alpha的地形开始(更亮=更接近地形)

当然,这种方法有几个缺点。您将不会因为没有使用光而投射阴影,也不会影响世界上的任何其他几何体(道具,树叶等)


-2

Light在火源处使用,并在脚本中播放其大小,以便产生燃烧效果。并使用您的粒子系统:)


现场没有火。我有稀少的粒子出现和不存在。粒子根本没有固定的位置。请阅读问题。
DarkDestry

那么,这是怎么回事?您可以在预定义的位置安装光你的粒子预制而不是
哈姆扎·哈桑

问题是如何做到这一点。我正在使用unity的粒子系统。而且我在那里没有看到预制件。除非您要我创建一个带有灯光并根据脚本生成基础的预制件
DarkDestry 2015年

因此,您在场景中有粒子gameObject。将灯光附加到同一游戏对象,并通过将gameObject拖动到Unity File Explorer对其进行预制。
Hamza Hasan 2015年

我在场景中有一个粒子系统游戏对象。不是粒子。
DarkDestry 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.