Making Tera

たまに書く不定期ブログ

Modoで自動マップ生成機能を作成しようと格闘中

最近、時間があったのでマップ自動作成機能を作ろうと格闘しておりました。

せっかくModoもバージョンアップしたばかりなので手を付けていなかったスケマティックまわりにようやく触れました!
ノードはやはり強力ですね。

完成したららせつのMAP作成に使えるかなぁ・・・。
Unityに持っていくことも考えないとですね。

とりあえず現状は以下のような感じになってます。

分割数、凹ませ具合、地形の形などはすべてあとから変更できる仕組みです。


AutoGround

次は境界にアイテムを自動で置いたり、テクスチャあたりに着手予定!

今年は色々やれそうです!

去年は引っ越しなどで色々と忙しかったのですが、
今年は時間が取れそうなので3Dやゲーム制作に力を入れていきたいと思っています。

早速、ずっとやっていなかったModo10のアップデートを行いました!
f:id:makingT:20170107001819j:plain
酉年ということで・・・。

とりあえずプロシージャナルモデリングが気になります。
Mapの自動生成なんかに使えないかなぁ~と。

C#(WPF)とDLLでシステムコマンドをグローバルフックする

先日、BUFFALO製のマウスやキーボードを他の機器にBlueToothを飛ばせる製品を購入しました

BlueTooth製品の入力を別のBlueToothとして飛ばしたりできて非常に面白いし使いやすい商品!

 

・・・・だった・・のですが!

飛ばす元でAltキーを単発で押すとメニューにフォーカスが移ってしまい、

気付かないうちに設定を変更してしまうという問題に直面しました

 

「その動きだけ制約加えるソフト作成してみよっかな」と思い立って作り始めたのですが

・どうもグローバルフックが必要 しかもDLL化しないとダメ。言語はもう忘れ気味のC++

・資料が古いものばかり DEFファイルなんてほとんど作ったことないよ・・・

・APP側がC#で作成されているサンプルが少ない

・フック横取りして無効化しているのはキー入力ばかりでシステム系のものが見当たらない

 

ということでブログに書くことにしました!

製作環境はVS2015の無料のやつです

 

まずはDLLから始めます

 

新規作成 > C++Win32プロジェクト > 名前はHook > OK > 次へ >DLLにチェック > 完了

 

dllmain.cppを以下に書き換える(ヘッダー追加するまでエラーでてるけど気にしない)

 

次にソリューションのヘッダーファイルを右くり > 追加 > 新しい項目 > Hook.h を作成

中身は以下

 

ビルドしたらDLL完成

次にC#側でAPPを作成開始!

 

新規作成 > WPFアプリケーション > LockAltMenuという名前で作成

 

常駐ソフトにするので、まずはソリューションにあるMainWindowsを削除

App.xaml内 の StartupUri="MainWindow.xaml" という部分も削除

App.xaml.csを以下に書き換える

参照にSystem.Windows.FormsとSystem.Drawingを追加

プロジェクト右クリック > プロパティ > リソース > icon.ico という適当な画像をドラッグしてアイコンリソースを作成

最後に先ほど作ったDLLを実行ファイルと同じ場所に移動※!これで完成!!

 

※ 同じ断層に作成してある場合はプロジェクトプロパティのビルド前イベントに

Copy "../../../../Hook\Debug\Hook.dll" $(TargetDir)Hook.dll と追加しておくと便利

 

 

 

【解説らしきもの】

ソースがすべてですが、注意点だけ抜き出しておきます

 

・フック内容を書き換えたい場合はSetWindowsHookExの第一引数に気をつけろ!

・グローバルフックDLLをC#で扱う場合、DllImportはエントリポイントまで記入しないと動作しない

・似たような方法でDLLインジェクション+サブクラス化を検討している場合は、SetWindowLongPtr(GWL_WNDPROC指定)で拾えるシステムコマンドの種類は少ないので実装前に確認したほうが無駄な時間を食わずに済むよ!

・操作したいターゲットが決まっている場合はSetWindowsHookExの第3,4引数を変えてローカルフックにする(コメント参照)

・実験に失敗したらOS再起動しないと治らなくなるので注意されたし!

 

技術が古いためか動作しないサンプルもチラホラあり、簡単にできると思ったのに意外に大変だった orz

誰かのお役に立てば幸いです

SmartMaterialについて

SmartMaterialの機能を知ってかなり感動したんですが、日本語の記事がほとんどヒットしないという悲しさ。

SPの基本的な考え方は

素材を割り当て→マスクして隠す

です

マスクの部分にはペイントだけではなくジェネレータを利用できます。

ジェネレーターは非常に強力なのですが、PositionMapやAOMap、ThicknessMap等、モデルから抽出した固有の情報が必要になります。(ジェネレーターによって種類が異なります)

SPはこの情報をモデルごと(正確にはTextureSetごと)に記憶することしました。

(どの情報も好きなタイミングでMeshからベイクできます。)

