bugfix> unity3d > 投稿

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やビルド手順などの正式なものがありません。ただし、ほとんどの情報はサブモジュールにあります。