Неправильные трансформации в единственном билде игрока - PullRequest
0 голосов
/ 25 мая 2018

Я разрабатываю нативный (c ++) плагин (пока только для windows) для Unity (2018.1.0f2).Плагин загружает текстуры и сетки и обеспечивает их единство.Существует много шаблонного кода, от которого я бы хотел избавиться.В любом случае, рендеринг делается так:

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

Есть два режима управления.Либо камера Unity контролируется камерой в плагине, либо камера плагина управляется камерой Unity.В моем текущем сценарии камера плагина управляется камерой единства.За кулисами нет особой магии, но некоторые преобразования должны быть выполнены с двойной точностью, чтобы работать без "скачущих" сеток.

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

Все отлично работает - в редакторе.Это также хорошо работает в автономной сборке РАЗРАБОТКИ.Но преобразования происходят неправильно, когда в сборках 'deploy'.Отрисованные детали выглядят так, как будто они вращаются вокруг неправильных осей или с разной полярностью.

Можете ли вы заметить некоторые очевидные ошибки?

Моим первым подозрением было отличие OpenGL от DirectX, но «развертывание»и сборки 'development' должны использовать то же самое, не так ли?Кроме того, я попытался изменить настройку плеера, чтобы заставить один или другой, но без каких-либо различий.

Редактировать:

Хорошее изображение: https://drive.google.com/open?id=1RTlVZBSAj7LIml1sBCX7nYTvMNaN0xK-

Плохое изображение:https://drive.google.com/open?id=176ahft7En6MqT-aS2RdKXOVW68NmvK2L

Обратите внимание, как местность правильно выровнена с атмосферой.

Шаги для воспроизведения

1) Создайте новый проект в единстве

2) Загрузите ресурсы https://drive.google.com/open?id=18uKuiya5XycjGWEcsF-xjy0fn7sf-D82 и извлеките их во вновь созданный проект

3) Попробуйте в редакторе -> все должно работать нормально (оно начнет загружать меши и текстуры от нас, так что наберитесь терпения;загруженные ресурсы кэшируются, например, в C: //users//.cache/vts-browser) Плоскость управляется мышью с нажатой ЛКМ.

4) Сборка в процессе разработки и запуск -> должна работатьтоже хорошо

5) Сборка НЕ ​​в разработке, сборка и запуск -> преобразования ландшафта ведут себя некорректно.

Более того, я опубликовал репозиторий.Вот код, связанный с единицей: https://github.com/Melown/vts-browser-unity-plugin К сожалению, я не собирался публиковать его в ближайшее время, поэтому в хранилище отсутствуют некоторые формальные вещи, такие как readme и инструкции по сборке.Однако большую часть информации можно найти в подмодулях.

1 Ответ

0 голосов
/ 31 мая 2018

CommandBuffer.SetProjectionMatrix, очевидно, нужна матрица, которая была откорректирована GL.GetGPUProjectionMatrix.

buffer.SetProjectionMatrix(GL.GetGPUProjectionMatrix(cam.projectionMatrix, false));

К сожалению, я до сих пор не понимаю, почему это может вызывать различное поведение между сборками развертывания и разработки.Я ожидал, что это будет иметь значение только на разных платформах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...