You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
5.9 KiB
153 lines
5.9 KiB
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" |
|
}
|
|
|