Search Unity

how to access/assign matrix members for use in a pixel shader?

Discussion in 'Shaders' started by tswalk, Apr 12, 2014.

  1. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    I've tried a few different approaches to packing data into a matrix for use in the fragment portion of my shader and I just am having some troubles understanding the correct syntax to use.

    I've tried both the Cg 3.1 standard and HLSL version and keep getting errors similar to the following:

    Code (csharp):
    1. Program 'vert', invalid subscript '_m11_m12_m13' (compiling for d3d11) at line 23
    What I've tried so far is defining a simple float3x3 with the TEXCOORD# semantic in the structure of my output, and assigning values such as

    Code (csharp):
    1.  
    2. "o.mymatrix._m11_m12_m13 = ...
    3. o.mymatrix[1] = ...."
    4.  
    then attempting to retrieve those values for use in formulas within the fragment similar to:

    Code (csharp):
    1.  
    2. float3 result = something.r * i.mymatrix._m11_m12_m13;
    3.  

    I even tried the HLSL way of being specific about the type of matrix (which isn't complained about):
    Code (csharp):
    1.  
    2. struct vOut{
    3. float4 pos : SV_POSITION;
    4. matrix <float, 3, 3> mymatrix : TEXCOORD0;
    5. }
    6.  
    but yet, I still get invalid subscript errors.


    so, how do I correctly assign and then access the members as I would with a simple scalar like float? (color.rgb)

    I even went so far to make a really hacky attempt to replicate the UNITY_MATRIX_TEXTURE setup:

    Code (csharp):
    1.             float3 mtex[2];
    2.             float3 mtex0;
    3.             float3 mtex1;
    4.            
    5.             #define MTEX mtex
    6.             #define MTEX0 mtex0
    7.             #define MTEX1 mtex1
    8.  
    and then...
    Code (csharp):
    1.  
    2. struct vOut{
    3. float4 pos : SV_POSITION;
    4. MTEX mymatrix : TEXCOORD0;
    5. }
    6.  
    which provided "Program 'vert', unrecognized identifier 'mtex'...."


    so, I dunno... any ideas what I am doing wrong?
     
  2. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    ok, well.. I figured it out, but I reached a limit:

    Program 'frag', error X4506: ps_4_0_level_9_1 input limit (8) exceeded

    because I had to use a float3x3 matrix when I really only needed a float3x2, but I was running into problems:

    Program 'vert', cannot implicitly convert from 'float2' to 'float3'

    which made no sense to me when in the structure I defined a "float3x2 mymatrix : TEXCOORD5;" (which takes only 2 registers)

    and then constructed the block o.mymatrix = float3x2(float3setA, float3setB); << this seems to be my problem

    both float3setA and float3setB are defined as float3

    i'm confused.
     
  3. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    The limits for ps_4_0_level_9_1 are lower than you might expect. I assume you're working in DX11 mode, and that it simply defaulted to 4.0. If your target hardware supports it, you could simply use:
    Code (csharp):
    1. #pragma target 5.0
     
  4. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    in a way:

    Code (csharp):
    1.  
    2. #pragma only_renderers d3d11_9x d3d11
    3. #pragma target 2.0
    4.  
    i'll try 5.0 to see how it compiles, but i'm pretty confident that the Tegra 3 (ARM) platform is only target 2.0

    and yes, the limits are pretty damn tight... but you know, I've learned a lot trying to "get things to work".

    right now i'm trying to figure out how to implement the cube normalization technique from chapter 8 (cg tutorial), but I still need to verify the operations in bytecode that are actually being translated/compiled by Unity into the final shader to make sure it will actually reduce instructions from 3 to 2. I believe this was the technique that the folks from Madfinger used on their optimized shaders.

    http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter08.html

    so far I've been able to build a shader to use tangent based normal map with gloss,specular, and light mapping with only 18 ALU and 22 instructions

    Code (csharp):
    1. // 22 instructions, 3 temp regs, 0 temp arrays:
    2. // ALU 18 float, 0 int, 0 uint
    3. // TEX 0 (0 load, 0 comp, 0 bias, 0 grad)
    4. // FLOW 1 static, 0 dynamic
    5. "vs_4_0_level_9_1
    its' currently running ~30fps on the Tegra 3, but I think I can squeeze more out and was earlier attempting to pack some calculations from vertex to fragment in a matrix.
     
    Last edited: Apr 13, 2014