Created
June 12, 2019 05:15
-
-
Save yukatayu/70764be655da422f006aec3434d1ef2d to your computer and use it in GitHub Desktop.
ステンドグラス (後ろを歪ませるだけ)
This file contains 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 "Yukatayu/Stend Grass" { | |
Properties { | |
[Header(Stend Glass)] [Space(7)] | |
_MainTex ("テクスチャ", 2D) = "white" {} | |
_Division ("分割数", Int) = 60 | |
_Threshold ("枠線の太さ", Range(0,1)) = 0.08 | |
_Height("盛り上がり", Range(-4, 4)) = 0.5 | |
_Opacity("ガラス全体の不透明度", Range(0, 1)) = 0.5 | |
_EdgeOpacity("枠線の不透明度", Range(0, 1)) = 0.85 | |
[Space(7)] [Header(Advanced)] [Space(7)] | |
_PerinNoiseStrength("歪みの強さ", Float) = 0.1 | |
_PerinNoiseStrengthBack("背景の歪みの強さ", Float) = 0.1 | |
_PerinNoiseColor("歪みによる黒ずみ", Float) = 10 | |
} | |
SubShader { | |
Tags { "RenderType"="Transparent" "Queue"="Transparent" } | |
LOD 100 | |
ZWrite Off | |
Cull Off | |
Blend SrcAlpha OneMinusSrcAlpha | |
| |
GrabPass { "_GrabTexture"} | |
| |
Pass { | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
// make fog work | |
#pragma multi_compile_fog | |
#include "UnityCG.cginc" | |
| |
// | |
// 乱数 | |
// | |
float rand(float2 xy) { | |
return frac(sin(dot(xy, fixed2(12.9898,78.233))) * 43758.5453); | |
} | |
| |
// | |
// セルラーノイズ | |
// | |
float3x3 cellularNoise(float2 uv){ | |
float2 resPos = 0; // 最近傍の位置 | |
float nearest = 1e7; // 最近傍からの距離 | |
float nearest2 = 1e7; // 二番目の近傍からの距離 | |
for (int y = -1; y <= 1; ++y){ | |
for (int x = -1; x <= 1; ++x){ | |
float2 base_pos = floor(uv) + float2(x, y); | |
float2 rand_pos = base_pos + rand(base_pos) * 0.8 + 0.2; | |
float dist = length(rand_pos - uv); | |
if (dist < nearest){ | |
// 最近傍を更新 | |
nearest2 = nearest; | |
nearest = dist; | |
resPos = rand_pos; | |
} else{ | |
// 二番目の近傍を更新 | |
nearest2 = min(nearest2, dist); | |
} | |
} | |
} | |
float height = pow(saturate(nearest - 0.2), 1.5); | |
float2 normal = float2(ddx(height), ddy(height)); | |
//normal = height; | |
return float3x3(resPos, 0, normal, 0, nearest2 - nearest, 0, 0); | |
} | |
| |
// | |
// パーリンノイズ | |
// | |
fixed2 random2(fixed2 st) { | |
st = fixed2( dot(st,fixed2(127.1,311.7)), | |
dot(st,fixed2(269.5,183.3)) ); | |
return -1.0 + 2.0*frac(sin(st)*43758.5453123); | |
} | |
| |
float perlinNoise(fixed2 st) { | |
fixed2 p = floor(st); | |
fixed2 f = frac(st); | |
fixed2 u = f*f*(3.0-2.0*f); | |
| |
float v00 = random2(p+fixed2(0,0)); | |
float v10 = random2(p+fixed2(1,0)); | |
float v01 = random2(p+fixed2(0,1)); | |
float v11 = random2(p+fixed2(1,1)); | |
| |
return lerp( lerp( dot( v00, f - fixed2(0,0) ), dot( v10, f - fixed2(1,0) ), u.x ), | |
lerp( dot( v01, f - fixed2(0,1) ), dot( v11, f - fixed2(1,1) ), u.x ), | |
u.y)+0.5f; | |
} | |
| |
struct appdata { | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
| |
struct v2f { | |
float2 uv : TEXCOORD0; | |
float4 uv_screen : TEXCOORD1; | |
UNITY_FOG_COORDS(1) | |
float4 vertex : SV_POSITION; | |
}; | |
| |
sampler2D _MainTex; | |
sampler2D _GrabTexture; | |
float4 _MainTex_ST; | |
int _Division; | |
half _Threshold; | |
half _Height; | |
float _PerinNoiseColor; | |
float _PerinNoiseStrength; | |
float _PerinNoiseStrengthBack; | |
float _Opacity; | |
float _EdgeOpacity; | |
v2f vert (appdata v) { | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv_screen = ComputeGrabScreenPos(o.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
UNITY_TRANSFER_FOG(o,o.vertex); | |
return o; | |
} | |
fixed4 frag (v2f i) : SV_Target { | |
half alpha = _Opacity; | |
clip(tex2D (_MainTex, i.uv).a - 0.01); | |
// ガラスの歪み | |
float perin = perlinNoise(i.uv * 26); | |
float2 perlinNormal = float2(ddx(perin), ddy(perin)); | |
// セルラーノイズの最近傍のテクスチャを取得、代表点とする | |
float3x3 cn = cellularNoise((i.uv + perlinNormal * _PerinNoiseStrength) * _Division); | |
fixed4 mainCol = tex2D (_MainTex, cn[0].xy / _Division); | |
mainCol.a = 1; | |
float2 cellularNormal = cn[1].xy; | |
// 背景の歪みの計算 | |
float2 uv_screen = i.uv_screen.xy / i.uv_screen.w; | |
uv_screen += (cellularNormal + perlinNormal * _PerinNoiseStrengthBack) * _Height * alpha * 2; | |
fixed4 grabCol = tex2D (_GrabTexture, uv_screen); | |
fixed4 col = lerp(grabCol, mainCol, alpha); | |
// 歪みによる黒ずみの計算 | |
// 歪みによる法線が下を向いているところを黒くする | |
float perlinShadow = saturate(-perlinNormal.y); | |
col.rgb *= 1-perlinShadow * _PerinNoiseColor; | |
// ついでに不透明度も落とす | |
col = lerp(col, mainCol, perlinShadow); | |
//col.a = 1 - (1-col.a)*(1-perlinShadow) * 0.4; | |
| |
// 最近傍の二つの点の距離の差が一定以下 → ボロノイ境界付近にいるので黒 | |
col = lerp(col, fixed4(0, 0, 0, _EdgeOpacity), step(cn[2][0], _Threshold)); | |
//alpha *= col.a; | |
| |
UNITY_APPLY_FOG(i.fogCoord, col); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment