Skip to content

Instantly share code, notes, and snippets.

@rondreas
Created October 11, 2018 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rondreas/cd8f587ffa09f0c4df27e0506d6e0a21 to your computer and use it in GitHub Desktop.
Save rondreas/cd8f587ffa09f0c4df27e0506d6e0a21 to your computer and use it in GitHub Desktop.
// Implementation of effect described at: https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/
Shader "Custom/DrawSimple" {
SubShader{
ZWrite Off
ZTest Always
Lighting Off
Pass {
CGPROGRAM
#pragma vertex VShader
#pragma fragment FShader
struct v2f {
//float4 pos: SV_POSITION;
float4 pos: POSITION;
};
// Return vertex position,
v2f VShader(v2f i) {
v2f o;
o.pos = UnityObjectToClipPos(i.pos);
return o;
}
// Return white
half4 FShader():COLOR0{
return half4(1,1,1,1);
}
ENDCG
}
}
}
// Implementation of effect described at: https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/
using System.Collections;
using UnityEngine;
public class OutlinePostEffect : MonoBehaviour {
Camera AttachedCamera;
public Shader PostOutline;
public Shader DrawSimple;
Camera TempCam;
public Material PostMaterial;
// public RenderTexture TempRT;
void Start () {
AttachedCamera = GetComponent<Camera>();
TempCam = new GameObject().AddComponent<Camera>();
TempCam.enabled = false;
// PostMaterial = new Material(PostOutline);
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
//set up a temporary camera
TempCam.CopyFrom(AttachedCamera);
TempCam.clearFlags = CameraClearFlags.Color;
TempCam.backgroundColor = Color.black;
//cull any layer that isn't the outline
TempCam.cullingMask = 1 << LayerMask.NameToLayer("Outline");
//make the temporary rendertexture
RenderTexture TempRT = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.R8);
//put it to video memory
TempRT.Create();
//set the camera's target texture when rendering
TempCam.targetTexture = TempRT;
//render all objects this camera can render, but with our custom shader.
TempCam.RenderWithShader(DrawSimple, "");
// Get the rendered scene as a texture
PostMaterial.SetTexture("_SceneTex", source);
// copy the temporary RT to the final image
// Graphics.Blit(source, destination); // The normally rendered image.
Graphics.Blit(TempRT, destination, PostMaterial); // The outline
// release the temporary Render Texture
TempRT.Release();
}
}
// Implementation of effect described at: https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/
Shader "Custom/PostOutline" {
Properties
{
_MainTex("Main Texture", 2D) = "black"{}
_SceneTex("Scene Texture", 2D) = "black"{}
_OutlineColor("Outline Color", Color) = (0, 1, 1, 1)
_Strength("Strength", Range(0, 10)) = 1
}
SubShader
{
Pass {
CGPROGRAM
sampler2D _MainTex;
float2 _MainTex_TexelSize;
half _Strength;
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : POSITION;
float2 uvs : TEXCOORD0;
};
v2f vert(appdata_base v) {
v2f o;
// Despite the fact that we are only drawing a quad to the screen,
// Unity requires us to multiply vertices by our MVP matrix,
// presumably to keep things working when inexperienced people try copying code from other shaders.
o.pos = UnityObjectToClipPos(v.vertex);
// Also, we need to fix the UVs to match our screen space coordinates.
// There is a Unity define for this that should normally be used.
o.uvs = o.pos.xy / 2 + 0.5;
return o;
}
half4 frag(v2f IN) : COLOR
{
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y > 0)
IN.uvs.y = 1 - IN.uvs.y;
#endif
int NumberOfIterations = 20;
float TX_x = _MainTex_TexelSize.x;
float ColorIntensityInRadius;
for (int i = 0; i < NumberOfIterations; i++) {
ColorIntensityInRadius += tex2D(
_MainTex,
IN.uvs.xy + float2((i - NumberOfIterations / 2) * TX_x, 0)
).r / NumberOfIterations;
}
//return ColorIntensityInRadius * half4(0, 1, 1, 1);
return ColorIntensityInRadius;
}
ENDCG
}
GrabPass{}
Pass{
CGPROGRAM
sampler2D _MainTex;
sampler2D _SceneTex;
sampler2D _GrabTexture;
float2 _GrabTexture_TexelSize;
half _Strength;
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos: POSITION;
float2 uvs: TEXCOORD0;
};
half4 _OutlineColor;
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uvs = o.pos.xy / 2 + 0.5;
return o;
}
half4 frag(v2f IN) : COLOR {
#if UNITY_UV_STARTS_AT_TOP
if (_GrabTexture_TexelSize.y > 0)
IN.uvs.y = 1 - IN.uvs.y;
#endif
int NumberOfIterations = 20;
float TX_y = _GrabTexture_TexelSize.y;
half ColorIntensityInRadius = 0;
if (tex2D(_MainTex, IN.uvs.xy).r > 0) {
return tex2D(_SceneTex, float2(IN.uvs.x, IN.uvs.y));
}
for (int i = 0; i < NumberOfIterations; i++) {
ColorIntensityInRadius += tex2D(
_GrabTexture,
IN.uvs.xy + float2(0, (i - NumberOfIterations / 2) * TX_y)
).r / NumberOfIterations;
}
// Blending of the colors, the half4 is the color for the outline which we should be able to change,
// half4 outcolor = ColorIntensityInRadius * _OutlineColor * 2 + (1 - ColorIntensityInRadius) * tex2D(_SceneTex, float2(IN.uvs.x, IN.uvs.y));
// half4 outcolor = ColorIntensityInRadius * _OutlineColor * _Strength + (1 - ColorIntensityInRadius) * tex2D(_SceneTex, float2(IN.uvs.x, IN.uvs.y));
half4 foo = ColorIntensityInRadius * _OutlineColor * _Strength + tex2D(_SceneTex, float2(IN.uvs.x, IN.uvs.y));
return foo;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment