1. はじめに
以前、ARKit3を使ってAR空間上のカメラ映像の一部分を変形させるという記事を書きました。
カメラ映像をテクスチャにするやつやっとできた#arkit3 #ARFoundation pic.twitter.com/gRDyynsN6O
— koyo arai (@koyoarai_) April 26, 2020
この記事を書いた時点ではあまり気にならなかったですが、よく見てみると変形のつなぎ目が目立ってしまい、あまり空間に溶け込んでいません。
そこで、今回 AR空間の変形のつなぎ目を滑らかにするようにシェーダーを書き換えてみたので、そのテクニックを紹介します。
2. 準備
基本準備は、ARKit3を使ってAR空間上のカメラ映像の一部分を変形させるに記載しているので、そちらをご覧ください。
3. 実装
変形処理のつなぎ目を滑らかにするため、シェーダー (CameraPlane.shader)を書き換えます。
Planeの中心から遠ざかるにつれ、パラメタを小さくし、つなぎ目では変形させないようにします。
そこで、tex2Dlodを使って、テクスチャ情報から頂点をいじる処理を追加します。
下記の画像をインポートし、_ScopeTexとして利用します。
また、Thresholdによって変形のパラメータを調整できるようにします。
追加する処理はこのような感じです。
float4 deform = tex2Dlod (_ScopeTex, float4(IN.uv.xy,0,0));
float ratio = _Threshold * deform;
float4 _vertex = IN.vertex;
float ampX = 0.1f * sin(_Time * 100 + IN.vertex.x) * ratio;
float ampZ = 0.1f * sin(_Time * 100 + IN.vertex.z) * ratio;
_vertex.xyz = float3(IN.vertex.x + ampX, IN.vertex.y, IN.vertex.z + ampZ);
全文はこちら
Shader "Custom/CameraPlane"
{
Properties
{
_MainTex ("Albedo (RGB)", 2D) = "white" {}
// _ScopeTexと_Thresholdを追加
_ScopeTex ("Texture", 2D) = "white" {}
_Threshold("Threshold", Range(0,10))= 0.0
}
SubShader
{
Pass
{
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float2 screenpos : TEXCOORD1;
};
sampler2D _MainTex;
sampler2D _ScopeTex;
float _Threshold;
v2f vert(appdata_t IN)
{
v2f OUT;
// --------- : 追加
float4 deform = tex2Dlod (_ScopeTex, float4(IN.uv.xy,0,0));
float ratio = _Threshold * deform;
float4 _vertex = IN.vertex;
float ampX = 0.1f * sin(_Time * 100 + IN.vertex.x) * ratio;
float ampZ = 0.1f * sin(_Time * 100 + IN.vertex.z) * ratio;
// ---------
_vertex.xyz = float3(IN.vertex.x + ampX, IN.vertex.y, IN.vertex.z + ampZ);
OUT.vertex = UnityObjectToClipPos(_vertex);
OUT.uv = IN.uv;
OUT.color = IN.color;
float4 objectToClipPos = UnityObjectToClipPos(IN.vertex);
float4 spreenPos = ComputeScreenPos(objectToClipPos);
float2 uv = spreenPos.xy/spreenPos.w;
OUT.screenpos = uv;
return OUT;
}
fixed4 frag(v2f IN) : COLOR
{
float2 xy = IN.screenpos.xy;
half4 c = tex2D(_MainTex, xy);
return c;
}
ENDCG
}
}
FallBack "Diffuse"
}
4. 実行結果
処理を入れる前
処理を入れた後
5. おわりに
今回はARFoundation向けのシェーダーを紹介しましたが、その他のプラットフォームでも適用できそうなテクニックの紹介でした🍎
おまけ
変形処理をちょっと変えたやつです。
AR空間の変形のつなぎ目を滑らかにする#ARKit #ARFoundation pic.twitter.com/i8FTS5U9vO
— koyo arai (@koyoarai_) November 29, 2020