mirror of
https://github.com/FriendshipIsEpic/FiE-Game.git
synced 2024-11-22 05:47:59 +01:00
Added Highlighting System library.
This commit is contained in:
parent
ae34b2d806
commit
1789a03ea3
28 changed files with 2289 additions and 0 deletions
5
Assets/Highlighting System/Resources.meta
Normal file
5
Assets/Highlighting System/Resources.meta
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e2dd921d0779af4dad3fbd326388e14
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
100
Assets/Highlighting System/Resources/HighlightingBlur.shader
Normal file
100
Assets/Highlighting System/Resources/HighlightingBlur.shader
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||||
|
|
||||||
|
Shader "Hidden/Highlighted/Blur"
|
||||||
|
{
|
||||||
|
Properties
|
||||||
|
{
|
||||||
|
[HideInInspector] _MainTex ("", 2D) = "" {}
|
||||||
|
[HideInInspector] _Intensity ("", Range (0.25,0.5)) = 0.3
|
||||||
|
}
|
||||||
|
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
ZTest Always
|
||||||
|
Cull Off
|
||||||
|
ZWrite Off
|
||||||
|
Lighting Off
|
||||||
|
Fog { Mode Off }
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
uniform sampler2D _MainTex;
|
||||||
|
uniform half4 _MainTex_TexelSize;
|
||||||
|
|
||||||
|
uniform half _HighlightingBlurOffset;
|
||||||
|
uniform half _Intensity;
|
||||||
|
|
||||||
|
struct v2f
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float2 uv[4] : TEXCOORD0; // 8 to add straight directions
|
||||||
|
};
|
||||||
|
|
||||||
|
v2f vert (appdata_img v)
|
||||||
|
{
|
||||||
|
// Shader code optimized for the Unity shader compiler
|
||||||
|
v2f o;
|
||||||
|
o.pos = UnityObjectToClipPos(v.vertex);
|
||||||
|
float2 offs = _HighlightingBlurOffset * _MainTex_TexelSize.xy;
|
||||||
|
|
||||||
|
// Diagonal directions
|
||||||
|
o.uv[0].x = v.texcoord.x - offs.x;
|
||||||
|
o.uv[0].y = v.texcoord.y - offs.y;
|
||||||
|
|
||||||
|
o.uv[1].x = v.texcoord.x + offs.x;
|
||||||
|
o.uv[1].y = v.texcoord.y - offs.y;
|
||||||
|
|
||||||
|
o.uv[2].x = v.texcoord.x + offs.x;
|
||||||
|
o.uv[2].y = v.texcoord.y + offs.y;
|
||||||
|
|
||||||
|
o.uv[3].x = v.texcoord.x - offs.x;
|
||||||
|
o.uv[3].y = v.texcoord.y + offs.y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Straight directions
|
||||||
|
o.uv[4].x = v.texcoord.x - offs.x;
|
||||||
|
o.uv[4].y = v.texcoord.y;
|
||||||
|
|
||||||
|
o.uv[5].x = v.texcoord.x + offs.x;
|
||||||
|
o.uv[5].y = v.texcoord.y;
|
||||||
|
|
||||||
|
o.uv[6].x = v.texcoord.x;
|
||||||
|
o.uv[6].y = v.texcoord.y - offs.y;
|
||||||
|
|
||||||
|
o.uv[7].x = v.texcoord.x;
|
||||||
|
o.uv[7].y = v.texcoord.y + offs.y;
|
||||||
|
*/
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
half4 frag(v2f i) : COLOR
|
||||||
|
{
|
||||||
|
int start = 0;
|
||||||
|
int end = 4;
|
||||||
|
|
||||||
|
half4 color1 = tex2D(_MainTex, i.uv[start]);
|
||||||
|
fixed4 color2;
|
||||||
|
for (int n = start + 1; n < end; n++)
|
||||||
|
{
|
||||||
|
color2 = tex2D(_MainTex, i.uv[n]);
|
||||||
|
color1.rgb = max(color1.rgb, color2.rgb);
|
||||||
|
color1.a += color2.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
color1.a *= _Intensity;
|
||||||
|
return color1;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fallback off
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3070218404d1de94c9d081d248597046
|
||||||
|
ShaderImporter:
|
||||||
|
defaultTextures: []
|
||||||
|
userData:
|
|
@ -0,0 +1,69 @@
|
||||||
|
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||||
|
|
||||||
|
Shader "Hidden/Highlighted/Composite"
|
||||||
|
{
|
||||||
|
Properties
|
||||||
|
{
|
||||||
|
[HideInInspector] _MainTex ("", 2D) = "" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
Lighting Off
|
||||||
|
Fog { Mode off }
|
||||||
|
ZWrite Off
|
||||||
|
ZTest Always
|
||||||
|
Cull Off
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
struct v2f
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
half2 uv0 : TEXCOORD0;
|
||||||
|
half2 uv1 : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform sampler2D _MainTex;
|
||||||
|
uniform float4 _MainTex_TexelSize;
|
||||||
|
uniform sampler2D _HighlightingBuffer;
|
||||||
|
|
||||||
|
v2f vert(appdata_img v)
|
||||||
|
{
|
||||||
|
v2f o;
|
||||||
|
o.pos = UnityObjectToClipPos(v.vertex);
|
||||||
|
o.uv0 = v.texcoord.xy;
|
||||||
|
o.uv1 = v.texcoord.xy;
|
||||||
|
|
||||||
|
#if UNITY_UV_STARTS_AT_TOP
|
||||||
|
if (_MainTex_TexelSize.y < 0)
|
||||||
|
{
|
||||||
|
o.uv1.y = 1-o.uv1.y;
|
||||||
|
#if defined(UNITY_HALF_TEXEL_OFFSET)
|
||||||
|
o.uv1.y -= _MainTex_TexelSize.y;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag(v2f i) : COLOR
|
||||||
|
{
|
||||||
|
fixed4 c1 = tex2D(_MainTex, i.uv0);
|
||||||
|
fixed4 c2 = tex2D(_HighlightingBuffer, i.uv1);
|
||||||
|
c1.rgb = lerp(c1.rgb, c2.rgb, c2.a);
|
||||||
|
return c1;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FallBack Off
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b0bd9de6a4f20954f9704e56568224a6
|
||||||
|
ShaderImporter:
|
||||||
|
defaultTextures: []
|
||||||
|
userData:
|
101
Assets/Highlighting System/Resources/HighlightingCut.shader
Normal file
101
Assets/Highlighting System/Resources/HighlightingCut.shader
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
Shader "Hidden/Highlighted/Cut"
|
||||||
|
{
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Lighting Off
|
||||||
|
Fog { Mode off }
|
||||||
|
ZWrite Off
|
||||||
|
ZTest Always
|
||||||
|
Cull Back
|
||||||
|
Blend Off
|
||||||
|
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
Stencil
|
||||||
|
{
|
||||||
|
Ref 1
|
||||||
|
Comp NotEqual
|
||||||
|
Pass Keep
|
||||||
|
ZFail Keep
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
struct v2f
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
half2 uv : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform sampler2D _HighlightingBlurred;
|
||||||
|
uniform float2 _HighlightingBufferTexelSize;
|
||||||
|
|
||||||
|
v2f vert(appdata_img v)
|
||||||
|
{
|
||||||
|
v2f o;
|
||||||
|
o.pos = v.vertex;
|
||||||
|
|
||||||
|
#if defined(UNITY_HALF_TEXEL_OFFSET)
|
||||||
|
o.pos.xy += _HighlightingBufferTexelSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
o.uv = v.texcoord.xy;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag(v2f i) : COLOR
|
||||||
|
{
|
||||||
|
return tex2D(_HighlightingBlurred, i.uv);
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
Stencil
|
||||||
|
{
|
||||||
|
Ref 1
|
||||||
|
Comp Equal
|
||||||
|
Pass Keep
|
||||||
|
ZFail Keep
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
struct appdata_vert
|
||||||
|
{
|
||||||
|
float4 vertex : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform float2 _HighlightingBufferTexelSize;
|
||||||
|
|
||||||
|
float4 vert(appdata_vert v) : POSITION
|
||||||
|
{
|
||||||
|
float4 pos = v.vertex;
|
||||||
|
|
||||||
|
#if defined(UNITY_HALF_TEXEL_OFFSET)
|
||||||
|
pos.xy += _HighlightingBufferTexelSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag() : COLOR
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FallBack Off
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 376af14ed82e64793b326012b8591fa9
|
||||||
|
ShaderImporter:
|
||||||
|
defaultTextures: []
|
||||||
|
userData:
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||||
|
|
||||||
|
Shader "Hidden/Highlighted/Opaque"
|
||||||
|
{
|
||||||
|
Properties
|
||||||
|
{
|
||||||
|
[HideInInspector] _ZTest ("", Float) = 8 // UnityEngine.Rendering.CompareFunction. 4 = LessEqual, 8 = Always
|
||||||
|
[HideInInspector] _StencilRef ("", Float) = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
Lighting Off
|
||||||
|
Fog { Mode Off }
|
||||||
|
ZWrite [_HighlightingZWrite]
|
||||||
|
ZTest [_ZTest]
|
||||||
|
Offset [_HighlightingOffsetFactor], [_HighlightingOffsetUnits]
|
||||||
|
Stencil
|
||||||
|
{
|
||||||
|
Ref [_StencilRef]
|
||||||
|
Comp Always
|
||||||
|
Pass Replace
|
||||||
|
ZFail Keep
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
uniform fixed4 _Outline;
|
||||||
|
|
||||||
|
struct appdata_vert
|
||||||
|
{
|
||||||
|
float4 vertex : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 vert(appdata_vert v) : POSITION
|
||||||
|
{
|
||||||
|
return UnityObjectToClipPos(v.vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag() : COLOR
|
||||||
|
{
|
||||||
|
return _Outline;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fallback Off
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ce3b12ca636563c48afb814d9aeb5b90
|
||||||
|
ShaderImporter:
|
||||||
|
defaultTextures: []
|
||||||
|
userData:
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||||
|
|
||||||
|
Shader "Hidden/Highlighted/Transparent"
|
||||||
|
{
|
||||||
|
Properties
|
||||||
|
{
|
||||||
|
[HideInInspector] _MainTex ("", 2D) = "" {}
|
||||||
|
[HideInInspector] _Cutoff ("", Float) = 0.5
|
||||||
|
[HideInInspector] _ZTest ("", Float) = 8 // UnityEngine.Rendering.CompareFunction. 4 = LessEqual, 8 = Always
|
||||||
|
[HideInInspector] _StencilRef ("", Float) = 1
|
||||||
|
[HideInInspector] _Cull ("", Float) = 2 // UnityEngine.Rendering.CullMode.Back
|
||||||
|
}
|
||||||
|
|
||||||
|
SubShader
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
Lighting Off
|
||||||
|
Fog { Mode Off }
|
||||||
|
ZWrite [_HighlightingZWrite]
|
||||||
|
ZTest [_ZTest]
|
||||||
|
Offset [_HighlightingOffsetFactor], [_HighlightingOffsetUnits]
|
||||||
|
Cull [_Cull]
|
||||||
|
Stencil
|
||||||
|
{
|
||||||
|
Ref [_StencilRef]
|
||||||
|
Comp Always
|
||||||
|
Pass Replace
|
||||||
|
ZFail Keep
|
||||||
|
}
|
||||||
|
|
||||||
|
CGPROGRAM
|
||||||
|
#pragma vertex vert
|
||||||
|
#pragma fragment frag
|
||||||
|
#pragma fragmentoption ARB_precision_hint_fastest
|
||||||
|
#include "UnityCG.cginc"
|
||||||
|
|
||||||
|
uniform fixed4 _Outline;
|
||||||
|
uniform sampler2D _MainTex;
|
||||||
|
uniform float4 _MainTex_ST;
|
||||||
|
uniform fixed _Cutoff;
|
||||||
|
|
||||||
|
struct appdata_vert_tex
|
||||||
|
{
|
||||||
|
float4 vertex : POSITION;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
fixed4 color : COLOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct v2f
|
||||||
|
{
|
||||||
|
float4 pos : POSITION;
|
||||||
|
float2 texcoord : TEXCOORD0;
|
||||||
|
fixed alpha : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
v2f vert(appdata_vert_tex v)
|
||||||
|
{
|
||||||
|
v2f o;
|
||||||
|
o.pos = UnityObjectToClipPos(v.vertex);
|
||||||
|
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
|
||||||
|
o.alpha = v.color.a;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed4 frag(v2f i) : COLOR
|
||||||
|
{
|
||||||
|
fixed a = tex2D(_MainTex, i.texcoord).a;
|
||||||
|
clip(a - _Cutoff);
|
||||||
|
fixed4 c = _Outline;
|
||||||
|
c.a *= i.alpha;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
ENDCG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fallback Off
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9fc04a058c8768648a6532aa07540ca5
|
||||||
|
ShaderImporter:
|
||||||
|
defaultTextures: []
|
||||||
|
userData:
|
5
Assets/Highlighting System/Scripts.meta
Normal file
5
Assets/Highlighting System/Scripts.meta
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4b92650ecd71b67409ab3aafea97bd7d
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
344
Assets/Highlighting System/Scripts/Highlighter.cs
Normal file
344
Assets/Highlighting System/Scripts/Highlighter.cs
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
public partial class Highlighter : MonoBehaviour
|
||||||
|
{
|
||||||
|
#region Editable Parameters
|
||||||
|
// Constant highlighting turning on speed (common property for all Highlighters)
|
||||||
|
static private float constantOnSpeed = 4.5f;
|
||||||
|
|
||||||
|
// Constant highlighting turning off speed (common property for all Highlighters)
|
||||||
|
static private float constantOffSpeed = 4f;
|
||||||
|
|
||||||
|
// Default transparency cutoff value (used for shaders without _Cutoff property)
|
||||||
|
static private float transparentCutoff = 0.5f;
|
||||||
|
|
||||||
|
// Builtin layer reserved for the highlighting. This layer shouldn't be used for anything else in the project!
|
||||||
|
public const int highlightingLayer = 7;
|
||||||
|
|
||||||
|
// Only these types of Renderers will be highlighted
|
||||||
|
static public readonly List<System.Type> types = new List<System.Type>()
|
||||||
|
{
|
||||||
|
typeof(MeshRenderer),
|
||||||
|
typeof(SkinnedMeshRenderer),
|
||||||
|
typeof(SpriteRenderer),
|
||||||
|
typeof(ParticleRenderer),
|
||||||
|
typeof(ParticleSystemRenderer),
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
/// <summary>
|
||||||
|
/// Renderers reinitialization.
|
||||||
|
/// Call this method if your highlighted object has changed it's materials, renderers or child objects.
|
||||||
|
/// Can be called multiple times per update - renderers reinitialization will occur only once.
|
||||||
|
/// </summary>
|
||||||
|
public void ReinitMaterials()
|
||||||
|
{
|
||||||
|
renderersDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set color for one-frame highlighting mode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color'>
|
||||||
|
/// Highlighting color.
|
||||||
|
/// </param>
|
||||||
|
public void OnParams(Color color)
|
||||||
|
{
|
||||||
|
onceColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on one-frame highlighting.
|
||||||
|
/// </summary>
|
||||||
|
public void On()
|
||||||
|
{
|
||||||
|
// Highlight object only in this frame
|
||||||
|
once = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on one-frame highlighting with given color.
|
||||||
|
/// Can be called multiple times per update, color only from the latest call will be used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color'>
|
||||||
|
/// Highlighting color.
|
||||||
|
/// </param>
|
||||||
|
public void On(Color color)
|
||||||
|
{
|
||||||
|
// Set new color for one-frame highlighting
|
||||||
|
onceColor = color;
|
||||||
|
On();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set flashing parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color1'>
|
||||||
|
/// Starting color.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='color2'>
|
||||||
|
/// Ending color.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='freq'>
|
||||||
|
/// Flashing frequency (times per second).
|
||||||
|
/// </param>
|
||||||
|
public void FlashingParams(Color color1, Color color2, float freq)
|
||||||
|
{
|
||||||
|
flashingColorMin = color1;
|
||||||
|
flashingColorMax = color2;
|
||||||
|
flashingFreq = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on flashing.
|
||||||
|
/// </summary>
|
||||||
|
public void FlashingOn()
|
||||||
|
{
|
||||||
|
flashing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on flashing from color1 to color2.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color1'>
|
||||||
|
/// Starting color.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='color2'>
|
||||||
|
/// Ending color.
|
||||||
|
/// </param>
|
||||||
|
public void FlashingOn(Color color1, Color color2)
|
||||||
|
{
|
||||||
|
flashingColorMin = color1;
|
||||||
|
flashingColorMax = color2;
|
||||||
|
FlashingOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on flashing from color1 to color2 with given frequency.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color1'>
|
||||||
|
/// Starting color.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='color2'>
|
||||||
|
/// Ending color.
|
||||||
|
/// </param>
|
||||||
|
/// <param name='freq'>
|
||||||
|
/// Flashing frequency (times per second).
|
||||||
|
/// </param>
|
||||||
|
public void FlashingOn(Color color1, Color color2, float freq)
|
||||||
|
{
|
||||||
|
flashingFreq = freq;
|
||||||
|
FlashingOn(color1, color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on flashing with given frequency.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='f'>
|
||||||
|
/// Flashing frequency (times per second).
|
||||||
|
/// </param>
|
||||||
|
public void FlashingOn(float freq)
|
||||||
|
{
|
||||||
|
flashingFreq = freq;
|
||||||
|
FlashingOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn off flashing.
|
||||||
|
/// </summary>
|
||||||
|
public void FlashingOff()
|
||||||
|
{
|
||||||
|
flashing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch flashing mode.
|
||||||
|
/// </summary>
|
||||||
|
public void FlashingSwitch()
|
||||||
|
{
|
||||||
|
flashing = !flashing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set constant highlighting color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color'>
|
||||||
|
/// Constant highlighting color.
|
||||||
|
/// </param>
|
||||||
|
public void ConstantParams(Color color)
|
||||||
|
{
|
||||||
|
constantColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fade in constant highlighting.
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantOn()
|
||||||
|
{
|
||||||
|
// Enable constant highlighting
|
||||||
|
constantly = true;
|
||||||
|
// Start transition
|
||||||
|
transitionActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fade in constant highlighting with given color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color'>
|
||||||
|
/// Constant highlighting color.
|
||||||
|
/// </param>
|
||||||
|
public void ConstantOn(Color color)
|
||||||
|
{
|
||||||
|
// Set constant highlighting color
|
||||||
|
constantColor = color;
|
||||||
|
ConstantOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fade out constant highlighting.
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantOff()
|
||||||
|
{
|
||||||
|
// Disable constant highlighting
|
||||||
|
constantly = false;
|
||||||
|
// Start transition
|
||||||
|
transitionActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch Constant Highlighting.
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantSwitch()
|
||||||
|
{
|
||||||
|
// Switch constant highlighting
|
||||||
|
constantly = !constantly;
|
||||||
|
// Start transition
|
||||||
|
transitionActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on constant highlighting immediately (without fading in).
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantOnImmediate()
|
||||||
|
{
|
||||||
|
constantly = true;
|
||||||
|
// Set transition value to 1
|
||||||
|
transitionValue = 1f;
|
||||||
|
// Stop transition
|
||||||
|
transitionActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on constant highlighting with given color immediately (without fading in).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='color'>
|
||||||
|
/// Constant highlighting color.
|
||||||
|
/// </param>
|
||||||
|
public void ConstantOnImmediate(Color color)
|
||||||
|
{
|
||||||
|
// Set constant highlighting color
|
||||||
|
constantColor = color;
|
||||||
|
ConstantOnImmediate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn off constant highlighting immediately (without fading out).
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantOffImmediate()
|
||||||
|
{
|
||||||
|
constantly = false;
|
||||||
|
// Set transition value to 0
|
||||||
|
transitionValue = 0f;
|
||||||
|
// Stop transition
|
||||||
|
transitionActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch constant highlighting immediately (without fading in/out).
|
||||||
|
/// </summary>
|
||||||
|
public void ConstantSwitchImmediate()
|
||||||
|
{
|
||||||
|
constantly = !constantly;
|
||||||
|
// Set transition value to the final value
|
||||||
|
transitionValue = constantly ? 1f : 0f;
|
||||||
|
// Stop transition
|
||||||
|
transitionActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable see-through mode
|
||||||
|
/// </summary>
|
||||||
|
public void SeeThroughOn()
|
||||||
|
{
|
||||||
|
seeThrough = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disable see-through mode
|
||||||
|
/// </summary>
|
||||||
|
public void SeeThroughOff()
|
||||||
|
{
|
||||||
|
seeThrough = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch see-through mode
|
||||||
|
/// </summary>
|
||||||
|
public void SeeThroughSwitch()
|
||||||
|
{
|
||||||
|
seeThrough = !seeThrough;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable occluder mode. Non-see-through occluders will be used only in case frame depth buffer is not accessible.
|
||||||
|
/// </summary>
|
||||||
|
public void OccluderOn()
|
||||||
|
{
|
||||||
|
occluder = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disable occluder mode. Non-see-through occluders will be used only in case frame depth buffer is not accessible.
|
||||||
|
/// </summary>
|
||||||
|
public void OccluderOff()
|
||||||
|
{
|
||||||
|
occluder = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Switch occluder mode. Non-see-through occluders will be used only in case frame depth buffer is not accessible.
|
||||||
|
/// </summary>
|
||||||
|
public void OccluderSwitch()
|
||||||
|
{
|
||||||
|
occluder = !occluder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn off all types of highlighting.
|
||||||
|
/// </summary>
|
||||||
|
public void Off()
|
||||||
|
{
|
||||||
|
once = false;
|
||||||
|
flashing = false;
|
||||||
|
constantly = false;
|
||||||
|
// Set transition value to 0
|
||||||
|
transitionValue = 0f;
|
||||||
|
// Stop transition
|
||||||
|
transitionActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destroy this Highlighter component.
|
||||||
|
/// </summary>
|
||||||
|
public void Die()
|
||||||
|
{
|
||||||
|
Destroy(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
8
Assets/Highlighting System/Scripts/Highlighter.cs.meta
Normal file
8
Assets/Highlighting System/Scripts/Highlighter.cs.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 67d4de287b46eb34e83a61e4f9115070
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
10
Assets/Highlighting System/Scripts/HighlightingRenderer.cs
Normal file
10
Assets/Highlighting System/Scripts/HighlightingRenderer.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
public class HighlightingRenderer : HighlightingBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b765e0b5af3bcf4a9deb5895e477da8
|
||||||
|
labels:
|
||||||
|
- Glow
|
||||||
|
- Effect
|
||||||
|
- Outline
|
||||||
|
- Highlight
|
||||||
|
- Selection
|
||||||
|
- System
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
5
Assets/Highlighting System/Scripts/Internal.meta
Normal file
5
Assets/Highlighting System/Scripts/Internal.meta
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3e2a98eec43f4f04788ccf35d4ae8ec4
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
|
@ -0,0 +1,542 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
public partial class Highlighter : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Constants (don't touch this!)
|
||||||
|
#region Constants
|
||||||
|
// 2 * PI constant required for flashing
|
||||||
|
private const float doublePI = 2f * Mathf.PI;
|
||||||
|
|
||||||
|
// Occlusion color
|
||||||
|
private readonly Color occluderColor = new Color(0f, 0f, 0f, 0f);
|
||||||
|
|
||||||
|
// ZTest LEqual
|
||||||
|
private const float zTestLessEqual = (float)CompareFunction.LessEqual;
|
||||||
|
|
||||||
|
// ZTest Always
|
||||||
|
private const float zTestAlways = (float)CompareFunction.Always;
|
||||||
|
|
||||||
|
// Cull Off
|
||||||
|
private const float cullOff = (float)CullMode.Off;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Static Fields
|
||||||
|
// Global highlighting shaders ZWrite property
|
||||||
|
static private float zWrite = -1f; // Set to unusual default value to force initialization on start
|
||||||
|
|
||||||
|
// Global highlighting shaders Offset Factor property
|
||||||
|
static private float offsetFactor = float.NaN; // Set to unusual default value to force initialization on start
|
||||||
|
|
||||||
|
// Global highlighting shaders Offset Units property
|
||||||
|
static private float offsetUnits = float.NaN; // Set to unusual default value to force initialization on start
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Fields
|
||||||
|
// Current state of highlighting (true if highlighted and visible)
|
||||||
|
public bool highlighted { get; private set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Fields
|
||||||
|
// Cached transform component reference
|
||||||
|
private Transform tr;
|
||||||
|
|
||||||
|
// Cached Renderers
|
||||||
|
private List<RendererCache> highlightableRenderers;
|
||||||
|
|
||||||
|
// Contains frame number, in which Highlighter visibility has been checked
|
||||||
|
private int visibilityCheckFrame = -1;
|
||||||
|
|
||||||
|
// Visibility changed in this frame
|
||||||
|
private bool visibilityChanged = false;
|
||||||
|
|
||||||
|
// At least 1 renderer is visible in this frame
|
||||||
|
private bool visible = false;
|
||||||
|
|
||||||
|
// Materials reinitialization is required flag
|
||||||
|
private bool renderersDirty = true;
|
||||||
|
|
||||||
|
// Current highlighting color
|
||||||
|
private Color currentColor;
|
||||||
|
|
||||||
|
// Transition is active flag
|
||||||
|
private bool transitionActive = false;
|
||||||
|
|
||||||
|
// Current transition value
|
||||||
|
private float transitionValue = 0f;
|
||||||
|
|
||||||
|
// Flashing frequency (times per second)
|
||||||
|
private float flashingFreq = 2f;
|
||||||
|
|
||||||
|
// One-frame highlighting flag
|
||||||
|
private int _once = 0;
|
||||||
|
private bool once
|
||||||
|
{
|
||||||
|
get { return _once == Time.frameCount; }
|
||||||
|
set { _once = value ? Time.frameCount : 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// One-frame highlighting color
|
||||||
|
private Color onceColor = Color.red;
|
||||||
|
|
||||||
|
// Flashing state flag
|
||||||
|
private bool flashing = false;
|
||||||
|
|
||||||
|
// Flashing from color
|
||||||
|
private Color flashingColorMin = new Color(0f, 1f, 1f, 0f);
|
||||||
|
|
||||||
|
// Flashing to color
|
||||||
|
private Color flashingColorMax = new Color(0f, 1f, 1f, 1f);
|
||||||
|
|
||||||
|
// Constant highlighting state flag
|
||||||
|
private bool constantly = false;
|
||||||
|
|
||||||
|
// Constant highlighting color
|
||||||
|
private Color constantColor = Color.yellow;
|
||||||
|
|
||||||
|
// Occluder mode enabled flag
|
||||||
|
private bool occluder = false;
|
||||||
|
|
||||||
|
// See-through mode flag (should have same initial value with zTest and renderQueue variables!)
|
||||||
|
private bool seeThrough = true;
|
||||||
|
|
||||||
|
// RenderQueue (0 = Geometry, 1 = Geometry+1 (for seethrough mode on by default), 2 = Geometry+2)
|
||||||
|
private int renderQueue = 1;
|
||||||
|
|
||||||
|
// Current ZTest value (true = Always, false = LEqual)
|
||||||
|
private bool zTest = true;
|
||||||
|
|
||||||
|
// Current Stencil Ref value (true = 1, false = 0)
|
||||||
|
private bool stencilRef = true;
|
||||||
|
|
||||||
|
// Returns real ZTest float value which will be passed to the materials
|
||||||
|
private float zTestFloat { get { return zTest ? zTestAlways : zTestLessEqual; } }
|
||||||
|
|
||||||
|
// Returns real Stencil Ref float value which will be passed to the materials
|
||||||
|
private float stencilRefFloat { get { return stencilRef ? 1f : 0f; } }
|
||||||
|
|
||||||
|
// Opaque shader cached reference
|
||||||
|
static private Shader _opaqueShader;
|
||||||
|
static public Shader opaqueShader
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_opaqueShader == null)
|
||||||
|
{
|
||||||
|
_opaqueShader = Shader.Find("Hidden/Highlighted/Opaque");
|
||||||
|
}
|
||||||
|
return _opaqueShader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transparent shader cached reference
|
||||||
|
static private Shader _transparentShader;
|
||||||
|
static public Shader transparentShader
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_transparentShader == null)
|
||||||
|
{
|
||||||
|
_transparentShader = Shader.Find("Hidden/Highlighted/Transparent");
|
||||||
|
}
|
||||||
|
return _transparentShader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shared (for this component) replacement material for opaque geometry highlighting
|
||||||
|
private Material _opaqueMaterial;
|
||||||
|
private Material opaqueMaterial
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_opaqueMaterial == null)
|
||||||
|
{
|
||||||
|
_opaqueMaterial = new Material(opaqueShader);
|
||||||
|
|
||||||
|
// Make sure that ShaderPropertyIDs is initialized
|
||||||
|
ShaderPropertyID.Initialize();
|
||||||
|
|
||||||
|
// Make sure that shader will have proper default values
|
||||||
|
_opaqueMaterial.SetFloat(ShaderPropertyID._ZTest, zTestFloat);
|
||||||
|
_opaqueMaterial.SetFloat(ShaderPropertyID._StencilRef, stencilRefFloat);
|
||||||
|
}
|
||||||
|
return _opaqueMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MonoBehaviour
|
||||||
|
//
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
tr = GetComponent<Transform>();
|
||||||
|
ShaderPropertyID.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
if (!CheckInstance()) { return; }
|
||||||
|
|
||||||
|
HighlighterManager.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
HighlighterManager.Remove(this);
|
||||||
|
|
||||||
|
// Clear cached renderers
|
||||||
|
if (highlightableRenderers != null) { highlightableRenderers.Clear(); }
|
||||||
|
|
||||||
|
// Reset highlighting parameters to default values
|
||||||
|
renderersDirty = true;
|
||||||
|
highlighted = false;
|
||||||
|
currentColor = Color.clear;
|
||||||
|
transitionActive = false;
|
||||||
|
transitionValue = 0f;
|
||||||
|
once = false;
|
||||||
|
flashing = false;
|
||||||
|
constantly = false;
|
||||||
|
occluder = false;
|
||||||
|
seeThrough = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Reset custom parameters of the highlighting
|
||||||
|
onceColor = Color.red;
|
||||||
|
flashingColorMin = new Color(0f, 1f, 1f, 0f);
|
||||||
|
flashingColorMax = new Color(0f, 1f, 1f, 1f);
|
||||||
|
flashingFreq = 2f;
|
||||||
|
constantColor = Color.yellow;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// Update transition value
|
||||||
|
PerformTransition();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
// Returns true in case CommandBuffer should be rebuilt
|
||||||
|
public bool UpdateHighlighting(bool isDepthAvailable)
|
||||||
|
{
|
||||||
|
bool wasHighlighted = highlighted;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
changed |= UpdateRenderers();
|
||||||
|
|
||||||
|
// Is any highlighting mode is enabled?
|
||||||
|
highlighted = (once || flashing || constantly || transitionActive);
|
||||||
|
|
||||||
|
int rq = 0;
|
||||||
|
|
||||||
|
// Render as highlighter
|
||||||
|
if (highlighted)
|
||||||
|
{
|
||||||
|
// ZTest = (seeThrough ? Always : LEqual), Stencil Ref = 1
|
||||||
|
UpdateShaderParams(seeThrough, true);
|
||||||
|
// RenderQueue = (seeThrough ? Geometry+1 : Geometry)
|
||||||
|
rq = seeThrough ? 2 : 0;
|
||||||
|
}
|
||||||
|
// Render as occluder
|
||||||
|
else if (occluder && (seeThrough || !isDepthAvailable))
|
||||||
|
{
|
||||||
|
// ZTest = (isDepthAvailable ? LEqual : Always), Stencil Ref = seeThrough ? 1 : 0
|
||||||
|
UpdateShaderParams(false, seeThrough);
|
||||||
|
|
||||||
|
// RenderQueue = (seeThrough ? Occluder queue : Geometry queue)
|
||||||
|
rq = seeThrough ? 1 : 0;
|
||||||
|
|
||||||
|
highlighted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case renderer should be put to another render queue
|
||||||
|
if (renderQueue != rq)
|
||||||
|
{
|
||||||
|
renderQueue = rq;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlighted)
|
||||||
|
{
|
||||||
|
changed |= UpdateVisibility();
|
||||||
|
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
UpdateColors();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
highlighted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changed |= (wasHighlighted != highlighted);
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills given CommandBuffer with this Highlighter rendering commands
|
||||||
|
public void FillBuffer(CommandBuffer buffer, int renderQueue)
|
||||||
|
{
|
||||||
|
if (!highlighted) { return; }
|
||||||
|
|
||||||
|
if (this.renderQueue != renderQueue) { return; }
|
||||||
|
|
||||||
|
for (int i = highlightableRenderers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
RendererCache renderer = highlightableRenderers[i];
|
||||||
|
if (!renderer.FillBuffer(buffer))
|
||||||
|
{
|
||||||
|
highlightableRenderers.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
// Allow only single instance of the Highlighter component on a GameObject
|
||||||
|
private bool CheckInstance()
|
||||||
|
{
|
||||||
|
Highlighter[] highlighters = GetComponents<Highlighter>();
|
||||||
|
if (highlighters.Length > 1 && highlighters[0] != this)
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
Debug.LogWarning("HighlightingSystem : Multiple Highlighter components on a single GameObject is not allowed! Highlighter has been disabled on a GameObject with name '" + gameObject.name + "'.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method defines the way in which renderers are initialized
|
||||||
|
private bool UpdateRenderers()
|
||||||
|
{
|
||||||
|
if (renderersDirty)
|
||||||
|
{
|
||||||
|
List<Renderer> renderers = new List<Renderer>();
|
||||||
|
|
||||||
|
// Find all renderers which should be controlled by this Highlighter component
|
||||||
|
GrabRenderers(tr, ref renderers);
|
||||||
|
|
||||||
|
// Cache found renderers
|
||||||
|
highlightableRenderers = new List<RendererCache>();
|
||||||
|
int l = renderers.Count;
|
||||||
|
for (int i = 0; i < l; i++)
|
||||||
|
{
|
||||||
|
RendererCache cache = new RendererCache(renderers[i], opaqueMaterial, zTestFloat, stencilRefFloat);
|
||||||
|
highlightableRenderers.Add(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
highlighted = false;
|
||||||
|
renderersDirty = false;
|
||||||
|
currentColor = Color.clear;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// To avoid null-reference exceptions when cached GameObject or Renderer has been removed but ReinitMaterials wasn't called
|
||||||
|
bool changed = false;
|
||||||
|
for (int i = highlightableRenderers.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (highlightableRenderers[i].IsDestroyed())
|
||||||
|
{
|
||||||
|
highlightableRenderers.RemoveAt(i);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true in case visibility changed in this frame
|
||||||
|
private bool UpdateVisibility()
|
||||||
|
{
|
||||||
|
if (visibilityCheckFrame == Time.frameCount) { return visibilityChanged; }
|
||||||
|
visibilityCheckFrame = Time.frameCount;
|
||||||
|
|
||||||
|
visible = false;
|
||||||
|
visibilityChanged = false;
|
||||||
|
for (int i = 0, imax = highlightableRenderers.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
RendererCache rc = highlightableRenderers[i];
|
||||||
|
visibilityChanged |= rc.UpdateVisibility();
|
||||||
|
visible |= rc.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibilityChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Follows hierarchy of objects from t, searches for Renderers and adds them to the list. Breaks if another Highlighter component found
|
||||||
|
private void GrabRenderers(Transform t, ref List<Renderer> renderers)
|
||||||
|
{
|
||||||
|
GameObject g = t.gameObject;
|
||||||
|
IEnumerator e;
|
||||||
|
|
||||||
|
// Find all Renderers of all types on current GameObject g and add them to the renderers list
|
||||||
|
for (int i = 0, imax = types.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
Component[] c = g.GetComponents(types[i]);
|
||||||
|
|
||||||
|
e = c.GetEnumerator();
|
||||||
|
while (e.MoveNext())
|
||||||
|
{
|
||||||
|
renderers.Add(e.Current as Renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return if transform t doesn't have any children
|
||||||
|
if (t.childCount == 0) { return; }
|
||||||
|
|
||||||
|
// Recursively cache renderers on all child GameObjects
|
||||||
|
e = t.GetEnumerator();
|
||||||
|
while (e.MoveNext())
|
||||||
|
{
|
||||||
|
Transform childTransform = e.Current as Transform;
|
||||||
|
GameObject childGameObject = childTransform.gameObject;
|
||||||
|
Highlighter h = childGameObject.GetComponent<Highlighter>();
|
||||||
|
|
||||||
|
// Do not cache Renderers of this childTransform in case it has it's own Highlighter component
|
||||||
|
if (h != null) { continue; }
|
||||||
|
|
||||||
|
GrabRenderers(childTransform, ref renderers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets RenderQueue, ZTest and Stencil Ref parameters on all materials of all renderers of this object
|
||||||
|
private void UpdateShaderParams(bool zt, bool sr)
|
||||||
|
{
|
||||||
|
// ZTest
|
||||||
|
if (zTest != zt)
|
||||||
|
{
|
||||||
|
zTest = zt;
|
||||||
|
float ztf = zTestFloat;
|
||||||
|
opaqueMaterial.SetFloat(ShaderPropertyID._ZTest, ztf);
|
||||||
|
for (int i = 0; i < highlightableRenderers.Count; i++)
|
||||||
|
{
|
||||||
|
highlightableRenderers[i].SetZTestForTransparent(ztf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stencil Ref
|
||||||
|
if (stencilRef != sr)
|
||||||
|
{
|
||||||
|
stencilRef = sr;
|
||||||
|
float srf = stencilRefFloat;
|
||||||
|
opaqueMaterial.SetFloat(ShaderPropertyID._StencilRef, srf);
|
||||||
|
for (int i = 0; i < highlightableRenderers.Count; i++)
|
||||||
|
{
|
||||||
|
highlightableRenderers[i].SetStencilRefForTransparent(srf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update highlighting color if necessary
|
||||||
|
private void UpdateColors()
|
||||||
|
{
|
||||||
|
if (once)
|
||||||
|
{
|
||||||
|
SetColor(onceColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flashing)
|
||||||
|
{
|
||||||
|
// Flashing frequency is not affected by Time.timeScale
|
||||||
|
Color c = Color.Lerp(flashingColorMin, flashingColorMax, 0.5f * Mathf.Sin(Time.realtimeSinceStartup * flashingFreq * doublePI) + 0.5f);
|
||||||
|
SetColor(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transitionActive)
|
||||||
|
{
|
||||||
|
Color c = new Color(constantColor.r, constantColor.g, constantColor.b, constantColor.a * transitionValue);
|
||||||
|
SetColor(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (constantly)
|
||||||
|
{
|
||||||
|
SetColor(constantColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (occluder)
|
||||||
|
{
|
||||||
|
SetColor(occluderColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set given highlighting color
|
||||||
|
private void SetColor(Color value)
|
||||||
|
{
|
||||||
|
if (currentColor == value) { return; }
|
||||||
|
currentColor = value;
|
||||||
|
opaqueMaterial.SetColor(ShaderPropertyID._Outline, currentColor);
|
||||||
|
for (int i = 0; i < highlightableRenderers.Count; i++)
|
||||||
|
{
|
||||||
|
highlightableRenderers[i].SetColorForTransparent(currentColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new transition value if necessary
|
||||||
|
private void PerformTransition()
|
||||||
|
{
|
||||||
|
if (transitionActive == false) { return; }
|
||||||
|
|
||||||
|
float targetValue = constantly ? 1f : 0f;
|
||||||
|
|
||||||
|
// Is transition finished?
|
||||||
|
if (transitionValue == targetValue)
|
||||||
|
{
|
||||||
|
transitionActive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.timeScale != 0f)
|
||||||
|
{
|
||||||
|
// Calculating delta time untouched by Time.timeScale
|
||||||
|
float unscaledDeltaTime = Time.deltaTime / Time.timeScale;
|
||||||
|
|
||||||
|
// Calculating new transition value
|
||||||
|
transitionValue = Mathf.Clamp01(transitionValue + (constantly ? constantOnSpeed : -constantOffSpeed) * unscaledDeltaTime);
|
||||||
|
}
|
||||||
|
else { return; }
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Static Methods
|
||||||
|
// Globally sets ZWrite shader parameter for all highlighting materials
|
||||||
|
static public void SetZWrite(float value)
|
||||||
|
{
|
||||||
|
if (zWrite == value) { return; }
|
||||||
|
zWrite = value;
|
||||||
|
Shader.SetGlobalFloat(ShaderPropertyID._HighlightingZWrite, zWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Globally sets Offset Factor shader parameter for all highlighting materials
|
||||||
|
static public void SetOffsetFactor(float value)
|
||||||
|
{
|
||||||
|
if (offsetFactor == value) { return; }
|
||||||
|
offsetFactor = value;
|
||||||
|
Shader.SetGlobalFloat(ShaderPropertyID._HighlightingOffsetFactor, offsetFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Globally sets Offset Units shader parameter for all highlighting materials
|
||||||
|
static public void SetOffsetUnits(float value)
|
||||||
|
{
|
||||||
|
if (offsetUnits == value) { return; }
|
||||||
|
offsetUnits = value;
|
||||||
|
Shader.SetGlobalFloat(ShaderPropertyID._HighlightingOffsetUnits, offsetUnits);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bd0100e03c13140a894e7744d95e3a1b
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
|
@ -0,0 +1,46 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
static public class HighlighterManager
|
||||||
|
{
|
||||||
|
static private int dirtyFrame = -1;
|
||||||
|
static public bool isDirty
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return dirtyFrame == Time.frameCount;
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
dirtyFrame = value ? Time.frameCount : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static private HashSet<Highlighter> highlighters = new HashSet<Highlighter>();
|
||||||
|
|
||||||
|
//
|
||||||
|
static public void Add(Highlighter highlighter)
|
||||||
|
{
|
||||||
|
highlighters.Add(highlighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
static public void Remove(Highlighter instance)
|
||||||
|
{
|
||||||
|
if (highlighters.Remove(instance) && instance.highlighted)
|
||||||
|
{
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
static public HashSet<Highlighter>.Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return highlighters.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 051745279da5dc949a624a73543c6373
|
||||||
|
timeCreated: 1432018011
|
||||||
|
licenseType: Store
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
593
Assets/Highlighting System/Scripts/Internal/HighlightingBase.cs
Normal file
593
Assets/Highlighting System/Scripts/Internal/HighlightingBase.cs
Normal file
|
@ -0,0 +1,593 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(Camera))]
|
||||||
|
public class HighlightingBase : MonoBehaviour
|
||||||
|
{
|
||||||
|
#region Static Fields and Constants
|
||||||
|
static protected readonly Color colorClear = new Color(0f, 0f, 0f, 0f);
|
||||||
|
static protected readonly string renderBufferName = "HighlightingSystem";
|
||||||
|
static protected readonly Matrix4x4 identityMatrix = Matrix4x4.identity;
|
||||||
|
protected const CameraEvent queue = CameraEvent.BeforeImageEffectsOpaque;
|
||||||
|
|
||||||
|
static protected RenderTargetIdentifier cameraTargetID;
|
||||||
|
|
||||||
|
static protected Mesh quad;
|
||||||
|
|
||||||
|
// Graphics device version identifiers
|
||||||
|
protected const int OGL = 0;
|
||||||
|
protected const int D3D9 = 1;
|
||||||
|
protected const int D3D11 = 2;
|
||||||
|
|
||||||
|
// Current graphics device version: 0 = OpenGL or unknown (default), 1 = Direct3D 9, 2 = Direct3D 11
|
||||||
|
static protected int graphicsDeviceVersion = D3D9;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Fields
|
||||||
|
// Depth offset factor for highlighting shaders
|
||||||
|
public float offsetFactor = 0f;
|
||||||
|
|
||||||
|
// Depth offset units for highlighting shaders
|
||||||
|
public float offsetUnits = 0f;
|
||||||
|
|
||||||
|
// Highlighting buffer size downsample factor
|
||||||
|
public int downsampleFactor
|
||||||
|
{
|
||||||
|
get { return _downsampleFactor; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_downsampleFactor != value)
|
||||||
|
{
|
||||||
|
// Is power of two check
|
||||||
|
if ((value != 0) && ((value & (value - 1)) == 0))
|
||||||
|
{
|
||||||
|
_downsampleFactor = value;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("HighlightingSystem : Prevented attempt to set incorrect downsample factor value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blur iterations
|
||||||
|
public int iterations
|
||||||
|
{
|
||||||
|
get { return _iterations; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_iterations != value)
|
||||||
|
{
|
||||||
|
_iterations = value;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blur minimal spread
|
||||||
|
public float blurMinSpread
|
||||||
|
{
|
||||||
|
get { return _blurMinSpread; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_blurMinSpread != value)
|
||||||
|
{
|
||||||
|
_blurMinSpread = value;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blur spread per iteration
|
||||||
|
public float blurSpread
|
||||||
|
{
|
||||||
|
get { return _blurSpread; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_blurSpread != value)
|
||||||
|
{
|
||||||
|
_blurSpread = value;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blurring intensity for the blur material
|
||||||
|
public float blurIntensity
|
||||||
|
{
|
||||||
|
get { return _blurIntensity; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_blurIntensity != value)
|
||||||
|
{
|
||||||
|
_blurIntensity = value;
|
||||||
|
if (Application.isPlaying)
|
||||||
|
{
|
||||||
|
blurMaterial.SetFloat(ShaderPropertyID._Intensity, _blurIntensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Protected Fields
|
||||||
|
protected CommandBuffer renderBuffer;
|
||||||
|
|
||||||
|
protected bool isDirty = true;
|
||||||
|
|
||||||
|
protected int cachedWidth = -1;
|
||||||
|
protected int cachedHeight = -1;
|
||||||
|
protected int cachedAA = -1;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("downsampleFactor")]
|
||||||
|
[SerializeField]
|
||||||
|
protected int _downsampleFactor = 4;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("iterations")]
|
||||||
|
[SerializeField]
|
||||||
|
protected int _iterations = 2;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("blurMinSpread")]
|
||||||
|
[SerializeField]
|
||||||
|
protected float _blurMinSpread = 0.65f;
|
||||||
|
|
||||||
|
[FormerlySerializedAs("blurSpread")]
|
||||||
|
[SerializeField]
|
||||||
|
protected float _blurSpread = 0.25f;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
protected float _blurIntensity = 0.3f;
|
||||||
|
|
||||||
|
// RenderTargetidentifier for the highlightingBuffer RenderTexture
|
||||||
|
protected RenderTargetIdentifier highlightingBufferID;
|
||||||
|
|
||||||
|
// RenderTexture with highlighting buffer
|
||||||
|
protected RenderTexture highlightingBuffer = null;
|
||||||
|
|
||||||
|
// Camera reference
|
||||||
|
protected Camera cam = null;
|
||||||
|
|
||||||
|
// True if HighlightingSystem is supported on this platform
|
||||||
|
protected bool isSupported = false;
|
||||||
|
|
||||||
|
// True if framebuffer depth data is currently available (it is required for the highlighting occlusion feature)
|
||||||
|
protected bool isDepthAvailable = true;
|
||||||
|
|
||||||
|
// Material parameters
|
||||||
|
protected const int BLUR = 0;
|
||||||
|
protected const int CUT = 1;
|
||||||
|
protected const int COMP = 2;
|
||||||
|
static protected readonly string[] shaderPaths = new string[]
|
||||||
|
{
|
||||||
|
"Hidden/Highlighted/Blur",
|
||||||
|
"Hidden/Highlighted/Cut",
|
||||||
|
"Hidden/Highlighted/Composite",
|
||||||
|
};
|
||||||
|
static protected Shader[] shaders;
|
||||||
|
static protected Material[] materials;
|
||||||
|
|
||||||
|
// Static materials
|
||||||
|
static protected Material cutMaterial;
|
||||||
|
static protected Material compMaterial;
|
||||||
|
|
||||||
|
// Dynamic materials
|
||||||
|
protected Material blurMaterial;
|
||||||
|
|
||||||
|
static protected bool initialized = false;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MonoBehaviour
|
||||||
|
//
|
||||||
|
protected virtual void OnEnable()
|
||||||
|
{
|
||||||
|
if (!CheckInstance()) { return; }
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
isSupported = CheckSupported();
|
||||||
|
if (!isSupported)
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
Debug.LogError("HighlightingSystem : Highlighting System has been disabled due to unsupported Unity features on the current platform!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
blurMaterial = new Material(materials[BLUR]);
|
||||||
|
|
||||||
|
// Set initial intensity in blur material
|
||||||
|
blurMaterial.SetFloat(ShaderPropertyID._Intensity, _blurIntensity);
|
||||||
|
|
||||||
|
renderBuffer = new CommandBuffer();
|
||||||
|
renderBuffer.name = renderBufferName;
|
||||||
|
|
||||||
|
cam = GetComponent<Camera>();
|
||||||
|
UpdateHighlightingBuffer();
|
||||||
|
|
||||||
|
// Force-rebuild renderBuffer
|
||||||
|
isDirty = true;
|
||||||
|
|
||||||
|
cam.AddCommandBuffer(queue, renderBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void OnDisable()
|
||||||
|
{
|
||||||
|
if (renderBuffer != null)
|
||||||
|
{
|
||||||
|
cam.RemoveCommandBuffer(queue, renderBuffer);
|
||||||
|
renderBuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlightingBuffer != null && highlightingBuffer.IsCreated())
|
||||||
|
{
|
||||||
|
highlightingBuffer.Release();
|
||||||
|
highlightingBuffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void OnPreRender()
|
||||||
|
{
|
||||||
|
UpdateHighlightingBuffer();
|
||||||
|
|
||||||
|
int aa = GetAA();
|
||||||
|
|
||||||
|
bool depthAvailable = (aa == 1);
|
||||||
|
|
||||||
|
// In case MSAA is enabled in forward/vertex lit rendeirng paths - depth buffer is not available
|
||||||
|
if (aa > 1 && (cam.actualRenderingPath == RenderingPath.Forward || cam.actualRenderingPath == RenderingPath.VertexLit))
|
||||||
|
{
|
||||||
|
depthAvailable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if framebuffer depth data availability has changed
|
||||||
|
if (isDepthAvailable != depthAvailable)
|
||||||
|
{
|
||||||
|
isDepthAvailable = depthAvailable;
|
||||||
|
// Update ZWrite value for all highlighting shaders correspondingly (isDepthAvailable ? ZWrite Off : ZWrite On)
|
||||||
|
Highlighter.SetZWrite(isDepthAvailable ? 0f : 1f);
|
||||||
|
if (isDepthAvailable)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("HighlightingSystem : Framebuffer depth data is available back again and will be used to occlude highlighting. Highlighting occluders disabled.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("HighlightingSystem : Framebuffer depth data is not available and can't be used to occlude highlighting. Highlighting occluders enabled.");
|
||||||
|
}
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set global depth offset properties for highlighting shaders to the values which has this HighlightingBase component
|
||||||
|
Highlighter.SetOffsetFactor(offsetFactor);
|
||||||
|
Highlighter.SetOffsetUnits(offsetUnits);
|
||||||
|
|
||||||
|
isDirty |= HighlighterManager.isDirty;
|
||||||
|
isDirty |= HighlightersChanged();
|
||||||
|
|
||||||
|
if (isDirty)
|
||||||
|
{
|
||||||
|
RebuildCommandBuffer();
|
||||||
|
isDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void OnRenderImage(RenderTexture src, RenderTexture dst)
|
||||||
|
{
|
||||||
|
Graphics.Blit(src, dst, compMaterial);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Internal
|
||||||
|
//
|
||||||
|
static protected void Initialize()
|
||||||
|
{
|
||||||
|
if (initialized) { return; }
|
||||||
|
|
||||||
|
// Determine graphics device version
|
||||||
|
string version = SystemInfo.graphicsDeviceVersion.ToLower();
|
||||||
|
if (version.Contains("direct3d") || version.Contains("directx"))
|
||||||
|
{
|
||||||
|
if (version.Contains("direct3d 11") || version.Contains("directx 11")) { graphicsDeviceVersion = D3D11; }
|
||||||
|
else { graphicsDeviceVersion = D3D9; }
|
||||||
|
}
|
||||||
|
#if UNITY_EDITOR_WIN && (UNITY_ANDROID || UNITY_IOS)
|
||||||
|
else if (version.Contains("emulated"))
|
||||||
|
{
|
||||||
|
graphicsDeviceVersion = D3D9;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphicsDeviceVersion = OGL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize shader property constants
|
||||||
|
ShaderPropertyID.Initialize();
|
||||||
|
|
||||||
|
// Initialize shaders and materials
|
||||||
|
int l = shaderPaths.Length;
|
||||||
|
shaders = new Shader[l];
|
||||||
|
materials = new Material[l];
|
||||||
|
for (int i = 0; i < l; i++)
|
||||||
|
{
|
||||||
|
Shader shader = Shader.Find(shaderPaths[i]);
|
||||||
|
shaders[i] = shader;
|
||||||
|
|
||||||
|
Material material = new Material(shader);
|
||||||
|
materials[i] = material;
|
||||||
|
}
|
||||||
|
cutMaterial = materials[CUT];
|
||||||
|
compMaterial = materials[COMP];
|
||||||
|
|
||||||
|
// Initialize static RenderTargetIdentifiers
|
||||||
|
cameraTargetID = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);
|
||||||
|
|
||||||
|
// Create static quad mesh
|
||||||
|
CreateQuad();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
static protected void CreateQuad()
|
||||||
|
{
|
||||||
|
if (quad == null)
|
||||||
|
{
|
||||||
|
quad = new Mesh();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quad.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
float y1 = 1f;
|
||||||
|
float y2 = -1f;
|
||||||
|
|
||||||
|
if (graphicsDeviceVersion == OGL)
|
||||||
|
{
|
||||||
|
y1 = -1f;
|
||||||
|
y2 = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
quad.vertices = new Vector3[]
|
||||||
|
{
|
||||||
|
new Vector3(-1f, y1, 0f), // Bottom-Left
|
||||||
|
new Vector3(-1f, y2, 0f), // Upper-Left
|
||||||
|
new Vector3( 1f, y2, 0f), // Upper-Right
|
||||||
|
new Vector3( 1f, y1, 0f) // Bottom-Right
|
||||||
|
};
|
||||||
|
|
||||||
|
quad.uv = new Vector2[]
|
||||||
|
{
|
||||||
|
new Vector2(0f, 0f),
|
||||||
|
new Vector2(0f, 1f),
|
||||||
|
new Vector2(1f, 1f),
|
||||||
|
new Vector2(1f, 0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
quad.colors = new Color[]
|
||||||
|
{
|
||||||
|
colorClear,
|
||||||
|
colorClear,
|
||||||
|
colorClear,
|
||||||
|
colorClear
|
||||||
|
};
|
||||||
|
|
||||||
|
quad.triangles = new int[] { 0, 1, 2, 2, 3, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual int GetAA()
|
||||||
|
{
|
||||||
|
int aa = QualitySettings.antiAliasing;
|
||||||
|
if (aa == 0) { aa = 1; }
|
||||||
|
|
||||||
|
// Reset aa value to 1 in case camera is in DeferredLighting or DeferredShading Rendering Path
|
||||||
|
if (cam.actualRenderingPath == RenderingPath.DeferredLighting || cam.actualRenderingPath == RenderingPath.DeferredShading) { aa = 1; }
|
||||||
|
|
||||||
|
return aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void UpdateHighlightingBuffer()
|
||||||
|
{
|
||||||
|
int aa = GetAA();
|
||||||
|
|
||||||
|
if (cam.pixelWidth == cachedWidth && cam.pixelHeight == cachedHeight && aa == cachedAA) { return; }
|
||||||
|
|
||||||
|
cachedWidth = cam.pixelWidth;
|
||||||
|
cachedHeight = cam.pixelHeight;
|
||||||
|
cachedAA = aa;
|
||||||
|
|
||||||
|
if (highlightingBuffer != null && highlightingBuffer.IsCreated())
|
||||||
|
{
|
||||||
|
highlightingBuffer.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightingBuffer = new RenderTexture(cachedWidth, cachedHeight, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
|
||||||
|
highlightingBuffer.antiAliasing = cachedAA;
|
||||||
|
highlightingBuffer.filterMode = FilterMode.Point;
|
||||||
|
highlightingBuffer.useMipMap = false;
|
||||||
|
highlightingBuffer.wrapMode = TextureWrapMode.Clamp;
|
||||||
|
if (!highlightingBuffer.Create())
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : UpdateHighlightingBuffer() : Failed to create highlightingBuffer RenderTexture!");
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightingBufferID = new RenderTargetIdentifier(highlightingBuffer);
|
||||||
|
Shader.SetGlobalTexture(ShaderPropertyID._HighlightingBuffer, highlightingBuffer);
|
||||||
|
|
||||||
|
Vector4 v = new Vector4((graphicsDeviceVersion == OGL ? 1f : -1f) / (float)highlightingBuffer.width, 1f / (float)highlightingBuffer.height, 0f, 0f);
|
||||||
|
Shader.SetGlobalVector(ShaderPropertyID._HighlightingBufferTexelSize, v);
|
||||||
|
|
||||||
|
// Always set as dirty, because camera width/height/anti-aliasing has changed
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow only single instance of the HighlightingBase component on a GameObject
|
||||||
|
public virtual bool CheckInstance()
|
||||||
|
{
|
||||||
|
HighlightingBase[] highlightingBases = GetComponents<HighlightingBase>();
|
||||||
|
if (highlightingBases.Length > 1 && highlightingBases[0] != this)
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
string className = this.GetType().ToString();
|
||||||
|
Debug.LogWarning(string.Format("HighlightingSystem : Only single instance of the HighlightingRenderer component is allowed on a single Gameobject! {0} has been disabled on GameObject with name '{1}'.", className, name));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual bool CheckSupported()
|
||||||
|
{
|
||||||
|
// Image Effects supported?
|
||||||
|
if (!SystemInfo.supportsImageEffects)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : Image effects is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render Textures supported?
|
||||||
|
if (!SystemInfo.supportsRenderTextures)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : RenderTextures is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required Render Texture Format supported?
|
||||||
|
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : RenderTextureFormat.ARGB32 is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SystemInfo.supportsStencil < 1)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : Stencil buffer is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HighlightingOpaque shader supported?
|
||||||
|
if (!Highlighter.opaqueShader.isSupported)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : HighlightingOpaque shader is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HighlightingTransparent shader supported?
|
||||||
|
if (!Highlighter.transparentShader.isSupported)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : HighlightingTransparent shader is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required shaders supported?
|
||||||
|
for (int i = 0; i < shaders.Length; i++)
|
||||||
|
{
|
||||||
|
Shader shader = shaders[i];
|
||||||
|
if (!shader.isSupported)
|
||||||
|
{
|
||||||
|
Debug.LogError("HighlightingSystem : Shader '" + shader.name + "' is not supported on this platform!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual bool HighlightersChanged()
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
// Check if list of highlighted objects has changed
|
||||||
|
HashSet<Highlighter>.Enumerator e = HighlighterManager.GetEnumerator();
|
||||||
|
while (e.MoveNext())
|
||||||
|
{
|
||||||
|
Highlighter highlighter = e.Current;
|
||||||
|
changed |= highlighter.UpdateHighlighting(isDepthAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void RebuildCommandBuffer()
|
||||||
|
{
|
||||||
|
renderBuffer.Clear();
|
||||||
|
|
||||||
|
RenderTargetIdentifier depthID = isDepthAvailable ? cameraTargetID : highlightingBufferID;
|
||||||
|
|
||||||
|
// Prepare and clear render target
|
||||||
|
renderBuffer.SetRenderTarget(highlightingBufferID, depthID);
|
||||||
|
renderBuffer.ClearRenderTarget(!isDepthAvailable, true, colorClear);
|
||||||
|
|
||||||
|
// Fill buffer with highlighters rendering commands
|
||||||
|
FillBuffer(renderBuffer, 0); // Highlighters
|
||||||
|
FillBuffer(renderBuffer, 1); // Occluders
|
||||||
|
FillBuffer(renderBuffer, 2); // See-through Highlighters
|
||||||
|
|
||||||
|
// Create two buffers for blurring the image
|
||||||
|
RenderTargetIdentifier blur1ID = new RenderTargetIdentifier(ShaderPropertyID._HighlightingBlur1);
|
||||||
|
RenderTargetIdentifier blur2ID = new RenderTargetIdentifier(ShaderPropertyID._HighlightingBlur2);
|
||||||
|
|
||||||
|
int width = highlightingBuffer.width / _downsampleFactor;
|
||||||
|
int height = highlightingBuffer.height / _downsampleFactor;
|
||||||
|
|
||||||
|
renderBuffer.GetTemporaryRT(ShaderPropertyID._HighlightingBlur1, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
|
||||||
|
renderBuffer.GetTemporaryRT(ShaderPropertyID._HighlightingBlur2, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);
|
||||||
|
|
||||||
|
renderBuffer.Blit(highlightingBufferID, blur1ID);
|
||||||
|
|
||||||
|
// Blur the small texture
|
||||||
|
bool oddEven = true;
|
||||||
|
for (int i = 0; i < _iterations; i++)
|
||||||
|
{
|
||||||
|
float off = _blurMinSpread + _blurSpread * i;
|
||||||
|
renderBuffer.SetGlobalFloat(ShaderPropertyID._HighlightingBlurOffset, off);
|
||||||
|
|
||||||
|
if (oddEven)
|
||||||
|
{
|
||||||
|
renderBuffer.Blit(blur1ID, blur2ID, blurMaterial);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renderBuffer.Blit(blur2ID, blur1ID, blurMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
oddEven = !oddEven;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upscale blurred texture and cut stencil from it
|
||||||
|
renderBuffer.SetGlobalTexture(ShaderPropertyID._HighlightingBlurred, oddEven ? blur1ID : blur2ID);
|
||||||
|
renderBuffer.SetRenderTarget(highlightingBufferID, depthID);
|
||||||
|
renderBuffer.DrawMesh(quad, identityMatrix, cutMaterial);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
renderBuffer.ReleaseTemporaryRT(ShaderPropertyID._HighlightingBlur1);
|
||||||
|
renderBuffer.ReleaseTemporaryRT(ShaderPropertyID._HighlightingBlur2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected virtual void FillBuffer(CommandBuffer buffer, int renderQueue)
|
||||||
|
{
|
||||||
|
HashSet<Highlighter>.Enumerator e;
|
||||||
|
e = HighlighterManager.GetEnumerator();
|
||||||
|
while (e.MoveNext())
|
||||||
|
{
|
||||||
|
Highlighter highlighter = e.Current;
|
||||||
|
highlighter.FillBuffer(renderBuffer, renderQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c9a69acb2622340e39a2b84d908232e3
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
170
Assets/Highlighting System/Scripts/Internal/RendererCache.cs
Normal file
170
Assets/Highlighting System/Scripts/Internal/RendererCache.cs
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
public partial class Highlighter : MonoBehaviour
|
||||||
|
{
|
||||||
|
// Internal class for renderers caching
|
||||||
|
private class RendererCache
|
||||||
|
{
|
||||||
|
private static readonly string sRenderType = "RenderType";
|
||||||
|
private static readonly string sOpaque = "Opaque";
|
||||||
|
private static readonly string sTransparent = "Transparent";
|
||||||
|
private static readonly string sTransparentCutout = "TransparentCutout";
|
||||||
|
private static readonly string sMainTex = "_MainTex";
|
||||||
|
|
||||||
|
private struct Data
|
||||||
|
{
|
||||||
|
public Material material;
|
||||||
|
public int submeshIndex;
|
||||||
|
public bool transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private const int opaquePassID = 0;
|
||||||
|
private const int transparentPassID = 1;
|
||||||
|
|
||||||
|
public bool visible { get; private set; }
|
||||||
|
|
||||||
|
private GameObject go;
|
||||||
|
private Renderer renderer;
|
||||||
|
private List<Data> data;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public RendererCache(Renderer r, Material sharedOpaqueMaterial, float zTest, float stencilRef)
|
||||||
|
{
|
||||||
|
data = new List<Data>();
|
||||||
|
renderer = r;
|
||||||
|
go = r.gameObject;
|
||||||
|
|
||||||
|
Material[] materials = r.sharedMaterials;
|
||||||
|
|
||||||
|
if (materials != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < materials.Length; i++)
|
||||||
|
{
|
||||||
|
Material sourceMat = materials[i];
|
||||||
|
|
||||||
|
if (sourceMat == null) { continue; }
|
||||||
|
|
||||||
|
Data d = new Data();
|
||||||
|
|
||||||
|
string tag = sourceMat.GetTag(sRenderType, true, sOpaque);
|
||||||
|
if (tag == sTransparent || tag == sTransparentCutout)
|
||||||
|
{
|
||||||
|
Material replacementMat = new Material(transparentShader);
|
||||||
|
replacementMat.SetFloat(ShaderPropertyID._ZTest, zTest);
|
||||||
|
replacementMat.SetFloat(ShaderPropertyID._StencilRef, stencilRef);
|
||||||
|
if (r is SpriteRenderer) { replacementMat.SetFloat(ShaderPropertyID._Cull, cullOff); }
|
||||||
|
if (sourceMat.HasProperty(ShaderPropertyID._MainTex))
|
||||||
|
{
|
||||||
|
replacementMat.SetTexture(ShaderPropertyID._MainTex, sourceMat.mainTexture);
|
||||||
|
replacementMat.SetTextureOffset(sMainTex, sourceMat.mainTextureOffset);
|
||||||
|
replacementMat.SetTextureScale(sMainTex, sourceMat.mainTextureScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cutoff = ShaderPropertyID._Cutoff;
|
||||||
|
replacementMat.SetFloat(cutoff, sourceMat.HasProperty(cutoff) ? sourceMat.GetFloat(cutoff) : transparentCutoff);
|
||||||
|
|
||||||
|
d.material = replacementMat;
|
||||||
|
d.transparent = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d.material = sharedOpaqueMaterial;
|
||||||
|
d.transparent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.submeshIndex = i;
|
||||||
|
data.Add(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visible = !IsDestroyed() && IsVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
public bool UpdateVisibility()
|
||||||
|
{
|
||||||
|
bool visibleNow = !IsDestroyed() && IsVisible();
|
||||||
|
|
||||||
|
if (visible != visibleNow)
|
||||||
|
{
|
||||||
|
visible = visibleNow;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills given command buffer with this highlighter rendering commands
|
||||||
|
public bool FillBuffer(CommandBuffer buffer)
|
||||||
|
{
|
||||||
|
if (IsDestroyed()) { return false; }
|
||||||
|
|
||||||
|
if (IsVisible())
|
||||||
|
{
|
||||||
|
for (int i = 0, imax = data.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
Data d = data[i];
|
||||||
|
buffer.DrawRenderer(renderer, d.material, d.submeshIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets given color as highlighting color on all transparent materials of this renderer
|
||||||
|
public void SetColorForTransparent(Color clr)
|
||||||
|
{
|
||||||
|
for (int i = 0, imax = data.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
Data d = data[i];
|
||||||
|
if (d.transparent)
|
||||||
|
{
|
||||||
|
d.material.SetColor(ShaderPropertyID._Outline, clr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets ZTest parameter on all transparent materials of this renderer
|
||||||
|
public void SetZTestForTransparent(float zTest)
|
||||||
|
{
|
||||||
|
for (int i = 0, imax = data.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
Data d = data[i];
|
||||||
|
if (d.transparent)
|
||||||
|
{
|
||||||
|
d.material.SetFloat(ShaderPropertyID._ZTest, zTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets Stencil Ref parameter on all transparent materials of this renderer
|
||||||
|
public void SetStencilRefForTransparent(float stencilRef)
|
||||||
|
{
|
||||||
|
for (int i = 0, imax = data.Count; i < imax; i++)
|
||||||
|
{
|
||||||
|
Data d = data[i];
|
||||||
|
if (d.transparent)
|
||||||
|
{
|
||||||
|
d.material.SetFloat(ShaderPropertyID._StencilRef, stencilRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private bool IsVisible()
|
||||||
|
{
|
||||||
|
return renderer.enabled && renderer.isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
public bool IsDestroyed()
|
||||||
|
{
|
||||||
|
return go == null || renderer == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f97757299618eab4490066e41a69a6ca
|
||||||
|
timeCreated: 1432110880
|
||||||
|
licenseType: Store
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,63 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace HighlightingSystem
|
||||||
|
{
|
||||||
|
static public class ShaderPropertyID
|
||||||
|
{
|
||||||
|
#region PUBLIC FIELDS
|
||||||
|
// Common
|
||||||
|
static public int _MainTex { get; private set; }
|
||||||
|
|
||||||
|
// HighlightingSystem
|
||||||
|
static public int _Outline { get; private set; }
|
||||||
|
static public int _Cutoff { get; private set; }
|
||||||
|
static public int _Intensity { get; private set; }
|
||||||
|
static public int _ZTest { get; private set; }
|
||||||
|
static public int _StencilRef { get; private set; }
|
||||||
|
static public int _Cull { get; private set; }
|
||||||
|
static public int _HighlightingBlur1 { get; private set; }
|
||||||
|
static public int _HighlightingBlur2 { get; private set; }
|
||||||
|
|
||||||
|
// HighlightingSystem global shader properties. Should be unique!
|
||||||
|
static public int _HighlightingBuffer { get; private set; }
|
||||||
|
static public int _HighlightingBlurred { get; private set; }
|
||||||
|
static public int _HighlightingBlurOffset { get; private set; }
|
||||||
|
static public int _HighlightingZWrite { get; private set; }
|
||||||
|
static public int _HighlightingOffsetFactor { get; private set; }
|
||||||
|
static public int _HighlightingOffsetUnits { get; private set; }
|
||||||
|
static public int _HighlightingBufferTexelSize { get; private set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region PRIVATE FIELDS
|
||||||
|
static private bool initialized = false;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
static public void Initialize()
|
||||||
|
{
|
||||||
|
if (initialized) { return; }
|
||||||
|
|
||||||
|
_MainTex = Shader.PropertyToID("_MainTex");
|
||||||
|
|
||||||
|
_Outline = Shader.PropertyToID("_Outline");
|
||||||
|
_Cutoff = Shader.PropertyToID("_Cutoff");
|
||||||
|
_Intensity = Shader.PropertyToID("_Intensity");
|
||||||
|
_ZTest = Shader.PropertyToID("_ZTest");
|
||||||
|
_StencilRef = Shader.PropertyToID("_StencilRef");
|
||||||
|
_Cull = Shader.PropertyToID("_Cull");
|
||||||
|
_HighlightingBlur1 = Shader.PropertyToID("_HighlightingBlur1");
|
||||||
|
_HighlightingBlur2 = Shader.PropertyToID("_HighlightingBlur2");
|
||||||
|
|
||||||
|
_HighlightingBuffer = Shader.PropertyToID("_HighlightingBuffer");
|
||||||
|
_HighlightingBlurred = Shader.PropertyToID("_HighlightingBlurred");
|
||||||
|
_HighlightingBlurOffset = Shader.PropertyToID("_HighlightingBlurOffset");
|
||||||
|
_HighlightingZWrite = Shader.PropertyToID("_HighlightingZWrite");
|
||||||
|
_HighlightingOffsetFactor = Shader.PropertyToID("_HighlightingOffsetFactor");
|
||||||
|
_HighlightingOffsetUnits = Shader.PropertyToID("_HighlightingOffsetUnits");
|
||||||
|
_HighlightingBufferTexelSize = Shader.PropertyToID("_HighlightingBufferTexelSize");
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bdf8fd90b69cf684cbbb8f6ec27bf953
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
|
@ -2259,6 +2259,13 @@
|
||||||
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundBrushPresetC.cs" />
|
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundBrushPresetC.cs" />
|
||||||
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundPresetCircleShotC.cs" />
|
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundPresetCircleShotC.cs" />
|
||||||
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundPresetLaserC.cs" />
|
<Compile Include="Assets\Particle Playground\Scripts\Presets\PlaygroundPresetLaserC.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Highlighter.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\HighlightingRenderer.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Internal\HighlighterInternal.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Internal\HighlighterManager.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Internal\HighlightingBase.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Internal\RendererCache.cs" />
|
||||||
|
<Compile Include="Assets\Highlighting System\Scripts\Internal\ShaderPropertyID.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include=".gitattributes" />
|
<None Include=".gitattributes" />
|
||||||
|
|
Loading…
Reference in a new issue