Is there any way to set length of integer array with variable in hlsl? - unity3d

firstly, I wish you guys can understand awkward grammar skills of next writing. English is not my first language.
Im currently using UnityEngine Now. what i wanna do is sending a number of rows to a shader, so that i can set a count of rows of stripes in Gameobject mesh using the shader which got the number of stripes.
And I made to send a number variable to a shader, but when i try to create int array in CG program part(which is HLSL) with size of the rows that i want using the number, unity Engine gives me this error message - "array dimensions must be literal scalar expressions".
This is the integer variable that i set in my unity shader script. This gets integer value from c# script function(this part doenst have any issue)
_LowCount ("LowCount", int) = 0
And this is CG Program part which im struggling with.
The variable below is declared in global field. It receives number value from the properties.
int _LowCount;
And this is fragment shader function part and it declares integer array in its local field setting the array size on integer variable - "_LowCount"
fixed4 frag(v2f i):COLOR{
fixed4 c=0;
int ColorsArray[_LowCount];
for(int aa=0;aa<_LowCount;aa++){
ColorsArray[aa]=0;
}
return c;
And below part from fragment shader function gives me the error that i mentioned in above.
int ColorsArray[_LowCount];
I searched this issue in google, then i realized i have to set array size with number value( not a variable). But I need an integer array with size of number variable that i can give any integer value anytime i want. Is there any solution?
*ps. I started to learn CG graphics from just 2 weeks ago. So I might be wrong in my understading and my knowledge. Thank you.

There is no way to define an hlsl array with variable size. From the docs:
Literal scalar expressions declared containing most other types
Either preallocate with the maximum array size int ColorsArray[maximum possible _LowCount];
It's not super clear what your end goal is, but another solution may be to execute a different shader for each object instead. See if you can update your question a little and I'll update the answer.

Related

Dividing a character with a Float in Ada

So i´m trying to divide a character with a float using an operator, but I dont know why my code gets the error message "unexpected argument for "Position" attribute"
function "/"(Teck: in Character;
Flyt: in Float) return Float is
begin
return Float(Character'Position(Teck))/Flyt;
end "/";
Can somebody explain how Character'position works and what I need to change here, because I´ve used pretty much the same code previously in a different assigment.
Regarding the ARM, characters are, for example, defined as
UC_C_Cedilla : constant Character := 'Ç'; --Character'Val(199)
And if you read the operations on discrete types in the ARM, you'll se that the inverse attribute of Val is Pos, not Position.

Create constant for specifying array size in MATLAB Coder

How can I create a constant variable in MATLAB (and its results the generated C code), so I can use it later in my code to specify the size of variables.
I want to have an array that its size is not hardcoded via number all over the code.
I want to specify the size at the beginning of the code like how we do in C code using one of the followings:
const int arraySize=5
#define arraysize 5
Later: int array[arraySize];
When I write the following in MATLAB, Coder just replaces arraySize with the actual number which is 5:
arraySize=int8(5);
array=zeros(1,arraySize); % zeros is just used for specifying size
Generated code:
void coder(double A[5])
{
memset(&A[0], 0, sizeof(double) << 16);
}
I tried using the following but it does not allow me to use arraySize in MATLAB calculations:
arraySize=coder.opaque('const int16','5');
A=zeros(1,arraySize);
This may be related to constant folding which I can not disable!
This array size may be repeated throughout the different functions and code many times, so global probably may be related to this
Having a constant variable appear by name (rather than the value) in the sizes of other variables is unfortunately not supported in MATLAB Coder as of MATLAB R2019a. We've made an internal note of your request so we can look at lifting that limitation in the future.

Why is find in matlab returning double values

The find function within matlab returns indices where the given locigal argument evaluates true.
Thus I'm wondering, why the return values (for the indices) are of type double and not uint32 or uint64 like the biggest index into a matrix could be.
Another strange thing which might be connected to that here is, that running
[~,max_num_of_elem]=computer
returns the maximal number of elements allowed for a matrix in the variable max_num_of_elem which is also of type double.
I can only guess, but probably because a wide range of functions only support double. Run
setdiff(methods('double'), methods('uint32'))
to see what functions are defined for double and not for uint32 on your version of MATLAB.
Also there is the overflow issue with integer data types in MATLAB that can introduce some hard to detect bugs.

glUniform4fv is giving GL_INVALID_OPERATION

I' trying to develop a basic game in iOS and OpenGL ES but I'm stuck on this problem with the uniforms, here is the code that passes the value to my uniform:
glBindVertexArrayOES(_vertexArray);
// Render the object with ES2
glUseProgram(self.shaderProgram);
glUniformMatrix4fv(uniformModelViewProjection, 1, 0, modelViewProjectionMatrix.m);
// Get uniform center position
glUniform4fv(uniformCenterPosition, 1, centerPosition.v);
// Get uniform time position
glUniform1f(uniformTime, time);
// Set the sampler texture unit to 0
glUniform1i(uniformTexture, 0);
glDrawArrays(GL_POINTS, 0, numVertices);
Notice that care has been taken to position the glUniform function preceded with glUseProgram and before the glDrawArrays call is made. The uniform locations look fine also as confirmed via tracing. Here is what I get when I run the OpenGL ES Analyzer tool in XCode:
It returns a GL_INVALID_OPERATION for glUniform4fv, notice that the values represented seem to be correct.
Here are the possible causes for the GL_INVALID_OPERATION error I found from the documentation:
there is no current program object.
the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.
one of the signed or unsigned integer variants of this function is used to load a uniform variable of type float, vec2, vec3, vec4, or an array of these, or if one of the floating-point variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4, or an array of these.
one of the signed integer variants of this function is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these.
one of the unsigned integer variants of this function is used to load a uniform variable of type int, ivec2, ivec3, ivec4, or an array of these.
location is an invalid uniform location for the current program object and location is not equal to -1.
count is greater than 1 and the indicated uniform variable is not an array variable.
a sampler is loaded using a command other than glUniform1i and glUniform1iv.
None of them seem to explain why the heck I am receiving this error. It's driving me crazy, please help!
Adding my comment as an answer, since it turned out to be the solution:
The only causes from that list that I could imagine are points 2 and 3:
the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.
one of the signed or unsigned integer variants of this function is used to load a uniform variable of type float, vec2, vec3, vec4, or an
array of these, or if one of the floating-point variants of this
function is used to load a uniform variable of type int, ivec2, ivec3,
ivec4, unsigned int, uvec2, uvec3, uvec4, or an array of these.
So make sure that the corresponding uniform variable is really declared as vec4 in the shader (maybe it's a vec3?).

Can you explain this Embedded MATLAB Function error?

I'm having a problem sending a value from a GUI to an Embedded MATLAB Function (EMF) in a Simulink model. I get this value from a slider in my GUI and send it to an EMF block in my model. I can confirm that the value is being transferred correctly from my GUI to my Simulink block, since I can display the value with a display block in my model and see the value change when I change the slider position in my GUI. However I keep getting this error when I run my model:
Could not determine the size of this expression.
Function 'Kastl' (#18.282.283), line 14, column 1:
"f"
This is part of my EMF block code:
function y = input_par(u,fstart)
...
f_end = 1000;
f = fstart:f_end;
...
I believe MikeT is correct: you can't redefine the size of a variable in an embedded function. If you look at this Embedded MATLAB Function documentation page under the subsection Defining Local Variables, it says:
Once you define a variable, you cannot
redefine it to any other type or size
in the function body.
You will have to rework your embedded function such that the variables you declare are not changing size. Since I don't know what you are subsequently doing with the variable f, there's not much more specific help I can give you.
In general, if you absolutely need to use data that changes size, one solution is to pad the data with "garbage" values in order to maintain a constant size. For example:
MAX_ELEMS = 1000; % Define the maximum number of elements in the vector
f = [fstart:MAX_ELEMS nan(1,fstart-1)]; % Create vector and pad with NaNs
In the above example, the variable f will always have 1000 elements (assuming the value of fstart is an integer value less than or equal to 1000). The value NaN is used to pad the vector to the appropriate constant size. Any subsequent code would have to be able to recognize that a value of NaN should be ignored. Depending on what calculations are subsequently done in the embedded function, different pad values might be needed in place of NaN (such as 0, negative values, etc.).
I believe the issue you are running into is that you can't change a parameter during simulation that will cause the dimension of a signal to change. In your example, the code,
f = fstart:f_end;
changes size whenever fstart changes. I think this is what EMF block is complaining about. I don't have any easy workaround for this particular issue, but maybe there's an equivalent way of doing what you want that avoids this issue.