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 }