pouët.net

GLSL arrays

category: code [glöplog]
Is there any way to declare a variable size array on a GLSL shader, or do I have do declare an int n and a vec3 xxx[BIG_NUMBER]?
added on the 2010-01-19 01:21:04 by xernobyl xernobyl
you can't have variable size arrays in GLSL. From http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf:

4.1.9 Arrays

Variables of the same type can be aggregated into arrays by declaring a name followed by brackets ( [ ] ) enclosing an optional size. When an array size is specified in a declaration, it must be an integral constant expression (see Section 4.3.3 “Constant Expressions” ) greater than zero. If an array is indexed with an expression that is not an integral constant expression, or if an array is passed as an argument to a function, then its size must be declared before any such use. It is legal to declare an array without a size and then later re-declare the same name as an array of the same type and specify a size. It is illegal to declare an array with a size, and then later (in the same shader) index the same array with an integral constant expression greater than or equal to the declared size. It is also illegal to index an array with a negative
constant expression. Arrays declared as formal parameters in a function declaration must specify a size.
Undefined behavior results from indexing an array with a non-constant expression that’s greater than or equal to the array’s size or less than 0. Only one-dimensional arrays may be declared. All basic types and structures can be formed into arrays. Some examples are:

float frequencies[3];
uniform vec4 lightPosition[4];
light lights[];
const int numLights = 2;
light lights[numLights];

An array type can be formed by specifying a type followed by square brackets ([ ]) and including a size:

float[5]

This type can be used anywhere any other type can be used, including as the return value from a function

float[5] foo() { }

as a constructor of an array

float[5](3.4, 4.2, 5.0, 5.2, 1.1)

as an unnamed parameter

void foo(float[5])

and as an alternate way of declaring a variable or function parameter.

float[5] a;

It is an error to declare arrays of arrays:

float a[5][3]; // illegal
float[5] a[3]; // illegal

Arrays can have initializers formed from array constructors:

float a[5] = float[5](3.4, 4.2, 5.0, 5.2, 1.1);
float a[5] = float[](3.4, 4.2, 5.0, 5.2, 1.1); // same thing

Unsized arrays can be explicitly sized by an initializer at declaration time:

float a[5];
...
float b[] = a; // b is explicitly size 5
float b[5] = a; // means the same thing

However, implicitly sized arrays cannot be assigned to. Note, this is a rare case that initializers and assignments appear to have different semantics.
Arrays know the number of elements they contain. This can be obtained by using the length method:

a.length(); // returns 5 for the above declarations

The length method cannot be called on an array that has not been explicitly sized.
added on the 2010-01-19 05:35:27 by iq iq
I'm doing this
Quote:

uniform float apples[32];
uniform int banana;

(...)

for(int carrot=0; carrot<banana; ++carrot)
Eat(apples[carrot]);

So, defining a variable amount of apples is still impossible?
added on the 2010-01-19 07:02:43 by xernobyl xernobyl
just use a texture for bob's sake. this whole high level shader language thing is so sickening.
added on the 2010-01-19 07:40:17 by shiva shiva
xernobyl: that will work, yes... just be careful not to mess around with your carrot too much. IIRC, in shader model 3 and lower, arrays are unrolled into that many variables, so there's no real "indexing" being done.
added on the 2010-01-19 09:18:34 by xTr1m xTr1m
... an for model 2 If I'm correct, your banana value must be static. Anduse a texture as a table for bob's sake :+1.
added on the 2010-01-19 09:38:03 by krabob krabob
well, what xernobyl said, and also you could have a look at these, i'm guessing they're pretty useful in this situation (iq only focuses on the GLSL side which is a mistake obviously here, and well, people also know reading the GLSL language reference manual).

EXT_bindable_uniform
EXT_texture_buffer_object

added on the 2010-01-19 11:01:16 by nystep nystep
the interrest of texture buffer objects is that
Quote:

While buffer textures can be substantially larger than equivalent
one-dimensional textures; the maximum texture size supported for buffer
textures in the initial implementation of this extension is 2^27 texels,
versus 2^13 (8192) texels for otherwise equivalent one-dimensional
textures.

added on the 2010-01-19 11:03:00 by nystep nystep
Well, i just bump this thread to mention this article, uniform buffers vs texture buffers.

and to quote the most important results, (also in case their site doesn't work),
Quote:
Uniform Buffers

Maximum size: 64KByte (or more)
Memory access pattern: coherent access
Memory storage: usually local memory


Quote:
Texture Buffers

Maximum size: 128MByte (or more)
Memory access pattern: random access
Memory storage: global texture memory


added on the 2010-01-20 11:15:15 by nystep nystep
Quote:
Uniform Buffers - Maximum size: 64KByte (or more)

i don't think my uberpowerful GMA950 can do that...
added on the 2010-01-20 11:27:43 by blala blala
Well, indeed, and it's sad.

But according to the december 2009 steam hardware survey, intel graphic chips amount for 3,6% of steam users (which are quite representative of gamers machines nowadays).. so you can honestly just ignore intel GMA users. The other interesting fact is that 70% of people have a shader model 4 compatible graphics card (but only 45% of these have vista or win7 which enables the developers to use the full feature set only in that case under d3d 10 - i don't mean that geometry shaders are useful no, but texture arrays and rendering to 3d textures is quite interesting for nowadays 3d engines, and afaik it's only possible under d3d10 (can't wait for the D3D fanboys to scream for the scandal if i mistake here lol)). You can get however the whole feature set in opengl and target 70% of users with just one graphics codepath, in your 3d renderer though..

Steam Hardware Survey: December 2009
added on the 2010-01-20 12:32:50 by nystep nystep
Quote:
so you can honestly just ignore intel GMA users

except that i'm myself a GMA user, and i can hardly ignore *that*...
added on the 2010-01-20 13:00:42 by blala blala
blala: but you weren't the one asking the question.
added on the 2010-01-20 14:02:41 by kusma kusma
that's true. But hijacking pouet threads is as close to the meaning of life as it gets!!
added on the 2010-01-20 14:22:42 by blala blala
At the moment I the end user is me. If it works on my machine that's awesome.
added on the 2010-01-20 14:23:20 by xernobyl xernobyl
Quote:
hijacking pouet threads

seriously... if you don't want to hear about me, then ban me. it will save my time. so it's good & ok to me.

but i find it "funny" really how people's point of view can change from one person to another who posts. If the nickname was "iq", with the same speech, everyone would applause and lick my penis.. it seems i'm the little nystep black sheep of pouet, i have no idea how it happened, but i don't care what people think about me here. :)

that's it!
bye :)

added on the 2010-01-20 14:45:24 by nystep nystep
huh? i was talking about myself hijacking, not you :)
added on the 2010-01-20 14:54:17 by blala blala
Dramaqueen.
added on the 2010-01-20 15:00:54 by xernobyl xernobyl
( ..)
o_O
added on the 2010-01-20 18:29:28 by iq iq
What I understood Xernobyl was asking is "Is there any way to declare a variable size array on a GLSL shader". It's long I don't write shaders, but iirc

Code: uniforrm int numApples; uniform float apples[numApples]; uniform int banana; // banana<=numApples (...) for(int carrot=0; carrot<banana; ++carrot) Eat(apples[carrot]);


can't be done. I think the question was very clearl that, at least xernobyl made it again: "So, defining a variable amount of apples is still impossible?". The answer seems to be "yes" to me, that's why the solution himself proposes seems ok to me: "do I have do declare an int n and a vec3 xxx[BIG_NUMBER]".

Now, of course, use your favourite tech to provide a xxx[BIG_NUMBER], be it the old uniform arryas, regular textures, uniform buffers or texture buffer. Given that we are speaking of 32 apples here, not 2^27, imho focusing on just-listing-the-last-extensions-cause-I-know-them is a mistake obviously here, the proper answer (that nobody clearly gave) would have been: "yes, use your proposed method with the regular uniform arrays just are you are doing"

Bad morning!
added on the 2010-01-20 18:52:19 by iq iq
(I have a bad morning, I mean!)
added on the 2010-01-20 18:52:30 by iq iq
Good morning to you too! And thanks.
added on the 2010-01-21 14:16:35 by xernobyl xernobyl
Hi, guys! I'm trying to emulate stack operations (for the Forth translator). Please, check the line of GLSL code. Stack is "a" array and "pop" is a shift/roll function.

Code:void pop(out float a[8], out int k) { a[0]=a[1]; a[1]=a[2]; a[2]=a[3]; a[3]=a[4]; a[4]=a[5]; a[5]=a[6]; a[6]=a[7]; a[7]=0.0; k--; }


It was a bad idea, right? Looks like all that "a[n]=a[m]" runs in parallel (i.e. in random order).
Is there any solution?
added on the 2014-07-30 15:40:28 by Manwe Manwe
Update: Ized/Quite suggested to use "inout" instead of "out". It suddenly helps.
added on the 2014-07-30 16:54:10 by Manwe Manwe

login