Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved AddNode placement (+ additional fixes) #820

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 130 additions & 67 deletions Assets/Resources/Shaders/TransparentEdgePortalShader.shader
Original file line number Diff line number Diff line change
Expand Up @@ -20,106 +20,169 @@ Shader "Unlit/SEE/TransparentEdgePortalShader"
SubShader
{
Tags {
"Queue"="Transparent"
"RenderType"="Transparent"
"IgnoreProjector"="True"
"Queue" = "Transparent+1"
"RenderType" = "Transparent"
"IgnoreProjector" = "True"
"ForceNoShadowCasting" = "True"
"PreviewType" = "Plane"
}

// Alpha blending mode for transparency
Blend SrcAlpha OneMinusSrcAlpha
// Do not write to depth buffer to allow transparency effect
// Note: We will be able to see parts of the edge through other parts of the same edge, that should be occluded
// on full opacity. This is not a desired effect but not a big issue either.
ZWrite Off
// Makes the inside visible at clipping planes
Cull Off
// Unity's lighting will not be applied
Lighting Off

Pass
// Shared code for both passes
HLSLINCLUDE

#include "UnityCG.cginc"

struct appdata
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};

#include "UnityCG.cginc"
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD0;
float1 doDiscard : TEXCOORD1;
float4 color : TEXCOORD2;
};

struct appdata
// Color
fixed4 _Color;
fixed4 _EndColor;
float _ColorGradientEnabled;
float _AlphaThreshold;

// Data Flow
float _EdgeFlowEnabled;
float _AnimationFactor;
float _AnimationPause;
float _EffectWidth;
float _GrowthAmount;

// Clipping
float4 _Portal;

v2f SharedVertexManipulation(appdata v)
{
v2f o;

if (_EdgeFlowEnabled > 0.5)
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
// The effect is supposed to move automatically based on the time and the animation factor.
// The position is calculated based on the assumption that the object has a uniform UV mapping (0.0 to 1.0 along the y axis).
// We stretch the effect scale by the effect width so that the effect fades in and out smoothly at both ends, respectively.
// Additionally, the effect scale is stretched to add a pause between the animations.
float effectPosition = frac(_Time.y * _AnimationFactor) * (1.0 + 2 * _EffectWidth + _AnimationPause) - _EffectWidth;

// Distance between the vertex and the effect position on the y axis in world-space
float distance = abs(v.uv.y - effectPosition);

if (distance < _EffectWidth)
{
// The effect strength is based on the distance to the effect position
float effectFactor = 1.0 - pow(distance / _EffectWidth, 3);
effectFactor = clamp(effectFactor, 0.0, 1.0);
// We use the direction of the normal to grow outward
float3 outwardDir = normalize(v.normal);
v.vertex.xyz += outwardDir * effectFactor * _GrowthAmount;
}
}

o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);

struct v2f
// Note: The following is not strictly vertex related but we do this in the shared function
// to prevent clutter and code duplication.

// Flag coordinates as discardable outside portal
// Note: We use a 2D portal that spans over Unity's XZ plane: (x_min, z_min, x_max, z_max)
if (o.worldPos.x < _Portal.x || o.worldPos.z < _Portal.y ||
o.worldPos.x > _Portal.z || o.worldPos.z > _Portal.w)
{
o.doDiscard = 1;
}
else
{
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD0;
float2 uv : TEXCOORD1;
};

// Color
fixed4 _Color;
fixed4 _EndColor;
float _ColorGradientEnabled;

// Data Flow
float _EdgeFlowEnabled;
float _AnimationFactor;
float _AnimationPause;
float _EffectWidth;
float _GrowthAmount;

// Clipping
float4 _Portal;
o.doDiscard = 0;
}

o.color = _ColorGradientEnabled > 0.5 ? lerp(_Color, _EndColor, v.uv.y) : _Color;;

return o;
}
ENDHLSL

