こちらでも試してみたところ、おっしゃる通り背景色漏れが観察されました。
通常は下図のように描画されるシーンにおいて...
カメラ用スクリプトとして下記のようなコードを使用し...
C#
1using UnityEngine;
2
3[RequireComponent(typeof(Camera))]
4[ExecuteAlways]
5public class DotEffect : MonoBehaviour
6{
7 [SerializeField] private Material effectMaterial;
8
9 private void OnRenderImage(RenderTexture src, RenderTexture dest)
10 {
11 if (this.effectMaterial == null)
12 {
13 Graphics.Blit(src, dest);
14 }
15 else
16 {
17 Graphics.Blit(src, dest, this.effectMaterial);
18 }
19 }
20}
effectMaterial
にはご質問者さんのシェーダーコードを使ったマテリアルをセットしたところ、下図のようにオブジェクトの縁に背景のマゼンタ色が混じったドットが出現しました。
なお、ドットをある程度大きくして見やすくするため、マテリアルのPixelNumは40に設定しています。
これはおそらくhalf2 uv = floor(i.uv * _PixelNumber) / _PixelNumber;
によって求めた結果のUVが、必ずしもぴったり処理前映像のテクセル中心を指しているとは限らないことによるのだろうと思います。
サンプリング位置がテクセル中心からずれていると、ずれに応じて近傍のテクセルの色と線形補間された色が取得され、結果として背景色が混ざり込んだ状態になってしまったのでしょう。
そこでカメラ用スクリプトを下記のように変更して、線形補間をオフにしたところ...
C#
1using UnityEngine;
2
3[RequireComponent(typeof(Camera))]
4[ExecuteAlways]
5public class DotEffect : MonoBehaviour
6{
7 [SerializeField] private Material effectMaterial;
8
9 private void OnRenderImage(RenderTexture src, RenderTexture dest)
10 {
11 if (this.effectMaterial == null)
12 {
13 Graphics.Blit(src, dest);
14 }
15 else
16 {
17 src.filterMode = FilterMode.Point;
18 Graphics.Blit(src, dest, this.effectMaterial);
19 }
20 }
21}
下図のように背景色漏れが起こらなくなりました。
余計なお世話かもしれませんが、ドット化したときの映像が元の映像に対して斜めにずれたり、個々のドットの形が画面のアスペクト比に応じた長方形になるのが気にならないでしょうかね?
ずれはfloor
の代わりにround
で丸めてやればいいでしょうし、ドットを正方形にする場合はアスペクト比に応じて縦横のピクセル数を調整してやるといいでしょう。
シェーダーコードを下記のように改変したところ...
ShaderLab
1Shader "Custom/DotEffect"
2{
3 Properties
4 {
5 _MainTex ("Base (RGB)", 2D) = "white" {}
6 _PixelNumber ("PixelNum", float) = 100
7 }
8
9 SubShader
10 {
11 Pass
12 {
13 Tags { "RenderType"="Opaque" }
14
15 CGPROGRAM
16 #pragma vertex vert
17 #pragma fragment frag
18 #include "UnityCG.cginc"
19
20 sampler2D _MainTex;
21 float _PixelNumber;
22
23 struct v2f
24 {
25 half4 pos : POSITION;
26 half2 uv : TEXCOORD0;
27 };
28
29 float4 _MainTex_ST;
30
31 v2f vert(appdata_base v)
32 {
33 v2f o;
34 o.pos = UnityObjectToClipPos(v.vertex);
35 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
36 return o;
37 }
38
39 float4 _MainTex_TexelSize;
40
41 half4 frag(v2f i) : COLOR
42 {
43 float2 pixelNumber = float2(_MainTex_TexelSize.z * _MainTex_TexelSize.y * _PixelNumber, _PixelNumber);
44 half2 uv = round(i.uv * pixelNumber) / pixelNumber;
45 fixed4 col = tex2D(_MainTex, uv);
46 return col;
47 }
48 ENDCG
49 }
50 }
51}
下図のようになりました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/22 02:32