Created
May 11, 2017 13:40
-
-
Save onotchi/6dc0a3f7208cfc9bec36637b024b4e94 to your computer and use it in GitHub Desktop.
距離感主義みたいなエフェクト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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