Я разрабатываю нативный (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 и инструкции по сборке.Однако большую часть информации можно найти в подмодулях.