/ Assets / shaders / silhoutte / silhoutte.shader
silhoutte.shader
  1  Shader "Custom/silhoutte"
  2  {
  3      Properties
  4      {
  5          [MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)
  6          [MainTexture] _BaseMap("Base Map", 2D) = "white"
  7          _PyramidHeight("Pyramid Height", Float) = 1
  8      }
  9  
 10      SubShader
 11      {
 12          Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
 13  
 14          Pass
 15          {
 16              Name "ForwardLit"
 17              Tags { "LightMode" = "UniversalForward" }
 18              Cull Back
 19              
 20              HLSLPROGRAM
 21  
 22              #pragma prefer_hlslcc gles
 23              #pragma exclude_renderers d3d11_9x
 24              #pragma target 2.0
 25              #pragma require geometry
 26                          
 27              #pragma vertex vert
 28              #pragma geometry Geometry
 29              #pragma fragment frag
 30  
 31              #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 32  
 33              struct Attributes
 34              {
 35                  float4 positionOS : POSITION;
 36                  float3 normalOS : NORMAL;
 37                  float2 uv : TEXCOORD0;
 38              };
 39  
 40              struct VertexOutput {
 41                  float4 positionWS   : SV_POSITION; // Position in world space
 42                  float3 normalWS : NORMAL;
 43                  float2 uv           : TEXCOORD1; // UVs
 44              };
 45  
 46              struct GeometryOutput {
 47                  float4 positionCS               : SV_POSITION; // Position in clip space
 48                  float3 positionWS               : POSITION_WS; // Position in world space
 49                  float3 normalWS                 : NORMAL_WS; // Normal vector in world space
 50                  float2 uv                       : TEXCOORD2; // UVs
 51                  float3 normalCS : NORMAL;
 52              };
 53  
 54              TEXTURE2D(_BaseMap);
 55              SAMPLER(sampler_BaseMap);
 56  
 57              CBUFFER_START(UnityPerMaterial)
 58                  half4 _BaseColor;
 59                  float4 _BaseMap_ST;
 60              CBUFFER_END
 61  
 62              VertexOutput vert(Attributes IN)
 63              {
 64                  VertexOutput OUT;
 65                  OUT.positionWS = float4(TransformObjectToWorld(IN.positionOS.xyz),1);
 66                  OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS);
 67                  OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
 68                  return OUT;
 69              }
 70  
 71              GeometryOutput SetupVertex(float3 positionWS, float3 normalWS, float2 uv) {
 72                  // Setup an output struct
 73                  GeometryOutput output;
 74                  output.positionWS = positionWS;
 75                  output.normalWS = normalWS;
 76                  output.uv = uv;
 77                  // This function calculates clip space position, taking the shadow caster pass into account
 78                  output.positionCS = TransformWorldToHClip(positionWS);
 79                  output.normalCS = TransformWorldToHClipDir(normalWS);
 80                  return output;
 81              }
 82  
 83              bool TryGetZeroPoint(float3 p1, float3 p2, float dot1, float dot2, out float3 zeroPoint) {
 84                  zeroPoint = float3(0,0,0);
 85                  if (dot1 * dot2 > 0) {
 86                      return false;
 87                  }
 88                  float t = dot1 / (dot1 - dot2);
 89                  zeroPoint = lerp(p1, p2, t);
 90                  return true;
 91              }
 92              
 93              [maxvertexcount(9)]
 94              void Geometry(triangle VertexOutput inputs[3], inout TriangleStream<GeometryOutput> outputStream) {
 95                  // outputStream.RestartStrip();
 96                  // outputStream.Append(SetupVertex(inputs[0].positionWS, inputs[0].normalWS, inputs[0].uv));
 97                  // outputStream.Append(SetupVertex(inputs[1].positionWS, inputs[1].normalWS, inputs[1].uv));
 98                  // outputStream.Append(SetupVertex(inputs[2].positionWS, inputs[2].normalWS, inputs[2].uv));
 99  
100                  float3 dirToCam0 = normalize(_WorldSpaceCameraPos - inputs[0].positionWS);
101                  float3 dirToCam1 = normalize(_WorldSpaceCameraPos - inputs[1].positionWS);
102                  float3 dirToCam2 = normalize(_WorldSpaceCameraPos - inputs[2].positionWS);
103  
104                  float dot0 = dot(inputs[0].normalWS, dirToCam0);
105                  float dot1 = dot(inputs[1].normalWS, dirToCam1);
106                  float dot2 = dot(inputs[2].normalWS, dirToCam2);
107  
108                  int index = 0;
109                  float3 zero1;
110                  bool h1 = TryGetZeroPoint(inputs[0].positionWS, inputs[1].positionWS, dot0, dot1, zero1);
111                  float3 zero2;
112                  bool h2 = TryGetZeroPoint(inputs[1].positionWS, inputs[2].positionWS, dot1, dot2, zero2);
113                  float3 zero3;
114                  bool h3 = TryGetZeroPoint(inputs[2].positionWS, inputs[0].positionWS, dot2, dot0, zero3);
115                  if (h1 && h2) {
116                      outputStream.RestartStrip();
117                      outputStream.Append(SetupVertex(zero1, inputs[0].normalWS, inputs[0].uv));
118                      outputStream.Append(SetupVertex(inputs[1].positionWS, inputs[1].normalWS, inputs[1].uv));
119                      outputStream.Append(SetupVertex(zero2, inputs[2].normalWS, inputs[2].uv));
120                  }
121                  if (h2 && h3) {
122                      outputStream.RestartStrip();
123                      outputStream.Append(SetupVertex(zero2, inputs[1].normalWS, inputs[1].uv));
124                      outputStream.Append(SetupVertex(inputs[2].positionWS, inputs[2].normalWS, inputs[2].uv));
125                      outputStream.Append(SetupVertex(zero3, inputs[0].normalWS, inputs[0].uv));
126                  }
127                  if (h3 && h1) {
128                      outputStream.RestartStrip();
129                      outputStream.Append(SetupVertex(zero3, inputs[2].normalWS, inputs[2].uv));
130                      outputStream.Append(SetupVertex(inputs[0].positionWS, inputs[0].normalWS, inputs[0].uv));
131                      outputStream.Append(SetupVertex(zero1, inputs[0].normalWS, inputs[0].uv));
132                  }
133              }
134  
135              
136              half4 frag(GeometryOutput IN) : SV_Target
137              {
138                  half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv) * _BaseColor;
139                  return color;
140              }
141              ENDHLSL
142          }
143      }
144  }