Help us understand the problem. What is going on with this article?

Unity 網掛けシェーダー

More than 3 years have passed since last update.

image

こういう漫画っぽい表現やってみたかったんですよね。

DiffuseDither.shader
Shader "Legacy Shaders/Diffuse Dither" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
    Tags { "RenderType"="Opaque" }
    LOD 200

CGPROGRAM
#pragma surface surf Lambert

sampler2D _MainTex;
fixed4 _Color;

struct Input {
    float2 uv_MainTex;
    float4 screenPos;
};

void surf (Input IN, inout SurfaceOutput o) {
    float2 s = IN.screenPos.xy / IN.screenPos.w * 640.0;
    s.y *= _ScreenParams.y / _ScreenParams.x;
    clip(0.5 + (sin(s.x) + sin(s.y)) * 0.25 - (1.0 - _Color.a));
    o.Albedo = _Color.rgb;
    o.Alpha = _Color.a;
}
ENDCG
}

Fallback "Legacy Shaders/Diffuse"
}

解説

サーフェースシェーダーです。Unity ビルトインの Diffuse シェーダーをベースに、マスク処理を追加してます。他のシェーダーベースでも同じようにやれば出来るかと。

ポイントは clip() の呼び出しです。この関数は、与えられた引数が 0 より小さい位場合は、描画を行いません。これを利用してマスク処理を行います。

surf の処理を上から見ていきましょう。

float2 s = IN.screenPos.xy / IN.screenPos.w * 640.0;

今回は、スクリーンスペースでのエフェクトにしたかったので、screenPos を使います。xyw で割ることで、(0, 0)〜(1, 1) に正規化された状態で描画先の座標が得られます。640.0 は調整用の係数です。これを変えると網掛けの大きさの具合が変わります。

s.y *= _ScreenParams.y / _ScreenParams.x;

_ScreenParams にはレンダリング先の画面の情報が入ってます。y / x でアスペクト比が求まります。先ほど求めた s は正規化された状態であるため、画面の比率が考慮されていません。縦長だろうが横長だろうが (0, 0)〜(1, 1) になってしまいます。そこで、アスペクト比を掛けておくことで正しい比率になり、この後行う網掛けが楕円ではなく正円で行えるようになります。

clip(0.5 + (sin(s.x) + sin(s.y)) * 0.25 - (1.0 - _Color.a));

いよいよクリッピングです。sin(s.x) + sin(s.y) で、いい感じにグリッド上に丸が配置された感じの値が -2.0〜+2.0 で求まります。それを * 0.25 して -0.5〜+0.5 の範囲に収め、+ 0.5 することで、0.0〜1.0 の値が得られます。

こうして得られた値から、一律で定数を引くと、1.0 に近いピクセル以外はだんだんマイナスの値となり、結果クリップ関数によって消えていくという寸法です。元の値を sin + sin で求めているので、この消え方が円状になります。

この例では、(1.0 - _Color.a) を引くことで、アルファの値に応じて消え具合を調整できるようにしてあります。アルファが 1.0 の時は完全に描画され、0.0 の時は完全に消えます。このシェーダーを指定したマテリアルを作成して、ベースカラーのアルファの値を弄ると網掛けが変わる様子がわかると思います。

sin + sin の部分を別の式にすると別の消え方になったりして面白いので是非カスタマイズしてみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした