Question by 
               miloszecket · May 07, 2020 at 06:23 AM · 
                shadersshader programmingvertex shadertessellation  
              
 
              How can I get the maximum texture value within a tri in a shader?
I'm making a shader for dynamically tessellating a plane to accommodate the use of an image as a displacement map, but currently the only values used for tessellation are those at each vertex of a tri (which means that if the image has a bright dot in the middle of a tri, the shader won't take it into account for tessellation). How can I get the maximum value within a tri so I can use it to determine tessellation amount?
Code:
 Shader "QI/Sample"
 {
     Properties
     {
         _Array ("Array", 2DArray) = ""{}
         _ArrayLength ("Length", Int) = 1
         _UVScale ("UVScale", Float) = 1.0
         _DispMap("Heightmap", 2D) = "black" {}
         _Uniform("Uniform Tesselation", Range(1, 64)) = 1
         _Height("Height", Range(0, 2)) = 1
         _DispDetail("Detail", Range(0, 5)) = 3
     }
     SubShader
     {
         
 
         Pass
         {
             CGPROGRAM
             #pragma vertex TessellationVertexProgram
             #pragma fragment frag 
             #pragma hull HullProgram
             #pragma domain DomainProgram
             #pragma require 2darray
             #pragma require tessellation tessHW
             #include "UnityCG.cginc"
             #include "Tessellation.cginc"
             int _ArrayLength;
             float _Uniform;
             UNITY_DECLARE_TEX2DARRAY(_Array);
             float _UVScale;
             sampler2D _DispMap;
             float4 _DispMap_ST;
             float _Height;
             float _DispDetail;
             struct v2f
             {
                 float2 uv : TEXCOORD0;
                 float4 vertex : SV_POSITION;
             };
             struct appdata{
                 float4 vertex : POSITION;
                 float2 uv : TEXCOORD0;
                 float3 normal : NORMAL;
             };
             struct ControlPoint
             {
                 float4 vertex : INTERNALTESSPOS;
                 float2 uv : TEXCOORD0;
                 float3 normal : NORMAL;
             };
             struct TessellationFactors 
             {
                 float edge[3] : SV_TessFactor;
                 float inside : SV_InsideTessFactor;
             };
             
 
             float3 RGBToHSV(float3 c)
             {
                 float4 K = float4(0.0f, -1.0f / 3.0f, 2.0f / 3.0f, -1.0f);
                 float4 p = lerp( float4( c.bg, K.wz ), float4( c.gb, K.xy ), step( c.b, c.g ) );
                 float4 q = lerp( float4( p.xyw, c.r ), float4( c.r, p.yzx ), step( p.x, c.r ) );
                 float d = q.x - min( q.w, q.y );
                 float e = 1.0e-10;
                 return float3( abs(q.z + (q.w - q.y) / (6.0f * d + e)), d / (q.x + e), q.x);
             }
             TessellationFactors PatchConstantFunction(InputPatch<ControlPoint, 3> patch) 
             {
                 float p0factor = RGBToHSV(tex2Dlod(_DispMap, float4(patch[0].uv.x, patch[0].uv.y, 0, 0))).z;
                 float p1factor = RGBToHSV(tex2Dlod(_DispMap, float4(patch[1].uv.x, patch[1].uv.y, 0, 0))).z;
                 float p2factor = RGBToHSV(tex2Dlod(_DispMap, float4(patch[2].uv.x, patch[2].uv.y, 0, 0))).z;
                 float factor = p0factor + p1factor + p2factor;
                 TessellationFactors f;
                 f.edge[0] = factor > 0.0 ? _Uniform + ((factor + 1) * _DispDetail) : 1.0;
                 f.edge[1] = factor > 0.0 ? _Uniform + ((factor + 1) * _DispDetail) : 1.0;
                 f.edge[2] = factor > 0.0 ? _Uniform + ((factor + 1) * _DispDetail) : 1.0;
                 f.inside = factor > 0.0 ? _Uniform + ((factor + 1) * _DispDetail) : 1.0;
                 return f;
             }
             ControlPoint TessellationVertexProgram(appdata v)
             {
                 ControlPoint p;
                 p.vertex = v.vertex;
                 p.uv = v.uv;
                 p.normal = v.normal;
                 return p;
             }
             [UNITY_domain("tri")]
             [UNITY_outputcontrolpoints(3)]
             [UNITY_outputtopology("triangle_cw")]
             [UNITY_partitioning("fractional_odd")]
             [UNITY_patchconstantfunc("PatchConstantFunction")]
             ControlPoint HullProgram(InputPatch<ControlPoint, 3> patch, uint id : SV_OutputControlPointID)
             {
                 return patch[id];
             }
 
             v2f vert (appdata IN)
             {
                 v2f o;
                 o.uv = IN.uv;
                 float2 uv_DispMap = IN.uv * _DispMap_ST.xy + _DispMap_ST.zw;
                 float height = RGBToHSV(tex2Dlod(_DispMap, float4(uv_DispMap, 0, 0))).z;
                 o.vertex = UnityObjectToClipPos(IN.vertex * 2) + UnityObjectToClipPos(float4(height * _Height * IN.normal, 0));
                 return o;
             }
             [UNITY_domain("tri")]
             v2f DomainProgram(TessellationFactors factors, 
             OutputPatch<ControlPoint, 3> patch,
             float3 barycentricCoordinates : SV_DomainLocation) 
             {
                 appdata data;
 
                 data.vertex = patch[0].vertex * barycentricCoordinates.x + 
                 patch[1].vertex * barycentricCoordinates.y +
                 patch[2].vertex * barycentricCoordinates.z;
                 data.uv = patch[0].uv * barycentricCoordinates.x +
                 patch[1].uv * barycentricCoordinates.y +
                 patch[2].uv * barycentricCoordinates.z;
                 data.normal = patch[0].normal * barycentricCoordinates.x +
                 patch[1].normal * barycentricCoordinates.y +
                 patch[2].normal * barycentricCoordinates.z;
 
                 return vert(data);
             }
 
             fixed4 frag (v2f i) : SV_Target
             {
                 half4 col = half4(0, 0, 0, 0);
                 for(int index = 0; index < _ArrayLength; index ++){
                     col = UNITY_SAMPLE_TEX2DARRAY(_Array, float3(i.uv.x, i.uv.y, index)) + col;
                 }
                 return col;
             }
             ENDCG
         }
     }
 }
 
 
              
               Comment
              
 
               
              Your answer
 
             Follow this Question
Related Questions
Very basic shader problem 0 Answers
Reversed UV Light with 2D PointLight (shader graph) 0 Answers
Standard Cutout Double Sided? 0 Answers
A Blend Shader That Uses Vertex Information 0 Answers
Shader - SV_Target 1 Answer