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

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

よく使う記事リスト

++頻繁に更新する記事

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

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

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

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

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

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

 

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

 

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

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

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

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

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

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

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

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

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

unity shader テクスチャの値をそのまま取得する方法

++テクスチャ作成C#コード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class OutTest : MonoBehaviour {
	int _Size = 512;
	Texture2D GetTexture2D(){
		Texture2D tex = new Texture2D(_Size,_Size, TextureFormat.ARGB32, false);
		Color c = new Color(0,1f,0,1f);
		//Color c = new Color(1f,0,0,1);
		for(int x=0;x<_Size;x++){
			for(int y=0;y<_Size;y++){
				tex.SetPixel(x,y,c);
			}
		}
		return tex;
	}

	void Start () {
		Texture2D tex = GetTexture2D();
		tex.SetPixel(0,0,new Color(1f,0,0,1));
		tex.Apply();
		byte [] testPng = tex.EncodeToPNG();
		string dirPath = EditorUtility.SaveFolderPanel("Save Texture", "", "");
		string fp = dirPath + "/test_tex.png";
		File.WriteAllBytes(fp,testPng);
	}

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

	}
}

これでuv座標(0,0)にのみ赤を、それ以外が緑のテクスチャが出来る。 出来たテクスチャを以下の設定にする

TextureType=>Sprite
wrap Mode=>Clamp
FilterMode=>Point
にして、テクスチャサイズは2の乗数倍である必要あり(多分)

f:id:arumogina:20191103114153p:plain

 

 

 

以下のシェーダで色を取得

