123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- Shader "Universal Render Pipeline/VR/SpatialMapping/Wireframe"
- {
- Properties
- {
- _WireThickness ("Wire Thickness", RANGE(0, 800)) = 100
- }
- SubShader
- {
- Tags {"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
- LOD 100
- Pass
- {
- Name "Spatial Mapping Wireframe"
- // Wireframe shader based on the the following
- // http://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf
- HLSLPROGRAM
- #pragma require geometry
- #pragma vertex vert
- #pragma geometry geom
- #pragma fragment frag
- // -------------------------------------
- // Unity defined keywords
- #pragma multi_compile_instancing
- #include "UnlitInput.hlsl"
- float _WireThickness;
- struct Attributes
- {
- float4 positionOS : POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct v2g
- {
- float4 projectionSpaceVertex : SV_POSITION;
- float4 worldSpacePosition : TEXCOORD1;
- UNITY_VERTEX_OUTPUT_STEREO
- };
- v2g vert(Attributes input)
- {
- v2g output = (v2g)0;
- UNITY_SETUP_INSTANCE_ID(input);
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
- VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
- output.projectionSpaceVertex = vertexInput.positionCS;
- output.worldSpacePosition = mul(unity_ObjectToWorld, input.positionOS);
- return output;
- }
- struct g2f
- {
- float4 projectionSpaceVertex : SV_POSITION;
- float4 worldSpacePosition : TEXCOORD0;
- float4 dist : TEXCOORD1;
- UNITY_VERTEX_OUTPUT_STEREO
- };
- [maxvertexcount(3)]
- void geom(triangle v2g i[3], inout TriangleStream<g2f> triangleStream)
- {
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i[0]);
- float2 p0 = i[0].projectionSpaceVertex.xy / i[0].projectionSpaceVertex.w;
- float2 p1 = i[1].projectionSpaceVertex.xy / i[1].projectionSpaceVertex.w;
- float2 p2 = i[2].projectionSpaceVertex.xy / i[2].projectionSpaceVertex.w;
- float2 edge0 = p2 - p1;
- float2 edge1 = p2 - p0;
- float2 edge2 = p1 - p0;
- // To find the distance to the opposite edge, we take the
- // formula for finding the area of a triangle Area = Base/2 * Height,
- // and solve for the Height = (Area * 2)/Base.
- // We can get the area of a triangle by taking its cross product
- // divided by 2. However we can avoid dividing our area/base by 2
- // since our cross product will already be double our area.
- float area = abs(edge1.x * edge2.y - edge1.y * edge2.x);
- float wireThickness = 800 - _WireThickness;
- g2f o;
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
- o.worldSpacePosition = i[0].worldSpacePosition;
- o.projectionSpaceVertex = i[0].projectionSpaceVertex;
- o.dist.xyz = float3( (area / length(edge0)), 0.0, 0.0) * o.projectionSpaceVertex.w * wireThickness;
- o.dist.w = 1.0 / o.projectionSpaceVertex.w;
- triangleStream.Append(o);
- o.worldSpacePosition = i[1].worldSpacePosition;
- o.projectionSpaceVertex = i[1].projectionSpaceVertex;
- o.dist.xyz = float3(0.0, (area / length(edge1)), 0.0) * o.projectionSpaceVertex.w * wireThickness;
- o.dist.w = 1.0 / o.projectionSpaceVertex.w;
- triangleStream.Append(o);
- o.worldSpacePosition = i[2].worldSpacePosition;
- o.projectionSpaceVertex = i[2].projectionSpaceVertex;
- o.dist.xyz = float3(0.0, 0.0, (area / length(edge2))) * o.projectionSpaceVertex.w * wireThickness;
- o.dist.w = 1.0 / o.projectionSpaceVertex.w;
- triangleStream.Append(o);
- }
- half4 frag(g2f i) : SV_Target
- {
- float minDistanceToEdge = min(i.dist[0], min(i.dist[1], i.dist[2])) * i.dist[3];
- // Early out if we know we are not on a line segment.
- if(minDistanceToEdge > 0.9)
- {
- return half4(0,0,0,0);
- }
- // Smooth our line out
- float t = exp2(-2 * minDistanceToEdge * minDistanceToEdge);
- const half4 colors[11] = {
- half4(1.0, 1.0, 1.0, 1.0), // White
- half4(1.0, 0.0, 0.0, 1.0), // Red
- half4(0.0, 1.0, 0.0, 1.0), // Green
- half4(0.0, 0.0, 1.0, 1.0), // Blue
- half4(1.0, 1.0, 0.0, 1.0), // Yellow
- half4(0.0, 1.0, 1.0, 1.0), // Cyan/Aqua
- half4(1.0, 0.0, 1.0, 1.0), // Magenta
- half4(0.5, 0.0, 0.0, 1.0), // Maroon
- half4(0.0, 0.5, 0.5, 1.0), // Teal
- half4(1.0, 0.65, 0.0, 1.0), // Orange
- half4(1.0, 1.0, 1.0, 1.0) // White
- };
- float cameraToVertexDistance = length(_WorldSpaceCameraPos - i.worldSpacePosition.xyz);
- int index = clamp(floor(cameraToVertexDistance), 0, 10);
- half4 wireColor = colors[index];
- half4 finalColor = lerp(float4(0,0,0,1), wireColor, t);
- finalColor.a = t;
- return finalColor;
- }
- ENDHLSL
- }
- }
- FallBack "Hidden/Universal Render Pipeline/FallbackError"
- }
|