読者です 読者をやめる 読者になる 読者になる

【Unityで始める初めてのShader】ポストエフェクトの作り方1

shader1_2

はじめに

適当に書いておいて、後から分かりやすいように編集します。
さて、私はDXライブラリ、XNA、そしてUnityといろいろなツールでゲームなどを制作してきました。言語は異なっても普通のプログラムなら書けるのですが、シェーダ言語は何度も挫折しています。
そんな私がちょっとずつShaderを勉強していくエントリになります。このブログを見ながら一緒にShaderを勉強してくれる人がいたらうれしいです。

導入

まずはUnityのプロジェクトを作りましょう shader1_1 適当にオブジェクトを配置 shader1_2

カメラへの適用

ポストエフェクトはCameraに適用することで使います。まずはこんなコードを書いてカメラに適用しましょう。

using UnityEngine;

public class ImageEffect : MonoBehaviour {
    [SerializeField]
    Material mat;

    void OnRenderImage(RenderTexture source, RenderTexture destination) {
        Graphics.Blit(source, destination, mat);
    }
} 

OnRenderImageは全てのレンダリングが完了し、RenderTextureにレンダリングされた後に呼び出されます。sourceが元の画像, destinationが出力される画像です。Graphics.Blitは元の画像にマテリアルを適用し出力してくれる関数です。

続いて、Create->Materialでマテリアルを作成。 shader1_3

Create->Shaderでシェーダを作成し, マテリアルに適用。 shader1_4

そして、このマテリアルをカメラに適用
shader1_5

  1. カメラに付けたImageEffect.csのOnRenderImageが呼び出される
  2. 元の画像に対してマテリアルを適用し、出力
  3. マテリアルはさっき作ったPostEffect.shaderが適用されているので、その処理に従う

という流れでエフェクトが適用されます。
この状態で実行すると... shader1_6

真っ暗ですね。
PostEffect.shaderを見てみましょう。

Shader "Custom/PostEffect" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    } 
    FallBack "Diffuse";
}

うん、よく分からない。
実はデフォルトで記述されているシェーダはオブジェクトに付けるタイプのシェーダです。今回はポストエフェクトを作りたいのでこれの説明はしません。
とりあえず、カメラにエフェクトを適用できたところで、今回はこの辺で。