Search Unity

My own terrane shader is not working

Discussion in 'Shaders' started by fromPaxtaobod, Dec 2, 2014.

  1. fromPaxtaobod

    fromPaxtaobod

    Joined:
    Dec 2, 2014
    Posts:
    5
    Hi, I'm trying to write a shader for my terrane with quad tesselation. But I have a problem. In what may be the reason, any suggestions? With tri-tessellation mode there is no problem.

    Code (CSharp):
    1. Shader "Quad tesselation" {
    2. SubShader {
    3. Pass { Tags {"LightMode" = "Vertex"}
    4.  
    5. CGPROGRAM
    6. #pragma vertex vert
    7. #pragma hull hull
    8. #pragma domain domain
    9. #pragma fragment frag
    10.  
    11. #include "UnityCG.cginc"
    12. //=================================================================================================================================
    13. // Shader structures
    14. //=================================================================================================================================
    15.  
    16. struct VS_INPUT
    17. {
    18.     float3 position : POSITION;
    19. };
    20.  
    21. struct VS_OUTPUT
    22. {
    23.     float4 position : POSITION;
    24. };
    25.  
    26. struct HS_CONSTANT_DATA_OUTPUT
    27. {
    28.     float Edges[4]  : SV_TessFactor;
    29.     float Inside[2]    : SV_InsideTessFactor;
    30. };
    31.  
    32. struct HS_OUTPUT
    33. {
    34.     float3 position : POS;
    35. };
    36.  
    37. struct DS_OUTPUT
    38. {
    39.     float4 position : SV_Position;
    40. };
    41.  
    42. //=================================================================================================================================
    43. // Vertex shader
    44. //=================================================================================================================================
    45. VS_OUTPUT vert(VS_INPUT v)
    46. {
    47.     VS_OUTPUT output;
    48.     output.position = mul(UNITY_MATRIX_MV, float4(v.position, 1.0));
    49.     return output;
    50. }
    51.  
    52. //=================================================================================================================================
    53. // Hull shader
    54. //=================================================================================================================================
    55. HS_CONSTANT_DATA_OUTPUT constantsHS(InputPatch<VS_OUTPUT, 4> patch)
    56. {
    57.     HS_CONSTANT_DATA_OUTPUT output = (HS_CONSTANT_DATA_OUTPUT)0;
    58.     output.Edges[0] = output.Edges[1] = output.Edges[2] = output.Edges[3] = 2;
    59.     output.Inside[0] = output.Inside[1] = 2;
    60.    
    61.     return output;
    62. }
    63.  
    64. [domain("quad")]
    65. [partitioning("fractional_odd")]
    66. [outputtopology("triangle_cw")]
    67. [outputcontrolpoints(4)]
    68. [patchconstantfunc("constantsHS")]
    69. HS_OUTPUT hull(InputPatch<VS_OUTPUT, 4> patch, uint uCPID: SV_OutputControlPointID)
    70. {
    71.     HS_OUTPUT output = (HS_OUTPUT)0;
    72.     output.position = patch[uCPID].position.xyz;
    73.    
    74.     return output;
    75. }
    76.  
    77. //=================================================================================================================================
    78. // Domain shader
    79. //=================================================================================================================================
    80. [domain("quad")]
    81. DS_OUTPUT domain(HS_CONSTANT_DATA_OUTPUT input, const OutputPatch<HS_OUTPUT, 4> patch, float2 UV : SV_DomainLocation)
    82. {
    83.     DS_OUTPUT output = (DS_OUTPUT)0;
    84.  
    85.     float3 topMidpoint = lerp(patch[0].position, patch[1].position, UV.x);
    86.     float3 bottomMidpoint = lerp(patch[3].position, patch[2].position, UV.x);
    87.      float3 pos = lerp(topMidpoint, bottomMidpoint, UV.y);
    88.                        
    89.     output.position = mul(UNITY_MATRIX_P, float4(pos, 1.0));
    90.     return output;
    91. }
    92.  
    93. //=================================================================================================================================
    94. // Fragment shader
    95. //=================================================================================================================================
    96. float4 frag(DS_OUTPUT f) : COLOR
    97. {
    98.     float4 c;
    99.     c.b = 0.5;
    100.    
    101.     return c;
    102. }
    103.  
    104. ENDCG
    105. }
    106. }
    107. }
     

    Attached Files:

  2. Deleted User

    Deleted User

    Guest

    In import mesh settings you must check option "Keep quads" or use MeshTopology.Quads method for procedural generated quad mesh
    http://docs.unity3d.com/ScriptReference/MeshTopology.Quads.html

    Your shader works perfectly with quad mesh exported from Modo and imported by "Keep quads".
    Tesselated mesh can be visible in wireframe mode by using following script in Main Camera object from:
    http://docs.unity3d.com/ScriptReference/GL-wireframe.html

    I would like to apply distance based or edge length dynamic tessellation factors, depends of distance between camera and vertex positions (lines 58 and 59 of attached code), but I can't get proper solution. Maybe someone knows how to do it.
     
  3. fromPaxtaobod

    fromPaxtaobod

    Joined:
    Dec 2, 2014
    Posts:
    5
    Thank you, I have to deal with this issue. Perhaps what you are looking for:

    Code (CSharp):
    1. float UnityCalcDistanceTessFactor (float4 vertex, float minDist, float maxDist, float tess)
    2. {
    3.     float3 wpos = mul(_Object2World,vertex).xyz;
    4.     float dist = distance (wpos, _WorldSpaceCameraPos);
    5.     float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0) * tess;
    6.     return f;
    7. }
    8.  
    9. HS_CONSTANT_DATA_OUTPUT constantsHS(InputPatch<VS_OUTPUT, 4> patch,  uint PatchID : SV_PrimitiveID)
    10. {
    11.     HS_CONSTANT_DATA_OUTPUT output = (HS_CONSTANT_DATA_OUTPUT)0;
    12.    
    13.     tessFactor.x = UnityCalcDistanceTessFactor (patch[0].position, _MinDistance, _MaxDistance, _TessFactor);
    14.     tessFactor.y = UnityCalcDistanceTessFactor (patch[1].position, _MinDistance, _MaxDistance, _TessFactor);
    15.     tessFactor.z = UnityCalcDistanceTessFactor (patch[2].position, _MinDistance, _MaxDistance, _TessFactor);
    16.     tessFactor.w = UnityCalcDistanceTessFactor (patch[3].position, _MinDistance, _MaxDistance, _TessFactor);
    17.        
    18.     output.Edges[0] = max(tessFactor.x, tessFactor.w);
    19.     output.Edges[1] = max(tessFactor.x, tessFactor.y);
    20.     output.Edges[2] = max(tessFactor.y, tessFactor.z);
    21.     output.Edges[3] = max(tessFactor.z, tessFactor.w);
    22.     output.Inside[0] = output.Inside[1] = max(max(tessFactor.x, tessFactor.y), max(tessFactor.z, tessFactor.w));
    23.        
    24.     return output;
    25. }
     
  4. MBaadsgaard

    MBaadsgaard

    Joined:
    Mar 19, 2013
    Posts:
    39
    Reviving this thread and stitching the shader together for someone in the future to come by here.

    THIS IS A UNITY QUAD TESSELLATION SHADER WITH DISTANCE FACTOR
    I did nothing but stitch the above code together, please give credit to the two above gentlemen if using.


    Code (CSharp):
    1.  
    2. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
    3. Shader "Quad tessellation" {
    4.     Properties{
    5.         _TessFactor("Tessellation Factor", float) = 2
    6.         _MinDistance("Minimum Distance", float) = 2
    7.         _MaxDistance("Maximum Distance", float) = 2
    8.     }
    9.         SubShader{
    10.             Pass{ Tags{ "LightMode" = "Vertex" }
    11.             CGPROGRAM
    12.     #pragma vertex vert
    13.     #pragma hull hull
    14.     #pragma domain domain
    15.     #pragma fragment frag
    16.     #include "UnityCG.cginc"
    17.         //=================================================================================================================================
    18.         // Shader structures
    19.         //=================================================================================================================================
    20.         float _TessFactor;
    21.         float _MinDistance;
    22.         float _MaxDistance;
    23.         struct VS_INPUT
    24.     {
    25.         float3 position : POSITION;
    26.     };
    27.     struct VS_OUTPUT
    28.     {
    29.         float4 position : POSITION;
    30.     };
    31.     struct HS_CONSTANT_DATA_OUTPUT
    32.     {
    33.         float Edges[4]  : SV_TessFactor;
    34.         float Inside[2]    : SV_InsideTessFactor;
    35.     };
    36.     struct HS_OUTPUT
    37.     {
    38.         float3 position : POS;
    39.     };
    40.     struct DS_OUTPUT
    41.     {
    42.         float4 position : SV_Position;
    43.     };
    44.     //=================================================================================================================================
    45.     // Vertex shader
    46.     //=================================================================================================================================
    47.     VS_OUTPUT vert(VS_INPUT v)
    48.     {
    49.         VS_OUTPUT output;
    50.         output.position = mul(UNITY_MATRIX_MV, float4(v.position, 1.0));
    51.         return output;
    52.     }
    53.     //=================================================================================================================================
    54.     // Hull shader
    55.     //=================================================================================================================================
    56.     float UnityCalcDistanceTessFactor (float4 vertex, float minDist, float maxDist, float tess)
    57.     {
    58.         /// Wrong space to fit with rest of code
    59.         //float3 wpos = mul(unity_ObjectToWorld,vertex).xyz;
    60.         //float dist = distance(wpos, _WorldSpaceCameraPos);
    61.         // This is just depth in view space. Actual distance to camera is the out-commented, trailing code.
    62.         float dist = -vertex.z;//distance(vertex.xyz, float3(0, 0, 0));
    63.         float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0) * tess;
    64.         return f;
    65.     }
    66.     HS_CONSTANT_DATA_OUTPUT constantsHS(InputPatch<VS_OUTPUT, 4> patch,  uint PatchID : SV_PrimitiveID)
    67.     {
    68.         HS_CONSTANT_DATA_OUTPUT output = (HS_CONSTANT_DATA_OUTPUT)0;
    69.         float4 tessFactor;
    70.         tessFactor.x = UnityCalcDistanceTessFactor (patch[0].position, _MinDistance, _MaxDistance, _TessFactor);
    71.         tessFactor.y = UnityCalcDistanceTessFactor (patch[1].position, _MinDistance, _MaxDistance, _TessFactor);
    72.         tessFactor.z = UnityCalcDistanceTessFactor (patch[2].position, _MinDistance, _MaxDistance, _TessFactor);
    73.         tessFactor.w = UnityCalcDistanceTessFactor (patch[3].position, _MinDistance, _MaxDistance, _TessFactor);
    74.        
    75.         output.Edges[0] = max(tessFactor.x, tessFactor.w);
    76.         output.Edges[1] = max(tessFactor.x, tessFactor.y);
    77.         output.Edges[2] = max(tessFactor.y, tessFactor.z);
    78.         output.Edges[3] = max(tessFactor.z, tessFactor.w);
    79.         output.Inside[0] = output.Inside[1] = max(max(tessFactor.x, tessFactor.y), max(tessFactor.z, tessFactor.w));
    80.        
    81.         return output;
    82.     }
    83.     [domain("quad")]
    84.     [partitioning("fractional_odd")]
    85.     [outputtopology("triangle_cw")]
    86.     [outputcontrolpoints(4)]
    87.     [patchconstantfunc("constantsHS")]
    88.     HS_OUTPUT hull(InputPatch<VS_OUTPUT, 4> patch, uint uCPID: SV_OutputControlPointID)
    89.     {
    90.         HS_OUTPUT output = (HS_OUTPUT)0;
    91.         output.position = patch[uCPID].position.xyz;
    92.         return output;
    93.     }
    94.     //=================================================================================================================================
    95.     // Domain shader
    96.     //=================================================================================================================================
    97.     [domain("quad")]
    98.     DS_OUTPUT domain(HS_CONSTANT_DATA_OUTPUT input, const OutputPatch<HS_OUTPUT, 4> patch, float2 UV : SV_DomainLocation)
    99.     {
    100.         DS_OUTPUT output = (DS_OUTPUT)0;
    101.         float3 topMidpoint = lerp(patch[0].position, patch[1].position, UV.x);
    102.         float3 bottomMidpoint = lerp(patch[3].position, patch[2].position, UV.x);
    103.         float3 pos = lerp(topMidpoint, bottomMidpoint, UV.y);
    104.         output.position = mul(UNITY_MATRIX_P, float4(pos, 1.0));
    105.         return output;
    106.     }
    107.     //=================================================================================================================================
    108.     // Fragment shader
    109.     //=================================================================================================================================
    110.     float4 frag(DS_OUTPUT f) : COLOR
    111.     {
    112.         float4 c;
    113.     c.b = 0.5;
    114.     return c;
    115.     }
    116.         ENDCG
    117.     }
    118.     }
    119. }
    120.  
     
    Last edited: Aug 20, 2018