Below "uniform line" in shader gives "Expected datatype.-" error.
struct points{
vec2 p[8];
};
uniform points pointsArray;
Do I have syntax mistake?
Below "uniform line" in shader gives "Expected datatype.-" error.
struct points{
vec2 p[8];
};
uniform points pointsArray;
Do I have syntax mistake?
According to the documentation all GLSL types except void can be used as uniform. That does not include user defined data types.
Am no crack in Godot shading language but know a bit about GLSL. There, that can't work. Any implementation of a C or C++ compiler is free to choose whatever memory layout it pleases for user-defined data types (here structs and classes, which are the same). So there must be a way to transmit that extra description together with a struct, like what datatypes come, how many bytes do they use, their memory order, is there any padding in between to fill spaces, and GDScript would have to do the same.
GLSL and its C specification solves this with uniform blocks and pre defined memory layouts, and a set of functions to query a shader's interface, it's list of uniforms and other buffer objects. Unless Godot shading language offers an own way of handling these interfaces (that'll be a lot of work on all the platforms), I believe that you have to pass in all the uniforms one by one. Though that's very slow compared to a properly set up GLSL or Vulkan buffer object.
But wait for a crack to show up with better knowledge about Godot shading language, maybe there's a way I'm not aware of.
Brien Thx
"According to the documentation all GLSL types except void can be used as uniform. That does not include user defined data types.'
GLSL does support user-defined types as uniforms. See here: https://www.khronos.org/opengl/wiki/Uniform_(GLSL)
Uniforms can be of any type, or any aggregation of types. The following are all legal GLSL code:
struct TheStruct
{
vec3 first;
vec4 second;
mat4x3 third;
};
uniform vec3 oneUniform;
uniform TheStruct aUniformOfArrayType;
uniform mat4 matrixArrayUniform[25];
uniform TheStruct uniformArrayOfStructs[10];
Godot is not straight GLSL. It basically is, but not totally (for example, you can't use uniform arrays). However, you can pack data into existing types. For the OP, they could use a mat3, which gives you 12 floats (or doubles). And then just write a function to index it like you wish. I think the largest type is 16 floats for mat4. If you need more than that, you'll have to pack the data into a look up texture.
Thanks for heads up, did not know that. I use uniform buffers and blocks when necessary. They go like (example with std 140):
layout (std140) uniform block_name {
vec3 something;
float something_else;
}
And have a buffer object attached top them that can mapped and memcpy'd or glBufferData'd() by the application. The components are not set individually. I think a struct still needs querying locations from the application and set the components individually with one th glUniform*() functions.
Whatever, learnt something, though I'll probably never use it.
As of godot 3.2 arrays are supported but only as locals or varying. If you need to pass in a vector array, a workaround can be to codify them in a texture and pass that texture in via a uniform. Can't give further details since I haven't done this myself but I know some others have so there should be a way. (edit: I see Sabbatical already covered this...)
Electroscope GLSL does support user-defined types as uniforms. See here: https://www.khronos.org/opengl/wiki/Uniform_(GLSL)
Note that godot shaderlanguage is a subset of GLSL and that as of godot 3.x at least godot only really supports GLES, while it's true that on desktop it uses GL not GLES, it still follows the GLES spec. So if it's not supported by GLES 3.0 then it's likely not supported. Also note that GLSL itself has versions and specific GL/GLES versions only support specific GLSL versions.
In 4.0+ the vulkan renderer will likely alleviate many of these limitations, but if you want to support lower end machines then once it is released you'll likely end up using the (to be supported later) GLES renderer anyways.
So, yeah, structs in Godot shaders, and their use as uniforms appears to triggers an error.
In GLSL structs can be defined and used as uniforms (the latter was new to me), but the application can't just pass in a C or C++ struct because of the mentioned reasons. So the application must query the location of each component of a struct and use the data type specific functions to pass in data. So far for GLSL and C/C++.
Arrays are a different thing, as their layout in C and C++ is guaranteed to be sequential without gaps in memory, which is not the case for structs.
Apparently there is an open proposal:
https://github.com/godotengine/godot-proposals/issues/3569
With Vulkan and SPIR-V, I personally think that the use of structs as uniforms is not needed any more (if it ever was) even in low level shading languages, as it could have a bad influence on performance if overdone. Proper buffer objects with a clear design I think can be the better way. They also make it easier to keep the shader interfaces (the bunch of buffers and uniforms visible in the application) as re-usable as possible, which speeds up changes when pipelines are switched or otherwise re-arranged.
© 2022 - 2024 — McMap. All rights reserved.