Closed amyadzuki closed 6 years ago
I may have found it. It looks like the magic happens with the call to gs.Uniform3fvUP
inside RenderSetup
. If I create my own material type which implements IMaterial
, then I can buffer as many uniforms as I like by using repeated calls to gs.Uniform3fvUP
inside my type's RenderSetup
method. Right?
Right - you should create your own material type, and uniforms should be transferred inside a RenderSetup
function. You can see some internal examples of uniform transfer calls in gui/panel.go
, texture/texture2D.go
and material/standard.go
.
There are several gs.Uniform<*>
functions, one for each data type and quantity - see here for the full supported list. You can use repeated calls inside RenderSetup
and that would be a good way to start and probably fine to keep. However, cgo calls are very slow relative to normal Go functions and that slowness can quickly add up when those calls happen every frame. To make g3n as fast as possible, we try to minimize cgo calls per frame like uniform transfer calls. Therefore we often pack all uniforms into a single udata
object and send it to the GPU with only a single transfer call gs.Uniform3fvUP
or gs.Uniform4fvUP
depending on which is more convenient to unpack inside the shader. You can see an example of unpacking inside a shader here:
https://github.com/g3n/engine/blob/235d48ba1ac33f2992dcf66ba87e6c36858ae83f/renderer/shaders/physical_fragment.glsl#L47-L53
When transferring a udata
Go object we need to use an unsafe.Pointer
(that's why the "UP" in the function name) because we are assuming that the internal memory structure of udata
is unchanged when going from Go to C.
Thank you so so much! That helped a lot and I ended up getting it to work ^_^
I feel like I'm missing something obvious here, but how do I make a material for a custom shader that needs lots of uniforms? I'm implementing my human skin shader, and it needs uniforms for the bones to implement skeletal animation, as well as some values specific to my use case, such as skin color in a vec3, etc. Sorry if I missed something obvious.
Thanks, Amy
P.S. Exposing a ModelMatrix uniform would grant access to the position in world space of the current fragment inside fragment shaders, which might be helpful for things like texture tiling or fixed-location objects, etc. I don't need it because in my one use case it just happens that the model matrix was constant, but I thought I should mention it.