#.

1 messages · Page 2 of 1

hearty sluice
#

right

#

well

#

(70 x 70 x 4) / totalThreads then

hearty sluice
#

its a surfaceass level solution without much thought put into it i admit

astral bobcat
#

also you should take pixel buffer out of the loop

#

so u dont allocate and deallocate a massive buffer every frame

hearty sluice
#

same with startX and endX as well

#

no point declaring them every time

astral bobcat
#

true aswell

hearty sluice
#

this should be the final step

#

has to be offset somehow

#

"somehow"

astral bobcat
#

should be easy

#

just startingX

#

and size is (endX - startingX) by resolution

hearty sluice
#

well i had a much more complicated solution in mind

#

getting start vector3 and end vector3 with the worker number

#

but yours is better

#

fs

astral bobcat
#

lol

hearty sluice
#

i've got this feeling that the math.floors could result in not so correct results

astral bobcat
#

uhh

#

actually

#

workerid N endX == workerid N+1 startX
so there shouldnt be any gaps

hearty sluice
astral bobcat
#

no like for any workerid, its endX is equal to the next workers startX

hearty sluice
#

afterall

astral bobcat
#

?

hearty sluice
#

what worker 1 writes to the endX, worker 2 will write to the startX

#

which are the same

astral bobcat
#

oh right

#

umm

hearty sluice
#

instead worker 2 should start with worker 1's endX + 1

#

let me substitute for the worker id and see how the loop turns out

#

if everything is right one worker loop should fill exactly the pixel buffer's size

hearty sluice
astral bobcat
hearty sluice
#

and that wouldn't leave gaps, but error

#

because buffer size must be resolution x resolution x 4

#

actually it would leave gaps

#

buffer substitutes for what aren't filled by 0

#

so they'd be black

#

still a problem

#

will total to 540 pixels being just black

hearty sluice
#

very hard code-y i think

#

lol

#

any ideas?

#

a resolution of 80 ends up correct

#

or 72

astral bobcat
#

hmmm

astral bobcat
#

they all have their own like 24x70 chunk

hearty sluice
#

24?

astral bobcat
#

random number

#

but like 70/numthreads

hearty sluice
#

now i dont think a buffer can write to a pixel and a half

#

lol

astral bobcat
#

m

hearty sluice
#

a resolution of 72 for example works because 72 / 4 = 18

astral bobcat
#

i guess you could have some more complicated logic for splitting it up and then the main script can just tell each worker what their resolution is

hearty sluice
#

no halves here

#

well im not one for complicated logic dependent on maths

#

still quite a beginner in that area

astral bobcat
#

you jsut need something that divides it evenly enough

#

now what could that be..

hearty sluice
#

3 workers could do it completely evenly, while the last or first worker could deal with any buffer size gaps that come up

#

but i dont know exactly how to formulate that

#

not without quite a lot of effort that i'd only really spend on my own game ngl

#

for now

#

@scarlet terrace use a resolution that when divided by the number of threads results in an integer

#

so 72 / 4 = 18

#

70 / 4 would result in 17.5

#

we dont want any halves

#

whatever solution to that you can find out with someone more knowledgeable

