Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Optimizing craft lights - Crashing when multiple lights are added to the scene quickly.

edited January 20 in Questions Posts: 51

Has anybody experimented with this? I've been working on a particle system and today I decided to implement point lights, since I was having a lot of trouble when I first attempted it, I pushed it off. Since starting the project, I've purchased a new device and I'm happy to report that there has been a measurable increase in performance, however, whenever the particles light intensity is beyond 0, and if those particles lifespans are longer than a half a second, then the entire application crashes.

I was unable to even get a few lit particles on the screen with my iphone 8, however with an iphone 11, I can have up to 30 lit particles with a pretty heavy performance loss. The real problem occurs when I turn up the lifespan of the particles.

This leads me to assume, as I originally thought, that the lights are optimized for static entities, and not for runtime instantiation. Am I wrong in assuming so? The particle system works flawlessly with 1000s of particles as long as there are no lights involved.

Should I try to use shade to create a material with emission? is that even compatible with craft.renderer? I would have gone with that, but I assumed it's not possible.

So if you've tried something similar and figured out a workaround, or some way to fake emission please enlighten me :smiley:



  • Posts: 298

    You can try this, My test code:

    -- MultiLights
    function setup()
        -- Create a new craft scene
        scene = craft.scene()
        -- 使用 OrbitViewer 组件,设置镜头参数,提供旋转,移动,放大功能
        viewer =, vec3(0,2,0),5, 0, 1000) 
        -- 用于保存所有光源的参数:P[1].Color,P[2].Color
        P = {}
        -- 批量生成多个光源
        lights = {}
        for i=1,6 do
            P[i] = { Color = color(230, 249, 18), Type=2, Intensity=1, Penumbra=30,
            Decay=0, Height=5, X=2, Z=2, Angle=30}
            local l = scene:entity():add(craft.light, POINT)
            lights[i] = Light(i, l, 1, 1, 1, true)  
        -- 设置调试参数
    function update(dt)
        -- Update the scene (physics, transforms etc)
    -- Called automatically by codea 
    function draw()
        -- Draw the scene
    function modelInit()
        models = {}
        -- 增加砖块地面
        local ground = scene:entity()
        ground.position = vec3(0,0,0)
        ground.model = craft.model.cube(vec3(50,0.1,50))
        ground.material = craft.material.preset("Surfaces:Basic Bricks")
        -- ground.material = craft.material(asset.builtin.Materials.Standard)
        -- = readImage(asset.builtin.Surfaces.Desert_Cliff_Color)
        -- ground.material.normalMap = readImage(asset.builtin.Surfaces.Basic_Bricks_Normal)
        -- ground.material.diffuse = color(146, 82, 69)
        ground.material.offsetRepeat = vec4(1,20,20,20)
        -- = false
        -- 增加内置模型:悬浮空中的大立方体
        cube = scene:entity()
        cube.model = craft.model.cube(vec3(0.2,0.2,0.2),vec3(1,0.5,1))   
        cube.material = craft.material(asset.builtin.Materials.Specular)
        -- cube.material.diffuse = color(238, 237, 237, 255) = true    
    -- 灯光类
    Light = class()
    -- light 只能取:scene:entity():add(craft.light),scene.sun:get(craft.light)
    function Light:init(id,light,x,y,z) = id
        self.light = light
        self.light.color = P[].Color or color(18, 66, 249)
        self.light.type = Type or SPOT        
        self.light.intensity = Intensity or 1  
        self.light.penumbra = Penumbra or 30 
        self.light.decay = Decay or 0    
        self.light.entity.y = Height  or 4
        self.light.entity.x = X or 2   
        self.light.entity.z = Z or 2   
        self.light.angle = Angle  or 30
    function Light:update(dt)   
        self.light.color = P[].Color
        self.light.intensity = P[].Intensity    
        self.light.type = P[].Type         
        self.light.angle = P[].Angle  
        self.light.decay = P[].Decay
        self.light.penumbra = P[].Penumbra 
        self.light.entity.y = P[].Height  
        self.light.entity.x = P[].X  
        self.light.entity.z = P[].Z   
    function showParameter()
        types = {"DIRECTIONAL", "POINT", "SPOT"} "")  
        parameter.color("Color",color(249, 93, 18),function() P[ID].Color = Color end)
        parameter.integer("Type", DIRECTIONAL, SPOT, SPOT, function() P[ID].Type = Type end)   "types[Type+1]")
        parameter.number("Intensity", 0.0, 10.0, 1.0,function() P[ID].Intensity =  Intensity end)
        parameter.number("Penumbra", 0.0, 90, 30.0, function() P[ID].Penumbra = Penumbra end)
        parameter.number("Decay", 0.0, 10.0, 0.1, function() P[ID].Decay = Decay end)
        parameter.number("Height", -1, 50, 5, function() P[ID].Height = Height end)
        parameter.number("X", -25, 25, 2, function() P[ID].X = X end)
        parameter.number("Z", -25, 25, 2, function() P[ID].Z = Z end)
        parameter.number("Angle", 0.0, 90, 30, function() P[ID].Angle = Angle end)
  • Posts: 51

    I'm talking about potentially having 30-100 point light entities instantiated at nearly the same time, each having there own update functions affecting things like gravity, scale, and speed. I have this system working for standard unlit models, but as soon as you apply lights to them. At least, on my device, the performance is really, really bad. I don't have any issues with using lights normally, just in this particular way. Sorry if I wasn't clear! @binaryblues

  • edited January 20 Posts: 51
    Shade totally works. It’s extremely simple in my case. Just make a new shader with a color property node and hook that up into the emission and the diffuse input ports on the surface shader. Rename the color node from “Color” to “diffuse” and move that into your Codea folder. Also, make sure the render queue is set to transparent. Oh and I turned off the rest of the fancy stuff I could find in shade, for some extra performance.

    I finally have a bunch of “lit” particles on the screen. (:
  • Posts: 313

    can you make a video tutorial of how you got Shade to work with Codea?

  • Posts: 298

    @arismoko Sorry for my misunderstanding. In my test code, the max numbers of craft.light is nine. If I set ten lights, it will disappear.

  • edited January 21 Posts: 51
    No worries @binaryblues, and here you go @skar
  • JohnJohn Admin Mod
    Posts: 764

    Hey guys, lights in craft aren't implemented very optimally, all lights effect all geometry in the scene and passed into lit shaders, meaning that at some point you'll get very bad performance or exceed uniform block limits and it'll break in some way or another...

    In Codea 4 I'm working on getting clustered forward rendering working so there will be effectively much better performance and much higher light limits, but for now it's a bit crappy

  • Posts: 51

    @John that’s really exciting stuff, until then some bloom and an emission shader works just fine for my purposes (: i'm excited for that though! All craft needs at this point is a pathfinding/navmesh system plus some collision callbacks and we're golden.

  • JohnJohn Admin Mod
    Posts: 764

    Thanks. When I get the change I want to look at integrating this tool for navmesh and navigation stuff:

  • edited January 23 Posts: 51
    @John i was literally just learning about recast a few nights ago, it seems to be the go-to library for implementing navmesh generation. Great choice, should be performant as well. I think Roblox and Unreal Engine both use it.
Sign In or Register to comment.