#.
1 messages · Page 2 of 1
at least i hope so
its a surfaceass level solution without much thought put into it i admit
also you should take pixel buffer out of the loop
so u dont allocate and deallocate a massive buffer every frame
true aswell
all shame off me its his script
ok
this should be the final step
has to be offset somehow
"somehow"
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
lol
i've got this feeling that the math.floors could result in not so correct results
uhh
actually
workerid N endX == workerid N+1 startX
so there shouldnt be any gaps
is that like a solution to an existing problem or a formula of what i sent
no like for any workerid, its endX is equal to the next workers startX
shouldn't it be all that plus 1
afterall
?
what worker 1 writes to the endX, worker 2 will write to the startX
which are the same
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
yeah it fucks it up
i guess you just add 1 to startX for every worker except worker1
but it still leaves the problem of the positions filled not being equal to the buffer size
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
i think it has to be divisible by the number of threads leaving no decimals
very hard code-y i think
lol
any ideas?
a resolution of 80 ends up correct
or 72
hmmm
you dont need a 70x70 res buffer for every worker
they all have their own like 24x70 chunk
24?
that ended up being 17.5
now i dont think a buffer can write to a pixel and a half
lol
m
a resolution of 72 for example works because 72 / 4 = 18
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
no halves here
well im not one for complicated logic dependent on maths
still quite a beginner in that area
well
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
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?
number of threads should be only base workers i believe
we can make an extra worker that is added onto any number of threads
a leftover one
so we'd do 4 of them regularly, and the leftovers are processed through a 5th
a lot
we rewrote the whole thing pretty much
yes
bro you doing all this but telling me not to use it and just use it as a test💔
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
alr
because if you don't understand then the second you face another problem with this system you're gonna make another thread
i dont even like scripting i never liked it, i just learnt it so im able to make games
😭
i gotta sleep before i kill my sleep schedule
3 am but not sleeping
frfr
🫡
what is your average now
i dont think its a linear improvement
what
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
wdym
also i think you made a syntax error by accident herew
test
one can only test and see
wait
first
you have to make all actor scripts disabled
in workspace
alr
you can test after that
uh
both in workerscript and mainscript or just one of them?
eh
you told me to put workerscript in workspace
no
make it like this
same name?
disabled or
alr so like this
Workers folder under MainScript
do this here
and put main script in starter character scripts
well
where was it before
starterplayerscripts
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

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
remove this as well
tf is the point of this
there is only one lighting in the whole game
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
man idk
hold on
can you send a screenshot of your scripts
and are all worker scripts the same
@scarlet terrace
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
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 -
bruh
well that's a problem fs
ok
im afraid my script still has quite a lot to be dealt with
come back later
i did
probably coz it doesnt exist yet, maybe add an attribute for the worker scripts to wait for indicating it has loaded
so you dont get workers trying to get a reference to the editableimage without it being loaded yet
beo i got this too anyways
05:29:23.244 Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript:58: buffer access out of bounds - Client - WorkerScript:58
05:29:23.244 Stack Begin - Studio
05:29:23.244 Script 'Players.Pieflyo.PlayerScripts.MainScript.Workers.Actor.WorkerScript', Line 58 - Studio - WorkerScript:58
05:29:23.244 Stack End -
buffer overflow? - your offsets are wrong somewhere, prob off by 1
bro i didnt do the script dont tell me💔
yeahh im still figuring that out
but its off by more than one lol
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
with 2 threads i get 80 fps
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
dont task.syncrhonize before the writepixelsbuffer
you can call in parallel im 95% sure
or is it
oh shoot it isint
howd we let the GetSunDirection get back into the GetShadowFactor function
so it worked for you?
you cant
yea
it never did
@hearty sluice !!!
#1354636263587840030 message you dont remember?
you try it
its writing to the buffer successfully
its writing to the editable image successfuly
only
what was mainscript again
it just doesn't show up for me
no changes to main script
but here
if you need it
this is main script
hold on
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
where is that
alr so it worked there are pixels on the screen
but thing is
im getting lower fps
hold on a moment
wait did you remove other optimizations
oh
well
what needs changing
this gets the actual raycast for shadow
is this right?
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
and the origin is
man
why
this only affects me i believe
but the image label isn't really receiving any changes despite being written to
nvm
its working
its woorkiiiiing
is that armor meshparts?
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
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
wouldn't that just be
changing the alpha in the 4th buffer position
R, G, B, Alpha
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
doesnt it directly set the data
no idea
actually idk what you multiply color by, let me think this thru
@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
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
why
beo it was 20 fps average before that optimization
and before mutlithreading with all my optimizations it was 27 average
its good wym
ah
and i rendered 1/3 of the screen not 1/2
well my standards are different lol
so im rendering more
because im getting a 100-120 fps
beo my pc is bad
i can try and make it render 1/3
uh dont mind the other optimizations but do you see frameskip
resolution of 144 yeah
alr so i made it
render 1/3
and im getting 50 fps average now
what are other optimizations i made i forgor
color = color + (1 - color)*transparency
ok i came to realize i barely did any optimizations
but yay 50 fps average is really good
well i rewrote the whole syntax and did my own optimizations before sending you the script
thanks mobiser im gonna lick kiss and bite your left toe now
no thanks
💔
and wouldn't have done it without @astral bobcat
you too fudufin im gonna lick and bite it and kiss it and etc
well
i hope this is the end of that
never spent this much time on a stranger's problem before
lol
now solve the thread pls
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

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
Y already does 72 loops so we dont change that in the buffer index
we multiply it by 72 to do one row after row
but for X
beo ts HAD to take a long time
we use modulo so if X = 17
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
so it will be 18 pixels horizontally x 72 pixels vertically
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
i will but at the same time im gonna be crying to myself👍
Alr so this is before and after
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
hopefully
thank you guys for your help🙏
change it to your heart's content
@astral bobcat come here and let me lick your feet👅
but take my advice and try and give it a "leftover" handler thread
so you can avoid any buffer overheads
Yes, sir.
delete what
Dms beo
i think it would be shunned practice to delete messages in a help thread honestly
no one's gonna find this anyways
Bro just delete the code it not that hard🥀 pls
^
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
ok 
Thanks now again let me suck your rigjt toe instead of left now
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
Its gon be open source soon anyways
but that's your problem now
I just dont eant someone to make a game with it before me
The messages are there if they have the same problem
Now for the code itself they can wait a bit