Add IMaterial:SetFloat4( x, y, z, w )
Details
Having this function can save performance on really simple shaders by avoiding the round trips between Lua and C++, as it will only be two trip from 8 trips.
mat:SetFloat4("$c0", 1, 1, 1, 1) -- two C calls as mat.__index is a C one
vs
-- 8 C Calls
mat:SetFloat("$c0_x", 1)
mat:SetFloat("$c0_y", 1)
mat:SetFloat("$c0_z", 1)
mat:SetFloat("$c0_w", 1)
Does this not fulfill that purpose? https://wiki.facepunch.com/gmod/IMaterial:SetVector4D
Edit: Oh nevermind you want it to magically fill out different parameters
Edit: Oh nevermind you want it to magically fill out different parameters
Wouldn't it just work like SetVector4D?
Material parameters each have a type. Each function sets only 1 material parameter. You want a function that sets 4 individual material parameters, while assuming their names.
Could probably change the shader/material parameter to just be a vector4 instead of 4 separate ones, but idk.
Material parameters each have a type. Each function sets only 1 material parameter. You want a function that sets 4 individual material parameters, while assuming their names.
I'm not following, isn't float4 in shaders always x y z w? How would it need to assume their names?
I will try to change it to vector4 as they probably have same memory layout so maybe it could work? lol
I'm not following, isn't float4 in shaders always x y z w? How would it need to assume their names?
Imo, it's not a good practice to have functions assume the x,y,z,w suffix when setting parameters. Maybe an optional parameter for SetVector4D, but I am not really sure what's the best option to tackle this request is.
I will try to change it to vector4 as they probably have same memory layout so maybe it could work? lol
That is very unlikely to work, I meant changing the parameters from my end to just be a vector4.
You are basically asking for a function that is only useful for 1 shader.
I'm not sure if there is any other way to pass parameters to shaders without using float4, maybe currently it will only be useful for this use-case but more people will start using it once you release thirdparty shaders and it would be better practice for them to use it.
if someone is using all constants, the amount of C calls's cost will probably outweigh the cost of drawing the shader itself.
Your idea of adding optional parameter for SetVector4D is probably the best call.
It is indeed a stinky solution. What could be a better one is batched var changes, ala:
mat:SetFloats {
["$c0_x"] = 1,
["$c0_y"] = 1,
["$c0_z"] = 1,
["$c0_w"] = 1
}
This, however, is an allocation. Another way, that only uses stack, is this:
mat:SetFloats("$c0_x", 1, "$c0_y", 1, "$c0_z", 1, "$c0_w", 1)
This is, possibly, not exactly optimal if we consider developer experience and type declaration stuff, but its pretty efficient as it only works with the stack.
It is indeed a stinky solution. What could be a better one is batched var changes, ala:
mat:SetFloats { ["$c0_x"] = 1, ["$c0_y"] = 1, ["$c0_z"] = 1, ["$c0_w"] = 1 }
This, however, is an allocation. Another way, that only uses stack, is this:
mat:SetFloats("$c0_x", 1, "$c0_y", 1, "$c0_z", 1, "$c0_w", 1)
This is, possibly, not exactly optimal if we consider developer experience and type declaration stuff, but its pretty efficient as it only works with the stack.
For former one I can just use a local table and change values inside it, but it won't be viable for people to use it if they are calling lots of them.
The latter could work too but I prefer having an optional parameter to SetVector4D as it's simple with less work to do for us/him lol
The second solution is rather simple from the C side, so its not that much work imo.
Both would be very fast indeed, any of them would be better than 8 trips.
After thinking about it, artemking4's latter solution seems the best. It can allow any number of floats to set and also having the power of setting it for any key, also it's not hard to read/write:
mat:SetFloats(
"$c0_x", 1,
"$c0_y", 1,
"$c0_z", 1,
"$c0_w", 1,
...rest
)
After thinking about it, artemking4's latter solution seems the best. It can allow any number of floats to set and also having the power of setting it for any key, also it's not hard to read/write:
mat:SetFloats( "$c0_x", 1, "$c0_y", 1, "$c0_z", 1, "$c0_w", 1, ...rest )
We can develop this even further and come up with something like this:
-- Through stack
material:SetParameters(
'$<parameter1>', <any>,
'$<parameter2>', <any>,
'$<parameter3>', <any>,
...
)
-- Through table
material:SetKeyValues( {
['$<parameter1>'] = <any>,
['$<parameter2>'] = <any>,
['$<parameter3>'] = <any>,
...
} )