Nao_uの日記 このページをアンテナに追加 RSSフィード

2019-05-06

極座標シェーダー実験メモ 極座標シェーダー実験メモ - Nao_uの日記 を含むブックマーク はてなブックマーク - 極座標シェーダー実験メモ - Nao_uの日記 極座標シェーダー実験メモ - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20190506202125p:image

https://twitter.com/Cyanilux/status/1123944969125998592

Shader "Unlit/PolarCorrdinates"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_Rotate("Rotate", Float) = 0.0
		_RotateSpeed("RotateSpeed", Float) = 0.0
		_RadiusAdd("RadiusAdd", Float) = 0.0
		_RadiusSpeed("RadiusSpeed", Float) = 0.0
	}
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

			float _Rotate;
			float _RotateSpeed;
			float _RadiusAdd;
			float _RadiusSpeed;

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

            fixed4 frag (v2f i) : SV_Target
            {
				float2 uv = (i.uv * 2.0f) - float2(1,1);
				float r = 1.0 - length(uv);
				float theta = atan2(uv.y, uv.x)*(1.0f / (3.1415926535f*2.0f));
				
				r = pow(r+0.9, 2.0);
				float2 puv;
				puv.x = r + _RadiusAdd + _RadiusSpeed * _Time.x;
				puv.y = r + theta + _Rotate + _RotateSpeed * _Time.x;

                // sample the texture
                fixed4 col = tex2D(_MainTex, puv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);

				return col;
            }
            ENDCG
        }
    }
}

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190506

2019-05-05

Interleaved gradient noise Interleaved gradient noise - Nao_uの日記 を含むブックマーク はてなブックマーク - Interleaved gradient noise - Nao_uの日記 Interleaved gradient noise - Nao_uの日記 のブックマークコメント

レイマーチのアーティファクトを減らすのに使えそう

https://blog.demofox.org/2017/10/31/animating-noise-for-integration-over-time/

Interleaved gradient noise, which gives middle results, is actually very similar in generation costs as white noise believe it or not, and so can also be done in real time on either the CPU or GPU.

If you have X and Y pixel coordinates (not uv coordinates), you can generate the noise value for the pixel by using this formula:


float noise = std::fmodf(52.9829189f * std::fmodf(0.06711056f*float(x) + 0.00583715f*float


マテリアルシェーダーの実験ソースメモ マテリアルシェーダーの実験ソースメモ - Nao_uの日記 を含むブックマーク はてなブックマーク - マテリアルシェーダーの実験ソースメモ - Nao_uの日記 マテリアルシェーダーの実験ソースメモ - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20190506121430j:image

動画:https://twitter.com/Nao_u_/status/1125247333183057920

元ネタ:https://twitter.com/MrZulubo/status/1122611573510377472

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/TestShader2"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
		_MainTex("Albedo (RGB)", 2D) = "white" {}
		_Volume("Volume", 3D) = "" {}
		_SparkMap("SparkMap", 2D) = "white" {}
	//		_ParallaxMap("_ParallaxMap", 2D) = "white" {}
	
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
		_Distotion("Distotion", Float) = 0.5
		_Iteration("Iteration", int) = 5
	}
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows
		#pragma vertex vert
//		#pragma fragment frag

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.5

		sampler2D _MainTex;
		sampler2D _SparkMap;
		sampler3D _Volume;
		//		sampler2D _ParallaxMap;

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

		struct appdata
		{
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
			float3 normal : NORMAL;
			float4 tangent : TANGENT;
		};


		float _Distotion;
		int _Iteration;
		int _Type;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)


		struct Input {
			float2 uv_MainTex;
			float3 viewDirTangent;
			float4 screenPosition;
			float4 objPos;
			//UNITY_VPOS_TYPE vpos : VPOS;
		};

		void vert(inout appdata_full v, out Input o) {
			UNITY_INITIALIZE_OUTPUT(Input, o);

			float4 objCam = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0));
			float3 viewDir = v.vertex.xyz - objCam.xyz;
			float tangentSign = v.tangent.w * unity_WorldTransformParams.w;
			float3 bitangent = cross(v.normal.xyz, v.tangent.xyz) * tangentSign;
			o.viewDirTangent = float3(
				dot(viewDir, v.tangent.xyz),
				dot(viewDir, bitangent.xyz),
				dot(viewDir, v.normal.xyz)
				);

			o.screenPosition = ComputeScreenPos(v.vertex);
			o.objPos = UnityObjectToClipPos(v.vertex);
		}

		void surf(Input IN, inout SurfaceOutputStandard o)
		{
			// Interleaved gradient noiseでアーティファクトを消す実験
			float2 screenPos = IN.objPos.xy / IN.objPos.z;
			screenPos.xy *= 1;
			float x = screenPos.x;
			float y = screenPos.y*(16.0f / 9.0f);
			float ig_noise = frac(52.9829189f * frac(0.06711056f*float(x) + 0.00583715f*float(y)));
			float mm = 0.0001; // 100サンプルあるならいらないのでほとんど無効に
			float addNoize = -mm + (2 * mm *ig_noise);

			// テクスチャ歪み
			float2 warp = tex2D(_MainTex, -IN.uv_MainTex).rg;

			// パララックス
			float2 uv = IN.uv_MainTex;
			uv.x += _Time.x*-0.5;
			uv.y += _Time.x*-1.0;
			uv += warp*0.075;
			float parallax = 0;
			for (int j = 0; j < _Iteration; j++) {
				float ratio = (float)j / _Iteration;
				//float col = tex2D(_MainTex, uv + lerp(0, _Distotion, ratio+ addNoize) * normalize(IN.viewDirTangent)) * lerp(1, 0, ratio);
				float2 uv2 = uv + lerp(0, _Distotion, ratio + addNoize) * normalize(IN.viewDirTangent);
				float3 uv3 = float3(uv2.x, uv2.y, 0.5+_Time.x*2);
				float col = tex3D(_Volume, uv3) * lerp(1, 0, ratio)*1.0;

				if (col > ratio) {
					parallax +=  col;
				}
			}
			parallax /= _Iteration;

			// 適当に色を弄る
			fixed4 c = ((tex2D(_MainTex, IN.uv_MainTex+float2(_Time.x*-0.5,_Time.x*-1.1))-float4(0.2,0.5,0.5,0)) * 0.5) * float4(1, 0.5, 0.5, 1);
			o.Albedo = c.rgb + pow(parallax,1.7) * _Color.rgb*100;
			o.Albedo.gb = pow(o.Albedo.gb + float2(0.2, 0.1), 2.5);
			o.Albedo.r += c.r * 1.25;

			// 光の粒(3レイヤー)
			float4 spk_col0 = float4(1.0, 1.0, 1.0, 1);
			float4 spk_col1 = float4(2.0, 1.0, 2.0, 1);
			float4 spk_col2 = float4(2.0, 1.5, 2.0, 1);
			{
				float depth = 2.0;
				float2 uv = IN.uv_MainTex + float2(_Time.x * -3.1, _Time.x * -1.05);
				float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col0;
				o.Albedo += spk.rgb * 2;
			}
			{
				float depth = 0.5;
				float2 uv = IN.uv_MainTex + float2(_Time.x * 1.25, _Time.x * 0.25);
				float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col1;
				o.Albedo += spk.rgb * 3;
			}
			{
				float depth = 0.25;
				float2 uv = IN.uv_MainTex + float2(_Time.x * -0.20, _Time.x * -0.3);
				float4 spk = tex2D(_SparkMap, uv + depth * normalize(IN.viewDirTangent)) * spk_col2;
				o.Albedo += spk.rgb * 2;
			}

			// Metallic and smoothness come from slider variables
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}


        ENDCG
    }
    FallBack "Diffuse"
}


トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190505

2019-04-29