これにより「ジェネレータと必要情報の自動紐づけ」が可能となり、

モデルにより異なる情報は無視して、ジェネレータ(エフェクト)を含む素材をテンプレートとして保存できる仕組みが完成しました。

これが「SmartMaterial」です。

PositionMap等が必要な複雑な素材であってもテンプレートとして保存できるのは非常に強力で、時間短縮に繋がります。

現時点ではSmartMaterialを読み込んだ時に必要なマップがベイクされていない状態でもそのまま読み込めます。

警告のようなものが出るか、読み込み時に必要マップが確認できる仕組みがあってもいい気がします。

SubstancePainter1.5を試してみた

半年以上SubstancePainterアップデートしていなかったので早速アップデートしてみた。

 

f:id:makingT:20160207024216j:plain

相変わらず日本語情報が少ないので公式の動画を三つくらい視聴。

 

変わったところや気になった機能をまとめてみた。

 

SmartMaterialがやばい!

後述します。

 

sbsarファイルの管理が楽になった。

SettingのShelfの項目にフォルダを指定するとMaterialなどのカテゴリごとにフォルダを自動生成してくれるので、そのフォルダの中にsbsarファイルをぶち込めばOK。フォルダが断層になっていても問題なく参照してくれるのがGood!

 

日本語に対応。

NormalMapが「通常マップ」ってΣ

「法線マップ」でしょ!

日本の代理店とかから指摘がいかないのかなぁ・・・。

 

レイヤーやマスクにエフェクトがかけられるようになった。

SDの強力なジェネレーターがかけられるのもやばいんだけど、その上からペイントエフェクトで手軽に手直しできるのがかなり便利ですねこれ。以前だとレイヤー構造が複雑になりがちだったので便利です。

あとColorSectionEffectが神です。SDでMultiMaterialBlendノードを利用する必要がなくなりました。というかSubstancePainter一本でテクスチャを作成するワークフローに変更できそうです。

 

以前できなかった複数マテリアル(UVマップ)を持ったモデルのサポートや、ベイク種類の増加、テクスチャの合成方法も増えてるし、ビューアの強化等 ほんと至れり尽くせり。

 

全体を通して機能がかなり増えていて別ソフトになってましたが、流石はAllegorithmic社さん UIが洗練されているのでほとんどマニュアルなしで使えました。(3D初心者の方やDesignerの方を触ったことない人がいきなり操作できるかどうかと聞かれると疑問ではありますが・・・。)

今後も期待できる内容で大満足のアップデートだったと思います。

 

なんか思ったより長くなったのでSmartMaterialについては明日書きます。

PBRShader for UnityTerrain

結論から言うと恐らく現状ではPBR対応のサーフェイスシェーダーをTerrainのCustomShaderとして利用することはできない

http://forum.unity3d.com/threads/terrain-pbr.276734/

Unity Technologiesによると公式にて近日中に対応予定。とのこと。

 

PBRに拘らなければCustomShaderを適用したMaterialをTerrainの設定画面から指定することができた。

以下は角度によってテクスチャを自動で切り替えるシェーダーを適用した例

 

f:id:makingT:20160207023810j:plain

ただしTangentVectorが取得できない等Terrain特有の癖が分かるまではUnity上で細かくデバッグしながら作成したほうが良さそう。

 

シェーダーからTerrainのInspector内の PaintTexture にアクセスしたい場合は以下を記述する。

(4つのテクスチャが登録されていると過程)

プロパティ内

[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}

[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}

[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}

[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}

[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}

[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}

[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}

[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}

 

入力部分の構造体の例

struct Input {

float2 uv_Sample;

float2 uv_Main : TEXCOORD0;

float2 uv_Splat0 : TEXCOORD1;

float2 uv_Splat1 : TEXCOORD2;

float2 uv_Splat2 : TEXCOORD3;

float2 uv_Splat3 : TEXCOORD4;

};

 

変数宣言部でサンプラーを利用できるようにする

uniform sampler2D _Splat0,_Splat1,_Splat2,_Splat3;

 

サーフェイスシェーダー内部でのアクセス方法

tex2D(_Splat0, IN.uv_Splat0)

 

 

グーグル上で資料が増えたこともあって、シェーダーまわりの知りたいことは一通り調査が終わった!

次はずっとしたかったのにできなかったSubstanceDesignerとPainterのアップデートをやっていこうと思う~

Unity5のサーフェイスシェーダー

昨日の続きでUnity5のサーフェイスシェーダー内部を覗いてみた。

 

PBRに対応するため内部で面倒なことをしていると思い込んでいたら、まるごとすっきりとリメイクされている模様。

よってほとんど説明する内容が無い・・・。

 

Shader "Custom/NewShader" {

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"

}

 

Vertex/FragmentシェーダーをPBRで書く必要が無い限りは物理ベースの計算を隠蔽したままコーディングができそうな気配!

これはありがたい・・・。