Shader "Custom/Base" {
	Properties{
		_MainTex("MainTex",2D) = "white"{}
	}
	SubShader{
		Tags{"RenderType"="Opaque" "Queue" = "Geometry"}
		//透明部分のあるテクスチャを使う場合
		//Tags{"Queue" = "Transparent" "RenderType" = "Transparent"}
		//Blend SrcAlpha OneMinusSrcAlpha

		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
			};

			struct v2f {
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
			};

      float4 _MainTex_ST;
      sampler2D _MainTex;
			float4 _MainTex_TexelSize;

			v2f vert(appdata v){
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}

			float4 frag(v2f i) :SV_Target {
				float w = _MainTex_TexelSize.x;
				return tex2D(_MainTex,float2(0,0));
			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}
    

これでテクスチャのピクセルごとの素の色を取得出来る (0,0)以外のピクセルを取得したかったら_TexelSize*xという風に指定する テクスチャの設定をしないと、周囲の色と混ぜられた色になったりする。

 

注意

Texture2DでARGB32のテクスチャ生成してSetPixelで色をセットするとき、アルファ値を0にしてテクスチャを出力して、画像設定を2D,clamp:pointにしてtex2Dで読むと、float4(0.804,0.804,0.804,0)ぐらいの値を返すっぽい。これはテクスチャ生成時にrgbにどんな値を入れてても同じ。なので、アルファ値には0.01とかでもいいから何か数値を入れておく方がよい。

書きかけー初心者による初心者のためのパーティクルライブの解説ー汎用的なテクニック編

++++パーティクルライブを作るのに必要な技術

++必須

unityでのアニメーション作成スキル

ワールド固定などいくらかのvrchat関連技術

 

++準必須

パーティクルの操作

 

++あれば尚良し

Shader技術

Blender等にによるモデリング技術

 

とりあえず、アニメーション作成さえできれば、素材をboothやunityのアセットストアで購入することで、それなりのものを作ることが出来ると思います。

アニメーション作成とパーティクル関連については、こちらのfleyさんの記事にまとめられていますので、こちらを読むことをオススメします。

パーティクルライブ・パリピ砲の基礎知識について - バーチャル思考実験室

 

この記事では、私が動画のライブを作成していて得られた知見やどうやって作ったのか、より具体的な話を中心に書いていこうと思います。

 

++++++ライブ作成前に気をつけた方がいいこと

++++命名規則やオブジェクト管理のルールを予め作っておく

全体把握をしやすくするため

 

++++同一オブジェクトはprefab化する

後で変更が必要になったとき、一括変更しやすくなります。

 

++++ヒエラルキー上のオブジェクトのフォルダ構成

音楽を任意のパートごとに分割して番号を振り、その名前のオブジェクトの下位にそのパートで開始するオブジェクトを配置するのがいいのではないかと思う。

千本桜のライブを作ったとき、歌詞メッシュ、その他のメッシュ、パーティクルの3種のフォルダに分けて、その中で、音楽をパートごとに分けて番号を振り分けたのだが、これをやると分類を超えて連携させるとき、やや面倒であった

 

++++素材は使う段階に近くなってから作る

例えば、曲の最後までライブを作るつもりだったが、気力が付きて1番だけ、となってしまう場合や作ってる内に予定していた演出を変更するなど

 

++++ライブ用のunityプロジェクトを作り、そこで作る。

 

++++使用する独自シェーダは一つのフォルダにまとめて、

shaderのパスを独自パスにする

 

++++出現させる方式はエモートスイッチを使う

アニメーションオーバーライドで出すと、手のボーンの動きに追従するようにする処理が入るため、自分から見た場合重くなる。エモートスイッチで出すとこの処理がないために軽い。

 【VRChat】EmoteSwitch V3(エモートスイッチ)使ってみた!! | ケーキのPC情報集会所

 

++++素材を作る場合は汎用性の高いものの方がよい

光の玉だけのパーティクルやレーザーなど汎用性の高い素材の方が次のライブ作成時に使いやすくてよい。千本桜の場合、ハートの太陽の背景や富士山など、やや汎用性にかけるモデルを作成したが、あれは反省点である(デザイン能力がないので既にあるものを3D化しよう、というコンセプトのもとにライブを作成したのであるが)

 

++++++アニメーションの構成方式

一つのアニメーションで管理するか、一つのアニメーションから小分けにしたアニメーションをコールして作るか。

前者の方式はアニメーションを作成するにつれ、アニメーションが複雑化していき、見通しが悪くなる。

後者の場合、見通しは良くなるが、アニメーションを持つオブジェクトをアクティブ化したときメッシュが一瞬見えてしまう、みたいな問題に遭遇した。Shaderで非表示にして回避した。

 ちなみに2フレーム目ではなく、デフォルトの非表示にしておき、1フレーム目で見えるようにしても問題なかった。

初心者による初心者のためのパーティクルライブの解説ーリンクリスト

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

 

書きかけー初心者による初心者のためのパーティクルライブの解説ー汎用的なテクニック編 - イラスト、モデリング、Unity、VR関連

初心者による初心者のためのパーティクルライブの解説ー概要

++パーティクルライブとは?

https://youtu.be/CJtYhj5t_08

こんなの。

音楽のPVを3次元空間上に拡張することにより、VRで閲覧出来るようになり、表現の多彩化、より強いインパクトを与えることが可能です。

初めて作ったライブですので、ショボい部分等多いですが、イメージは掴めるかと

 

++どこで公開するの?

動画のものはvrchatで撮影しております。

基本的にパーティクルライブはvrchat上で講演されています。

ヒメヒナのライブなど企業案件もあります。

VRが浸透すればよりパーティクルライブの技術は仕事としての需要も増えていくでしょう。

 

++誰が見てくれるの?

現状はvrchatの人々です。

vrchatは誰かにその場で直接作品を見てもらうのに非常に適した環境です。vrchatではパーティクルライブの他にもキャラクターの3DモデルやShader芸等も見せやいです。

ライブを作ってる人数は現状、まだ20~30人ほどであり、いわば黎明期であるため、作ったものを特に見てもらいやすい環境なのではないかと思います。

 

shader GPUインスタンシング付きunlit

なぜかunityが落ちるので供養にアップ

Shader "A-Sakura/Unlit" {
	Properties{
		[MaterialToggle] _IsShow("IsShow",Float) = 1
		_MainTex("MainTex",2D) = "white"{}
		_Color("Color",Color) = (1,0,0,1)
	}
	SubShader{
		Tags{"Queue" = "Transparent+71" "RenderType" = "Transparent"}
		Blend SrcAlpha OneMinusSrcAlpha

		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#pragma target 3.0
		 	#pragma multi_compile_instancing

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

			struct v2f {
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};

      float4 _MainTex_ST;
			sampler2D _MainTex;
			//bool _IsShow;

			UNITY_INSTANCING_BUFFER_START(Props)
				UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
				UNITY_DEFINE_INSTANCED_PROP(bool, _IsShow)
			UNITY_INSTANCING_BUFFER_END(Props)

			v2f vert(appdata v){
				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}

			fixed4 frag(v2f i) :SV_Target {
				UNITY_SETUP_INSTANCE_ID(i);
				if(!UNITY_ACCESS_INSTANCED_PROP(Props, _IsShow)){ clip(-1);return 0;}
				fixed4 c = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
				fixed alpha = tex2D(_MainTex,i.uv).a;
				return fixed4(c.rgb,alpha);

			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}

shader 半透明の円的なやつ、パーティクルで使う

Shader "Custom/ParticleCircle" {
	Properties{
		[HideInInspector]
		_Tex("Tex",2D) = "white" {}
		_Color("Color",Color) = (1,1,0,1)
		_R("R",Range(1,10)) = 1
		_MaxAlpha("MaxAlpha",Range(0,1)) = 0.8
	}
	SubShader{
		Tags{"Queue" = "Geometry+39"}
		Blend SrcAlpha OneMinusSrcAlpha

		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
			};

			struct v2f {
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
			};

			float4 _Color;
			float _MaxAlpha;
			float _R;

			v2f vert(appdata v){
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			float4 frag(v2f i) :SV_Target {
				float len = length(i.uv*2 - 1);
				len = lerp(0,_R,len);
				float4 c = _Color;
				c.a = clamp(_MaxAlpha - lerp(0,_MaxAlpha,log(len)),0,1);
				return c;

			}
			ENDCG
		}//Pass
	}//SubShader
	FallBack "Diffuse"
}