プログラムの素

スマートフォンアプリ開発に携わっているペーペープログラマのブログです

Unity5で半透明オブジェクトに影を投影する方法

Unity5で半透明オブジェクトに影を投影する方法をメモ。

Standard ShaderにおいてRendering ModeFadeTransparentに設定すると、オブジェクトの影が描画されなくなってしまいます。
OpaqueCutoutなら描画されるみたいです)

  • Opaque

f:id:famme_fatale:20150318121647p:plain

  • Transparent

f:id:famme_fatale:20150318121702p:plain

Unityのドキュメントに以下のような記述があります。

次に,不透明のオブジェクトのみがシャドウを投影します/されます。すなわち,ビルトインの Transparent またはパーティクル シェーダを用いた場合シャドウは出来ません。

なので、半透明オブジェクトに影を投影させるためにはちょっと工夫が必要でした。

Rendering ModeCutoutなら影が描画されるみたいなので、Cutoutでシェーダーを記述します。

新規でShaderを作成するとStandard Shaderベースでシェーダーが作成されます。
それをちょっと改良して以下のように記述します。

Shader "Custom/Test" {
    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
        _Cutout ("Cutout", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "Queue"="AlphaTest" "IgnoreProjector"="true" "RenderType"="TransparentCutout" }
        Cull Off
        Blend SrcAlpha OneMinusSrcAlpha
        Offset -1, -1
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows alphatest:_Cutout

        // 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"
}

まずはプロパティに変数を追加します。

_Cutout ("Cutout", Range(0,1)) = 0.0

Cutoutのシェーダーにはアルファ値の閾値が必要です。
アルファ値がこの閾値未満の場合にはピクセルが描画されないようになります。

続いてTags等の部分は以下のようにします。

Tags { "Queue"="AlphaTest" "IgnoreProjector"="true" "RenderType"="TransparentCutout" }
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
Offset -1, -1

最後にオプションとして以下を記述します。

#pragma surface surf Standard fullforwardshadows alphatest:_Cutout

alphatest:変数名と記載することでCutoutシェーダーとして機能することになります。
詳細はこちらに記載があります。

このシェーダーを用いて地面にマテリアルを適用した結果が以下になります。

f:id:famme_fatale:20150318123752p:plain

f:id:famme_fatale:20150318123800p:plain

正しい方法かはわかりませんが、無事半透明オブジェクトにも影を投影することができました。

そもそも半透明オブジェクトに対して影が投影されるのがおかしいのかな。。。

Unity5のCustomLigtingについて

Unity5のStandard Shaderでカスタムライティングを記述しようと思ったけどできませんでした。。。

カスタムライティングの関数を追加してビルドエラーが出てしまっています。。。

Unityエディタ上でShaderを新規に作成して、以下のように実装してます。

Shader "Custom/Test" {
    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 Hoge fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
        
        half4 LightingHoge (
            SurfaceOutputStandard s,
            half3 viewDir,
            UnityGI gi) {
            
            half4 c;
            c.rgb = s.Albedo;
            c.a = s.Alpha;
            
            return c;
        }
        
        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"
}

変更した部分は

#pragma surface surf Standard fullforwardshadows

これを

#pragma surface surf Hoge fullforwardshadows

これに変更し、LightingHogeという関数を追加しただけです。

ちなみにLightingHogeという関数は、Unityのビルトインシェーダーの UnityPBSLighting.cgincファイル内のLightingStandard関数を 参考にして関数の引数を定義しています。

ドキュメントにもStandard Shaderのカスタムライティングに関する記載は 見当たらないし困った。。。

どなたかご存知の方いましたら、是非教えて下さい!!

UnityからUnreal Engine4へ ~その2~

前回の記事の続きです。

前回の記事はこちら。

UnityからUnreal Engine4へ - プログラムの素

Projects and files

  • Unreal EngineのプロジェクトはUnityのプロジェクト同様、そのプロジェクトのディレクトリ内に全てのプロジェクトファイルが配置される
  • .uprojectファイルをダブルクリックすることでエディタを起動することができ、右クリックで追加オプションが選択できる
  • プロジェクトのディレクトリ内にはいろんな種類のサブディレクトリが配置される
    • もっとも重要なのはContentSourceのサブディレクトリ
アセットの配置場所
  • ゲームで使用するアセットはContentディレクトリ内に配置する
  • アセットをインポートするには
    1. 物理的なプロジェクトのContentディレクトリ内にファイルを配置する
    2. エディタにおいてContent BrowserのContentディレクトリ内にインポートしたいファイルをドラッグ&ドロップ
サポートされているファイルフォーマット
Asset Type Supported Formats
3D .fbx .obj
Texture .png .jpeg .bmp .tga .dds .exr .psd .hdr
Sound .wav
Fonts .ttf .otf
Videos .mov .mp4 .wmv
Sceneについて
  • UnityではScene内にGameObjectを配置し、Sceneのアセットファイルとして保存される
  • UnrealではUnityのSceneと似たものにMap fileと呼ばれるものがある
  • Map fileはLevelやオブジェクト、ライティング情報やLevel内の設定を記憶する
Project Settingsの変更
  • エディタのメニューのEdit / Project Settings
  • Project Settingsについての詳細はUnreal Engine | Project Settingsを参照
  • Unityで"player settings"と呼ばれていたものは、Unrealにおいては"platform settings"であり、project settings内のPlatformカテゴリに該当する
ソースファイル
  • UnrealのプロジェクトではC++コードはSourceディレクトリ内に配置される
    • C++ source(.cpp)
    • header(.h)
    • build scripts(.Build.cs .Target.cs)
  • BlueprintのみのプロジェクトではSourceディレクトリは作成されない

GameObjectからActorへ

GameObject
  • Unityでは、GameObjectとはワールド内に配置される"モノ"
  • UnrealではActor
  • Unrealでは特殊なタイプのActorを提供している
    • Pawn(プレイヤーやAIオブジェクト用など)
    • Character(アニメーションするクリーチャー用など)
    • 特殊なタイプのActorについては、Unreal Engine | Gameplay Frameworkを参照
  • ActorはUnityのGameObjectとはちょっと違う
    • UnityのGameObjectはC#のクラスだが直接拡張することはできない
    • UnrealのActorはC++のクラスで、継承により拡張しカスタマイズすることができる
Component
  • UnityではGameObjectに複数のComponentを追加し、機能を提供することができる
  • UnrealではActorに複数のComponentを追加できる
  • UnityではGameObjectはComponentのリストを階層構造なしのリストで保持
  • UnrealではActorは階層構造になっているComponentを持つことができる
PrefabからBlueprintへ
  • UnityのPrefab
  • UnrealではBlueprint
    • ActorにComponentを付与し、Blueprint / Add ScriptボタンをクリックしてBlueprintの配置場所を選択したのちCleate Blueprintボタンで保存
    • 作成したBlueprintはContent Browserから見えるようになる
    • ダブルクリックすると編集でき、またレベル内にドラッグ&ドロップで配置ができる
Script ComponentとMonoBehaviour
  • Unity
    • GameObjectにScript ComponentをドロップすることによりC#スクリプトを追加
    • ComponentのクラスはMonoBehaviourを継承する
    • 作成したクラスにはファイルにStart()とUpdate()メソッドが定義されている
  • Unreal
    • Componentを作成することができActorにドロップする
    • ComponentのクラスはBlueprintもしくはC++を使用する
    • 作成したクラスにはInitializeComponent()とTickComponent()メソッドが定義されている
ActorのBlueprint
  • Unity C#
using UnityEngine;
using System.Collections;

public class MyComponent : MonoBehaviour
{
    int Count;

    // Use this for initialization.
    void Start ()
    {
        Count = 0;
    }

    // Update is called once per frame.
    void Update () 
    {

        Count = Count + 1;
        Debug.Log(Count);
    }
}
#pragma once
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()
    int Count;

    // Sets default values for this actor's properties.
    AMyActor() 
    {
        // Allows Tick() to be called
        PrimaryActorTick.bCanEverTick = true;  
    }

    // Called when the game starts or when spawned.
    void BeginPlay()
    {
        Super::BeginPlay();
        Count = 0;
    }

    // Called every frame.
    void Tick(float DeltaSeconds)
    {
        Super::Tick(DeltaSeconds);
        Count = Count + 1;
        GLog->Log(FString::FromInt(Count));
    }
};
  • UE4 Blueprint

f:id:famme_fatale:20150308161945p:plain

Transform
  • UnityではどのGameObjectもTransformコンポーネントを持っている
  • UnrealではActorはRoot Componentと呼ばれるScene Componentを持っている
    • Scene ComponentはワールドにおけるActorの位置、回転、スケールを提供し、それらは子階層の全てのコンポーネントに対して適用される
    • 位置情報を持つため、多くのComponentはScene Componentのサブクラスのものを使用される
    • Empty Actorを配置した場合、Actorに対して"Default Scene Root" Componentが作成され、それは純粋なScene Componentとなっている
    • 新しいScene Componentを適用した場合、Default Scene Rootは適用されたものに置き換わる
階層オブジェクト
  • UnityではGameObjectの階層構造を作成することができる

f:id:famme_fatale:20150308170157p:plain

  • UnrealではComponentを階層化することにより実現

f:id:famme_fatale:20150308170201p:plain

Actorの種類

UnrealではActorのサブクラスとして以下のものが提供されている

  • Pawn
    • プレイヤーアバターのような制御可能なゲームオブジェクト
    • PawnはプレイヤーやAIなどのような自身の制御により移動する
  • Character
    • Pawnの特殊バージョン
    • 二足歩行のアバターに対して使用
  • Controller
    • Pawnを持ち、制御する
  • Player Controller * Controllerの特殊バージョン
    • ゲームパッドやタッチ、マウス、キーボードなどから入力情報を得てPawnまたはCharacterを操作する
Objectについて
  • Actorはゲームプレイのためにたいていのクラスで使用され、ワールド内に配置できる
  • Level内に配置されるオブジェクトはActor

  • ObjectUnrealで使用されるクラスのベースとなるものでActorも例外ではない

  • Actorに適用しないタイプのオブジェクトを作成したい場合にObjectは使用される
    • 例えばActor ComponentはすべてのコンポーネントクラスのベースとなっているがActorではなくObjectから派生している

UnityからUnreal Engine4へ

UE4の無料化が発表されました。 これからUE4での開発が盛んになっていくような気がします。 自分は半年ほど前からちょこちょこ触っている程度なので、 これを機にがっつり勉強しようと思ってます!

Unityは触ったことあるけどUE4はよくわかんない...という人のために 公式サイトのドキュメントにこんなのがありました。

Unreal Engine | Unreal Engine 4 For Unity Developers

完全にUnity開発者を取り込もうっていう魂胆ですねw

上記のサイトに掲載されていた用語集が、UE4に取り掛かるときに便利だと思ったので 掲載しておきます。 対応する用語から調べものをして徐々に理解を深めていくのがよろしいのではないでしょうか。

カテゴリ Unity UE4
Gameplay Types Component Component
GameObject Actor, Pawn
Prefab Blueprint Class
Editor UI Hierarchy Panel World Outliner
Inspector Details Panel
Project Browser Content Browser
Scene View Viewport
Meshes Mesh Static Mesh
Skinned Mesh Skeletal Mesh
Materials Shader Material, Material Editor
Material Material Instance
Effects Particle Effect Effects, Particle, Cascade
Shuriken Cascade
Game UI UI UMG (Unreal Motion Graphics)
Animation Animation Skeletal Animation System
Mecanim Persona, Animation Blueprint
2D Sprite Editor Paper2D
Programming C# C++
Script Blueprint
Physics Raycast Line Trace, Shape Trace
Rigid Body Collision, Physics
Runtime Platforms iOS Player, Web Player Platforms