Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Force to use highp local variables in fragment shader on Android

Discussion in 'Shaders' started by ZhivaevDmitriy, Aug 1, 2020.

  1. ZhivaevDmitriy

    ZhivaevDmitriy

    Joined:
    May 15, 2018
    Posts:
    4
    Hello, I am using Unity 2020.1.0f1 and I need to get precise height data in fragment shader on Android.
    This is necessary in order to draw beautiful elevation lines.

    My shader (I've just simply modify and copy URP graph shader):

    Code (CSharp):
    1. Shader "Unlit Master"
    2. {
    3.     Properties
    4.     {
    5.         [NoScaleOffset]SurfaceHeightfield("SurfaceHeightfield", 2D) = "black" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags
    10.         {
    11.             "RenderPipeline"="UniversalPipeline"
    12.             "RenderType"="Opaque"
    13.             "Queue"="Geometry+0"
    14.         }
    15.        
    16.         Pass
    17.         {
    18.             Name "Pass"
    19.             Tags
    20.             {
    21.                 // LightMode: <None>
    22.             }
    23.          
    24.             // Render State
    25.             Blend One Zero, One Zero
    26.             Cull Back
    27.             ZTest LEqual
    28.             ZWrite On
    29.             // ColorMask: <None>
    30.            
    31.        
    32.             HLSLPROGRAM
    33.             #pragma vertex vert
    34.             #pragma fragment frag
    35.        
    36.             // Pragmas
    37.             #pragma prefer_hlslcc gles
    38.             #pragma exclude_renderers d3d11_9x
    39.             #pragma target 3.5
    40.             #pragma multi_compile_fog
    41.             #pragma multi_compile_instancing
    42.          
    43.             // Keywords
    44.             #pragma multi_compile _ LIGHTMAP_ON
    45.             #pragma multi_compile _ DIRLIGHTMAP_COMBINED
    46.             #pragma shader_feature _ _SAMPLE_GI
    47.             // GraphKeywords: <None>
    48.            
    49.             // Defines
    50.             #define ATTRIBUTES_NEED_NORMAL
    51.             #define ATTRIBUTES_NEED_TANGENT
    52.             #define ATTRIBUTES_NEED_TEXCOORD0
    53.             #define VARYINGS_NEED_TEXCOORD0
    54.             #pragma multi_compile_instancing
    55.             #define SHADERPASS_UNLIT
    56.            
    57.             #define PREFER_HALF 0
    58.             #define SHADER_HINT_NICE_QUALITY 1
    59.        
    60.             // Includes
    61.            
    62.             ...
    63.        
    64.             // --------------------------------------------------
    65.             // Graph
    66.        
    67.             // Graph Properties
    68.             CBUFFER_START(UnityPerMaterial)
    69.             CBUFFER_END
    70.             TEXTURE2D_FLOAT(SurfaceHeightfield);
    71.             SAMPLER(samplerSurfaceHeightfield);
    72.             float4 SurfaceHeightfield_TexelSize;
    73.             SAMPLER(SamplerState_Linear_Clamp);
    74.        
    75.             // Graph Vertex
    76.             // GraphVertex: <None>
    77.            
    78.             // Graph Pixel
    79.             struct SurfaceDescriptionInputs
    80.             {
    81.                 float4 uv0;
    82.             };
    83.            
    84.             struct SurfaceDescription
    85.             {
    86.                 float3 Color;
    87.                 float Alpha;
    88.                 float AlphaClipThreshold;
    89.             };
    90.            
    91.             SurfaceDescription SurfaceDescriptionFunction(SurfaceDescriptionInputs IN)
    92.             {
    93.                 SurfaceDescription surface = (SurfaceDescription)0;
    94.  
    95.                 surface.Color =
    96.                     SurfaceHeightfield.Sample(SamplerState_Linear_Clamp, IN.uv0);
    97.  
    98.                 surface.Alpha = 1;
    99.                 surface.AlphaClipThreshold = 0;
    100.  
    101.                 return surface;
    102.             }
    103.        
    104.            ...
    105.  
    106.             ENDHLSL
    107.         }
    108.  
    109.         ...
    110.  
    111.     }
    112. }
    113.  
    I have added line 57 and 58 by myself:

    #define PREFER_HALF 0
    #define SHADER_HINT_NICE_QUALITY 1


    After I press "compile and show code" and see this in glsl:
    Code (CSharp):
    1.  
    2.  
    3. ...
    4.  
    5. #ifdef VERTEX
    6. #version 300 es
    7.  
    8. ...
    9.  
    10. in highp vec3 in_POSITION0;
    11. in highp vec4 in_TEXCOORD0;
    12. out highp vec4 vs_TEXCOORD0;
    13. vec4 u_xlat0;
    14. vec4 u_xlat1;
    15. void main()
    16. {
    17.     u_xlat0.xyz = in_POSITION0.yyy * hlslcc_mtx4x4unity_ObjectToWorld[1].xyz;
    18.     u_xlat0.xyz = hlslcc_mtx4x4unity_ObjectToWorld[0].xyz * in_POSITION0.xxx + u_xlat0.xyz;
    19.     u_xlat0.xyz = hlslcc_mtx4x4unity_ObjectToWorld[2].xyz * in_POSITION0.zzz + u_xlat0.xyz;
    20.     u_xlat0.xyz = u_xlat0.xyz + hlslcc_mtx4x4unity_ObjectToWorld[3].xyz;
    21.     u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
    22.     u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
    23.     u_xlat0 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
    24.     gl_Position = u_xlat0 + hlslcc_mtx4x4unity_MatrixVP[3];
    25.     vs_TEXCOORD0 = in_TEXCOORD0;
    26.     return;
    27. }
    28.  
    29. #endif
    30. #ifdef FRAGMENT
    31. #version 300 es
    32.  
    33. precision highp float;
    34. precision highp int;
    35.  
    36. ...
    37.  
    38. UNITY_LOCATION(0) uniform highp sampler2D SurfaceHeightfield;
    39. in highp vec4 vs_TEXCOORD0;
    40. layout(location = 0) out highp vec4 SV_TARGET0;
    41. mediump vec3 u_xlat10_0;
    42. void main()
    43. {
    44.     u_xlat10_0.xyz = texture(SurfaceHeightfield, vs_TEXCOORD0.xy).xyz;
    45.     SV_TARGET0.xyz = u_xlat10_0.xyz;
    46.     SV_TARGET0.w = 1.0;
    47.     return;
    48. }
    49.  
    50. #endif
    51.  

    The problem is in line 41 :

    mediump vec3 u_xlat10_0;

    I need highp here. How can i archive that?
     
  2. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,090
    Perhaps #pragma fragmentoption ARB_precision_hint_nicest might do the trick!
     
  3. ZhivaevDmitriy

    ZhivaevDmitriy

    Joined:
    May 15, 2018
    Posts:
    4
    Nope, does not work(

    Unfortunately, as described here:
    https://docs.unity3d.com/Manual/SL-ShaderPrograms.html

    Directive "#pragma fragmentoption" deprecated and don't do anything.
     
  4. ZhivaevDmitriy

    ZhivaevDmitriy

    Joined:
    May 15, 2018
    Posts:
    4
    That's very strange and interesting.

    I have replaced line 95, 96 in shader by this:

    surface.Color = SAMPLE_TEXTURE2D(SurfaceHeightfield, samplerSurfaceHeightfield, IN.uv0).xyz;

    and then, success:

    Code (CSharp):
    1. #ifdef FRAGMENT
    2. #version 300 es
    3.  
    4. ...
    5.  
    6. UNITY_LOCATION(0) uniform highp sampler2D SurfaceHeightfield;
    7. in highp vec4 vs_TEXCOORD0;
    8. layout(location = 0) out highp vec4 SV_TARGET0;
    9. vec3 u_xlat0;
    10. void main()
    11. {
    12.     u_xlat0.xyz = texture(SurfaceHeightfield, vs_TEXCOORD0.xy).xyz;
    13.     SV_TARGET0.xyz = u_xlat0.xyz;
    14.     SV_TARGET0.w = 1.0;
    15.     return;
    16. }
    17.  
    18. #endif
    But if I change this line with (different SamplerState):

    surface.Color = SAMPLE_TEXTURE2D(SurfaceHeightfield, SamplerState_Linear_Clamp, IN.uv0).xyz;

    Again get precision reduction:

    Code (CSharp):
    1. #ifdef FRAGMENT
    2. #version 300 es
    3.  
    4. ...
    5.  
    6. UNITY_LOCATION(0) uniform highp sampler2D SurfaceHeightfield;
    7. in highp vec4 vs_TEXCOORD0;
    8. layout(location = 0) out highp vec4 SV_TARGET0;
    9. mediump vec3 u_xlat10_0;
    10. void main()
    11. {
    12.     u_xlat10_0.xyz = texture(SurfaceHeightfield, vs_TEXCOORD0.xy).xyz;
    13.     SV_TARGET0.xyz = u_xlat10_0.xyz;
    14.     SV_TARGET0.w = 1.0;
    15.     return;
    16. }
    17.  
    18. #endif
    Why this is happening?
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    1,537
    This pragma doesn't do anything.

    Can you please submit a bug report?
     
  6. ZhivaevDmitriy

    ZhivaevDmitriy

    Joined:
    May 15, 2018
    Posts:
    4
    aleksandrk likes this.
unityunity