イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

よく使う記事リスト

++頻繁に更新する記事

Unity シェーダ関連まとめ - イラスト、モデリング、Unity、VR関連

 

vrchat 関連情報 - イラスト、モデリング、Unity、VR関連

 

Unity しょうもないミス + 小ネタ集 - イラスト、モデリング、Unity、VR関連

 

ocurasgo開発関連記事のリスト - イラスト、モデリング、Unity、VR関連

 

Shaderの勉強に役立ったサイト - イラスト、モデリング、Unity、VR関連

 

パーティクルライブ 作成メモ、思ったこととかメモって行く - イラスト、モデリング、Unity、VR関連

 

初心者による初心者のためのパーティクルライブの解説ーリンクリスト - イラスト、モデリング、Unity、VR関連

 

vrchat ワールド作成 メモ - イラスト、モデリング、Unity、VR関連

 

Blender アドオン 開発資料 - イラスト、モデリング、Unity、VR関連

 

Shader 不可思議現象集 - イラスト、モデリング、Unity、VR関 

 

Vket4 メモ - イラスト、モデリング、Unity、VR関連

 

Unity2017とUnity2018の互換性・相違点 - イラスト、モデリング、Unity、VR関連

 

Shader 遭遇した問題とその解決 - イラスト、モデリング、Unity、VR関連

 

 

 

++サンプルベースコード

Shader frag Base - イラスト、モデリング、Unity、VR関連

shader surf base - イラスト、モデリング、Unity、VR関連

shader テッセレーションサンプルコード - イラスト、モデリング、Unity、VR関連

shader ジオメトリシェーダbase - イラスト、モデリング、Unity、VR関連

shader GrabPass Base - イラスト、モデリング、Unity、VR関連

shader utils - イラスト、モデリング、Unity、VR関連

レイマーチ サンプル - イラスト、モデリング、Unity、VR関連

shader volonoi - イラスト、モデリング、Unity、VR関連

shader lightingサンプル - イラスト、モデリング、Unity、VR関連

shader normal map + multi lighting - イラスト、モデリング、Unity、VR関連

unity shader 影の処理 - イラスト、モデリング、Unity、VR関連

blender で key "Text" not foundエラーが起きた原因

自作のblenderアドオンでkey "Text" not foundというエラーが起きるという報告が来た。無論、私の環境では起きない。

なぜ起きるのかは分からなかったが、原因は判明した。

インターフェース=>翻訳=>新規データ にチェックが入ってると起きることが判明した。エラーを回避するにはチェックを外せばよい

f:id:arumogina:20201004185555p:plain

 

さいとうなおき氏の練習法のメモ

https://www.youtube.com/watch?v=Zhcq6qQyvTM

1:商品化していてもおかしくない絵を描きtwitterに公開する

2:描いた絵を分析し問題点を発見する。この時、絵が上手い人の絵と見比べながら行うとより問題を発見しやすくなる。

3:発見した問題を1つずつ解決していく。ピンポイントで練習を行う。

 

*先に仕事をもらっちゃう

(これは基本的に画力のあるさいとうなおき氏だからできたのであってずぶの素人がやることではないと思う。というか受注出来んと思う。)

 

https://www.youtube.com/watch?v=lRmgLBCaV6Q

1:理想の絵柄の絵を探す

2:その人の絵柄でオリジナルイラストを本気で描き切る。描き切らないと課題を見つけられない。

=>何を描けばいいのか分からないときは?

二次創作、簡単なオリジナルキャラクターを作る

3:自分の絵とお手本を比較して、自分の絵の気に入らない点・問題点を箇条書きで描きだしていく

4:発見した問題を1つ決めて、その一つに絞って練習する。何かしらの発見があるまで練習する。発見や考察過程を書き出す

5:練習したことを反映して2に戻る

モデリングーウェイトペイントメモ

++使ったチップ

全てのウェイトを除去

bpy.ops.object.vertex_group_remove_from(use_all_groups=True)

を全ての頂点を選択しScriptingタブにあるコンソールに入力する。

 

Blender: ウェイトペイントで裏面も同時にペイントする方法 : ReflectOrange

ディープブリザード氏の超入門講座のメモ

++#1

mmに単位を変更。印刷する場合に実物大で作業できる。

単位のファイルメニュー=>環境設定=>定規単位で変更

 

新規作成するときも単位をmmにする。

 

Gペン : 筆圧による線の強弱が強い

丸ペン:筆圧による線の強弱が弱く比較的均一