astral bobcat
#
local numthreads, res
local step = res/numthreads
for i=2, numthreads do
  assign_worker(step // 1) -- split that evenly
end

local left_over = res - ((step // 1) * (numthreads - 1))
assign_worker(left_over)
#

maybe?

#

worst case scenario one gets numthreads-1 extra pixels i think

#

@hearty sluice u get me?

hearty sluice
#

we can make an extra worker that is added onto any number of threads

#

a leftover one

scarlet terrace
#

hi

#

im back

#

so what yall figure out

hearty sluice
#

so we'd do 4 of them regularly, and the leftovers are processed through a 5th

hearty sluice
#

we rewrote the whole thing pretty much

hearty sluice
#

ok

#

let's see to that after we make sure we have the base things working

scarlet terrace
hearty sluice
#

if i have to help someone without them coming out understanding what exactly i did to help them

#

then i'd rather not help at all

#

you can continue using whatever we make

#

but i'll explain what we did

#

how it differs from your approach

#

and why

scarlet terrace
#

alr

hearty sluice
#

because if you don't understand then the second you face another problem with this system you're gonna make another thread

scarlet terrace
#

i dont even like scripting i never liked it, i just learnt it so im able to make games

astral bobcat
#

i gotta sleep before i kill my sleep schedule

hearty sluice
#

ok

#

ill take it from here

#

gn

scarlet terrace
#

frfr

astral bobcat
scarlet terrace
#

ramadan

#

gn

#

alr so apparently if i do multithreading ill get 100 fps average

hearty sluice
#

what is your average now

scarlet terrace
#

lemme check

#

27

#

💔

hearty sluice
#

i dont think its a linear improvement

scarlet terrace
#

what

hearty sluice
#

ok

#
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local AssetService = game:GetService("AssetService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

local playerGui = game.StarterGui
local screenGui = playerGui:WaitForChild("ScreenGui")
local imageLabel: ImageLabel = screenGui:WaitForChild("ImageLabel")

local resolution = 72
local totalThreads = 4

local editableImage = AssetService:CreateEditableImage({
    Size = Vector2.new(resolution, resolution)
})

imageLabel.ImageContent = Content.fromObject(editableImage)
imageLabel.ResampleMode = Enum.ResamplerMode.Pixelated

local editableImage = imageLabel.ImageContent.Object


local workersFolder

repeat
    
    workersFolder = script:FindFirstChild("Workers")
    task.wait(0.1)
    
until workersFolder


for i, actor in ipairs(workersFolder:GetChildren()) do
    
    if not actor:IsA("Actor") then continue end

    local workerScript: Script = actor:FindFirstChild("WorkerScript")
    if not workerScript then continue end
    
    workerScript:SetAttribute("WorkerID", i)
    workerScript:SetAttribute("TotalThreads", totalThreads)
    workerScript:SetAttribute("Resolution", resolution)
    workerScript:SetAttribute("Camera", camera)
    workerScript:SetAttribute("Lighting", game:GetService("Lighting"))
    
    workerScript.Enabled = true
    
end

#

main script

#

worker script

scarlet terrace
#

should i add or remove anything

#

in layout

hearty sluice
#

wdym

scarlet terrace
#

also i think you made a syntax error by accident herew

hearty sluice
#

oh

#

remove those 2

#

buffer start size and buffer end size

scarlet terrace
#

ok so thats it?

#

i test now?

hearty sluice
#

test

#

one can only test and see

#

wait

#

first

#

you have to make all actor scripts disabled

#

in workspace

scarlet terrace
#

alr

hearty sluice
#

you can test after that

scarlet terrace
hearty sluice
#

oh yeah

#

uh

#

uh

#

is it the same image label you always used

scarlet terrace
#

is editableimage created

#

yes

hearty sluice
#

look at output

#

any errors?

scarlet terrace
hearty sluice
#

can you add print statements here and there

#

to tell me what runs

scarlet terrace
#

both in workerscript and mainscript or just one of them?

hearty sluice
#

both

#

also

#

you have 4 worker scripts

#

right?

#

all under an actor each

scarlet terrace
#

you told me to put workerscript in workspace

hearty sluice
#

didnt mean it like that

#

is this your setup rn

scarlet terrace
#

no

hearty sluice
#

ignore the UI

#

what is your setup

scarlet terrace
hearty sluice
scarlet terrace
#

same name?

hearty sluice
#

no

#

workerscript

scarlet terrace
#

disabled or

hearty sluice
#

it still does that

#

like this

#

worker scripts disabled though

#

yeah

scarlet terrace
#

actor1 actor2 or just actor

hearty sluice
#

just actor

#

doesn't matter really

scarlet terrace
#

alr so like this

hearty sluice
#

Workers folder under MainScript

scarlet terrace
hearty sluice
#

yes

#

wait

#

i did something wrong

scarlet terrace
#

got an error

#

yeah

hearty sluice
#

do this here

#

and put main script in starter character scripts

#

well

#

where was it before

scarlet terrace
#

starterplayerscripts

hearty sluice
#

hmm

#

ok

#

it should work

scarlet terrace
#

03:45:22.798 Instance is not a supported attribute type - Client - MainScript:45
03:45:22.799 Stack Begin - Studio
03:45:22.799 Script 'Players.Pieflyo.PlayerScripts.MainScript', Line 45 - Studio - MainScript:45
03:45:22.799 Stack End - Studio

hearty sluice
#

its because this

#

don't set its camera

#

you can't aslan

#

remove the line

scarlet terrace
#

what line is that

#

wait nvm

#

i got the same error

#

03:50:02.048 Instance is not a supported attribute type - Client - MainScript:45
03:50:02.048 Stack Begin - Studio
03:50:02.048 Script 'Players.Pieflyo.PlayerScripts.MainScript', Line 45 - Studio - MainScript:45
03:50:02.048 Stack End - Studio

hearty sluice
#

remove this as well

#

tf is the point of this

#

there is only one lighting in the whole game

scarlet terrace
#

03:50:52.042 Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript:55: buffer access out of bounds - Client - WorkerScript:55
03:50:52.042 Stack Begin - Studio
03:50:52.042 Script 'Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript', Line 55 - Studio - WorkerScript:55
03:50:52.043 Stack End - Studio

hearty sluice
#

what

#

how

#

wtf

scarlet terrace
#

man idk

hearty sluice
#

hold on

#

can you send a screenshot of your scripts

#

and are all worker scripts the same

#

@scarlet terrace

scarlet terrace
#

workerscript

#

layout

hearty sluice
#

oh yeah i see why

#

@scarlet terrace hey

#

no

#

dont go offline

#

nvm

#

hold on more

#

ok remove the * 4 here

#

just make it like this

#

and test

scarlet terrace
#

where is this

#

mainscript or worker

hearty sluice
#

workerscript

#

change it in ALL workerscripts mind you

scarlet terrace
#

what line

#

nvm i found it

#

04:08:59.461 Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript:62: attempt to index nil with 'WritePixelsBuffer' - Client - WorkerScript:62
04:08:59.461 Stack Begin - Studio
04:08:59.461 Script 'Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript', Line 62 - Studio - WorkerScript:62
04:08:59.461 Stack End -

hearty sluice
#

bruh

#

well that's a problem fs

#

ok

#

im afraid my script still has quite a lot to be dealt with

#

come back later

scarlet terrace
#

go drink water 10 mins until fajr

#

nvm its 1 min left

hearty sluice
#

i did

ivory ore
#

so you dont get workers trying to get a reference to the editableimage without it being loaded yet

scarlet terrace
ivory ore
scarlet terrace
hearty sluice
#

but its off by more than one lol

hearty sluice
#

ok i think i fixed it

#

worker script

#

buffer index miscalculation on my end

#

i added a modulo to the x in all worker scripts so X always ranges from 0-(Resolution / Total Threads - 1)

#

the image doesn't draw for me for some reason

#

but without the script as a whole i get 240 fps

#

with the script WITHOUT multithreading (or only 1 thread) i get 50 fps

#

with the script and 4 threads i get 110 fps

#

safe to say the base multithreading foundation is functional

hearty sluice
#

so yeah its not exactly linear

#

the improvements plateau more and more the more threads you use

#

but will probably vary from device to device

astral bobcat
#

you can call in parallel im 95% sure

#

or is it

#

oh shoot it isint

astral bobcat
# hearty sluice

howd we let the GetSunDirection get back into the GetShadowFactor function

scarlet terrace
hearty sluice
astral bobcat
#

yea

hearty sluice
hearty sluice
#

but it gave me no errors

#

and it sure as hell is fucking up my fps

hearty sluice
#

ok

#

wdym

astral bobcat
hearty sluice
#

oh

#

i thought he already did that

#

lol

hearty sluice
#

its writing to the buffer successfully

#

its writing to the editable image successfuly

#

only

scarlet terrace
#

what was mainscript again

hearty sluice
#

it just doesn't show up for me

hearty sluice
#

but here

#

if you need it

#

this is main script

#

hold on

astral bobcat
#

also shadow ray isnt being calculated properly ```lua
local function get_shadow_ray(origin, sundir)
local direction = origin - (sundir * 1000)
return workspace:Raycast(origin, direction.Unit * 100)
end

hearty sluice
#

i made a mistake

#

this is main script

#

@scarlet terrace

astral bobcat
#

sundirection is direction to the sun from 0,0,0

scarlet terrace
#

alr so it worked there are pixels on the screen

#

but thing is

#

im getting lower fps

hearty sluice
#

hold on a moment

scarlet terrace
#

wait did you remove other optimizations

hearty sluice
#

no

#

you did

#

lol

scarlet terrace
#

oh

hearty sluice
#

what needs changing

astral bobcat
hearty sluice
astral bobcat
#

no that just gets the ray result

#
local function getShadowFactor(point, sunDirection)
    local direction = (sunDirection * 1000) - point
    local shadowRay = workspace:Raycast(point, direction.Unit * 100, rayParams)
    return shadowRay and 0.4 or 1
end
astral bobcat
#

oh shoot

#

origin = point

#

looks good

hearty sluice
#

why

#

this only affects me i believe

#

but the image label isn't really receiving any changes despite being written to

#

its working

#

its woorkiiiiing

astral bobcat
#

yipee

#

looks like the rays are hitting some uncolored parts of the character

hearty sluice
#

its quite the difference

astral bobcat
#

is that armor meshparts?

hearty sluice
#

yes

#

the rest is just orange because it can't get the color of shirts and pants i believe

#

it gets skintone

#

the color of the body parts

astral bobcat
#

yea

#

time for transparency 😈

hearty sluice
#

you seem to know your way quite well around lighting and graphics

#

lol

astral bobcat
#

uhh

#

not too much

#

i just made one a while back

hearty sluice
#

i only really know the good programming habits

#

was still quite a challenge for me to divide the work over 4 threads

#

as im no master at multithreading either

#

whatever

#

here it is @scarlet terrace

#

this is main script

hearty sluice
#

changing the alpha in the 4th buffer position

#

R, G, B, Alpha

astral bobcat
# astral bobcat time for transparency 😈

i think u can do this by
casting ray: hit transparent part? multiply color by (part.Color * (1 - part.Transparency)): add transparent part to exclusion list and then cast again with the same parameters

astral bobcat
hearty sluice
#

no idea

astral bobcat
hearty sluice
#

@scarlet terrace very important note

#

for now

#

resolution always has to be divisible by the number of threads

#

70 / 4 didn't work so we used 72 instead

scarlet terrace
#

i added my frameskip optimization

#

and instead of rendering 1/3 it renders 1/2 cus i added multithreading

#

and im getting 37 average fps

hearty sluice
#

that

#

doesn't sound right

scarlet terrace
#

why

hearty sluice
#

are you using the exact same scripts i sent you

#

this

scarlet terrace
#

yes

#

si

hearty sluice
#

well

#

probably depends on your cpu then

scarlet terrace
#

beo it was 20 fps average before that optimization

#

and before mutlithreading with all my optimizations it was 27 average

#

its good wym

hearty sluice
#

ah

scarlet terrace
#

and i rendered 1/3 of the screen not 1/2

hearty sluice
#

well my standards are different lol

scarlet terrace
#

so im rendering more

hearty sluice
scarlet terrace
#

beo my pc is bad

hearty sluice
#

ok well

#

must be pretty good then

scarlet terrace
#

i can try and make it render 1/3

hearty sluice
#

wdym

#

how many threads are you using

scarlet terrace
#

4

#

beo i didnt change anything i just added something

#

look

#

wait

hearty sluice
#

this is 144p btw

#

getting 40 fps with this lol

scarlet terrace
#

uh dont mind the other optimizations but do you see frameskip

scarlet terrace
#

or what

hearty sluice
#

resolution of 144 yeah

scarlet terrace
#

alr so i made it

#

render 1/3

#

and im getting 50 fps average now

#

what are other optimizations i made i forgor

astral bobcat
scarlet terrace
#

ok i came to realize i barely did any optimizations

#

but yay 50 fps average is really good

hearty sluice
#

well i rewrote the whole syntax and did my own optimizations before sending you the script

scarlet terrace
#

thanks mobiser im gonna lick kiss and bite your left toe now

hearty sluice
#

no thanks

scarlet terrace
hearty sluice
#

and wouldn't have done it without @astral bobcat

scarlet terrace
#

you too fudufin im gonna lick and bite it and kiss it and etc

astral bobcat
#

uhh

#

no thanks

hearty sluice
#

well

#

i hope this is the end of that

#

never spent this much time on a stranger's problem before

#

lol

hearty sluice
#

now solve the thread pls

scarlet terrace
#

i guess this is it

#

goodbye 🫡

hearty sluice
#

its been a pleasure

#

bye

astral bobcat
hearty sluice
#

hmm

#

i realize i taught him nothing

#

we taught him nothing

#

lol

#

@scarlet terrace come back

#

do you know what changed

#

first we start the run service event by connecting in parallel from the get-go

#

this is the method used to connectparallel in multithreading

#

instead of regularly connecting, doing task.desync, then task.sync at the end

#

start x and end x are defined before depending on the thread's ID

#

multiplied by the thread ID

#

so it does it from 1 -> 18, 18 -> 36, up until it reaches the resolution which we have set here to 72

#

obviously you know that because you did it yourself

#

but this is done to make sure the buffer starts at 0

#

because the first buffer offset is 0 instead of 1

scarlet terrace
hearty sluice
#

but here comes the real deal

#

since we have 4 threads

#

each buffer is actually a 4th of the res x res x 4

#

so while in a single threaded approach the one and only buffer size would be

#

72 x 72 x 4 = 20736

#

here its (72 x 72 x 4) / number of threads (which is 4) = 5184 per buffer

hearty sluice
#

we multiply it by 72 to do one row after row

#

but for X

scarlet terrace
#

beo ts HAD to take a long time

hearty sluice
#

it would be % 18

#

getting you 17

#

but if its 35

#

it would also be % 18

#

getting you 17

#

for every thread

#

so it actually goes 0 -> 17 in all buffers

#

filling 18 positions in the X axis * 72 Positions in the Y axis

#

finally we just write to the buffer like normal

#

task.synchronize()

editableImage:WritePixelsBuffer( Vector2.new(startX, 0), Vector2.new(resolution / totalThreads, resolution), pixelBuffer)
#

but we do this in the end

#

since multithreading has some properties that can't be changed in parallel

#

we have to run task.synchronize() so it goes back to single threaded

#

WritePixelsBuffer has to be one of them

#

you can learn about this from the docs or when it gives you an error saying its not safe to write in parallel

#

the start position is startX here of course

#

and here

#

this is SIZE

#

not end position

hearty sluice
#

the 72 is the resolution

#

18 = resolution / total threads which substitutes for X

#

and finally the pixel buffer we wrote to

#

that's everything

#

now read everything every well so you won't need anyone's help in the future

#

i should have probably added comments around the script but too bad ig

scarlet terrace
hearty sluice
#

such is the way of scripting

#

cry now, relax later

scarlet terrace
#

Same resolution (i think)
144p

#

10-12 fps extra which is acruallt pretty good

#

Since there’s only 3 optimizations

#

Im not gonna use 144p anyways ill prob use 98

#

Which will hopefully get me to 60 fps on my phone

#

And ofc you can lower it to i’d say 68

#

Which again with other optimizations ill add would get me to 60 fps on pc

hearty sluice
#

hopefully

scarlet terrace
#

thank you guys for your help🙏

hearty sluice
#

change it to your heart's content

scarlet terrace
#

@astral bobcat come here and let me lick your feet👅

hearty sluice
#

but take my advice and try and give it a "leftover" handler thread

#

so you can avoid any buffer overheads

scarlet terrace
#

Yes, sir.salute

scarlet terrace
#

.

#

@hearty sluice delete pls uwu

hearty sluice
#

delete what

scarlet terrace
hearty sluice
#

i think it would be shunned practice to delete messages in a help thread honestly

#

no one's gonna find this anyways

scarlet terrace
#

^

#

And also do images if you can

#

No need for other messages

#

If someone makes their own version then applause to them i wouldnt care

hearty sluice
scarlet terrace
hearty sluice
#

i deleted what could possibly help any lost soul that happens to have the same problem you do

#

i hope that's not against the rules

scarlet terrace
hearty sluice
scarlet terrace
#

I just dont eant someone to make a game with it before me

scarlet terrace
#

Now for the code itself they can wait a bit