Houdini PDG 基本チュートリアル「都市を構築するためのタスク ワークフローを作成する」 Houdini PDG 基本チュートリアル「都市を構築するためのタスク ワークフローを作成する」 - Nao_uの日記 を含むブックマーク はてなブックマーク - Houdini PDG 基本チュートリアル「都市を構築するためのタスク ワークフローを作成する」 - Nao_uの日記 Houdini PDG 基本チュートリアル「都市を構築するためのタスク ワークフローを作成する」 - Nao_uの日記 のブックマークコメント

https://support.borndigital.co.jp/hc/ja/articles/360000229582-Houdini-PDG-%E5%9F%BA%E6%9C%AC%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB-%E9%83%BD%E5%B8%82%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%82%BF%E3%82%B9%E3%82%AF-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-

なんかROP_Geometry_outputとかでファイルに吐き出したあとにファイルが壊れてたりうまく読めなかったりすることがある?Houdiniを閉じて再起動したり、ちゃんとキャッシュされているかFileノードで読み込んだ後は動く、みたいなことがあった。よくわからない

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190429

2019-03-10

[][]新居の間取りVR 新居の間取りVR - Nao_uの日記 を含むブックマーク はてなブックマーク - 新居の間取りVR - Nao_uの日記 新居の間取りVR - Nao_uの日記 のブックマークコメント

新居の間取りを図面からモデリングしてVRで確認。壁や家具の配置も簡単に変えられて、トイレやロフトなど図面だけでは広さが実感しにくい所もわかりやすく体感できるので、とても役に立った


スイッチの位置や家事の動線も部屋の中を実際に歩きながら確認できるし、家具や壁紙の色を変えたらどんな雰囲気なるのかもすぐ見れる。部屋の実際の広さは図面の数字だけでは実感しづらいので、こういった用途にVRはほんと最適だと思った


新居の間取りをVRで確認しつつ決めて、今週末の引っ越しのために現地を見に行ったら、ちょうどVRで見たものと同じものがそのまま出来上がっててちょっと不思議な感覚。2Dの図面や平面のCGではわからない部屋のスケール感や光源の具合までちゃんと確認できるので、ほんとVR向きな案件だなぁ、と。


https://twitter.com/Nao_u_/status/1104573498066853888

家のモデリングにはHoudiniを使用。図面に変更があった時にも、大元の枠組みだけ変えれば簡単に修正できるので、プロシージャルモデリングの便利さを実感。


f:id:Nao_u:20190310125218p:image

外構工事の検討もUnityでレイアウトしてVRで確認してた。Unityなら簡単に複数パターンの配置を切り替えながら試せて、HMDを通してみると2DのCGで見るのとけっこう印象が違ってたり、塀の高さを変えたら家の中がどう見えるかの違いなども検討できたりなど、ここでもVRは有用だった

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190310

2019-02-02

次のマップ 次のマップ - Nao_uの日記 を含むブックマーク はてなブックマーク - 次のマップ - Nao_uの日記 次のマップ - Nao_uの日記 のブックマークコメント

構想のラクガキ

f:id:Nao_u:20190202163152p:image


とりあえず概形だけつくって長さを確認。ちょっと長いけどおおむね許容範囲かな?

f:id:Nao_u:20190202163146p:image

[]連続したnullをObject Mergeで参照する方法 連続したnullをObject Mergeで参照する方法 - Nao_uの日記 を含むブックマーク はてなブックマーク - 連続したnullをObject Mergeで参照する方法 - Nao_uの日記 連続したnullをObject Mergeで参照する方法 - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20190210124155p:image

Object Merge SOPのオブジェクト名にはワイルドカードが使える

TransformをInto This Objectにすると、そのオブジェクトのtransformを反映した座標を取ってこれる


これでnullにnormalを追加すれば、nullを編集することで回転情報のattributeが付いた連番の点が定義できるので、道路の傾きを自由に設定できるような仕組みが作れるはず。


点の増減はpythonでスクリプトを書く必要がある。


[]point列をカーブに変換する方法 point列をカーブに変換する方法 - Nao_uの日記 を含むブックマーク はてなブックマーク - point列をカーブに変換する方法 - Nao_uの日記 point列をカーブに変換する方法 - Nao_uの日記 のブックマークコメント

https://www.sidefx.com/forum/topic/42371/

https://forums.odforce.net/topic/29278-make-curve-in-vex/

addのあとFit SOPでカーブにできる

f:id:Nao_u:20190216132229p:image

FItはinterpolateでscopeをbreakpointにしないと必要以上に補間される

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190202

2019-01-25

Tofu Racer2 Tofu Racer2 - Nao_uの日記 を含むブックマーク はてなブックマーク - Tofu Racer2 - Nao_uの日記 Tofu Racer2 - Nao_uの日記 のブックマークコメント


https://unityroom.com/games/tofuracer2

とりあえずできたことにする。


通信回りのメモ 通信回りのメモ - Nao_uの日記 を含むブックマーク はてなブックマーク - 通信回りのメモ - Nao_uの日記 通信回りのメモ - Nao_uの日記 のブックマークコメント

ついでに前作Tofu Racerのランキングが正常に表示されなくなっていた問題も修正しました。一年以上放置してたら、ランキング登録数が増えた時に限界を超えるとおかしくなるバグがあることに気づいてなかった…


ランキングの実装は前作はGoogleスプレッドシートをDBとして使用してたんだけど、続編のランキング実装時に前作がちゃんと動かなくなってることに気づき、Google側の仕様が変わってたら面倒なので別のやり方を調べた結果、今回はNiftyCloudを採用。制限付きだけど無料で使えて便利そうだったので。


ニフクラはGoogleより通信速度がだいぶ早くてAPIも整ってて使いやすいし、無料版の制限もAPIアクセスの上限が100万回/月だったので問題ないだろうと思ってたら、初日だけでAPIが6万回も叩かれてて状況によっては制限に引っかかる可能性がありそうな使い方になってたところはちょっと想定外だった


ログを確認すると、初日だけで前作の累計に匹敵する2000人近いアクセスがあり、その中の上位10人だけ数えてもリトライ回数の合計が約9000回あったため、リトライのたびに状態をサーバに送ってるせいでAPIリクエスト数が想定以上に増えてたのはちょっと誤算だった。Googleは制限なしなので気楽に使える


一方でニフクラだと送受信が早いうえにDBに配列を入れたりファイルを送ることもできるので、リプレイの保存などのGoogleでは厳しい仕様も実装できるのは明確なメリット。次があるならゴーストは実装してみたいけど、容量制限はあるので工夫無しになんでもかんでもサーバに送ると簡単に破綻しそう。


ネットワークが絡むゲームも作ってみたいけどリアルタイム通信が必要だと簡単に過疎るのが目に見えてるので、他人のプレイが非同期に影響するようなものの方がよさそうかなとか以前から思ってて、ニフクラの仕様をちゃんと見てないけどこれを使えばいろいろやりたかったことが実装できそうな気はする


絵に関するメモ 絵に関するメモ - Nao_uの日記 を含むブックマーク はてなブックマーク - 絵に関するメモ - Nao_uの日記 絵に関するメモ - Nao_uの日記 のブックマークコメント

今回このゲームを作った目的の一つに「Houdiniである程度の規模の背景を作るノウハウを溜める」があって、この点については一定レベルの成果は出せたように思う。あと「テクスチャを一切貼らない」ことでマテリアルについてはほぼ何も考えなくてもよくなるので、相当なコストが削減できた


一人でゲームを作るときにはAssetStoreがすごく便利で、前作も既成コースのアセットをそのまま使ってたけどこれに頼りきるとアセットの改変が一切できなくて困る。かといってちゃんとしたアセットの自作はかなり大変なので、生ポリゴンでそれっぽく見える表現ができるなら製作コストを大幅に抑えられる


今回はコンセプト的にフラットシェーディング+影くらいまでならOKだが、スペキュラやGI要素を加えるとちょっと欲しい絵とは違うものになったのでやらなかったけど、「テクスチャを貼らない」縛りだけで今時風のいろんな要素を加えた形で低コストでそれなりに見える絵にできないかは模索してみたい

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20190125

2018-12-08

ボクセルから回転したドット絵のパターンを作る実験 ボクセルから回転したドット絵のパターンを作る実験 - Nao_uの日記 を含むブックマーク はてなブックマーク - ボクセルから回転したドット絵のパターンを作る実験 - Nao_uの日記 ボクセルから回転したドット絵のパターンを作る実験 - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20181209013346p:image

ボクセル化したR-9のドット絵を傾けて正射影レンダリングした時にどのくらい元のドット絵と一致するかを実験。右上がオリジナルのドット絵。もっと破綻するかと思ってたけど案外いけてる。このボクセルをベースにモデリングすれば、低解像度描画時にドット絵と一致するモデルが作れたりするかな?

奥行方向は再現できてなくて、黄色い銃やブースターは左右で分離する必要がありそう。とはいえ適当に立体化して傾けただけでもそれなりに一致してるので、32x16の限られたドットに傾いた絵の情報が立体としてちゃんと把握できる構造になってて、ドット絵に込められた情報量の凄さをあらためて再認識。


f:id:Nao_u:20181209013345p:image

ボクセル化はHoudiniでAttribute from Mapで取り込んだ絵を適当にPolyExpandで伸ばしたものをUnityでレンダリング。気分転換という名目の現実逃避にちょうどいい作業量だったので、余裕ができたらこれをベースにちゃんとモデリングしてみたい


f:id:Nao_u:20181209013347g:image

ちょうど15度傾けたところで上下の端はそのままに内部構造だけが1ドット上に上がってて、元画像の上傾きの絵と動きがだいたい一致してた。ドット絵を描く人はこういうのを脳内で計算しながらやってるんだなぁ、と。

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181208

2018-11-27

カメラが動いてもちらつきにくいディザパターンの作り方 カメラが動いてもちらつきにくいディザパターンの作り方 - Nao_uの日記 を含むブックマーク はてなブックマーク - カメラが動いてもちらつきにくいディザパターンの作り方 - Nao_uの日記 カメラが動いてもちらつきにくいディザパターンの作り方 - Nao_uの日記 のブックマークコメント

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181127

2018-11-16

「無限に都市が生成されるアルゴリズム」で生成された都市を自由に歩き回ってみた 「無限に都市が生成されるアルゴリズム」で生成された都市を自由に歩き回ってみた - Nao_uの日記 を含むブックマーク はてなブックマーク - 「無限に都市が生成されるアルゴリズム」で生成された都市を自由に歩き回ってみた - Nao_uの日記 「無限に都市が生成されるアルゴリズム」で生成された都市を自由に歩き回ってみた - Nao_uの日記 のブックマークコメント

「Wave Function Collapse algorithm(波動関数崩壊アルゴリズム)」と名付けられたアルゴリズムは、入力ビットマップに類似したビットマップをローカルに生成するという仕組み。RPGのマップのようなマップを描くことも可能で、三次元マップにも応用できる

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181116

2018-11-15

今さら聞けないGAN(1) 基本構造の理解 今さら聞けないGAN(1) 基本構造の理解 - Nao_uの日記 を含むブックマーク はてなブックマーク - 今さら聞けないGAN(1) 基本構造の理解 - Nao_uの日記 今さら聞けないGAN(1) 基本構造の理解 - Nao_uの日記 のブックマークコメント


【入門者向け解説】プーリング処理入門(TensorFlowで説明) 【入門者向け解説】プーリング処理入門(TensorFlowで説明) - Nao_uの日記 を含むブックマーク はてなブックマーク - 【入門者向け解説】プーリング処理入門(TensorFlowで説明) - Nao_uの日記 【入門者向け解説】プーリング処理入門(TensorFlowで説明) - Nao_uの日記 のブックマークコメント

畳み込みニューラルネットワークの基礎 畳み込みニューラルネットワークの基礎 - Nao_uの日記 を含むブックマーク はてなブックマーク - 畳み込みニューラルネットワークの基礎 - Nao_uの日記 畳み込みニューラルネットワークの基礎 - Nao_uの日記 のブックマークコメント

わかりやすい解説記事

レトロゲームエンジン Pyxel でプログラミングを始めよう! レトロゲームエンジン Pyxel でプログラミングを始めよう! - Nao_uの日記 を含むブックマーク はてなブックマーク - レトロゲームエンジン Pyxel でプログラミングを始めよう! - Nao_uの日記 レトロゲームエンジン Pyxel でプログラミングを始めよう! - Nao_uの日記 のブックマークコメント

かなりシンプルに絵が出せそうなので、機械学習結果のビジュアライズや、学習データを作るための簡単なゲーム開発環境として使えたりしないか?

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181115

2018-11-12

KerasでDeep Learning:KerasでMNISTデータを扱ってみる KerasでDeep Learning:KerasでMNISTデータを扱ってみる - Nao_uの日記 を含むブックマーク はてなブックマーク - KerasでDeep Learning:KerasでMNISTデータを扱ってみる - Nao_uの日記 KerasでDeep Learning:KerasでMNISTデータを扱ってみる - Nao_uの日記 のブックマークコメント

定番のConvolutional Neural Networkをゼロから理解する 定番のConvolutional Neural Networkをゼロから理解する - Nao_uの日記 を含むブックマーク はてなブックマーク - 定番のConvolutional Neural Networkをゼロから理解する - Nao_uの日記 定番のConvolutional Neural Networkをゼロから理解する - Nao_uの日記 のブックマークコメント

Kerasによるデータ拡張 Kerasによるデータ拡張 - Nao_uの日記 を含むブックマーク はてなブックマーク - Kerasによるデータ拡張 - Nao_uの日記 Kerasによるデータ拡張 - Nao_uの日記 のブックマークコメント

ImageDataGeneratorの使い方

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181112

2018-11-04

Colaboratryで作ったphythonコードをローカルのJupyter Notebookで動かそうとしてハマったときのメモ。

Windows10でTensorflowとKerasをインストールしようとしてハマった話 Windows10でTensorflowとKerasをインストールしようとしてハマった話  - Nao_uの日記 を含むブックマーク はてなブックマーク - Windows10でTensorflowとKerasをインストールしようとしてハマった話  - Nao_uの日記 Windows10でTensorflowとKerasをインストールしようとしてハマった話  - Nao_uの日記 のブックマークコメント

pip install tensorflow

でインストールしたtensorflowが「ダイナミック リンク ライブラリ (DLL) 初期化ルーチンの実行に失敗しました。」というエラーで動かず、

conda install tensorflow

で動いた。

たぶん vs2015_runtime: 14.0.25123-0 --> 14.0.25420-0 が入ったおかげかも。

こういう罠にはまらないのでColaboratoryは便利。

mnistのサンプルで TypeError: softmax() got an unexpected keyword argument ‘axis’というエラーが出る mnistのサンプルで TypeError: softmax() got an unexpected keyword argument ‘axis’というエラーが出る - Nao_uの日記 を含むブックマーク はてなブックマーク - mnistのサンプルで TypeError: softmax() got an unexpected keyword argument ‘axis’というエラーが出る - Nao_uの日記 mnistのサンプルで TypeError: softmax() got an unexpected keyword argument ‘axis’というエラーが出る - Nao_uの日記 のブックマークコメント

model.add(Dense(10, activation='softmax'))

を実行すると、kerasがバージョン2.1.6だとエラーが出るらしい。2.1.3に戻すとそのまま通る

pip install keras==2.1.3

