First Commit

This commit is contained in:
2025-05-18 22:39:39 +03:00
commit 042ede7228
440 changed files with 103153 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
using Golems.RenderFeatures;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Golems
{
public class ComposeOutlineScriptableRenderFeature : SourceToDestinationBlitRenderFeature
{
[SerializeField] private bool m_IsEnabled = true;
[Header("Compose things")]
[SerializeField] private Material m_CompositeMaterial = default;
private ComposeOutlinePass m_Pass;
public override void Create()
{
m_Pass = new ComposeOutlinePass(m_CompositeMaterial);
DoCreate();
}
private void DebugSetEnabledState(bool state)
{
m_IsEnabled = state;
}
private bool DebugGetEnabledState()
{
return m_IsEnabled;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (IsSourceAndDestinationSame())
{
//
// The source and destination are same can skip the pass if there is
// nothing to render.
//
var outlineObjects = OutlineCollection.RendererBundles;
if (outlineObjects == null || outlineObjects.Count <= 0)
{
return;
}
}
m_Pass.Setup(m_IsEnabled,m_WhenToInsert, renderer.cameraColorTarget,
m_SourceTextureSourceType, m_SourceNamedTemporaryNameHash,
m_DestinationTextureSourceType, m_DestinationNamedTemporaryNameHash,
m_TempCopyNamedTemporaryNameHash);
renderer.EnqueuePass(m_Pass);
}
}
public class ComposeOutlinePass : SourceToDestinationBlitRenderPass
{
private const string k_ProfilerIdent = "ComposeOutlinePass";
private Material m_CompositeMat = null;
private bool m_IsEnabled;
private readonly int m_BlurTexId = Shader.PropertyToID("_BlurTex");
private readonly int m_DefaultDrawObjectsTexId = Shader.PropertyToID("_DefaultDrawObjects");
public ComposeOutlinePass(Material compositeMaterial)
{
m_CompositeMat = compositeMaterial;
}
public void Setup(bool isEnabled, RenderPassEvent whenToRender, RenderTargetIdentifier cameraColourTargetIdentifier,
RenderFeatures.TextureSourceType sourceSourceType, int tempSourceTextureHash,
RenderFeatures.TextureSourceType destinationSourceType, int tempDestinationTextureHash,
int sameSourceDestTextureHash)
{
m_IsEnabled = isEnabled;
DoSetup(whenToRender, cameraColourTargetIdentifier,
sourceSourceType, tempSourceTextureHash,
destinationSourceType, tempDestinationTextureHash,
sameSourceDestTextureHash);
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
DoOnCameraSetup(cmd, ref renderingData);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
//
// The OutlineCollection.NumberOfObjectsRendered is set during the
// OutlineScriptableRenderPass.Execute() so if that did not render anything then there is
// nothing to compose.
//
if (!m_GoodToExecute)
{
return;
}
bool doCopyOnly = (OutlineCollection.NumberOfObjectsRendered <= 0) || !m_IsEnabled;
if (doCopyOnly)
{
if (!m_SourceAndDestinationSame)
{
//
// Copy the source to the destination
//
var copyCmd = CommandBufferPool.Get(k_ProfilerIdent);
copyCmd.Blit(m_SourceTargetIdentifier, m_DestinationTargetIdentifier);
context.ExecuteCommandBuffer(copyCmd);
CommandBufferPool.Release(copyCmd);
}
return;
}
var cmd = CommandBufferPool.Get(k_ProfilerIdent);
cmd.SetGlobalTexture("_BlurTex", m_BlurTexId);
cmd.SetGlobalTexture("_DefaultDrawObjects", m_DefaultDrawObjectsTexId);
if (m_SourceAndDestinationSame)
{
cmd.Blit(m_SourceTargetIdentifier, m_TempCopyTargetIdentifier, m_CompositeMat);
cmd.Blit(m_TempCopyTargetIdentifier, m_DestinationTargetIdentifier);
}
else
{
cmd.Blit(m_SourceTargetIdentifier, m_DestinationTargetIdentifier, m_CompositeMat);
}
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96781a865a3cc54488e7e18c2b1d66bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce653e0167dc8c94e8ae26729b6e04a5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: CompositeMaterial
m_Shader: {fileID: 4800000, guid: 5f0ea674bfa1ff042b2829daa5815e90, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EdgeTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &5329936352101645292
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 4

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 495a07472af496441a0c4612a21198c0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: DepthOnly
m_Shader: {fileID: 4800000, guid: 59ed4cb0e31a72c469f09fcf8614de92, type: 3}
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &1157606769240496216
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 79176156d5c314b43acbee3df46cfeb1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,123 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: SolidUnlitMaterial
m_Shader: {fileID: 4800000, guid: e249b16da4133f84e91d3718a2719884, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &7988618175867360684
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 4

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b7df10f98bf57cb43a96870442b5ed13
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,348 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Golems.Attributes;
using RogueUtils.Data;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.Serialization;
using Golems;
[DisallowMultipleComponent]
//This was used over outline entity due to it already being on the objects
public partial class Outline2 : MonoBehaviour
{
[Header("HighEndOutlineSettingsBelow ==================")]
/// <summary>
/// Renderer's attached to this GameObject
/// </summary>
///
[OnValueChanged("UpdateRendererBundle")]
[SerializeField]
private Renderer[] m_Renderers;
public Renderer[] Renderers
{
get => m_Renderers;
set => m_Renderers = value;
}
/// <summary>
/// Outline Colour
/// </summary>
[FormerlySerializedAs("outlineColor")]
[SerializeField]
private Color m_OutlineColor = Color.white;
[Header("The color variable will override local color if it exists")]
public ColorVariable OutlineColorVariable;
[SerializeField]
[Range(0, 10)]
private float m_BlurRadius = 2.5f;
public float BlurRadius
{
get => m_BlurRadius;
set => m_BlurRadius = value;
}
[SerializeField]
[Range(0, 1)]
private float m_Alpha = 1;
public float Alpha
{
get => m_Alpha;
set => m_Alpha = value;
}
[SerializeField] private float m_FadeSpeed = 7.0f;
/// <summary>
/// Returns True if Outline is currently active (m_Alpha >=1).
/// Otherwise, returns False.
/// </summary>
public bool IsOutlining => m_Alpha >= 1.0f;
/// <summary>
/// The current active Fade Coroutine
/// </summary>
private Coroutine m_FadeCoroutine = default;
/// <summary>
/// WaitForSeconds used before Fade in/out begins
/// </summary>
private WaitForSeconds m_FadeDelay = new WaitForSeconds(.1f);
[Header("OutlineTypeToggle ==================")]
[SerializeField]
private bool m_UseLowEndOutline = false;
private void Awake()
{
#if UNITY_SWITCH
m_UseLowEndOutline = true;
#endif
//if (GolemsGameManager.IsPlayerXR())
if (false)
{
m_UseLowEndOutline = true;
}
if (m_UseLowEndOutline)
{
}
else
{
HighEndAwake();
}
}
private void HighEndAwake()
{
if (m_Renderers.Length == 0)
{
Debug.LogWarning("No renderers setup for outline in editor on " + gameObject.name +
". Grabbing them through code");
var renderers = new List<Renderer>();
//
// Check OutlineEntity for Renderer
//
if (TryGetComponent<Renderer>(out var r))
{
renderers.Add(r);
}
SetRenderers(renderers);
}
OutlineCollection.AddRenderer(this);
Alpha = 0;
}
void OnEnable()
{
if (m_UseLowEndOutline)
{
}
else
{
HighEndOnEnable();
}
}
private void HighEndOnEnable()
{
}
private void OnValidate()
{
if (m_UseLowEndOutline)
{
}
else
{
}
}
private void Update()
{
if (m_UseLowEndOutline)
{
}
else
{
}
}
private void OnDisable()
{
Debug.Log("Disabling Outline");
Alpha = 0;
}
private void OnDestroy()
{
if (m_UseLowEndOutline)
{
}
else
{
HighEndOnDestroy();
}
}
private void HighEndOnDestroy()
{
OutlineCollection.RemoveRenderer(this);
Alpha = 0;
}
public void ToggleOutlining()
{
if (m_Alpha > 0)
{
StopOutlining();
}
else
{
StartOutlining();
}
}
/// <summary>
/// Activates/Deactivates the Outline,
/// depending on the given true or false value.
/// </summary>
/// <param name="active"> Activate or deactivate the Outline,
/// where true activates the Outline and false deactivates the Outline.</param>
public void SetOutlineActive(bool active)
{
if (active)
{
StartOutlining();
}
else
{
StopOutlining();
}
}
[Button]
public void StartOutlining()
{
if (m_UseLowEndOutline)
{
Debug.Log("Start Outlining");
}
else
{
StartHighEndOutlining();
}
}
public void StartHighEndOutlining()
{
//Debug.Log("StartOutlining");
if (m_FadeCoroutine != null)
{
StopCoroutine(m_FadeCoroutine);
m_FadeCoroutine = null;
}
//
// protect against running on disabled game objects
//
if (gameObject.activeInHierarchy)
{
m_FadeCoroutine = StartCoroutine(Fade(1));
}
}
[Button]
public void StopOutlining()
{
if (m_UseLowEndOutline)
{
Debug.Log("Stop Outlining");
}
else
{
StopHighEndOutlining();
}
}
public void StopHighEndOutlining()
{
if (m_FadeCoroutine != null)
{
StopCoroutine(m_FadeCoroutine);
m_FadeCoroutine = null;
}
//
// protect against running on disabled game objects
//
if (gameObject.activeInHierarchy)
{
m_FadeCoroutine = StartCoroutine(Fade(-1));
}
}
private IEnumerator Fade(int dir)
{
yield return new WaitForSeconds(0.1f);
bool faded = false;
while (!faded)
{
var alpha = Alpha;
alpha += (dir * m_FadeSpeed) * Time.deltaTime;
alpha = Mathf.Clamp01(alpha);
Alpha = alpha;
faded = dir < 0 ? alpha <= 0.0f : alpha >= 1.0f;
yield return null;
}
m_FadeCoroutine = null;
}
[ContextMenu("Force Stop Outlining")]
/// <summary>
/// Forces alpha to 0 to avoid showing if moved immediately
/// </summary>
public void ForceStopOutlining()
{
if (m_UseLowEndOutline)
{
}
else
{
Alpha = 0;
}
}
public void SetRenderers(List<Renderer> renderers)
{
m_Renderers = renderers.ToArray();
}
/// <summary>
/// Get the current Color for this Outline instance.
/// If the Outline has a OutlineColorVariable the value
/// of the passed Color variable will be set to the scriptable
/// variable value. Otherwise, it will be set to this Outlines m_OutlineColor.
/// </summary>
/// <param name="colour">Color variable to store this instances current outline colour</param>
public void GetColour(out Color colour)
{
colour = OutlineColorVariable == null ? m_OutlineColor : OutlineColorVariable.Value;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05d346d0dd4384f4fad966bd1340ddd5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using System.Collections.Generic;
using UnityEngine;
namespace Golems
{
public static class OutlineCollection
{
/// <summary>
/// Collection of renderers to be drawn with outline process
/// </summary>
public readonly static List<Outline2> RendererBundles = new List<Outline2>();
/// <summary>
/// The number of objects rendered in OutlineScriptableRenderPass.
/// This is reset in OutlineScriptableRenderPass.Execute() and incremented in
/// DrawObjectsDefault().
/// ComposeOutlinePass uses this in AddRenderPasses, if it's zero screen copy Blit is avoided.
///
/// N.B This is a sketchy place to do this sort of thing, full acknowledged but it's quick, easy and works...
/// </summary>
public static int NumberOfObjectsRendered = 0;
/// <summary>
/// Adds collection of renderers to the Outline Collection
/// </summary>
/// <param name="rendererBundle">Renderers to be drawn with Outline process</param>
public static void AddRenderer(Outline2 rendererBundle)
{
if (RendererBundles.Contains(rendererBundle))
{
return;
}
RendererBundles.Add(rendererBundle);
}
public static void RemoveRenderer(Outline2 rendererBundle)
{
RendererBundles.Remove(rendererBundle);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff2eba45467bff142ac34388a8cfe9b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,453 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
#if ENABLE_VR
using UnityEngine.XR;
#endif
namespace Golems
{
public class OutlineScriptableRenderFeature : ScriptableRendererFeature
{
[SerializeField] private bool m_IsEnabled = true;
[SerializeField]
private Material m_SolidUnlitMaterial = default;
[SerializeField]
private Material m_BlurMaterial = default;
private OutlineScriptableRenderPass m_Pass = default;
[SerializeField] private RenderPassEvent m_RenderPassEvent = RenderPassEvent.AfterRenderingOpaques;
/// <summary>
/// The number of Blur passes performed.
/// This effects ALL objects rendered
/// </summary>
[Tooltip("How many times we Blur all the objects. Note, the bigger the number, the bigger the performance hit")]
[Range(1, 10)][SerializeField] private int m_BlurPasses = 1;
/// <summary>
/// Effects how far off centre each Blur sample becomes
/// </summary>
[Tooltip("Effects how far off centre each Blur sample becomes. Note, the bigger the number, the bigger the pixelation")]
[Range(0.0f, 10.0f)] [SerializeField] private float m_BlurRadius = .5f;
/// <summary>
/// Index into the m_BlurTextureSizes
/// </summary>
[Range(0,4)] [SerializeField] private int m_BlurTextureSize = 3;
/// <summary>
/// Texture size of the blur textures
/// </summary>
private int[] m_BlurTextureSizes = new int[5] { 128, 256, 512, 1024, 2048 };
[Header("Outlines Occluders")]
/// <summary>
/// Material used to render the occluders
/// </summary>
[Tooltip("Material used to render the occluders")]
[SerializeField] Material m_OutlinesOccludersMat;
/// <summary>
/// Used to set the objects that will be part of the outlines occluders
/// </summary>
[Tooltip("Used to set the objects that will be part of the outlines occluders")]
[SerializeField] LayerMask m_OccludersMask;
/// <summary>
/// Initializes this feature's resources.
/// </summary>
public override void Create()
{
m_Pass = new OutlineScriptableRenderPass(m_SolidUnlitMaterial, m_BlurMaterial, m_OutlinesOccludersMat, m_OccludersMask);
}
private void DebugSetEnabledState(bool state)
{
m_IsEnabled = state;
}
private bool DebugGetEnabledState()
{
return m_IsEnabled;
}
/// <summary>
/// Injects the outline ScriptableRenderPass into the renderer.
/// </summary>
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (!m_IsEnabled)
{
return;
}
//
// Zeroing this here in case the pass is not added
//
OutlineCollection.NumberOfObjectsRendered = 0;
var outlineRenderers = OutlineCollection.RendererBundles;
if (outlineRenderers == null || outlineRenderers.Count <= 0) return;
m_Pass.Setup(
m_RenderPassEvent,
renderingData.cameraData.camera,
outlineRenderers,
m_BlurPasses,
m_BlurRadius,
m_BlurTextureSizes[Mathf.Max(0, Mathf.Min(m_BlurTextureSize, m_BlurTextureSizes.Length-1))]);
renderer.EnqueuePass(m_Pass);
}
}
public class OutlineScriptableRenderPass : ScriptableRenderPass
{
private const string k_ProfilerIdent = "Outline";
#region Texture Consts
private const string k_DefaultDrawObjectsTex = "_DefaultDrawObjects";
private const string k_SolidDrawObjectsTex = "_SolidDrawObjects";
private const string k_BlurTex = "_BlurTex";
private const string k_MainText = "_MainTex";
private const string k_TempTex = "_TempTex";
#endregion Texture Consts
#region Shader Fields
private readonly int m_ColourID = Shader.PropertyToID("_Color");
private readonly int m_AlphaID = Shader.PropertyToID("_Alpha");
private readonly int m_BlurResolution = Shader.PropertyToID("_BlurResolution");
private readonly int m_BlurRadius = Shader.PropertyToID("_BlurRadius");
private readonly int m_BlurDirectionX = Shader.PropertyToID("_BlurDirectionX");
private readonly int m_BlurDirectionY = Shader.PropertyToID("_BlurDirectionY");
#endregion Shader Fields
#region Render Texture IDs
private readonly int m_DefaultDrawObjects = Shader.PropertyToID(k_DefaultDrawObjectsTex);
private readonly int m_SolidDrawObjects = Shader.PropertyToID(k_SolidDrawObjectsTex);
private readonly int m_BlurPassRenderTexID = Shader.PropertyToID(k_BlurTex);
private readonly int m_TempRenderTexID = Shader.PropertyToID(k_TempTex);
#endregion
private Camera m_Camera;
private IList<Outline2> m_Renderers;
private Material m_SolidUnlitMaterial;
private Material m_BlurMaterial;
/// <summary>
/// The uniform Blur texture size, calculated from the current screen size
/// </summary>
private int m_BlurRes;
/// <summary>
/// Effects how far off centre each Blur sample becomes
/// </summary>
private float m_BlurRad = 1.0f;
/// <summary>
/// The number of Blur passes performed.
/// This effects ALL objects rendered
/// </summary>
private int m_BlurPasses = 1;
/// <summary>
/// Used in DrawObjectsXYZ. We use this in conjunction with GetSharedMaterials.
/// Avoids GC alloc from .sharedMaterials
/// </summary>
private readonly List<Material> m_SharedMaterials = new List<Material>();
/// <summary>
/// Used to Get and Store the each Outline instances Color
/// </summary>
private Color m_OutlineColour = new Color(1,1,1,1);
/// <summary>
/// Occluders shader tags list
/// </summary>
private List<ShaderTagId> m_ShaderTagsList = new List<ShaderTagId>();
/// <summary>
/// Filter settings for occluders rendering
/// </summary>
private FilteringSettings m_FilteringSettings;
/// <summary>
/// Material used to render the occluders
/// </summary>
private Material m_OccludersOverrideMaterial;
#if UNITY_EDITOR
private readonly HashSet<Outline2> m_EditorLoggedNullMaterialOutlines = new HashSet<Outline2>();
private readonly HashSet<Renderer> m_EditorLoggedNullMaterialRenderers = new HashSet<Renderer>();
#endif
public OutlineScriptableRenderPass(Material solidUnlitMaterial, Material blurMaterial, Material occludersOverrideMaterial, LayerMask occludersMask)
{
m_BlurMaterial = blurMaterial;
m_SolidUnlitMaterial = solidUnlitMaterial;
m_OccludersOverrideMaterial = occludersOverrideMaterial;
// Initialise occluders related properties
m_ShaderTagsList.Add(new ShaderTagId("SRPDefaultUnlit"));
m_ShaderTagsList.Add(new ShaderTagId("UniversalForward"));
m_ShaderTagsList.Add(new ShaderTagId("UniversalForwardOnly"));
m_ShaderTagsList.Add(new ShaderTagId("ForwardLit"));
m_FilteringSettings = new FilteringSettings(RenderQueueRange.opaque, occludersMask);
}
public void Setup(RenderPassEvent whenToRender, Camera camera, IList<Outline2> renderers, int blurPasses,
float blurRadius, int blurTextureSize)
{
renderPassEvent = whenToRender;
m_Renderers = renderers;
m_Camera = camera;
m_BlurPasses = blurPasses;
m_BlurRad = blurRadius;
m_BlurRes = blurTextureSize;
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
//
// Attempt to make RTs for XR, otherwise use Default Settings
//
if (!ConfigureTemporaryRenderTexturesForXR(in cmd)) ConfigureTemporaryRenderTextures(in cmd);
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
ConfigureTarget(m_SolidDrawObjects);
ConfigureClear(ClearFlag.All, Color.clear);
}
/// <summary>
/// Execute the pass. This is where custom rendering occurs. Specific details are left to the implementation
/// </summary>
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
//
// Always make sure we reset, this is the begining of a new Outline process
//
OutlineCollection.NumberOfObjectsRendered = 0;
var cmd = CommandBufferPool.Get(k_ProfilerIdent);
cmd.Clear();
//
// First render objects using their default materials
//
DrawObjectsDefault(cmd);
//
// OutlineCollection.NumberOfObjectsRendered is incremented
// inside DrawObjectsDefault. If it's 0 we rendered nothing.
//
if (OutlineCollection.NumberOfObjectsRendered > 0)
{
DrawOccluders(context, ref renderingData);
DrawObjectsSolid(cmd);
cmd.SetGlobalFloat(m_BlurResolution, m_BlurRes);
cmd.SetGlobalFloat(m_BlurRadius, m_BlurRad);
DrawBlur(in cmd);
context.ExecuteCommandBuffer(cmd);
}
cmd.Clear();
CommandBufferPool.Release(cmd);
}
/// <summary>
/// Draw outlines occluders
/// </summary>
private void DrawOccluders(ScriptableRenderContext context, ref RenderingData renderingData)
{
// Draw the occluders into m_SolidDrawObjects
// This pass will fill in the depth buffer so that the outlines could get occluded by the soldiers or other occluders as needed
DrawingSettings drawingSettings = CreateDrawingSettings(m_ShaderTagsList, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);
drawingSettings.overrideMaterial = m_OccludersOverrideMaterial;
context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings);
}
/// <summary>
/// Draw all objects using their default material/s
/// </summary>
private void DrawObjectsDefault(in CommandBuffer commandBuffer)
{
CoreUtils.SetRenderTarget(commandBuffer, m_DefaultDrawObjects, ClearFlag.All, Color.clear);
commandBuffer.ClearRenderTarget(true, true, Color.clear);
for (int i = 0, counti = m_Renderers.Count; i < counti; ++i)
{
var outline = m_Renderers[i];
//
// Don't waste time drawing objects which are currently invisible
//
if (outline.Alpha <= 0) continue;
++OutlineCollection.NumberOfObjectsRendered;
var outlineRenderers = outline.Renderers;
for (int j = 0; j < outlineRenderers.Length; j++)
{
var renderer = outlineRenderers[j];
if (renderer == null) continue;
m_SharedMaterials.Clear();
renderer.GetSharedMaterials(m_SharedMaterials);
if (m_SharedMaterials.Count > 0)
{
for (int m = 0, countm = m_SharedMaterials.Count; m < countm; ++m)
{
if (m_SharedMaterials[m] == null)
{
#if UNITY_EDITOR
if (!m_EditorLoggedNullMaterialOutlines.Contains(outline))
{
Debug.LogErrorFormat(outline, "Outline {0} has a renderer {1} with null material", outline.name, renderer.name);
m_EditorLoggedNullMaterialOutlines.Add(outline);
}
if (!m_EditorLoggedNullMaterialRenderers.Contains(renderer))
{
Debug.LogErrorFormat(outline, "Outline {0} has a renderer {1} with null material", outline.name, renderer.name);
m_EditorLoggedNullMaterialRenderers.Add(renderer);
}
#endif
continue;
}
commandBuffer.DrawRenderer(renderer, m_SharedMaterials[m], m, 0);
}
}
else
{
commandBuffer.DrawRenderer(renderer, renderer.material);
}
}
}
}
/// <summary>
/// Draw all objects using the special Solid Unlit shader
/// </summary>
private void DrawObjectsSolid(in CommandBuffer commandBuffer)
{
CoreUtils.SetRenderTarget(commandBuffer, m_SolidDrawObjects, ClearFlag.None, Color.clear);
//commandBuffer.ClearRenderTarget(true, true, Color.clear);
for (int i = 0, counti = m_Renderers.Count; i < counti; ++i)
{
var outline = m_Renderers[i];
if (outline.Alpha <= 0) continue;
outline.GetColour(out m_OutlineColour);
commandBuffer.SetGlobalColor(m_ColourID, m_OutlineColour);
commandBuffer.SetGlobalFloat(m_AlphaID, outline.Alpha);
var outlineRenderers = outline.Renderers;
for (int j = 0; j < outlineRenderers.Length; ++j)
{
var renderer = outlineRenderers[j];
if (renderer == null) continue;
m_SharedMaterials.Clear();
renderer.GetSharedMaterials(m_SharedMaterials);
if (m_SharedMaterials.Count > 0)
{
for (int m = 0, countm = m_SharedMaterials.Count; m < countm; ++m)
{
commandBuffer.DrawRenderer(renderer, m_SolidUnlitMaterial, m, 0);
}
}
else
{
commandBuffer.DrawRenderer(renderer, m_SolidUnlitMaterial);
}
}
}
}
/// <summary>
/// Creates the Blur mask RT. Blur the Outline objects
/// </summary>
private void DrawBlur(in CommandBuffer commandBuffer)
{
commandBuffer.Blit(m_SolidDrawObjects, m_BlurPassRenderTexID);
for (int i = 0, counti = m_BlurPasses; i < counti; ++i)
{
commandBuffer.SetGlobalFloat(m_BlurDirectionX, 0);
commandBuffer.SetGlobalFloat(m_BlurDirectionY, 1);
commandBuffer.SetGlobalTexture(k_MainText, m_BlurPassRenderTexID);
commandBuffer.Blit(m_BlurPassRenderTexID, m_TempRenderTexID,
m_BlurMaterial, 0);
commandBuffer.SetGlobalFloat(m_BlurDirectionX, 1);
commandBuffer.SetGlobalFloat(m_BlurDirectionY, 0);
commandBuffer.SetGlobalTexture(k_MainText, m_TempRenderTexID);
commandBuffer.Blit(m_TempRenderTexID, m_BlurPassRenderTexID,
m_BlurMaterial, 0);
}
}
/// <summary>
/// Configure Temporary RTs for XR
/// Relies on ENABLE_VR
/// </summary>
/// <param name="cmd">SRF CommandBuffer</param>
/// <returns>True if RTs were setup using XRSettings, Otherwise False.</returns>
private bool ConfigureTemporaryRenderTexturesForXR(in CommandBuffer cmd)
{
#if ENABLE_VR
if (!XRSettings.enabled) return false;
var renderTextureDescriptor = XRSettings.eyeTextureDesc;
cmd.GetTemporaryRT(m_DefaultDrawObjects, renderTextureDescriptor, FilterMode.Bilinear);
cmd.GetTemporaryRT(m_SolidDrawObjects, renderTextureDescriptor, FilterMode.Bilinear);
renderTextureDescriptor.depthBufferBits = 0;
renderTextureDescriptor.width = renderTextureDescriptor.height = m_BlurRes;
cmd.GetTemporaryRT(m_BlurPassRenderTexID, renderTextureDescriptor, FilterMode.Bilinear);
cmd.GetTemporaryRT(m_TempRenderTexID, renderTextureDescriptor, FilterMode.Bilinear);
return true;
#endif
return false;
}
/// <summary>
/// Configure Temporary RTs for SRF.
/// </summary>
/// <param name="cmd">SRF CommandBuffer</param>
private void ConfigureTemporaryRenderTextures(in CommandBuffer cmd)
{
var width = m_Camera.scaledPixelWidth;
var height = m_Camera.scaledPixelHeight;
var aa = Mathf.Max(1, QualitySettings.antiAliasing);
//
// We can't really down sample the Solid Render. This is the render of the
//
cmd.GetTemporaryRT(m_DefaultDrawObjects, width, height, 24, FilterMode.Bilinear,
RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, aa);
cmd.GetTemporaryRT(m_SolidDrawObjects, width >> 1, height >> 1, 24,
FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default,aa);
cmd.GetTemporaryRT(m_BlurPassRenderTexID, m_BlurRes, m_BlurRes, 0, FilterMode.Bilinear);
cmd.GetTemporaryRT(m_TempRenderTexID, m_BlurRes, m_BlurRes, 0, FilterMode.Bilinear);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8114b26188dce7043a962383e5b26228
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d0e655ad25360a540b63cad86a6c256d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,95 @@
Shader "Outline/Blur"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
//https://github.com/mattdesl/lwjgl-basics/blob/master/test/mdesl/test/shadertut/ShaderLesson5.java
SubShader
{
Cull Off ZWrite Off ZTest Always
// Combined
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
half4 _MainTex_ST;
uniform float _BlurResolution;
uniform float _BlurRadius;
uniform float _BlurDirectionX;
uniform float _BlurDirectionY;
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_OUTPUT(v2f, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//_BlurRadius = 2.5f;
//our original texcoord for this fragment
fixed2 tc = UnityStereoScreenSpaceUVAdjust(i.uv, _MainTex_ST);
//float r = lerp(_BlurResolution.y, _BlurResolution.x, step(_BlurDirection.x, 1.0f));
//the amount to blur, i.e. how far off center to sample from
//1.0 -> blur by one pixel
//2.0 -> blur by two pixels, etc.
float blur = _BlurRadius/_BlurResolution;
//the _BlurDirectionection of our blur
//(1.0, 0.0) -> x-axis blur
//(0.0, 1.0) -> y-axis blur
float hstep = _BlurDirectionX;
float vstep = _BlurDirectionY;
//apply blurring, using a 9-tap filter with predefined gaussian weights
fixed4 sum = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x, tc.y)) * 0.2270270270;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
sum += UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, fixed2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
return sum;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f88f058dc01de7343af2ff63b364efd1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
Shader "Outline/Compose"
{
Properties
{
_MainTex ("Texture", any) = "white" {}
_EdgeTex ("Edge Texture", 2D) = "white" {}
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
float2 _MainTex_TexelSize;
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_DefaultDrawObjects);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_BlurTex);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_TempTex);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_EdgeTex);
uniform float EdgeValue;
uniform float OffsetRedX;
uniform float OffsetGreenX;
uniform float OffsetBlueX;
uniform float OffsetRedY;
uniform float OffsetGreenY;
uniform float OffsetBlueY;
uniform float Brightness;
uniform float Contrast;
uniform float GlobalAlpha;
half4 _MainTex_ST;
half4 _EdgeTex_ST;
v2f vert (appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_OUTPUT(v2f, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv0 = TRANSFORM_TEX(v.uv, _MainTex);
o.uv1 = TRANSFORM_TEX(v.uv, _MainTex);
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
o.uv1.y = 1 - o.uv1.y;
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
EdgeValue = 1.0f;
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
//
// Sample the world RT (render so far without our outline objects)
//
fixed4 world = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex,
UnityStereoScreenSpaceUVAdjust(i.uv0, _MainTex_ST));
//
// Sample our outline texture
//
fixed4 outline = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_BlurTex,
UnityStereoScreenSpaceUVAdjust(i.uv1, _MainTex_ST));
//
// Sample the solid render of the game object to be outlined
//
fixed4 gameObject = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_DefaultDrawObjects,
UnityStereoScreenSpaceUVAdjust(i.uv1, _MainTex_ST));
world.xyz = world + EdgeValue * (outline * (1.0 - gameObject.a));
return world;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 27d8ba6291e352149af60962aa391bf9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
Shader "Outline/DepthOnly"
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
ColorMask 0
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(0.0, 0.0, 0.0, 0.0);
}
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e6b291dfa48d17347b6a1a85acb509c0
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
Shader "Outline/SolidUnlit"
{
SubShader
{
Tags { "RenderType" = "TransparentCutout" }
ZWrite Off
ZTest LEqual
Lighting Off
// Set up alpha blending
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 projPos : TEXCOORD0;
float2 convertedNormal : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.projPos = ComputeScreenPos(o.vertex);
COMPUTE_EYEDEPTH(o.projPos.z);
//o.viewNormal = COMPUTE_VIEW_NORMAL;
// work out camera position to vert position
float3 normalDir = UnityObjectToWorldNormal(v.normal);
float3 viewDir = normalize(WorldSpaceViewDir(v.vertex));
float3 upDir = float3(0.0, 1.0, 0.0);
float3 rightDir = normalize(cross(viewDir, upDir));
upDir = cross(rightDir, viewDir);
o.convertedNormal.x = dot(rightDir, normalDir);
o.convertedNormal.y = dot(upDir, normalDir);
return o;
}
float4 _Color;
float _Alpha;
fixed4 frag(v2f i) : COLOR0
{
fixed4 output = _Color;
output.a = output.a * _Alpha;
clip((output.a - 0));
return output;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e7aa60114ab92b94cbe33203434b8fa7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant: