Skip to content

Instantly share code, notes, and snippets.

@onotchi
Created May 11, 2017 13:40
Show Gist options
  • Save onotchi/6dc0a3f7208cfc9bec36637b024b4e94 to your computer and use it in GitHub Desktop.
Save onotchi/6dc0a3f7208cfc9bec36637b024b4e94 to your computer and use it in GitHub Desktop.
距離感主義みたいなエフェクト
using UnityEngine;
namespace Onoty3D
{
[ExecuteInEditMode]
public class DepthImageEffect : MonoBehaviour
{
public enum YDirectionType
{
Forward,
Reverse,
}
public enum DepthSourceType
{
Camera,
Custom,
}
public enum EasingModeType
{
None,
Quadratic,
Cubic,
Quartic,
Quintic,
Sinusoidal,
Exponential,
Circular,
}
public enum InOutModeType
{
In,
Out,
InOut,
}
public Color MainColor = Color.white;
public float ContourCount = 0;
public YDirectionType YDirection = YDirectionType.Forward;
public DepthSourceType DepthSource = DepthSourceType.Camera;
public float CustomDepthFrom = 0;
public float CustomDepthTo = 1;
public EasingModeType EasingMode = EasingModeType.None;
public InOutModeType InOutMode = InOutModeType.In;
private Shader _shader;
private Material _material;
private void CreateShaderAndMaterial()
{
if (this._shader == null)
{
this._shader = Shader.Find("Onoty3D/DepthImageEffect");
}
if (this._material == null && this._shader != null && this._shader.isSupported)
{
this._material = this.CreateMaterial(this._shader, this._material);
}
}
private Material CreateMaterial(Shader shader, Material material)
{
if (shader == null)
{
Debug.Log("Missing shader in " + ToString());
enabled = false;
return null;
}
if (shader.isSupported && material && material.shader == shader)
{
return material;
}
if (!shader.isSupported)
{
Debug.Log("The shader " + shader.ToString() + " on effect " + ToString() + " is not supported on this platform!");
return null;
}
else
{
material = new Material(shader);
if (material != null)
{
material.hideFlags = HideFlags.DontSave;
}
return material;
}
}
void OnDisable()
{
GameObject.DestroyImmediate(this._material);
this._material = null;
this._shader = null;
}
// Use this for initialization
private void Start()
{
}
// Update is called once per frame
private void Update()
{
}
private void OnEnable()
{
var camera = this.GetComponent<Camera>();
camera.depthTextureMode |= DepthTextureMode.Depth;
this.CreateShaderAndMaterial();
}
//[ImageEffectOpaque]
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
this._material.SetColor("_Color", this.MainColor);
this._material.SetFloat("_ContourCount", this.ContourCount);
this._material.SetInt("_YDirection", (int)this.YDirection);
this._material.SetInt("_DepthSource", (int)this.DepthSource);
this._material.SetFloat("_CustomDepthFrom", this.CustomDepthFrom);
this._material.SetFloat("_CustomDepthTo", this.CustomDepthTo);
this._material.SetInt("_EasingMode", (int)this.EasingMode);
this._material.SetInt("_InOutMode", (int)this.InOutMode);
Graphics.Blit(source, destination, this._material);
}
}
}
Shader "Onoty3D/DepthImageEffect"
{
Properties
{
_Color("Main Color", Color) = (.5,.5,.5,1)
_ContourCount("Contour Count", float) = 0
[Enum(Forward,0,Reverse,1)] _YDirection("Y Direction", int) = 0
[Enum(Camera,0,Custom,1)] _DepthSource("Depth Source", int) = 0
_CustomDepthFrom("Custom Depth From", float) = 0
_CustomDepthTo("Custom Depth To", float) = 0
[KeywordEnum(None,Quadratic,Cubic,Quartic,Quintic,Sinusoidal,Exponential,Circular)] _EasingMode("Easing Mode", int) = 0
[Enum(In,0,Out,1,InOut,2)] _InOutMode("InOut Mode", int) = 0
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#define PI 3.14159
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D_float _CameraDepthTexture;
float _ContourCount;
int _YDirection;
int _DepthSource;
float4 _Color;
float _CustomDepthFrom;
float _CustomDepthTo;
float _Far;
int _DistMode;
int _EasingMode;
int _InOutMode;
float easeInQuad(float x)
{
return x * x;
}
float easeOutQuad(float x)
{
return -x * (x - 2.0);
}
float easeInOutQuad(float x)
{
x /= 0.5;
if (x < 1.0) return 0.5 * x * x;
x--;
return -0.5 * (x * (x - 2.0) - 1.0);
}
float easeQuad(float x)
{
switch (_InOutMode)
{
case 0:
return easeInQuad(x);
case 1:
return easeOutQuad(x);
case 2:
return easeInOutQuad(x);
default:
return x;
}
}
float easeInCubic(float x)
{
return 1.0 * x * x * x;
}
float easeOutCubic(float x)
{
x--;
return 1.0 *(x * x * x + 1.0);
}
float easeInOutCubic(float x)
{
x /= 0.5;
if (x < 1.0) return 0.5 * x * x * x;
x -= 2.0;
return 0.5 * (x * x * x + 2.0);
}
float easeCubic(float x)
{
switch (_InOutMode)
{
case 0:
return easeInCubic(x);
case 1:
return easeOutCubic(x);
case 2:
return easeInOutCubic(x);
default:
return x;
}
}
float easeInQuart(float x)
{
return x * x * x * x;
}
float easeOutQuart(float x)
{
x--;
return -(x * x * x * x - 1.0);
}
float easeInOutQuart(float x)
{
x /= 0.5;
if (x < 1.0) return 0.5 * x * x * x * x;
x -= 2.0;
return -0.5 * (x * x * x * x - 2.0);
}
float easeQuart(float x)
{
switch (_InOutMode)
{
case 0:
return easeInQuart(x);
case 1:
return easeOutQuart(x);
case 2:
return easeInOutQuart(x);
default:
return x;
}
}
float easeInQuint(float x)
{
return x * x * x * x * x;
}
float easeOutQuint(float x)
{
x--;
return (x * x * x * x * x + 1.0);
}
float easeInOutQuint(float x)
{
x /= 0.5;
if (x < 1.0) return 0.5 * x * x * x * x * x;
x -= 2.0;
return 0.5 * (x * x * x * x * x + 2.0);
}
float easeQuint(float x)
{
switch (_InOutMode)
{
case 0:
return easeInQuint(x);
case 1:
return easeOutQuint(x);
case 2:
return easeInOutQuint(x);
default:
return x;
}
}
float easeInSine(float x)
{
return -cos(x / (PI / 2.0)) + 1.0;
}
float easeOutSine(float x)
{
return sin(x / (PI / 2.0));
}
float easeInOutSine(float x)
{
return -0.5 * (cos(PI * x) - 1.0);
}
float easeSine(float x)
{
switch (_InOutMode)
{
case 0:
return easeInSine(x);
case 1:
return easeOutSine(x);
case 2:
return easeInOutSine(x);
default:
return x;
}
}
float easeInExpo(float x)
{
return pow(2.0, 10.0 * (x - 1.0));
}
float easeOutExpo(float x)
{
return (-pow(2.0, -10.0 * x) + 1.0);
}
float easeInOutExpo(float x)
{
x /= 0.5;
if (x < 1.0) return 0.5 * pow(2.0, 10.0 * (x - 1.0));
x--;
return 0.5 * (-pow(2.0, -10.0 * x) + 2.0);
}
float easeExpo(float x)
{
switch (_InOutMode)
{
case 0:
return easeInExpo(x);
case 1:
return easeOutExpo(x);
case 2:
return easeInOutExpo(x);
default:
return x;
}
}
float easeInCirc(float x)
{
return -(sqrt(1.0 - x * x) - 1.0);
}
float easeOutCirc(float x)
{
x--;
return sqrt(1.0 - x * x);
}
float easeInOutCirc(float x) {
x /= 0.5;
if (x < 1.0) return -0.5 * (sqrt(1.0 - x * x) - 1.0);
x -= 2.0;
return -0.5 * (sqrt(1.0 - x * x) + 1.0);
};
float easeCirc(float x)
{
switch (_InOutMode)
{
case 0:
return easeInCirc(x);
case 1:
return easeOutCirc(x);
case 2:
return easeInOutCirc(x);
default:
return x;
}
}
float ease(float x) {
switch (_EasingMode)
{
case 0:
return x;
case 1:
return easeQuad(x);
case 2:
return easeCubic(x);
case 3:
return easeQuart(x);
case 4:
return easeQuint(x);
case 5:
return easeSine(x);
case 6:
return easeExpo(x);
case 7:
return easeCirc(x);
default:
return x;
}
}
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
if (_YDirection == 1)
{
o.uv.y = 1 - o.uv.y;
}
return o;
}
float4 frag(v2f i) : SV_Target
{
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
depth = Linear01Depth(depth);
if (depth < 1)
{
if (_DepthSource == 1)
{
float distance = depth * _ProjectionParams.z;
depth = saturate((distance - _CustomDepthFrom) / (_CustomDepthTo - _CustomDepthFrom));
}
depth = ease(depth);
if (_ContourCount != 0)
{
float denominator = 1 / _ContourCount;
depth = floor(depth / denominator) * denominator;
}
}
float4 col = 1;
col.r = 1 - depth;
col.g = 1 - depth;
col.b = 1 - depth;
col = col * _Color;
return col;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment