Unity3D Strange Shader Crash

on unity3d

Recently encountered a strange crash in Unity3D. I actually use Unity3D on Linux, so after working on the game for a while I wanted to see how it runs on Windows. Everything compiled fine but when running the game Unity3D would crash.

posts/unity3d_strange_shader_crash/crash.png

So I took a look at the crash log located here.

Crash Log

Crash!!!

========== OUTPUTING STACK TRACE ==================

(0x011B2C27) f:\dd\vctools\crtbld\SELFX86\crt\src\INTEL\memcpy.asm (185 + 0x0): memcpy + 0x57 \buildagent\work\d63dfc6385190b60\runtime\shaders\vbo.cpp (98 + 0x13): CopyVertexStream + 0x56 (0x010D38DF) c:\buildagent\work\d63dfc6385190b60\runtime\gfxdevice\d3d11\d3d11vbo.cpp (700 + 0x2f9): D3D11VBO::UpdateVertexData + 0x34f (0x01114038) c:\buildagent\work\d63dfc6385190b60\runtime\gfxdevice\threaded\gfxdeviceworker.cpp (1517 + 0x0): GfxDeviceWorker::RunCommand + 0x4e08 (0x01115DE1) c:\buildagent\work\d63dfc6385190b60\runtime\gfxdevice\threaded\gfxdeviceworker.cpp (215 + 0x14): GfxDeviceWorker::RunGfxDeviceWorker + 0x51 (0x0090993D) c:\buildagent\work\d63dfc6385190b60\runtime\threads\thread.cpp (40 + 0x9): Thread::RunThreadWrapper + 0x2d (0x774F338A) (kernel32): (filename not available): BaseThreadInitThunk + 0x12 (0x77EA9F72) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x63 (0x77EA9F45) (ntdll): (filename not available): RtlInitializeExceptionChain + 0x36

Ok so this has something to do with a shaders vbo? Searching around I found this post. In my game, custom meshes are created at boot up, so the problem must be with the way some mesh is being constructed.

Offending code

Mesh m = new Mesh();

m.vertices = tile.vertices;
m.uv = new Vector2[4];
m.uv[0] = new Vector2(0, 0);
m.uv[1] = new Vector2(0, 1);
m.uv[2] = new Vector2(1, 1);
m.uv[3] = new Vector2(1, 0);

m.triangles = tile.triangles;
m.RecalculateNormals();
GetComponent<MeshFilter>().mesh = m;

Everything looks fine to me.

Solution

Checking out the Unity Mesh Docs there is an important line:

Modifying vertex attributes every frame: 1) get vertices, 2) modify them, 3) assign them back to the mesh.

So the problem must be with the uv because it is being modified directly on the mesh. I rearranged the code so a uv array gets created on a temp variable and then set on the mesh.uv property.

Mesh m = new Mesh();
m.vertices = tile.vertices;

Vector2[] uvs = new Vector2[4];
uvs[0] = new Vector2(0, 0);
uvs[1] = new Vector2(0, 1);
uvs[2] = new Vector2(1, 1);
uvs[3] = new Vector2(1, 0);

m.uv = uvs;
m.triangles = tile.triangles;
m.RecalculateNormals();
GetComponent<MeshFilter>().mesh = m;

And that fixed the problem. Do not modify arrays once defined on a mesh.