// Pass 1: Render opaque fragments with depth writing
Pass
{
Name "OpaquePass"
// Write to depth buffer to make opaque fragments occlude other objects.
// All other fragments will be discarded in this step.
ZWrite On

HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

v2f vert (appdata v)
{
v2f o;
return SharedVertexManipulation(v);
}

if (_EdgeFlowEnabled > 0.5)
fixed4 frag (v2f i) : SV_Target
{
// Discard fragment if transparent or flagged earlier
if (i.doDiscard || i.color.a < 1.0)
{
// The effect is supposed to move automatically based on the time and the animation factor.
// The position is calculated based on the assumption that the object has a uniform UV mapping (0.0 to 1.0 along the y axis).
// We stretch the effect scale by the effect width so that the effect fades in and out smoothly at both ends, respectively.
// Additionally, the effect scale is stretched to add a pause between the animations.
float effectPosition = frac(_Time.y * _AnimationFactor) * (1.0 + 2 * _EffectWidth + _AnimationPause) - _EffectWidth;

// Distance between the vertex and the effect position on the y axis in world-space
float distance = abs(v.uv.y - effectPosition);

if (distance < _EffectWidth)
{
// The effect strength is based on the distance to the effect position
float effectFactor = 1.0 - pow(distance / _EffectWidth, 3);
effectFactor = clamp(effectFactor, 0.0, 1.0);
// We use the direction of the normal to grow outward
float3 outwardDir = normalize(v.normal);
v.vertex.xyz += outwardDir * effectFactor * _GrowthAmount;
}
discard;
}

o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.uv = v.uv;
return o;
return i.color;
}
ENDHLSL
}

// Pass 2: Render semitransparent fragments without depth writing
Pass
{
Name "TransparentPass"
// Do not write to depth buffer to allow transparency effect
// Note: We will be able to see parts of the edge through other parts of the same edge, that should be occluded
// on full opacity. This is not a desired effect but not a big issue either.
ZWrite Off

HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

v2f vert (appdata v)
{
return SharedVertexManipulation(v);
}

fixed4 frag (v2f i) : SV_Target
{
// Discard coordinates if transparent or outside portal
// Note: We use a 2D portal that spans over Unity's XZ plane: (x_min, z_min, x_max, z_max)
if (i.worldPos.x < _Portal.x || i.worldPos.z < _Portal.y ||
i.worldPos.x > _Portal.z || i.worldPos.z > _Portal.w)
// Discard fragment if transparent or flagged earlier
if (i.doDiscard || i.color.a <= 0)
{
discard;
}

return _ColorGradientEnabled > 0.5 ? lerp(_Color, _EndColor, i.uv.y) : _Color;
return i.color;
}
ENDCG
ENDHLSL
}
}
}
15 changes: 8 additions & 7 deletions Assets/Resources/Shaders/TransparentLinePortalShader.shader
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
"Queue" = "Transparent+1"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}

Cull Off
Expand All @@ -27,12 +27,13 @@

Pass
{
CGPROGRAM
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA

#include "UnityCG.cginc"

struct appdata_t
Expand Down Expand Up @@ -99,7 +100,7 @@
c.rgb *= c.a;
return c;
}
ENDCG
ENDHLSL
}
}
}
18 changes: 12 additions & 6 deletions Assets/Resources/Shaders/TransparentSpritePortalShader.shader
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
// Please note:
// This shader is currently not intended for semi-transparent sprites.
// It handles full transparency and opaque elements well with depth writing (ZWrite)
// for opaque fragments; fully transparent fragments are discarded.
// To allow for blending of semitransparent areas it is necessary to implement a two-pass
// mechanism akin to the edge shader that draws translucent parts without depth writing.
// Depth writing is necessary to achieve the correct order of edges and resize handles.

Shader "Unlit/TransparentSpritePortalShader"
{
Properties
Expand All @@ -10,23 +18,21 @@ Shader "Unlit/TransparentSpritePortalShader"
Tags {
"Queue" = "Transparent"
"RenderType" = "Transparent"
"IgnoreProjector"="True"
"IgnoreProjector" = "True"
"ForceNoShadowCasting" = "True"
"PreviewType" = "Plane"
}

// Alpha blending mode for transparency
Blend SrcAlpha OneMinusSrcAlpha
// Do not write to depth buffer to allow transparency effect
ZWrite Off
// Makes the back of the sprite plane visible
Cull Off
// Unity's lighting will not be applied
Lighting Off

Pass
{
CGPROGRAM
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag

Expand Down Expand Up @@ -65,7 +71,7 @@ Shader "Unlit/TransparentSpritePortalShader"

// Discard coordinates if transparent or outside portal
// Note: We use a 2D portal that spans over Unity's XZ plane: (x_min, z_min, x_max, z_max)
if ( col.a <= 0 ||
if (col.a <= 0 ||
i.worldPos.x < _Portal.x || i.worldPos.z < _Portal.y ||
i.worldPos.x > _Portal.z || i.worldPos.z > _Portal.w)
{
Expand All @@ -74,7 +80,7 @@ Shader "Unlit/TransparentSpritePortalShader"

return col;
}
ENDCG
ENDHLSL
}
}
}
Loading
Loading