public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { // 行列の場合は、それぞれCameraかLightか調べる。 EffectVariable Objectアノテーション = EffectParseHelper.アノテーションを取得する(variable, "Object", "string"); string obj = (Objectアノテーション == null) ? "" : Objectアノテーション.AsString().GetString(); // アノテーションが存在しない時は""とする switch (obj.ToLower()) { case "camera": return(行列変数登録インスタンスを生成して返す(Object種別.カメラ)); case "light": return(行列変数登録インスタンスを生成して返す(Object種別.ライト)); case "": return(行列変数登録インスタンスを生成して返す(Object種別.カメラ)); // 既定値 default: throw new InvalidMMEEffectShader例外( $"変数「{variable.TypeInfo.Description.TypeName.ToLower()} {variable.Description.Name}:{variable.Description.Semantic}」には、" + $"アノテーション「string Object=\"Camera\"」または、「string Object=\"Light\"」が必須ですが指定されたのは「string Object=\"{obj}\"」でした。(スペルミス?)"); } }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { var subscriber = new CURRENTSCENECOLOR変数(); // この時点ではまだ Texture2D は作成しない。 return(subscriber); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { var manager = new 定数バッファ管理 <定数バッファレイアウト>(); manager.初期化する( (EffectConstantBuffer)variable, new 定数バッファレイアウト(), 定数バッファレイアウト.SizeInBytes); return(new BASICMATERIALCONSTANT変数(manager)); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { var subscriber = new RENDERDEPTHSTENCILTARGET変数(); int width, height, depth, mip; Format textureFormat, viewFormat, resourceFormat; テクスチャのアノテーション解析.解析する(variable, Format.D24_UNorm_S8_UInt, new Vector2(1f, 1f), false, out width, out height, out depth, out mip, out textureFormat, out viewFormat, out resourceFormat); // テクスチャの作成 var tex2DDesc = new Texture2DDescription() { ArraySize = 1, BindFlags = BindFlags.DepthStencil | BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Format = textureFormat, Height = height, Width = width, MipLevels = mip, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; subscriber._depthStencilTexture = new Texture2D(RenderContext.Instance.DeviceManager.D3DDevice, tex2DDesc); // レンダーリソースビューの作成 var viewDesc = new DepthStencilViewDescription() { Format = viewFormat, Dimension = DepthStencilViewDimension.Texture2D, }; subscriber._depthStencilView = new DepthStencilView(RenderContext.Instance.DeviceManager.D3DDevice, subscriber._depthStencilTexture, viewDesc); // シェーダリソースビューの作成 var shaderDesc = new ShaderResourceViewDescription() { Format = resourceFormat, Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D, Texture2D = new ShaderResourceViewDescription.Texture2DResource() { MipLevels = 1, MostDetailedMip = 0, }, }; subscriber._shaderResource = new ShaderResourceView(RenderContext.Instance.DeviceManager.D3DDevice, subscriber._depthStencilTexture, shaderDesc); effect.深度ステンシルビューのマップ.Add(variable.Description.Name, subscriber._depthStencilView); return(subscriber); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { EffectVariable annotation = variable.GetAnnotationByName("SyncInEditMode"); bool syncMode = false; if (annotation != null) { syncMode = (annotation.AsScalar().GetInt() == 1); } return(時間変数登録インスタンスを生成して返す(syncMode)); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effectManager, int semanticIndex) { // アノテーション "string Object = ..." を取得 EffectVariable annotation = EffectParseHelper.アノテーションを取得する(variable, "Object", "string"); if (annotation == null || string.IsNullOrWhiteSpace(annotation.AsString().GetString())) { throw new InvalidMMEEffectShader例外( string.Format( "変数「{0} {1}:{2}」にはアノテーション「string Object=\"Light\"」または「string object=\"Camera\"」が必須ですが指定されませんでした。", variable.TypeInfo.Description.TypeName.ToLower(), variable.Description.Name, variable.Description.Semantic)); } // Object の内容で type を決める。 Object種別 type; string objectStr = annotation.AsString().GetString().ToLower(); switch (objectStr) { case "camera": type = Object種別.カメラ; break; case "light": type = Object種別.ライト; break; default: throw new InvalidMMEEffectShader例外( string.Format( "変数「{0} {1}:{2}」にはアノテーション「string Object=\"Light\"」または「string object=\"Camera\"」が必須ですが指定されたのは,「string object=\"{3}\"でした。(スペルミス?)", variable.TypeInfo.Description.TypeName.ToLower(), variable.Description.Name, variable.Description.Semantic, objectStr)); } // 決定された type へ引き継ぐ。 return(GetSubscriberInstance(type)); }
private void _ScriptCodeを解析する(エフェクト effect, テクニック technique = null, パス pass = null) { 実行するファンクションのリスト = new List <関数>(); if (string.IsNullOrWhiteSpace(ScriptCode)) { return; } string[] splittedFunctions = ScriptCode.Split(';'); // ';' で分割し1命令ごとにする foreach (string function in splittedFunctions) { if (string.IsNullOrWhiteSpace(function)) { continue; } int 連番 = 0; // 省略時は 0 string[] segments = function.Split('='); // '=' で分割し、関数名と引数を分ける if (segments.Length > 2) { throw new InvalidMMEEffectShader例外("スクリプト中の'='の数が多すぎます。"); } char 関数名の末尾の文字 = segments[0][segments[0].Length - 1]; if (char.IsNumber(関数名の末尾の文字)) { segments[0] = segments[0].Remove(segments[0].Length - 1); 連番 = int.Parse(関数名の末尾の文字.ToString()); } if (現在対応しているファンクションの一覧.ContainsKey(segments[0])) { 実行するファンクションのリスト.Add( 現在対応しているファンクションの一覧[segments[0]].ファンクションインスタンスを作成する(連番, segments[1], this, effect, technique, pass) ); } } }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable d3dEffectVariable, エフェクト effect, int semanticIndex) { bool isVector3 = d3dEffectVariable.TypeInfo.Description.TypeName.ToLower().Equals("float3"); if (!_Objectアノテーションが必須なセマンティクス.Contains(セマンティクス)) { // (A) Object アノテーションが不要なセマンティクスの場合 return(材質変数登録インスタンスを生成して返す(ターゲット種別.未使用, isVector3)); } else { // (B) Object アノテーションが必須のセマンティクスの場合 EffectVariable Objectアノテーション = EffectParseHelper.アノテーションを取得する(d3dEffectVariable, "Object", "string"); if (Objectアノテーション == null) { throw new InvalidMMEEffectShader例外($"このセマンティクス\"{セマンティクス}\"にはアノテーション「Object」が必須ですが、記述されませんでした。"); } string annotation = Objectアノテーション.AsString().GetString().ToLower(); if (string.IsNullOrWhiteSpace(annotation)) { throw new InvalidMMEEffectShader例外($"このセマンティクス\"{セマンティクス}\"にはアノテーション「Object」が必須ですが、記述されませんでした。"); } switch (annotation) { case "geometry": return(材質変数登録インスタンスを生成して返す(ターゲット種別.ジオメトリ, isVector3)); case "light": return(材質変数登録インスタンスを生成して返す(ターゲット種別.ライト, isVector3)); default: throw new InvalidMMEEffectShader例外($"アノテーション\"{annotation}\"は認識されません。"); } } }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { return(new TESSFACTOR変数()); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { var subscriber = new テクスチャ変数(); string typeName = variable.TypeInfo.Description.TypeName.ToLower(); int width, height, depth, mip; Format textureFormat, viewFormat, resourceFormat; テクスチャのアノテーション解析.解析する(variable, Format.B8G8R8A8_UNorm, Vector2.Zero, true, out width, out height, out depth, out mip, out textureFormat, out viewFormat, out resourceFormat); EffectVariable rawTypeVariable = EffectParseHelper.アノテーションを取得する(variable, "ResourceType", "string"); EffectVariable rawStringVariable = EffectParseHelper.アノテーションを取得する(variable, "ResourceName", "string"); // type を決定 string type; if (rawTypeVariable != null) { switch (rawTypeVariable.AsString().GetString().ToLower()) { case "cube": type = (typeName.Equals("texturecube")) ? "texturecube" : throw new InvalidMMEEffectShader例外("ResourceTypeにはCubeが指定されていますが、型がtextureCUBEではありません。"); break; case "2d": type = (typeName.Equals("texture2d") || typeName.Equals("texture")) ? "texture2d" : throw new InvalidMMEEffectShader例外("ResourceTypeには2Dが指定されていますが、型がtexture2Dもしくはtextureではありません。"); break; case "3d": type = (typeName.Equals("texture3d")) ? "texture3d" : throw new InvalidMMEEffectShader例外("ResourceTypeには3Dが指定されていますが、型がtexture3dではありません。"); break; default: throw new InvalidMMEEffectShader例外("認識できないResourceTypeが指定されました。"); } } else { type = typeName; } // テクスチャリソースを読み込む if (rawStringVariable != null) { string resourceName = rawStringVariable.AsString().GetString(); Stream stream; switch (type) { case "texture2d": stream = effect.テクスチャなどのパスの解決に利用するローダー.リソースのストリームを返す(resourceName); if (stream != null) { subscriber._resourceTexture = MMFTexture2D.FromStream(RenderContext.Instance.DeviceManager.D3DDevice, stream); } break; case "texture3d": stream = effect.テクスチャなどのパスの解決に利用するローダー.リソースのストリームを返す(resourceName); if (stream != null) { subscriber._resourceTexture = MMFTexture3D.FromStream(RenderContext.Instance.DeviceManager.D3DDevice, stream); } break; case "texturecube": //TODO CUBEの場合を実装する //stream = effectManager.SubresourceLoader.getSubresourceByName(resourceName); //subscriber.resourceTexture=.FromStream(context.DeviceManager.Device, stream, (int)stream.Length); break; } } // シェーダーリソースビューを割り当て subscriber._resourceView = new ShaderResourceView(RenderContext.Instance.DeviceManager.D3DDevice, subscriber._resourceTexture); return(subscriber); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { return(new MOUSEPOSITION変数()); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { var subscriber = new RENDERCOLORTARGET変数(); _variableName = variable.Description.Name; int width, height, depth, mip; Format textureformat, viewFormat, resourceFormat; テクスチャのアノテーション解析.解析する(variable, Format.R8G8B8A8_UNorm, new Vector2(1f, 1f), false, out width, out height, out depth, out mip, out textureformat, out viewFormat, out resourceFormat); if (depth != -1) { throw new InvalidMMEEffectShader例外(string.Format("RENDERCOLORTARGETの型はTexture2Dである必要があるためアノテーション「int depth」は指定できません。")); } // テクスチャの作成 var tex2DDesc = new Texture2DDescription() { ArraySize = 1, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Format = textureformat, Height = height, Width = width, MipLevels = mip, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; subscriber._renderTexture = new Texture2D(RenderContext.Instance.DeviceManager.D3DDevice, tex2DDesc); // レンダーリソースビューの作成 var viewDesc = new RenderTargetViewDescription() { Format = viewFormat, Dimension = RenderTargetViewDimension.Texture2D, }; subscriber._renderTarget = new RenderTargetView(RenderContext.Instance.DeviceManager.D3DDevice, subscriber._renderTexture, viewDesc); // シェーダリソースビューの作成 var shaderDesc = new ShaderResourceViewDescription() { Format = resourceFormat, Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D, Texture2D = new ShaderResourceViewDescription.Texture2DResource() { MipLevels = 1, MostDetailedMip = 0, }, }; subscriber._shaderResource = new ShaderResourceView(RenderContext.Instance.DeviceManager.D3DDevice, subscriber._renderTexture, shaderDesc); effect.レンダーターゲットビューのマップ.Add(_variableName, subscriber._renderTarget); return(subscriber); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new Pass関数(); if (technique == null) { throw new InvalidMMEEffectShader例外("スクリプト内でPassを利用できるのはテクニックに適用されたスクリプトのみです。パスのスクリプトでは実行できません。"); } // このメソッドの引数のパスは使わない。 if (!technique.パスリスト.ContainsKey(value)) { throw new InvalidMMEEffectShader例外($"スクリプトで指定されたテクニック中では指定されたパス\"{value}\"は見つかりませんでした。(スペルミス?)"); } func._実行対象のパス = technique.パスリスト[value]; return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public abstract 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass);
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new LoopEnd関数(); return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new LoopByCount関数(); func._runtime = runtime; if (string.IsNullOrWhiteSpace(value)) { throw new InvalidMMEEffectShader例外("LoopByCount=;(空文字列)は指定できません。int,float,boolいずれかの変数名を伴う必要があります。"); } EffectVariable d3dVariable = effect.D3DEffect.GetVariableByName(value); string typeName = d3dVariable.TypeInfo.Description.TypeName.ToLower(); int loopCount = 0; switch (typeName) { case "bool": case "int": loopCount = d3dVariable.AsScalar().GetInt(); break; case "float": loopCount = (int)d3dVariable.AsScalar().GetFloat(); break; default: throw new InvalidMMEEffectShader例外("LoopByCountに指定できる変数の型はfloat,int,boolのいずれかです。"); } func._ループ回数 = loopCount; return(func); }
public abstract 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex);
public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { return(new ScriptExternal関数()); // TODO: 未実装 }
public ScriptRuntime(string script, エフェクト effect, テクニック technique = null, パス pass = null) { ScriptCode = script; _ScriptCodeを解析する(effect, technique, pass); }
public void D3Dスキニングバッファを更新する(スキニング skelton, エフェクト effect) { if (!(D3Dスキニングバッファをリセットする)) { return; } var skinning = (skelton as PMXスケルトン) ?? throw new System.NotSupportedException("PMXバッファ管理クラスでは、スキニングとして PMXスケルトン クラスを指定してください。"); var d3dContext = RenderContext.Instance.DeviceManager.D3DDeviceContext; // エフェクト変数にボーンの情報を設定する。 this._D3DBoneTransデータストリーム.WriteRange(skinning.ボーンのモデルポーズ配列); this._D3DBoneTransデータストリーム.Position = 0; d3dContext.UpdateSubresource(new DataBox(_D3DBoneTransデータストリーム.DataPointer, 0, 0), _D3DBoneTrans定数バッファ, 0); effect.D3DEffect.GetConstantBufferByName("BoneTransBuffer").SetConstantBuffer(this._D3DBoneTrans定数バッファ); this._D3DBoneLocalPositionデータストリーム.WriteRange(skinning.ボーンのローカル位置); this._D3DBoneLocalPositionデータストリーム.Position = 0; d3dContext.UpdateSubresource(new DataBox(_D3DBoneLocalPositionデータストリーム.DataPointer, 0, 0), _D3DBoneLocalPosition定数バッファ, 0); effect.D3DEffect.GetConstantBufferByName("BoneLocalPositionBuffer").SetConstantBuffer(this._D3DBoneLocalPosition定数バッファ); this._D3DBoneQuaternionデータストリーム.WriteRange(skinning.ボーンの回転); this._D3DBoneQuaternionデータストリーム.Position = 0; d3dContext.UpdateSubresource(new DataBox(_D3DBoneQuaternionデータストリーム.DataPointer, 0, 0), _D3DBoneQuaternion定数バッファ, 0); effect.D3DEffect.GetConstantBufferByName("BoneQuaternionBuffer").SetConstantBuffer(this._D3DBoneQuaternion定数バッファ); // 現在の入力頂点リストをスキニングバッファに転送する。 this._頂点データストリーム.WriteRange(入力頂点リスト); this._頂点データストリーム.Position = 0; d3dContext.UpdateSubresource(new DataBox(_頂点データストリーム.DataPointer, 0, 0), D3Dスキニングバッファ, 0); // 使用するtechniqueを検索する。 テクニック technique = (from teq in effect.テクニックリスト where teq.テクニックを適用する描画対象 == MMDPass種別.スキニング select teq).FirstOrDefault(); if (null != technique) { // パスを通じてコンピュートシェーダーステートを設定する。 technique.パスリスト.ElementAt(0).Value.D3DPass.Apply(d3dContext); // コンピュートシェーダーでスキニングを実行し、結果を頂点バッファに格納する。 d3dContext.ComputeShader.SetShaderResource(0, this.D3DスキニングバッファSRView); d3dContext.ComputeShader.SetUnorderedAccessView(0, this.D3D頂点バッファビューUAView); d3dContext.Dispatch((入力頂点リスト.Length / 64) + 1, 1, 1); } // UAVを外す(このあと頂点シェーダーが使えるように) d3dContext.ComputeShader.SetUnorderedAccessView(0, null); #region " (CPUで行ったときのソース)" //---------------- /* * var boneTrans = skinning.ボーンのモデルポーズ配列; * var スキニング後の入力頂点リスト = new VS_INPUT[ 入力頂点リスト.Length ]; * * for( int i = 0; i < 入力頂点リスト.Length; i++ ) * { * switch( 入力頂点リスト[ i ].変形方式 ) * { * case (uint) 変形方式.BDEF1: #region " *** " * //---------------- * { * var 頂点 = 入力頂点リスト[ i ]; * * Matrix bt = * boneTrans[ 頂点.BoneIndex1 ]; * * if( Matrix.Zero == bt ) * bt = Matrix.Identity; * * スキニング後の入力頂点リスト[ i ].Position = Vector4.Transform( 頂点.Position, bt ); * スキニング後の入力頂点リスト[ i ].Normal = Vector3.TransformNormal( 頂点.Normal, bt ); * スキニング後の入力頂点リスト[ i ].Normal.Normalize(); * } * //---------------- #endregion * break; * * case (uint) 変形方式.BDEF2: #region " *** " * //---------------- * { * var 頂点 = 入力頂点リスト[ i ]; * * Matrix bt = * boneTrans[ 頂点.BoneIndex1 ] * 頂点.BoneWeight1 + * boneTrans[ 頂点.BoneIndex2 ] * 頂点.BoneWeight2; * * if( Matrix.Zero == bt ) * bt = Matrix.Identity; * * スキニング後の入力頂点リスト[ i ].Position = Vector4.Transform( 頂点.Position, bt ); * スキニング後の入力頂点リスト[ i ].Normal = Vector3.TransformNormal( 頂点.Normal, bt ); * スキニング後の入力頂点リスト[ i ].Normal.Normalize(); * } * //---------------- #endregion * break; * * case (uint) 変形方式.BDEF4: #region " *** " * //---------------- * { * var 頂点 = 入力頂点リスト[ i ]; * * Matrix bt = * boneTrans[ 頂点.BoneIndex1 ] * 頂点.BoneWeight1 + * boneTrans[ 頂点.BoneIndex2 ] * 頂点.BoneWeight2 + * boneTrans[ 頂点.BoneIndex3 ] * 頂点.BoneWeight3 + * boneTrans[ 頂点.BoneIndex4 ] * 頂点.BoneWeight4; * * if( Matrix.Zero == bt ) * bt = Matrix.Identity; * * スキニング後の入力頂点リスト[ i ].Position = Vector4.Transform( 頂点.Position, bt ); * スキニング後の入力頂点リスト[ i ].Normal = Vector3.TransformNormal( 頂点.Normal, bt ); * スキニング後の入力頂点リスト[ i ].Normal.Normalize(); * } * //---------------- #endregion * break; * * case (uint) 変形方式.SDEF: #region " *** " * //---------------- * { * // 参考: * // 自分用メモ「PMXのスフィリカルデフォームのコードっぽいもの」(sma42氏) * // https://www.pixiv.net/member_illust.php?mode=medium&illust_id=60755964 * * var 頂点 = 入力頂点リスト[ i ]; * #region " 影響度0,1 の算出 " * //---------------- * float 影響度0 = 0f; // 固定値であるSDEFパラメータにのみ依存するので、これらの値も固定値。 * float 影響度1 = 0f; // * { * float L0 = ( 頂点.SdefR0 - (Vector3) skinning.ボーン配列[ 頂点.BoneIndex2 ].ローカル位置 ).Length(); // 子ボーンからR0までの距離 * float L1 = ( 頂点.SdefR1 - (Vector3) skinning.ボーン配列[ 頂点.BoneIndex2 ].ローカル位置 ).Length(); // 子ボーンからR1までの距離 * * 影響度0 = ( System.Math.Abs( L0 - L1 ) < 0.0001f ) ? 0.5f : SharpDX.MathUtil.Clamp( L0 / ( L0 + L1 ), 0.0f, 1.0f ); * 影響度1 = 1.0f - 影響度0; * } * //---------------- #endregion * * Matrix モデルポーズ行列L = boneTrans[ 頂点.BoneIndex1 ] * 頂点.BoneWeight1; * Matrix モデルポーズ行列R = boneTrans[ 頂点.BoneIndex2 ] * 頂点.BoneWeight2; * Matrix モデルポーズ行列C = モデルポーズ行列L + モデルポーズ行列R; * * Vector4 点C = Vector4.Transform( 頂点.Sdef_C, モデルポーズ行列C ); // BDEF2で計算された点Cの位置 * Vector4 点P = Vector4.Transform( 頂点.Position, モデルポーズ行列C ); // BDEF2で計算された頂点の位置 * * Matrix 重み付き回転行列 = Matrix.RotationQuaternion( * Quaternion.Slerp( // 球体線形補間 * skinning.ボーン配列[ 頂点.BoneIndex1 ].回転 * 頂点.BoneWeight1, * skinning.ボーン配列[ 頂点.BoneIndex2 ].回転 * 頂点.BoneWeight2, * 頂点.BoneWeight1 ) ); * * Vector4 点R0 = Vector4.Transform( new Vector4( 頂点.SdefR0, 1f ), ( モデルポーズ行列L + ( モデルポーズ行列C * -頂点.BoneWeight1 ) ) ); * Vector4 点R1 = Vector4.Transform( new Vector4( 頂点.SdefR1, 1f ), ( モデルポーズ行列R + ( モデルポーズ行列C * -頂点.BoneWeight2 ) ) ); * 点C += ( 点R0 * 影響度0 ) + ( 点R1 * 影響度1 ); // 膨らみすぎ防止 * * 点P -= 点C; // 頂点を点Cが中心になるよう移動して * 点P = Vector4.Transform( 点P, 重み付き回転行列 ); // 回転して * 点P += 点C; // 元の位置へ * * スキニング後の入力頂点リスト[ i ].Position = 点P; * スキニング後の入力頂点リスト[ i ].Normal = Vector3.TransformNormal( 頂点.Normal, 重み付き回転行列 ); * スキニング後の入力頂点リスト[ i ].Normal.Normalize(); * } * //---------------- #endregion * break; * * case (uint) 変形方式.QDEF: #region " *** " * //---------------- * { * // ※ QDEFを使ったモデルが見つからないのでテストしてません。あれば教えてください! * * var 頂点 = 入力頂点リスト[ i ]; * * var dualQuaternion = new DualQuaternion[ 4 ]; // 最大4ボーンまで対応 * * var boneIndexes = new[] { 頂点.BoneIndex1, 頂点.BoneIndex2, 頂点.BoneIndex3, 頂点.BoneIndex4 }; * var boneWeights = new[] { 頂点.BoneWeight1, 頂点.BoneWeight2, 頂点.BoneWeight3, 頂点.BoneWeight4 }; * * for( int b = 0; b < 4; b++ ) * { * if( boneWeights[ b ] == 0f ) * { * dualQuaternion[ b ] = DualQuaternion.Zero; // 未使用 * } * else * { * dualQuaternion[ b ] = new DualQuaternion( boneTrans[ boneIndexes[ b ] ] ); * } * } * * Matrix bt = ( * dualQuaternion[ 0 ] * boneWeights[ 0 ] + * dualQuaternion[ 1 ] * boneWeights[ 1 ] + * dualQuaternion[ 2 ] * boneWeights[ 2 ] + * dualQuaternion[ 3 ] * boneWeights[ 3 ] ).ToMatrix(); * * if( Matrix.Zero == bt ) * bt = Matrix.Identity; * * スキニング後の入力頂点リスト[ i ].Position = Vector4.Transform( 頂点.Position, bt ); * スキニング後の入力頂点リスト[ i ].Normal = 頂点.Normal; * } * //---------------- #endregion * break; * } * * スキニング後の入力頂点リスト[ i ].UV = 入力頂点リスト[ i ].UV; * スキニング後の入力頂点リスト[ i ].AddUV1 = 入力頂点リスト[ i ].AddUV1; * スキニング後の入力頂点リスト[ i ].AddUV2 = 入力頂点リスト[ i ].AddUV2; * スキニング後の入力頂点リスト[ i ].AddUV3 = 入力頂点リスト[ i ].AddUV3; * スキニング後の入力頂点リスト[ i ].AddUV4 = 入力頂点リスト[ i ].AddUV4; * スキニング後の入力頂点リスト[ i ].EdgeWeight = 入力頂点リスト[ i ].EdgeWeight; * スキニング後の入力頂点リスト[ i ].Index = 入力頂点リスト[ i ].Index; * } * * // データストリームに、スキニング後の入力頂点リストを書き込む。 * _頂点データストリーム.WriteRange( スキニング後の入力頂点リスト ); * _頂点データストリーム.Position = 0; * * // D3D頂点バッファに、スキニング後の入力頂点リストを(データストリーム経由で)書き込む。 * RenderContext.Instance.DeviceManager.D3DDeviceContext.UpdateSubresource( new DataBox( _頂点データストリーム.DataPointer, 0, 0 ), D3D頂点バッファ, 0 ); */ //---------------- #endregion D3Dスキニングバッファをリセットする = false; }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new Clear関数(); switch (value) { case "Color": func._対象 = 対象.Color; break; case "Depth": func._対象 = 対象.Depth; break; default: throw new InvalidMMEEffectShader例外($"Clear={value}が指定されましたが、\"{value}\"は指定可能ではありません。\"Clear\"もしくは\"Depth\"が指定可能です。"); } func._index = index; return(func); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { 数型 type = 0; TargetObject target = TargetObject.UnUsed; string itemName = null; string typeName = variable.TypeInfo.Description.TypeName.ToLower(); switch (typeName) { case "bool": type = 数型.Bool; break; case "float": type = 数型.Float; break; case "float3": type = 数型.Float3; break; case "float4": type = 数型.Float4; break; case "float4x4": type = 数型.Float4x4; break; default: break; } EffectVariable nameVariable = EffectParseHelper.アノテーションを取得する(variable, "name", "string"); if (nameVariable == null) { throw new InvalidMMEEffectShader例外($"定義済みセマンティクス「CONTROLOBJECT」の適用されている変数「{typeName} {variable.Description.Name}:CONTROLOBJECT」に対してはアノテーション「string name」は必須ですが、指定されませんでした。"); } string name = nameVariable.AsString().GetString(); // Selfの場合はターゲットは自分自身となる if (name.ToLower().Equals("(self)")) { _isSelf = true; } else { // TODO: (OffscreenOwner)がnameに指定されたときの対応 } EffectVariable itemVariable = EffectParseHelper.アノテーションを取得する(variable, "item", "string"); if (itemVariable != null) { itemName = itemVariable.AsString().GetString(); switch (itemName.ToLower()) { case "x": target = TargetObject.X; break; case "y": target = TargetObject.Y; break; case "z": target = TargetObject.Z; break; case "xyz": target = TargetObject.XYZ; break; case "rx": target = TargetObject.Rx; break; case "ry": target = TargetObject.Ry; break; case "rz": target = TargetObject.Rz; break; case "rxyz": target = TargetObject.Rxyz; break; case "si": target = TargetObject.Si; break; case "tr": target = TargetObject.Tr; break; default: target = type == 数型.Float ? TargetObject.FaceName : TargetObject.BoneName; break; } if (NeedFloat.Contains(target) && type != 数型.Float) { throw new InvalidMMEEffectShader例外($"定義済みセマンティクス「CONTROLOBJECT」の適用されている変数「{typeName} {variable.Description.Name}:CONTROLOBJECT」にはアノテーション「string item=\"{itemName}\"」が適用されていますが、「{itemName}」の場合は「float {variable.Description.Name}:CONTROLOBJECT」である必要があります。"); } if (NeedFloat3.Contains(target) && type != 数型.Float3) { throw new InvalidMMEEffectShader例外($"定義済みセマンティクス「CONTROLOBJECT」の適用されている変数「{typeName} {variable.Description.Name}:CONTROLOBJECT」にはアノテーション「string item=\"{itemName}\"」が適用されていますが、「{itemName}」の場合は「float3 {variable.Description.Name}:CONTROLOBJECT」である必要があります。"); } } return(new CONTROLOBJECT変数(type, itemName, name, target, _isSelf)); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new ClearSetColor関数(); func._sourceVariable = effect.D3DEffect.GetVariableByName(value); if (func._sourceVariable == null) { throw new InvalidMMEEffectShader例外($"ClearSetColor={value};が指定されましたが、変数\"{value}\"は見つかりませんでした。"); } if (!func._sourceVariable.TypeInfo.Description.TypeName.ToLower().Equals("float4")) { throw new InvalidMMEEffectShader例外($"ClearSetColor={value};が指定されましたが、変数\"{value}\"はfloat4型ではありません。"); } return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new Draw関数(); func._描画に使用するバス = pass ?? throw new InvalidMMEEffectShader例外("Drawはテクニックのスクリプトに関して適用できません。"); switch (value) { case "Geometry": func._描画するもの = 描画するもの.Geometry; break; case "Buffer": func._描画するもの = 描画するもの.Buffer; break; default: throw new InvalidMMEEffectShader例外($"Draw={value}が指定されましたが、Drawに指定できるのは\"Geometry\"または\"Buffer\"です。"); } if (func._描画するもの == 描画するもの.Geometry && effect.ScriptClass == ScriptClass.Scene) { throw new InvalidMMEEffectShader例外("Draw=Geometryが指定されましたが、STANDARDSGLOBALのScriptClassに\"scene\"を指定している場合、これはできません。"); } if (func._描画するもの == 描画するもの.Buffer && effect.ScriptClass == ScriptClass.Object) { throw new InvalidMMEEffectShader例外("Draw=Bufferが指定されましたが、STANDARDSGLOBALのScriptClassに\"object\"を指定している場合、これはできません。"); } return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new LoopGetIndex関数(); func._targetVariable = effect.D3DEffect.GetVariableByName(value); func._runtime = runtime; return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new RenderDepthStencilTarget関数(); if (index != 0) { throw new InvalidMMEEffectShader例外("RenderDepthStencilTargetにはインデックス値を指定できません。"); } if (!string.IsNullOrWhiteSpace(value) && !effect.深度ステンシルビューのマップ.ContainsKey(value)) { throw new InvalidMMEEffectShader例外("スクリプトに指定された名前の深度ステンシルバッファは存在しません。"); } // valueが空なら→デフォルトの深度ステンシルバッファ // valueがあるなら→その名前のテクスチャ変数から取得 if (string.IsNullOrWhiteSpace(value)) { func._既定のターゲットを使う = true; func._DepthStencilView = null; } else { func._既定のターゲットを使う = false; func._DepthStencilView = effect.深度ステンシルビューのマップ[value]; // 名前で検索 } return(func); }
/// <summary> /// 自身のインスタンスを作成して返す。 /// </summary> /// <param name="index">連番。ファンクション名の末尾に付与される1桁の数値(0~9)。省略時は 0 。</param> /// <param name="value">値。ファンクション名と '=' を挟んだ右辺に記された文字列。</param> /// <param name="runtime"></param> /// <param name="effect">ファンクションが属しているエフェクト。</param> /// <param name="technique">ファンクションが属しているテクニック。パスに属している場合には null を指定。</param> /// <param name="pass">ファンクションが属しているパス。テクニックに属している場合には null を指定。</param> /// <returns></returns> public override 関数 ファンクションインスタンスを作成する(int index, string value, ScriptRuntime runtime, エフェクト effect, テクニック technique, パス pass) { var func = new RenderColorTarget関数(); if (index < 0 || index > 7) { throw new InvalidMMEEffectShader例外("RenderColorTarget[n](0<=n<=7)のnの制約が満たされていません。"); } func._index = index; if (!string.IsNullOrWhiteSpace(value) && !effect.レンダーターゲットビューのマップ.ContainsKey(value)) { throw new InvalidMMEEffectShader例外("指定されたRENDERCOLORTARGETの変数は存在しません。"); } // 右辺が空白だったら、既定のターゲットを設定する。 if (string.IsNullOrWhiteSpace(value)) { func._既定のターゲットを使う = true; } func._renderTargetView = string.IsNullOrWhiteSpace(value) ? index == 0 ? RenderContext.Instance.描画ターゲットコンテキスト.D3Dレンダーターゲットビュー : null : effect.レンダーターゲットビューのマップ[value]; return(func); }
public override 数管理 数登録インスタンスを生成して返す(EffectVariable variable, エフェクト effect, int semanticIndex) { return(new VIEWPORTPIXELSIZE変数()); }