init
This commit is contained in:
commit
f5c1616018
679 changed files with 188502 additions and 0 deletions
161
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader
Normal file
161
Assets/Pixel3D/Shaders/PixelPerfectOutline.shader
Normal file
|
@ -0,0 +1,161 @@
|
|||
Shader "Custom/PixelPerfectOutline"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Opaque" }
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
Name "Outline"
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 vertex : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
sampler2D _CameraDepthNormalsTexture;
|
||||
sampler2D _CameraDepthTexture;
|
||||
|
||||
float2 _ScreenSize;
|
||||
|
||||
float _DepthThreshold;
|
||||
float _NormalThreshold;
|
||||
float3 _NormalEdgeBias;
|
||||
|
||||
float _AngleThreshold;
|
||||
float _AngleFactorScale;
|
||||
|
||||
bool _DebugOutline;
|
||||
|
||||
float4 _OutlineColor;
|
||||
float4 _EdgeColor;
|
||||
float _ColorShift;
|
||||
|
||||
#define SAMPLE_DEPTH_NORMAL(uv, name) \
|
||||
float name##Depth; \
|
||||
float3 name##Normal; \
|
||||
DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv), name##Depth, name##Normal);
|
||||
|
||||
struct PassValue
|
||||
{
|
||||
float depth;
|
||||
float normal;
|
||||
};
|
||||
|
||||
float getDepthDiff(float depth, float neighborDepth)
|
||||
{
|
||||
return neighborDepth - depth;
|
||||
return saturate(neighborDepth - depth);
|
||||
}
|
||||
|
||||
float getNormalDiff(float3 normal, float3 neighborNormal, float depth, float neighborDepth)
|
||||
{
|
||||
float3 normalDiff = normal - neighborNormal;
|
||||
float normalBiasDiff = dot(normalDiff, _NormalEdgeBias);
|
||||
float normalIndicator = saturate(smoothstep(-0.1, 0.1, normalBiasDiff));
|
||||
|
||||
float depthDiff = neighborDepth - depth;
|
||||
float depthIndicator = saturate(sign(depthDiff * .25 + .0025));
|
||||
|
||||
return (1 - dot(normal, neighborNormal)) * normalIndicator * depthIndicator;
|
||||
}
|
||||
|
||||
// Sources:
|
||||
// https://roystan.net/articles/outline-shader/
|
||||
// https://www.youtube.com/watch?v=LRDpEnpWohM
|
||||
// https://www.youtube.com/watch?v=jFevm02NJ5M
|
||||
// https://github.com/KodyJKing/three.js/blob/outlined-pixel-example/examples/jsm/postprocessing/RenderPixelatedPass.js
|
||||
PassValue edgePass(float2 uv)
|
||||
{
|
||||
// Convolution offset sizes
|
||||
float2 offset = 1 / _ScreenSize;
|
||||
|
||||
// UVs for convolution sampling
|
||||
float2 top = uv + offset * float2(0, 1);
|
||||
float2 bottom = uv + offset * float2(0, -1);
|
||||
float2 left = uv + offset * float2(-1, 0);
|
||||
float2 right = uv + offset * float2(1, 0);
|
||||
|
||||
// Sample depth and normal
|
||||
SAMPLE_DEPTH_NORMAL(uv, center);
|
||||
SAMPLE_DEPTH_NORMAL(top, top);
|
||||
SAMPLE_DEPTH_NORMAL(bottom, bottom);
|
||||
SAMPLE_DEPTH_NORMAL(left, left);
|
||||
SAMPLE_DEPTH_NORMAL(right, right);
|
||||
|
||||
// Calculate the angle threshold
|
||||
float angle = 1 - dot(centerNormal, float3(0, 0, 1));
|
||||
float angleThreshold = saturate((angle - _AngleThreshold) / (1 - _AngleThreshold));
|
||||
float angleFactor = angleThreshold * _AngleFactorScale + 1;
|
||||
|
||||
// Calculate the depth edge
|
||||
float depthDiff = 0;
|
||||
depthDiff += getDepthDiff(centerDepth, topDepth);
|
||||
depthDiff += getDepthDiff(centerDepth, bottomDepth);
|
||||
depthDiff += getDepthDiff(centerDepth, leftDepth);
|
||||
depthDiff += getDepthDiff(centerDepth, rightDepth);
|
||||
float depthThreshold = _DepthThreshold * centerDepth * angleFactor;
|
||||
float depth = step(depthThreshold, depthDiff);
|
||||
|
||||
// Calculate the normal edge
|
||||
float normalDiff = 0;
|
||||
normalDiff += getNormalDiff(centerNormal, topNormal, centerDepth, topDepth);
|
||||
normalDiff += getNormalDiff(centerNormal, bottomNormal, centerDepth, bottomDepth);
|
||||
normalDiff += getNormalDiff(centerNormal, leftNormal, centerDepth, leftDepth);
|
||||
normalDiff += getNormalDiff(centerNormal, rightNormal, centerDepth, rightDepth);
|
||||
float normal = step(_NormalThreshold, normalDiff);
|
||||
|
||||
PassValue edge = { depth, normal };
|
||||
return edge;
|
||||
}
|
||||
|
||||
v2f vert(appdata v)
|
||||
{
|
||||
v2f o = { UnityObjectToClipPos(v.vertex), TRANSFORM_TEX(v.uv, _MainTex) };
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float4 color = tex2D(_MainTex, i.uv);
|
||||
float4 outlineColor = float4(lerp(color.rgb, _OutlineColor.rgb, _OutlineColor.a), 1);
|
||||
float4 edgeColor = float4(lerp(color.rgb, _EdgeColor.rgb, _EdgeColor.a), 1);
|
||||
|
||||
PassValue edge = edgePass(i.uv);
|
||||
|
||||
if (_DebugOutline) return float4(edge.depth, edge.normal, 0, 1);
|
||||
|
||||
// Any depth overrides normal
|
||||
edge.normal = step(edge.depth, 0) * edge.normal;
|
||||
|
||||
color = lerp(color, outlineColor, edge.depth);
|
||||
color = lerp(color, edgeColor, edge.normal);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
Fallback Off
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue