Unityシェーダーによる3Dモデルのアレンジ方法

この記事では、Unityに取り込んだ3Dモデルをシェーダーを使ってアレンジする方法を紹介します。
シェーダーを変化させることで多様な視覚表現が可能となり、同じ3Dモデルでも印象が大きく変わります。
オリジナリティあふれるシーンの作成に役立つ個性的なシェーダーもいくつか紹介します。

サンプル

STYLY GALLERYからサンプル空間を体験できます。
Shaded City

サンプルプロジェクトのダウンロードはこちらからできます。
STYLY-Unity-Examples

サンプルアセットをWebEditorで確認する

サンプルアセットをWebEditorで確認するLaunch the WebEditor

※STYLYに登録していれば、本TIPSで作成したサンプルアセットをWebEditorで確認することができます。
アカウント未登録の場合、新規登録を行ってから再度、本ボタンをクリックしてください。

アカウント登録はこちらから
Click here

 

シェーダーとは?

シェーダーとは、「物の見え方を決めるプログラム」のことです。
シェーダーの中身を書き換えることによって、コンピューター上に映し出されるオブジェクトの見え方はさまざまに変化します。

Unityで絵作りをする上でも、シェーダーは最も重要な役割の一角を担っているといえるでしょう。
STYLYはUnityで動作する大半のシェーダーをインポートすることができますので、これをうまく利用して自分がイメージする世界を作り上げましょう。

STYLYで使用できるシェーダー

STYLYは基本的にあらゆるUnity用のシェーダーをインポートすることができます。
また、ShaderForgeなどのノードベースで制作するシェーダーも使用することができます。(詳しくはこちらの記事で解説しています)

ただしSTYLYはC#スクリプトをインポートできないため、C#スクリプトと組み合わせて使用するシェーダーを使用することはできません
Unity Asset Storeで配布されているシェーダーの一部はC#スクリプトと組み合わせているものも存在し、そういったシェーダーはSTYLYにインポートできないので注意が必要です。

シェーダーの使い方

ここではシェーダーの基本的な使用方法を紹介します。シェーダーを使用したことがある方はこの項を飛ばして構いません。

シェーダーには「どんなテクスチャを使うか」「光をどれくらい反射させるのか」などのいくつかのパラメーターが存在しており、これを定義するのがマテリアルです。
ですので、Unityでシェーダーを使用する際はマテリアルにシェーダーをアタッチし、パラメーターを設定したうえでシーンのオブジェクトにアタッチする必要があります。

Unityでシェーダーを変更する

まずはシェーダーでアレンジしたい3Dモデルをシーンに置きましょう。
ここでは「Cube」をシーンに配置します。

ヒエラルキーウィンドウにて右クリックし、「3D Object」から「Cube」を選択し作成します。

3Dモデルをシーンに配置

3Dモデルをシーンに配置

次にマテリアルを作成しましょう。
プロジェクトウィンドウで右クリックし、「Create」から「Material」を選択し作成します。
あとでごちゃごちゃになってしまわないように、マテリアルには固有の名前を付けてあげるとよいでしょう。ここでは「New Material 01」と名前を付けました。

マテリアルの作成

マテリアルの作成

あとは先ほど作成した「Cube」に「New Material 01」を適用すれば自由にシェーダーを変更できるようになります。
プロジェクトウィンドウの「New Material 01」をドラッグ&ドロップで「Cube」にアタッチします。

マテリアルのアタッチ

マテリアルのアタッチ

これでシェーダーを変更する準備が整いました。
マテリアルをアタッチしたオブジェクトのインスペクタを開き、「Shader」のプルダウンメニューからシェーダーを変更することができます。
新しく作成したシェーダーやUnity Asset Storeからダウンロードしたシェーダーもこのプルダウンメニューに表示されますので、それらを使用する際もここから変更することができます。

シェーダーの変更

シェーダーの変更

マテリアルにはいくつかのパラメーターがありますので、これを変更することでオブジェクトの見え方を調整することができます。

マテリアルのパラメーター

マテリアルのパラメーター

ネットでコードが公開されているシェーダーを使用する

ネット上でコードが紹介されているシェーダーを使用する場合は、自分でシェーダーを作成する必要があります。
一見難しそうに聞こえるかもしれませんが、この作業は非常に簡単です。

まずはプロジェクトウィンドウにて右クリックし、「Create」から「Sandard Surface Shader」を選択して新規シェーダーを作成します。
あとでごちゃごちゃになってしまわないように、シェーダーには固有の名前を付けてあげるとよいでしょう。

シェーダーの作成

シェーダーの作成

作成したシェーダーをダブルクリックし、コードの編集を行います。
元のコードをすべて削除したら、シェーダーのコードをコピー&ペーストします。

シェーダーの編集

シェーダーの編集

シェーダーの編集が完了したら保存を行い、Unityの画面に戻りましょう。
このように作成したシェーダーも、「Shader」のプルダウンメニューに表示されます。

Unity Asset Storeのシェーダーを利用する

Unity Asset Storeでは個性的なシェーダーが様々取り揃えられているので、これを利用するのもよいでしょう。
無料で配布されているシェーダーもたくさんあります。

Unity Asset Storeで配布されているシェーダーを使用する場合は、ストアの「Import」ボタンをクリックするだけですぐに使えるようになります。
このように入手したシェーダーも、「Shader」のプルダウンメニューに表示されます。

Unity Asset Storeからアセットをインポートする

Unity Asset Storeからアセットをインポートする

Unityの内蔵シェーダーで質感をアレンジする

ここではUnityの内蔵シェーダーのパラメーターを変更して、3Dモデルの見え方をアレンジする方法を紹介します。

UnityのStandard Shaderを使ってプラスチックや金属のような質感を表現する

「Stamdard Shader」はUnityのデフォルトのシェーダーです。
「Stamdard Shader」を使うにはマテリアルのインスペクタを開き、「Shader」のプルダウンメニューから「Stamdard」を選択しましょう。

Standard Shader

Standard Shader

Unityの「Standard Shader」には「Metallic」と「Smoothness」といったパラメーターがあり、これらを変更することでプラスチックや金属など様々な質感を表現することができます。
ざっくり説明すると、「Metallic」を「1」に近づけるほど金属っぽくなり、「Smoothness」を「1」に近づけるほどつるつるした質感になります。

パラメーターの調整

パラメーターの調整

このふたつのパラメーターの数値をうまく調整することで、オブジェクトの質感をアレンジすることができます。
Unityのスタンダードシェーダーのマテリアルパラメーターについてより詳しく知りたい場合は、Unityの公式ドキュメントを読むと良いでしょう。

MetallicとSmoothness

MetallicとSmoothness

UnityのUnlit Shaderを使う

Unlit Shaderはライティングを反映しない光の影響を無視したシェーダーです。
光の影響を受けないため、陰影が付かず影も落ちません。

Unlit Shader

Unlit Shader

オブジェクトに光の影響を受けさせたくない時や、わざと平面的に見せたい場合に役立ちます。フォトグラメトリで作成した3Dモデルとも相性の良いシェーダーです。
「Unlit Shader」を使うにはマテリアルのインスペクタを開き、「Shader」のプルダウンメニューから「Unlit」→「Texture」と選択しましょう。

Unlit Shaderを選択

Unlit Shaderを選択

個性的なシェーダーでアレンジする

ここからは3Dモデルのアレンジに使える個性的なシェーダーを紹介していきます。
これらを上手に使用してオリジナリティあふれる作品を作りましょう。

ワイヤーフレームシェーダー

Wireframe Shader

Wireframe Shader

ワイヤーフレームだけを表示させるシェーダーの一種で、「Shaders Laboratory」という海外のサイト様で紹介されているものです。
ワイヤーフレームのシェーダーはネットでもいくつか紹介されていますが、このシェーダーはワイヤーフレームの対角線を取り除く機能が追加されており、すっきりとした見た目になります。

コードの紹介

Shader "Custom/Geometry/Wireframe"
{
    Properties
    {
        [PowerSlider(3.0)]
        _WireframeVal ("Wireframe width", Range(0., 0.5)) = 0.05
        _FrontColor ("Front color", color) = (1., 1., 1., 1.)
        _BackColor ("Back color", color) = (1., 1., 1., 1.)
        [Toggle] _RemoveDiag("Remove diagonals?", Float) = 0.
    }
    SubShader
    {
        Tags { "Queue"="Geometry" "RenderType"="Opaque" }

        Pass
        {
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom

            // Change "shader_feature" with "pragma_compile" if you want set this keyword from c# code
            #pragma shader_feature __ _REMOVEDIAG_ON

            #include "UnityCG.cginc"

            struct v2g {
                float4 worldPos : SV_POSITION;
            };

            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };

            v2g vert(appdata_base v) {
                v2g o;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }

            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream triStream) {
                float3 param = float3(0., 0., 0.);

                #if _REMOVEDIAG_ON
                float EdgeA = length(IN[0].worldPos - IN[1].worldPos);
                float EdgeB = length(IN[1].worldPos - IN[2].worldPos);
                float EdgeC = length(IN[2].worldPos - IN[0].worldPos);

                if(EdgeA > EdgeB && EdgeA > EdgeC)
                    param.y = 1.;
                else if (EdgeB > EdgeC && EdgeB > EdgeA)
                    param.x = 1.;
                else
                    param.z = 1.;
                #endif

                g2f o;
                o.pos = mul(UNITY_MATRIX_VP, IN[0].worldPos);
                o.bary = float3(1., 0., 0.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[1].worldPos);
                o.bary = float3(0., 0., 1.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[2].worldPos);
                o.bary = float3(0., 1., 0.) + param;
                triStream.Append(o);
            }

            float _WireframeVal;
            fixed4 _BackColor;

            fixed4 frag(g2f i) : SV_Target {
            if(!any(bool3(i.bary.x < _WireframeVal, i.bary.y < _WireframeVal, i.bary.z < _WireframeVal)))
                 discard;

                return _BackColor;
            }

            ENDCG
        }

        Pass
        {
            Cull Back
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma geometry geom

            // Change "shader_feature" with "pragma_compile" if you want set this keyword from c# code
            #pragma shader_feature __ _REMOVEDIAG_ON

            #include "UnityCG.cginc"

            struct v2g {
                float4 worldPos : SV_POSITION;
            };

            struct g2f {
                float4 pos : SV_POSITION;
                float3 bary : TEXCOORD0;
            };

            v2g vert(appdata_base v) {
                v2g o;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }

            [maxvertexcount(3)]
            void geom(triangle v2g IN[3], inout TriangleStream triStream) {
                float3 param = float3(0., 0., 0.);

                #if _REMOVEDIAG_ON
                float EdgeA = length(IN[0].worldPos - IN[1].worldPos);
                float EdgeB = length(IN[1].worldPos - IN[2].worldPos);
                float EdgeC = length(IN[2].worldPos - IN[0].worldPos);

                if(EdgeA > EdgeB && EdgeA > EdgeC)
                    param.y = 1.;
                else if (EdgeB > EdgeC && EdgeB > EdgeA)
                    param.x = 1.;
                else
                    param.z = 1.;
                #endif

                g2f o;
                o.pos = mul(UNITY_MATRIX_VP, IN[0].worldPos);
                o.bary = float3(1., 0., 0.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[1].worldPos);
                o.bary = float3(0., 0., 1.) + param;
                triStream.Append(o);
                o.pos = mul(UNITY_MATRIX_VP, IN[2].worldPos);
                o.bary = float3(0., 1., 0.) + param;
                triStream.Append(o);
            }

            float _WireframeVal;
            fixed4 _FrontColor;

            fixed4 frag(g2f i) : SV_Target {
            if(!any(bool3(i.bary.x <= _WireframeVal, i.bary.y <= _WireframeVal, i.bary.z <= _WireframeVal)))
                 discard;

                return _FrontColor;
            }

            ENDCG
        }
    }
}

使い方