手書きひらがなの認識で99.78%の精度をディープラーニングで 手書きひらがなの認識で99.78%の精度をディープラーニングで - Nao_uの日記 を含むブックマーク はてなブックマーク - 手書きひらがなの認識で99.78%の精度をディープラーニングで - Nao_uの日記 手書きひらがなの認識で99.78%の精度をディープラーニングで - Nao_uの日記 のブックマークコメント


Deep learningで画像認識⑦〜Kerasで畳み込みニューラルネットワーク Deep learningで画像認識⑦〜Kerasで畳み込みニューラルネットワーク - Nao_uの日記 を含むブックマーク はてなブックマーク - Deep learningで画像認識⑦〜Kerasで畳み込みニューラルネットワーク - Nao_uの日記 Deep learningで画像認識⑦〜Kerasで畳み込みニューラルネットワーク - Nao_uの日記 のブックマークコメント

Kerasでは、「ImageDataGenerator」というクラスが用意されており、元画像に移動、回転、拡大・縮小、反転などの人為的な操作を加えることによって、画像数を増やすことができます

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20181104

2018-06-30 このエントリーを含むブックマーク このエントリーのブックマークコメント

フォトグラメトリの実験として、iPhoneで撮った動画を3DF Zephyrで3D化したものをUnityでVR表示してみた。デフォルト設定でそのまま変換しただけでも予想以上に高精度で形状の破綻も少なく、まつ毛くらいの細かさまでちゃんと識別できるくらいに再現できてる

f:id:Nao_u:20180701030037p:image


今回は一分半くらいの動画から500枚を切り出して加工したんだけど、このくらいの枚数があれば十分っぽい。写真だとシャッター音で目が覚めることもあるし、枚数を取るのも大変なので動画からの切り出しでどこまでできるか気になってた。切り出した画像に多少ボケたものが混ざっててもあまり問題はないっぽい

f:id:Nao_u:20180701030050p:image


子供のスケール感は時間がたつと忘れてしまいそうなので、今のうちに3D化して保存しておいて、後でVRで比較できるようにしておきたくて、これまでも定期的にいろんな角度からの写真だけ撮り溜めてたけど、写真を大量に撮るより動画のほうがだいぶ楽なので今後は気軽に撮れそう。欠点は寝てるときしか撮れないことか

f:id:Nao_u:20180701030043p:image

VRが当たり前になったら、適当に撮った動画をサーバに送って3D化してVRで見る、みたいなサービスも当たり前になったりするのかな。周りからぐるぐる撮るだけでいいので「ちょっとめんどくさいパノラマ写真」くらいの感覚で3D空間を切り取って保存したりできそう。


静止画で見てもぱっと見で写真と区別がつかないくらいの品質のものが、そのままくるくる回せるのは結構なインパクトが。フォトグラメトリも4年前に試してた時より色々進歩してる。Houdiniが使えるようになったおかげで後処理もかなりやりやすくなった

http://game.g.hatena.ne.jp/Nao_u/00140312

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20180630

2018-05-03

最近は子供が昼寝から起きたら作業中断になるので昼間はほぼ何もできない…

[]プリミティブ端のエッジを除去して中のラインだけ残す プリミティブ端のエッジを除去して中のラインだけ残す - Nao_uの日記 を含むブックマーク はてなブックマーク - プリミティブ端のエッジを除去して中のラインだけ残す - Nao_uの日記 プリミティブ端のエッジを除去して中のラインだけ残す - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20180504010944p:image

convertLineを参考に。

int n[] = neighbours(1, @ptnum);

foreach(int pt; n){

int e0 = inpointgroup(1, "edge", @ptnum);

int e1 = inpointgroup(1, "edge", pt);

if( (e0==0 || e1==0) && pt<@ptnum){

int pr = addprim(geoself(), "polyline");

addvertex(geoself(), pr, @ptnum);

addvertex(geoself(), pr, pt);

}

}


追記:上記だとまずいパターンがあった。単純なvoronoiであれば問題ないが、複数の分割が重なって、エッジの中央に他のポリゴンの点があるなど、共有されない頂点で割られている時にうまく動かない

f:id:Nao_u:20180505174003p:image

