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

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

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;
	}