(Urgent!) How can I make raycasting less laggy?

I’m working on a rendering engine and I get around 1 fps on a basic scene:

I’m using a simple for loop and raycasting to get that result on a 200x200 pixel canvas.

Code:

GraphicsCast:
image

I am using boatbomber’s ViewportCanvas module if you question what the variable screen is.

Please help!

9 Likes

Um, are you expecting that you should be able to make a rendering engine inside roblox?

Just making a bunch of pixels can lag roblox
I made something similar here

From what I can see, your use of parallel lua only uses a single actor? If I am right on this, this means you are using a single thread for all of your raycasts, which would be the same as running it in serial. Rendering more complex scenes is not that much worse on performance btw, what is are the raycasts.


This is a 72x128 screen
It runs at 30-35 fps on my 5600g

Rendering on the cpu will never be performant, unless maybe you don’t render using rays

6 Likes

I tried your module and I’m just getting an error:
image

I think I used it properly though:

image

Module:
image

1 Like

One small trick you could use is instead of using Frames, you could instead use ImageLabels and update their ImageColor3 instead (make sure their background transparency is set to 0. Also dont forget to give said ImageLabels a flat image). For whatever reason this does come with a slight-decent performance boost whenever updating the pixels.

(nvm only now i realize that youre using a module for the canvas)

1 Like

Keep in mind, the length of your ray’s can greatly impact the overall end performance. You can work with a length of 5000 but you’ll be sacrificing a lot of performance for practically nothing. Set it to a WAY lower value, something like 128-512.

2 Likes

GraphicsCast:Work() should be called in serial. With the module, there is no need to use task.desyncronize()

The module will always be worse than a direct implementation (unless that implementation is bad), so if you know how to use parallel lua, then make a direct implementation. The module also has quite a bit of overhead, so running more raycasts per task/actor will be better (and with ~10000 pixels on my rendering thing, it made quite a big different).

I was looking at boatbomber’s ViewportCanvas module and, does it use parts inside a viewportframe to render the image? I was looking at it and it uses BulkMoveTo to move a bunch of parts around

Edit: it uses frames, but it’s super buggy when I move around


And it doesn’t seem faster

1 Like

Sadly another thing to note is the fact that you cannot expect great performance of a resolution like 200x200. Currently my own ray tracer for roblox runs at around 5 fps at that resolution (with 32 parallel threads) with nothing else enabled (just the albedo). There’s so much that can be done to greatly improve performance currently. Your best way to bank on a little more performance is by taking advantage of parallel luau a little more.

1 Like

One simple way of taking advantage of parallel luau would be by dividing the canvas into multiple sections then creating one actor for each section. Each actor being able to render its individual section should come at a decent performance boost. However do keep in mind that theres a point of diminishing returns from either having too many actors or from your canvas being too high resolution.

What I did with mine was asign one actor per row, so 72 actors computing 128 pixels

Those might be too many actors but cannot say for sure due to the fact that we both have different CPU’s. Personally i have found the sweet spot to be around 32 actors, at least for my CPU.

My cpu has 12 threads, though roblox seems to be only using 8.
If you look at the documentation for parallel lua, it’s stated to use more actors than the amount of cores you have

Still, I doubt thousands of actors is a good idea lol

2 Likes

If you want a straight example of this, then you can try my own ray tracer ive made from a while ago.

2023.9.2 Extract.rbxl (161.6 KB)

Do keep in mind that i kinda ripped it off from another studio file (that has a lot of random stuff) just to make it a bit more straight forward to research. It will still have a few features baked into it however so do keep that in mind. You can do single renders by just clicking “Render” or you can make it keep rendering every frame by enabling/clicking on “ShaderData_ActiveRender” on the list from the right bottom of your screen. Every property can also be changed at runtime aswell (even while its already rendering).

Do keep in mind that it will (probably) max out your CPU. You can also make your own custom shaders for it. You can also modify the already existing shaders.

Yeaaah, thousands of actors are well past any sort of “diminishing returns” point. At that point they might even provide lower performance than just plain raw serial (Along with magnitudes higher memory usage).

I think I’ll try that method

minimum character fix

Well, shooting 40,000 Raycasts every single frame is of course gonna be a little laggy, and there is simply no way around this (afaik). To add onto this heavy lag, you also have the issue of Frames being extremely unperforment. Although it seems like Roblox is allow you to paint pixels manually soon.

I’m stuck in a pickle, I’m trying that method you talked about, but I get this result:

This is the code inside the actor for each pixel:

Not sure what’s wrong, I think it might be because I’m using the pixel’s absolute position. Any ideas?

1 Like

If you are using that method, you’ll end up with less actors than pixels

What you want to do is have 1 actor binded to RenderStepped (or heartbeat if you’d rather have some more performance for glitchiness) (this also makes it so you don’t need a bindable event)
The code that the actor runs will loop through the first pixel of the row to the last, and run the same code you had before, with the y value (which is constant) and the x value (from the for loop)
This is for 1 actor per row

1 Like

Have you thought about using a viewport frame then add in an image distortion/blur as an imagelabel?

I tried it and I’ve gotten a slight performance increase:

Instead of 1 fps, I get about 7-10 on a 128x128 screen. Not sure what else I could optimize

1 Like

That level of performance seems about right, depending on your system

Also the video doesn’t work