ミリペン:強弱がない

粗い鉛筆:拡大すると鉛筆っぽい質感が見える。

紙質=>用紙で書き味を変えられる。ブリザード氏は漆喰を使っている。

 

作成するキャンパス

イラスト

単位をmm

サイズはA4

カラー350pdi

 

++#2(超入門講座じゃなかったこれ

https://www.youtube.com/watch?v=RChnEct47pU

 

レイヤーカラーで線の色を変更出来て、清書しやすくできる。

ベクターレイヤーにすると、消しゴムで交点まで消すように設定すると、線の交点のところまで消してくれるようになり綺麗に線を消せる。髪などに有効

=>線画はベクターレイヤー

 

カラーはラスターレイヤーで行う。

塗りつぶしツールを

他レイヤーを参照

ベクターの中心線で塗りどまり

にチェックを入れる。

 

線画が切れており塗りつぶすと他まで塗りつぶしてしまう箇所は、塗りつぶす色で線を引いて塗りつぶす部分を囲ってから塗りつぶす。

 

影は乗算に設定したラスターレイヤーで塗る。

 

++#02

https://www.youtube.com/watch?v=71CvrCPmOyY

アタリ=>大ラフ=>ラフ、とラフも段階を経て描く。

ラフを分けないと線画にするとき線が混ざりすぎて線画にしにくくなる。

 

複数人数や複雑な構図を描く場合、ラフレベルでレイヤーを分ける。

隠れる部分もパーツ単位では隠れる部分も描いておく。

 

++#03

https://www.youtube.com/watch?v=H7pq05r7JXI

模写ではなくトレースによる練習法の紹介。

最初はトレースから始め、髪を追加したり、目の形を変えたりし、

より簡易なトレースやガイド線のみで描く,自分でアタリを描いて描くなど。

 

++#4

https://www.youtube.com/watch?v=RHhyMraAxlI

色を塗る場合は、使用する色の彩度と明度を揃える(完全に同じにする必要はない)

 

++#5

https://www.youtube.com/watch?v=ibLN85CTOco

影と肌の色の色相をずらす

 

++#6

https://www.youtube.com/watch?v=XLHBf_6YQlQ

光源、陰(シェード)、影(シャドウ)、ハイライトの説明

 

シェードはグラデーションで表現できる。

ハイライトのデフォルメでポップな感じになる。

 

陰影の参考資料として3Dソフトがあげられてる。Blenderは書かれてないがBlenderが良い。

 

++#7

https://www.youtube.com/watch?v=63cQvMWCav8

目の書き方。

目の影の原理も説明されている。

 

瞳のベースの色を塗る

=>

通常もしくは乗算レイヤーを新規に作成し、ベースから色相をずらした色で虹彩・瞳孔を塗る。エアブラシやペンなど好みのブラシを使用

=>

エアブラシで陰を塗る。

=>

スクリーンレイヤーにし、光彩・角膜に色を置く。

角膜の光の反射、虹彩の色の深み

=>

通常レイヤーを作成しハイライトを置く。

丸く色を置いてから小さい丸を白で置く。

=>

瞳に点々と2~3種類の色を置くと宇宙のように出来る。

ブラシの星などをスクリーンレイヤーで合成することでよりキラキラさせられる

 

++#8

https://www.youtube.com/watch?v=PCSNLWKq5aE

投げ縄塗りの説明

図形を描くとその内側を塗りつぶす

クリッピングマスクと組み合わせて使用する。

 

下書きレイヤーにすると、親レイヤーの影響を受けずに表示される

陰をペンの身で塗る場合、大きく書いてはみ出した部分を削る。

 

ペン+塗りつぶしの場合、ペンで囲い塗りつぶす

 

投げなわツールで影を塗るのが早い。

 

図形=>投げなわ塗りで使用出来る。

 

++#9

https://www.youtube.com/watch?v=AqKyNzcUnKU

写真のイラスト風にする加工方法

 

++#10

https://www.youtube.com/watch?v=Phw4bH4Yj5w

髪の毛。

3つのパーツに分けて考える。

前髪・横髪・後髪

髪は頭頂部付近から生えて垂れ下がってるようになることを意識する。

髪の毛は頭の形に添って流れを作る。ストレートの場合、頭の形にそってカーブを作る。

毛先に違いほどが髪が曲がりやすいのでこれを意識してウェーブ等を描く。

ストレートを描く場合でも毛先を少し丸めると自然になる。

 

