Search Unity

Unity CG, Packing float2 to float

Discussion in 'Shaders' started by augustinus, Dec 29, 2016.

  1. augustinus

    augustinus

    Joined:
    Feb 3, 2015
    Posts:
    25
    In CG Shader, I can pass data from vertex function to surface function using this predefined struct.

    Code (CSharp):
    1. structInput{
    2.     float4 pos : SV_POSITION;
    3.     float2 uv_MainTex : TEXCOORD0;
    4.     float4 numBuffer : TEXCOORD1;
    5.     //float4 numBuffer2 : TEXCOORD2; //not support some devices.
    6. };
    I need more variables to pass, But I don't want to add TEXCOORD2.
    Because It is supported OpenGL 3.0 device only.

    So, I am trying to pack my float variables into one float with some data loss.

    This is my code snipet. But, it's doesn't work. Maybe pack and unpack function have some error logic. In C#, pack/unpacking function works perfectly. In Cg, is there any differenece?


    Code (CSharp):
    1. float pack_float2(float2 val)
    2. {
    3.     return (float)(floor(10000.0f*val.x)*65536.0f + floor(10000.0f*val.y));
    4. }
    5.  
    6. float2 unpack_float(float val)
    7. {
    8.     float2 result;
    9.     result.x = round(val/65536.0f) / 10000.0f;
    10.     result.y = (val - 10000.0f*65536.0f*result.x) / 10000.0f;
    11.     return result;
    12. }
    13.  
    14.  
    15. void vert (inout appdata_full v, out Input o)
    16. {
    17.     UNITY_INITIALIZE_OUTPUT(Input, o);
    18.  
    19.     ...
    20.     //test code. meaningful data will be passed in real code.
    21.     float2 xy = float2(0.1234, 0.1234);
    22.     o.numBuffer.x = pack_float2(xy);
    23.     xy = float2(0.5566, 0.5566);
    24.     o.numBuffer.y = pack_float2(xy);
    25.     xy = float2(0.2233, 0.2233);
    26.     o.numBuffer.z = pack_float2(xy);
    27.     xy = float2(0.3344, 0.3344);
    28.     o.numBuffer.w = pack_float2(xy);
    29.  
    30.     ...
    31. }
    32.  
    33. void surf(Input IN, inout SurfaceOutput o)
    34. {
    35.     ...
    36.  
    37.     float2 data = unpack_float(IN.numBuffer.x);
    38.  
    39.     ...
    40. }
    41.  
    Any Idea please.
     
  2. McDev02

    McDev02

    Joined:
    Nov 22, 2010
    Posts:
    664
    This looks expensive, especially for lower end devices. Try COLOR instead. But I am not sure if this will work with all kind of values.
     
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,620
    Can't you change uv_MainTex from float2 to float4, then do your own texture coordinate transformation in the vertex shader. Store the result in uv_MainTex.xy and use uv_MainTex.zw for something else?!

    If you do the texcoord transform yourself, you might need to change uv_MainTex to st_MainTex for example, because Unity is doing magic if a variable is prefixed with uv_.