①プロジェクトウィンドウにて新規シェーダーを作成し、シェーダーをダブルクリックで開いて上記のコードをコピー&ペーストする。
②マテリアルを作成してオブジェクトにアタッチし、インスペクタの「Shader」のプルダウンメニューから「Custom」→「Geometry」→「Wireframe」と選択。
③対角線を消す場合は、パラメーターの「Remove diagonals ?」の項をチェック

パラメーターの調整

パラメーター 説明 設定方法
Wireframe width ワイヤーフレームの線の太さ 0~0.5の間で設定
Front color 線の表面の色 カラーダイアログで好きな色を指定
Back color 線の裏面の色 カラーダイアログで好きな色を指定
Remove diagonals ? 対角線を消すかどうか チェックを入れると対角線が消える

Gem Shader

Gem Shader

Gem Shader

Gem ShaderはUnity Asset Storeで無料で配布されているシェーダーで、3Dモデルを宝石のようなきらきらとした見た目に変化させることができます。

使い方

①Unity Asset Storeの「Gem Shader」のページにアクセスし、「import」ボタンをクリックしてアセットをインポートする。
②プロジェクトウィンドウにて「Gem」→「Material」と開いていくとアテリアルがあるので、これをオブジェクトにアタッチする。

パラメーターの調整

パラメーター 説明 設定方法
color 宝石の色 カラーダイアログで好きな色を指定
Reflection Strength 光を反射する強さ
Environment Light 環境光の影響を受ける度合
Emission 表面から放出される光の強度 値を大きくすると自己発光しているように見える

Minimalist Free

Minimalist Free

Minimalist Free

Minimalist FreeはUnity Asset Storeで無料で配布されているシェーダーで、3Dモデルの前後左右上下のそれぞれの面の色をそれぞれ指定できるシェーダーです。
特に立方体や直方体で構成されたオブジェクトと相性の良いシェーダーです。

使い方

①Unity Asset Storeの「Minimalist Free」のページにアクセスし、「import」ボタンをクリックしてアセットをインポートする。
②マテリアルを作成してオブジェクトにアタッチし、インスペクタの「Shader」のプルダウンメニューから「Minimalist Free」→「Standard」と選択。
③パラメーターを自分好みに調整する。

パラメーターの調整

パラメーター 説明 設定方法
Main Texture テクスチャ テクスチャを指定することができます
Custom Shading/Front 正面の色 Shading ModeをSolid Colorにするとカラーダイアログで好きな色を指定できるようになります。
無料版ではグラデーションは使用できません。
Custom Shading/Back 背面の色
Custom Shading/Left 左面の色
Custom Shading/Right 右面の色
Custom Shading/Top 上面の色
Custom Shading/Down 下面の色

Colour By Height Shader

Colour By Height

Colour By Height

Colour By Height ShaderはUnity Asset Storeで無料で配布されているシェーダーで、3Dモデルの高さ方向にグラデーションを作れるシェーダーです。

使い方

①Unity Asset Storeの「Colour By Height Shader」のページにアクセスし、「import」ボタンをクリックしてアセットをインポートする。
②マテリアルを作成してオブジェクトにアタッチし、インスペクタの「Shader」のプルダウンメニューから「Unlit」→「Colour By Height」と選択。
(光の影響を受ける「Lit」版も存在します。こちらを使用する場合は「Lit」→「Frat Shaded Colour By Height」と選択)
③パラメーターを自分好みに調整する。

パラメーターの調整

パラメーター 説明 設定方法
Highest Point/~Highest 色が変化し始める高さ バグか仕様か不明ですが、2色以上のグラデーションは正しく機能しないことも多々あります。
~Colour 高さごとの色

STYLYにインポート

STYLYにシェーダーをアタッチしたオブジェクトをインポートする方法はとても簡単です。
作成したオブジェクトをプレハブ化し、STYLYにアップロードするだけです。

UnityからSTYLYにアセットをアップロードする方法は以下の記事で詳しく解説しています。
記事を読む

 

シェーダーを利用することで3Dモデルの見え方が大きく変わります。
いろいろな面白いシェーダーが存在していますので、自分好みのシェーダーを探してみてください。