毛束のサイズや流れに差異を持たせたり、隣の毛束と重ねたりすることでより良い表現になる。

 

++#11

https://www.youtube.com/watch?v=2MTRalGaLa0

男性の髪の描き方。

髪をはねたり反らせたりすると男性らしい髪型になる

横上が短い。

その他、髪型別の説明がされている

 

++#12

https://www.youtube.com/watch?v=Dcxt0HDF4MA&t=49s

ポニーテール,ツインテール,三つ編み,お団子ヘアの描き方。

おさげ、ツーサイドアップ,ピッグテールの紹介

 

++#13

超入門講座#13 - YouTube

五感を使った色選び。

その色から連想される感覚・印象。

 

色の五感を身に着けるにはその色から受ける印象を書き出していく。

それをもとに色選びを行う。

(正直これは感覚的な話で分かったような分からなかったような感じである)

 

++#16

https://www.youtube.com/watch?v=P9Wow8bOJkA

フリルの書き方

ガイドラインを描く。

ガイドラインにそってうねうねを描く。

うねうねの山の中心線に向かってうねうねの谷から線を引く。

裏側も同じ。

 

++#17

https://www.youtube.com/watch?v=LQLeP2hC-dw

レースの書き方

レースの線画:ガイドライン=>絶対値のsin波=>その波にフラクタル図形のように波を描いていく。穴をあける。

 

レースの線の色は明るい色にすることで軽やかな印象に出来る。

 

++#19

https://www.youtube.com/watch?v=SzieECLBjKU

レースの山とレースの穴の数は同じにする。

 

++#20

厚塗りの講座。

ただしメイキング動画が多く上級者向けという感じ。

 

++#21

チェック柄など模様の作り方とそれを服等に張りつける方法

メッシュ変形を使ったチェック柄の服を立体的に見せる方法

 

++#22

グラデーションツール or エアブラシ

加算発光レイヤー

透明ピクセルの保護

ガウスぼかし

虹を使ったゲーミングハイライトの塗り方の説明

 

ゲーミングハイライトの使い時:非日常、SFなど

https://www.youtube.com/watch?v=oBNdAGHA0nA

 

++#23~25

クリスタの基本的な使い方。

カラーヒストリーで今まで使った色を選択出来る。

線画説明についてはこちらの方が丁寧かも

https://www.youtube.com/watch?v=RChnEct47pU

 

++#26

https://www.youtube.com/watch?v=_R3HVVmbIWI

レイヤーの説明

通常:色を上書き。そのレイヤーの色をそのまま出力

乗算:下のレイヤーの色と掛け合わせた色を出力。色が暗くなるので影を描くときなどに使用

 

塗りつぶし、自動選択の便利な設定の紹介

 

色の塗り方

全体に肌の色を塗る。これで塗り忘れがなくなる。

線で囲まれてない部分を塗る場合は塗る色で囲ってから塗りつぶす

囲っても漏れてしまう場合は塗りつぶしツールの色の誤差の数値が高いのが原因。これを2くらいに下げる

 

 ++

https://youtu.be/h2WESb6I9hw

 ベクター線繋ぎ、ベクター線単純化の紹介。

短く引いた荒くなった線を綺麗に出来る

 

 

 

unity shader 影の処理

 

 

参考:

【Unity】【Shader】影を描画する、影を受け取る - Qiita

 

1pass目で他のオブジェクトからの影を受け取り自身にかかる影を描画

2pass目で他のオブジェクトに自身から伸びる影を情報を渡している

 

Shader "Unlit/ShadowVF"
{
    Properties
    {
        _Color("Color",Color) = (0,1,0,1)
        _ShadowColor("ShadowColor",Color) = (1,0,0,1)
    }
    SubShader
    {
        Pass
        {
            Tags { "LightMode"="ForwardBase" }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"
            float4 _Color;
            float4 _ShadowColor;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                fixed4 diff : COLOR0;
                float4 pos : SV_POSITION; // posに変更する!!TRANSFER_SHADOWがposとうい名前でないと受け付けない。
                SHADOW_COORDS(1)
            };

            v2f vert (appdata v)
            {
                v2f o;
                // ここの左辺もposに変更
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                half3 worldNormal = UnityObjectToWorldNormal(v.normal);
                half NdotL = saturate(dot(worldNormal, _WorldSpaceLightPos0.xyz));
                o.diff = NdotL * _LightColor0;
                TRANSFER_SHADOW(o)
                return o;
            }

            fixed4 frag (v2f i) : SV_Target{
                //影はここで計算する
                //SHADOW_ATTENUATIONで他のオブジェクトから影の濃度を受け取っている
                //濃度に合わせて任意の色を掛ければそれが影の色に出来る
                float shadow = SHADOW_ATTENUATION(i);
                float4 col = i.diff * lerp(_ShadowColor,_Color,shadow);
                return col;
            }
            ENDCG
        }

        Pass{
          /*
            他のオブジェクトに影の情報を渡している
            上記のSHADOW_ATTENUATION(i)の返り値となる値を考えればよいと思う
          */
            Tags{ "LightMode"="ShadowCaster" }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f{
                V2F_SHADOW_CASTER;
            };

            v2f vert (appdata v)
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
                return o;
            }

            fixed4 frag (v2f i) : SV_Target{
              SHADOW_CASTER_FRAGMENT(i)
            }
            ENDCG
        }

    }
}    

