Unity(2018.1.0f2)向けのネイティブ(c ++)プラグイン(現時点ではWindowsのみ)を開発しています。 プラグインはテクスチャとメッシュをダウンロードし、それらを統一に提供します。 多くの定型コードがあります。 とにかく、レンダリングは次のように行われます。
void RegenerateCommandBuffer(CommandBuffer buffer, List<DrawTask> tasks)
{
buffer.Clear();
buffer.SetProjectionMatrix(cam.projectionMatrix); // protected Camera cam; cam = GetComponent<Camera>();
foreach (DrawTask t in tasks)
{
if (t.mesh == null)
continue;
MaterialPropertyBlock mat = new MaterialPropertyBlock();
bool monochromatic = false;
if (t.texColor != null)
{
var tt = t.texColor as VtsTexture;
mat.SetTexture(shaderPropertyMainTex, tt.Get());
monochromatic = tt.monochromatic;
}
if (t.texMask != null)
{
var tt = t.texMask as VtsTexture;
mat.SetTexture(shaderPropertyMaskTex, tt.Get());
}
mat.SetMatrix(shaderPropertyUvMat, VtsUtil.V2U33(t.data.uvm));
mat.SetVector(shaderPropertyUvClip, VtsUtil.V2U4(t.data.uvClip));
mat.SetVector(shaderPropertyColor, VtsUtil.V2U4(t.data.color));
// flags: mask, monochromatic, flat shading, uv source
mat.SetVector(shaderPropertyFlags, new Vector4(t.texMask == null ? 0 : 1, monochromatic ? 1 : 0, 0, t.data.externalUv ? 1 : 0));
buffer.DrawMesh((t.mesh as VtsMesh).Get(), VtsUtil.V2U44(t.data.mv), material, 0, -1, mat);
}
}
2つの制御モードがあります。単一カメラはプラグイン内のカメラによって制御されるか、プラグインカメラは単一カメラによって制御されます。私の現在のシナリオでは、プラグインカメラは単一カメラによって制御されています。舞台裏には特別な魔法はありませんが、一部の変換は、メッシュが「ジャンプ」することなく機能するために倍精度で実行する必要があります。
void CamOverrideView(ref double[] values)
{
Matrix4x4 Mu = mapTrans.localToWorldMatrix * VtsUtil.UnityToVtsMatrix;
// view matrix
if (controlTransformation == VtsDataControl.Vts)
cam.worldToCameraMatrix = VtsUtil.V2U44(Math.Mul44x44(values, Math.Inverse44(VtsUtil.U2V44(Mu))));
else
values = Math.Mul44x44(VtsUtil.U2V44(cam.worldToCameraMatrix), VtsUtil.U2V44(Mu));
}
void CamOverrideParameters(ref double fov, ref double aspect, ref double near, ref double far)
{
// fov
if (controlFov == VtsDataControl.Vts)
cam.fieldOfView = (float)fov;
else
fov = cam.fieldOfView;
// near & far
if (controlNearFar == VtsDataControl.Vts)
{
cam.nearClipPlane = (float)near;
cam.farClipPlane = (float)far;
}
else
{
near = cam.nearClipPlane;
far = cam.farClipPlane;
}
}
そしてシェーダー:
Shader "Vts/UnlitShader"
{
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vIn
{
float4 vertex : POSITION;
float2 uvInternal : TEXCOORD0;
float2 uvExternal : TEXCOORD1;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uvTex : TEXCOORD0;
float2 uvClip : TEXCOORD1;
};
struct fOut
{
float4 color : SV_Target;
};
sampler2D _MainTex;
sampler2D _MaskTex;
float4x4 _UvMat;
float4 _UvClip;
float4 _Color;
float4 _Flags; // mask, monochromatic, flat shading, uv source
v2f vert (vIn i)
{
v2f o;
o.vertex = UnityObjectToClipPos(i.vertex);
o.uvTex = mul((float3x3)_UvMat, float3(_Flags.w > 0 ? i.uvExternal : i.uvInternal, 1.0)).xy;
o.uvClip = i.uvExternal;
return o;
}
fOut frag (v2f i)
{
fOut o;
// texture color
o.color = tex2D(_MainTex, i.uvTex);
if (_Flags.y > 0)
o.color = o.color.rrra; // monochromatic texture
// uv clipping
if ( i.uvClip.x < _UvClip.x
|| i.uvClip.y < _UvClip.y
|| i.uvClip.x > _UvClip.z
|| i.uvClip.y > _UvClip.w)
discard;
// mask
if (_Flags.x > 0)
{
if (tex2D(_MaskTex, i.uvTex).r < 0.5)
discard;
}
// uniform tint
o.color *= _Color;
return o;
}
ENDCG
}
}
}
それはすべて完全に機能します-エディターで。また、スタンドアロンのDEVELOPMENTビルドでもうまく機能します。しかし、「デプロイ」ビルドの場合、変換は間違っています。レンダリングされたパーツは、間違った軸を中心に回転したり、異なる極性で回転したように見えます。
明らかな間違いを見つけられますか?
私の最初の容疑者はOpenGLとDirectXの違いでしたが、「デプロイ」ビルドと「開発」ビルドは同じものを使用する必要がありますか?さらに、プレイヤー設定を変更して、どちらか一方を強制的に変更しようとしましたが、違いはありませんでした。
編集:
良い画像:https://drive.google.com/open?id=1RTlVZBSAj7LIml1sBCX7nYTvMNaN0xK-
悪い画像:https://drive.google.com/open?id=176ahft7En6MqT-aS2RdKXOVW68NmvK2L
地形が大気と正しく整合していることに注意してください。
再現する手順
1)Unityで新しいプロジェクトを作成する
2)アセットをダウンロードするhttps://drive.google.com/open?id=18uKuiya5XycjGWEcsF-xjy0fn7sf-D82 新しく作成したプロジェクトにそれらを抽出します
3)エディターで試してください-> 正常に動作するはずです(メッシュとテクスチャのダウンロードを開始しますので、しばらくお待ちください。ダウンロードしたリソースは、たとえばC://users//.cache/vts-browserにキャッシュされます) 平面は、LMBを押しながらマウスで制御されます。
4)開発ビルドでビルドして実行-> うまくいくはずです
5)開発ビルドではなくビルドして実行-> 地形変換は正しく動作しません。
さらに、リポジトリを公開しました。ユニティ固有のコードは次のとおりです。https://github.com/Melown/vts-browser-unity-plugin 残念ながら、私はこれをすぐに公開するつもりはなかったので、リポジトリにはreadmeやビルド手順などの正式なものがありません。ただし、ほとんどの情報はサブモジュールにあります。
関連記事
- Unity:2Dトップダウンプレーヤーが奇妙に回転してマウスに向かいます
- Unity Animatorはプレーヤーをアニメーション化しませんが、Animatorウィンドウでトランジションを完全に追跡します
- 小さなシーンをロードするとUnityエディター/スタンドアロンビルドがクラッシュする
- ユニティは間違った角度で球を反射します
- Unityチュートリアル「ローカルプレーヤーの識別」OnStartLocalPlayer()のバグを修正する方法
- C#Visual Unityスタンドアロンexeデバッグシンボルの読み込みの問題
- 自由落下中のUnity Rotate Playerが機能しない
- 団結したプレイヤーの位置に基づく音声
- Unityなぜ3Dトップダウンゲームでプレイヤーがカーソルの方を向くことができないのですか? (Y軸のみ)パースペクティブカメラ/ルックアット
CommandBuffer.SetProjectionMatrixは明らかにGL.GetGPUProjectionMatrixによって調整されたマトリックスを必要とします。
残念ながら、なぜこれがデプロイビルドと開発ビルドとで異なる動作を引き起こすのか、私はまだ理解していません。異なるプラットフォームでのみ違いが出ると期待していたでしょう。