Search Unity

Texcoord 4 and Surface Shaders

Discussion in 'Shaders' started by PrimalSeed_Requiem, Jul 11, 2019.

  1. PrimalSeed_Requiem

    PrimalSeed_Requiem

    Joined:
    Oct 2, 2017
    Posts:
    1
    Hello, I'm currently creating a splatmap-like shader that must use 6 textures, and I just encoutered a problem with the macro UNITY_SAMPLE_TEX2DARRAY, specifically to the layer 4 (line 158, see attached file).

    I'm getting the error message :

    "invalid subscript 'texcoord4' at line 320 (on d3d11)"

    It looks like from the generated code that layer4 and layer5 are packed into pack 2 which use the binding TEXCOORD2 (line 274 from generated code, see below).

    However, later the pack is initialized with "o.pack2.xy = TRANSFORM_TEX(v.texcoord4, layer4);" (line 385).

    Is there a limit of the number of UV sets you can use in a surface shader ? What are the workarounds ?
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    7,002
    Unfortunately, yes. Surface Shaders are limited to TEXCOORD0 through TEXCOORD3, and can only use the first two components of each TEXCOORD# for uv# input struct variables. This is because Unity uses the built in appdata_full struct which doesn't include the full set of texcoords that the mesh format currently supports.

    The work around is to pack two UV sets per texcoord and use a vertex function to pass the data manually. Alternatively, if the UVs are all roughly the same with only different scales and offsets, use only one uv on both the mesh and in the Input struct and apply the scale & offset in the surf function. This is far more efficient on multiple levels as you're passing much less data to the GPU and between the vertex and fragment shaders. The Surface Shader default of applying offsets in the vertex shader and passing multiple UVs even when they're using a single texcoord is a legacy thing related to DirectX 9 and some OpenGLES 2.0 hardware that serves no benefits today.