Unity C#でTexture2Dを回転させる場合

	Vector2 Rot2D(Vector2 xy,float rad){
		rad *= (float)(Math.PI/180f);
		return new Vector2(xy.x*Mathf.Cos(rad)-xy.y*Mathf.Sin(rad),
		                   xy.x*Mathf.Sin(rad)+xy.y*Mathf.Cos(rad));
	}

回転には普通の回転行列を使用。 回転するとfloat型で処理するが書き込むピクセルを指定するときはint型であるため、本来書き込むべきピクセルとズレてしまう場合がある。

するとこのようなドット抜けのような感じになる。

f:id:arumogina:20200329171659p:plain

なんとか正常なピクセル座標を取得出来ないかと色々やったが無理だった。結局、一度最後まで書き込んだのちに、テクスチャ生成時の初期色と同じ色のピクセルがあれば上下左右4マスの色を平均して代入する、という色を補正する方法で対応した。

 

全体コード

	Texture2D GetSpreadTex(){
		var tex_list = new List();
		for(int k=0;k<_Num;k++){
			Texture2D tex = GetTexture2D();
			Texture2D part_tex = GetRandomPartTex();
			float resize = UnityEngine.Random.Range(_ResizeFrom,_ResizeTo);
			TextureScale.Bilinear (part_tex,(int)(part_tex.width*resize),(int)(part_tex.height*resize));
			Vector2 offset = GetOffset();
			offset.x += _Size.x/2;
			offset.y += _Size.y/2;
			float rot = UnityEngine.Random.Range(_RotFrom,_RotTo);
			for(int w=0;w<part_tex.width;w++){
				for(int h=0;h<part_tex.height;h++){
					Color c = part_tex.GetPixel(w,h);
					Vector2 wh = new Vector2(w,h);
					wh.x -= part_tex.width/2;
					wh.y -= part_tex.height/2;
					wh = Rot2D(wh,rot);
					wh += offset;
					int ix = (int)wh.x;
					int iy = (int)wh.y;
					if(wh.x<0 || wh.y<0 || wh.x>_Size.x || wh.y>_Size.y) continue;
				  tex.SetPixel(ix,iy,c);
				}
			}
			//dot抜け補正
			for(int a=0;a<=tex.width;a++){
				for(int b=0;b<=tex.height;b++){
					Color cu_c = tex.GetPixel(a,b);
					if(cu_c.a == 0){//テクスチャを初期化する
						Color c1 = tex.GetPixel(a-1,b);
						Color c2 = tex.GetPixel(a+1,b);
						Color c3 = tex.GetPixel(a,b+1);
						Color c4 = tex.GetPixel(a,b-1);
						tex.SetPixel(a,b,(c1+c2+c3+c4)/4);
					}
				}
			}
			tex.Apply();
			tex_list.Add(tex);
		}//for(int k=0;k<_Num;k++){

		/*
		tex_listには一枚ごとに移動・回転・色補正をかけたテクスチャが入っている。
		tex_listのテクスチャから各ピクセル座標ごとに色を取り出し、最も先に初期色以外の色を取り出した時
		その色をそのピクセルの色に決定している。
		*/
		var res_tex = GetTexture2D();
		for(int w=0;w<res_tex.width;w++){
			for(int h=0;h<res_tex.height;h++){
				for(int f=0;f<_Num;f++){
					Color cuc = tex_list[f].GetPixel(w,h);
					if(cuc.a != 0) {
						res_tex.SetPixel(w,h,cuc);
						continue;
					}
				}
			}
		}

		return res_tex;
	}