Search Unity

Surface Shaders and general opengl issues

Discussion in 'Shaders' started by Noisecrime, Jul 22, 2014.

  1. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    Hi,

    Come across a number of issues with opengl/gles but not found any answers searching online, so figured i'd ask and see if anyone else has run into them and found any solutions.


    GLSL: array sizes larger than 99 not supported
    I'm declaring a uniform array to pass values to the shader, but if i have more than 99 elements in an array I get this error. Searching online I've been unable to find anything in the glsl specs so it would appear to be an arbitrary Unity restriction.

    This appears on Mac, and sometimes on Windows if building for a gles target or using the editor with -force-opengl command line.


    GLSL: Version 1.2
    I've ran into a few isues with Unity being limited to glsl 1 (or 1.1 whichever version it defaults too). For example not supporting non-square matrices. As far as I can tell non-square matrices are supported in glsl 1.2 and above, but I cannot find any means (at least in a surface shader) to force Unity's glsl compiler to use 1.2.

    Has anyone found a method to achieve this?


    Matrix Row/Col Access
    I wanted to extract a row or column ( can never remember which is which in openGL) from a matrix using m[n] where n =0 to 3. It works fine but looking at Unity's compiled code for opengl/gles it always converts to the opposite (row or column).

    e.g.

    Code (CSharp):
    1. float4 r =_InputMatrix[ whichRow ];
    becomes
    Code (CSharp):
    1. mat4 m_11;
    2. m_11 = (_InputMatrix[tmpvar_4]);
    3. vec4 v_12;
    4. v_12.x = m_11[0][tmpvar_3];
    5. v_12.y = m_11[1][tmpvar_3];
    6. v_12.z = m_11[2][tmpvar_3];
    7. v_12.w = m_11[3][tmpvar_3];
    Now I can understand it doing this if based on row-column ordering I was trying to get non-consective values, but ignoring my propensity to get the terminology mixed up if I was trying to get the four consecutive floats from a matrix then it would seem to be impossible.

    I've not analysed the dx9 assembly in depth, but I don't think it suffers from the same issue. From checking glsl sources it would seem matrix[n] is meant to work fine and give you back the row/column, it would seem like again Unity is deliberately doing this. Perhaps Unity matrices are not using the same structure layout as glsl so this would sort of make sense, but this then means it is impossible to directly copy a row/col from a matrix efficiently, assuming that doing it long hand like in the above code is in-efficient.

    Anyone got any ideas about this?


    Multi-dimensional arrays
    These should be supported (e.g. float4[4] or float[4][4], but i've been unable to get Unity's cg compiler to accept them.
     
  2. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    Hello! May you explain how do you use a arrays to pass a data to the shader?
     
  3. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    Just define a uniform array in the shader, then use material Set<property> function using the name of the array and appending the index value to it. Remember that arrays start at 0.

    In the shader

    float4 _myArray[25];

    in code,
    material.SetVector("_myArray0", myVector);
    material.SetVector("_myArray9", myVector);
    material.SetVector("_myArray14", myVector);
    material.SetVector("_myArray24", myVector);

    If you check out the compiled source to a shader using an array in Unity for Dx9 you're see the arrays defined one element at a time, though I guess it may be treated as a single continuous piece of memory.

    I can't be sure but in testing I suspect opengl/gles may not be as optimal as dx using this technique.
     
    mouurusai likes this.
  4. mouurusai

    mouurusai

    Joined:
    Dec 2, 2011
    Posts:
    350
    Thanks you it's may add some interesting usage ways.