そういう形状の時は、いったん綺麗な形のポリゴンになるように前処理してやる必要がある

  • scatter→voronoifractureだと裏面ポリゴンが生まれるケースが多いので、deleteで裏面を削除してから作業開始
  • エッジが共有されていない時には、groupのunshared Edgesがうまく動かないので、fuseで連結した後にcleanで重複したラインやポリゴンを削除してから実行する必要がある

追記2:さらにまずいパターンを発見。エッジが共有されていない分割だと、Group SOPのエッジ検出がポリゴンの内側にエッジがあるとみなしてしまっておかしくなる

f:id:Nao_u:20180505215210p:image

対策として、ConvertLineしたラインの向きベクトルを微小にしたものから計算した、左右斜め前両方のポジションでレイキャストしてどちらかが抜けてたら弾く、という処理にしてみた。

float delta = 0.01;

int pn0 = primpoint(0,@primnum,0);

int pn1 = primpoint(0,@primnum,1);

vector p0 = point(0,"P",pn0);

vector p1 = point(0,"P",pn1);

vector dirVec = normalize(p1-p0) * delta;

vector crossVec = dirVec;

crossVec.x = dirVec.z;

crossVec.z = dirVec.x;

vector chkPos = p0;

chkPos.y = delta;

vector chkDir = {0,-1,0};

vector cp0 = chkPos+(dirVec+crossVec);

vector cp1 = chkPos+(dirVec-crossVec);

vector retPos;

float retU, retV;

int ck_l = intersect(1, cp0, chkDir, retPos, retU, retV);

int ck_r = intersect(1, cp1, chkDir, retPos, retU, retV);

if( ck_l == -1 || ck_r == -1){

removeprim(geoself(), @primnum, 0);

}

余りに鋭角なポリゴンだと検出点に引っかからない可能性はあるが、それ以外はたぶんこれでほぼどんな形状になっても大丈夫?


[]polyExpand2Dで失敗するケースへの対策 polyExpand2Dで失敗するケースへの対策 - Nao_uの日記 を含むブックマーク はてなブックマーク - polyExpand2Dで失敗するケースへの対策 - Nao_uの日記 polyExpand2Dで失敗するケースへの対策 - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20180506154438p:image

上記で作ったLineをpolyExpand2Dでポリゴン化しようとすると、重複したラインがある為にそのままでは失敗する。

intersectionStichで交点で分割することで、長いポリゴンの辺になっていて、間に点のある重複したラインを分割できる

f:id:Nao_u:20180506154510p:image

実用的な複雑な形状だと、intersectionStichしても失敗するケースがある。

その時は、intersectionStich → fuse → intersectionStich とつなぐことで、polyExpand2Dが成功するようになる

これで、ブロック内を任意のポリゴンで分割したときに、間にできる道をpolyExpand2Dで作ることができるようになる…

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20180503

2018-05-02

[]プリミティブ内の最長ラインを検索 プリミティブ内の最長ラインを検索 - Nao_uの日記 を含むブックマーク はてなブックマーク - プリミティブ内の最長ラインを検索 - Nao_uの日記 プリミティブ内の最長ラインを検索 - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20180504010938p:image

先端になるpoint配列を生成してインデクスをbasePtNumのattributeに詰めて、findshortestpathのStart PointsとEnd Pointsを、

`point("../pointwrangle3/",detail("../foreach_count1/","iteration",0),"basePtNum",0)`

みたいな形でインデクスを二重ループで取り出した。

findshortestpathのStart PointsとEnd Pointsは文字列なので `` で括る必要があったが、よく見たら Output Pathsに「Fron any start ton any end」って項目があったので、もしかして頂点番号リストを文字列で渡せば二重ループはいらない?要検証。

元ネタ:

https://twitter.com/veltman/status/973570650429206528

https://bl.ocks.org/veltman/403f95aee728d4a043b142c52c113f82

トラックバック - http://game.g.hatena.ne.jp/Nao_u/20180502