Stable Diffusionで部屋を作る その3 Unity Shaderも投入
結論から書きますと、時刻で生成するには自分のプロンプト力が足りませんでした(笑
前回からの言い訳
部屋はフォトグラメトリーして3Dで作る方針へ、といったな。あれは嘘だ。
いまだ決定打に至らずだけど、健忘録として書く。何かメモしておくと夜中寝てる時にハッと気づいたりするじゃん?
フォトグラメトリーにするには四方八方から撮った写真が必要
1枚の写真から深度を推測するのはControlNet のDepthプリプロセッサーでもできるんだけど、所詮推測なわけで変なところが出っ張ったりしちゃう。
へた絵からデプスを作ると余計なものがでてきて生成後のデプスバッファをいちいちクリスタで手で消ないといけなくて、めんどくさくなった。
しかもよくみたらパース狂ってるんですよ!
いや、元のへた絵のパースが狂ってるから悪いのは自分なんですが!!
という事で、Unityで部屋の3Dオブジェクトを並べて、そこからデプスバッファの値を表示すればいいんじゃーん、と考えました。
Unityの素材探し
Unityのアセットストアで4階建のアパートがフリーで手に入ります。
いろいろな部屋と家具が配置されているという理想的なアセットです。
気に入ったら作者のページから有料アセットも買ってあげてね!
さらにCameraとDepthバッファを表示するプログラムをお借りしました。
ちくわ様の該当ページ
そのままでは距離に対してオフセットや深度の倍率がつけられず殆どのシーンで真っ黒か真っ白になってしまうので、そこを実行時に変更できるようにしました。
Depth.shader
Shader "Unlit/depth"
{
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _Times = 22.; // 倍率。4-32くらいまで
float _Offset = 0.; // 追加。-1 〜 1 の範囲
sampler2D _CameraDepthTexture;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv)) * _Times + _Offset;
return fixed4(depth,depth,depth,1);
}
ENDCG
}
}
}
で、今度はc#のスクリプト
using UnityEngine;
public class DispDepth : MonoBehaviour {
public Material mat;
// shaderに渡す光具合の倍率。2-32程度
public float Times = 22;
// shaderに渡すデプスのオフセット -1〜1 だけど0でいい
public float Offset = 0;
void Start()
{
GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
}
public void OnRenderImage(RenderTexture source, RenderTexture dest)
{
Graphics.Blit(source, dest, mat);
}
private void Update()
{
Shader.SetGlobalFloat("_Times", Times);
Shader.SetGlobalFloat("_Offset", Offset);
}
}
CameraにC#のスクリプト(Depth.cs)をくっつけて、シェーダー(Depth.shader)がついたマテリアル(Depth.material)をInspector上のMatに追加。そして実行します。
実行すると画面が真っ黒や真っ白になる場合は、Timesの値を1から64程度までいい感じになるまで手動で値を調整します。
今回は倍率(Times)24倍、オフセット 0でいい感じの白黒画像がでました。
これをスナップショットして、512x512に整形します。
ControlNetをEnableにしてSingle Imageにさっきクリスタで整形したDepth.pngを貼り付け。Preprocessorはnone、modelは control_v11f1p_sd15_depth を選択
Negativeプロンプトは EasyNegativeだけ入れて、実行だ!
なんで夜は壁が黒くなるんだよぉぉ
プロンプト力か、そうなのか?
かっちり正確にするんだったら、普通に3DでUnity Assetのアパートをそのまま使ってUWPでライトを凝った方がいいんじゃないかな〜。
(Stable Diffusion 意味なくない?と凹む)
終わりに
でもまぁ統一感はあるから、early moning を元に、それをテクスチャーとしてUnityに貼り直すとかすればいいかも。UWPで高級なソファーを表現するのってそれだけでも職人技が必要なんですよね。
次のアイディアがでるまで、キャラクターでも作るか
この記事が気に入ったらサポートをしてみませんか?