Search Unity

Texture to 3D weapon

Discussion in 'Editor & General Support' started by Bladesfist, Jan 8, 2012.

  1. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    For my game I want to use a simillar pixel style weapons as minecraft and I was wondering how he gets the 2D textures and turns them into 3D models in game.

    I guessed that I could just create a plane and apply a texture to it. But if anyone has any better ideas please post them
     
  2. TehWut

    TehWut

    Joined:
    Jun 18, 2011
    Posts:
    1,577
    I don't think he uses planes for weapons. I think they are actually 3D models. (voxels? I dunno)
     
  3. StormGamer

    StormGamer

    Joined:
    Oct 26, 2011
    Posts:
    283
    ive been thinking about that too, i think its just a script that automaticaly turns a texture into a model, take a look at texture packs they are just textures but some of them change the weapons apearence and as you don´t change nor add anything to your game files id say its automated.
     
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Extrude shader might work also?
     
  5. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    If you edit a 2d image in minecrafts items.png the "model" changes as well.

    Yup, Its probably this, but I still dont know how its done.

    Im not sure I understand. Could you go into some more detail?
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Made some testing with extrude shader.
    (this is using default plane mesh, doesnt look nice with so few vertices)

    The shader is based on this, "Normal Extrusion with Vertex Modifier"
    http://unity3d.com/support/documentation/Components/SL-SurfaceShaderExamples.html
    That is then modified it to extrude vertices, based on texture color:

    Currently its using 2 bitmaps, one for color, one for extrude amount..
    (not really need 2, can take extrude from the main image)

    Attached 2 images, viewport shader properties
     

    Attached Files:

  7. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Hmmm. But minecrafts weapons / items have a "top" kind of.
     
  8. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Yup..that might be fixed with better mesh/image,
    but would be just easier to build a mesh from bitmap..

    check pixel alpha values (x,y),
    if its > 0, then add meshpiece..
     
  9. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Good idea, Ill look into that
     
  10. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
  11. TylerPerry

    TylerPerry

    Joined:
    May 29, 2011
    Posts:
    5,577
    I think he proboly uses a script that makes the voxels in the positions of the pixels then makes them the same colours, how he dose it i dont know.
     
  12. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Yep, something like that.
     
  13. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    testing..something went wrong with the vertices..but almost : )

    (also would need to drop the not needed vertices..)
     

    Attached Files:

  14. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Nice, are you willing to share the source or explain how you achieved that?
     
  15. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    yes, source will be published on my blog later,
    but the the link on my previous post does all the hard work. (that 2D polygon to mesh extrude)
     
  16. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
  17. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    I hope someone tries different techniques aswell : )

    bitmap outline detection works,
    just need to combine this to the meshmaker..

    screenshot, showing bitmap outline as default boxes:
     

    Attached Files:

  18. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    I would give it a go but I have an extremely limited knowledge of meshes and vertices. I don't think I would be able to make anything worthwile. However what your doing looks very promising.
     
  19. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Kind of works now.. atleast for a start, can add more stuff later.

    Need to clean it up a bit, before upload the source,
    hopefully in the next few days.
     

    Attached Files:

  20. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Is the width that the mesh extrudes easily customizable?
     
  21. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    yes, its adjustable (the extrusion depth)

    one more test, before upload source (tomorrow hopefully)
    code still has bugs, but others can try to improve it also..

    image: using planar UV for a testing with material and no more extra vertices.
     

    Attached Files:

  22. TylerPerry

    TylerPerry

    Joined:
    May 29, 2011
    Posts:
    5,577
    Looks cool but the end model dosent look like that picture? oh never mind i thout it was the arkerpart that was extruded not the white :)
     
  23. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    I have one test source online now,
    but it still needs work..

    .|
    .|
    \ /
     
  24. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    nice looks good
     
  25. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Last edited: Feb 6, 2012
  26. jamexist

    jamexist

    Joined:
    Mar 2, 2010
    Posts:
    11
    Awesome mgear, but is it possible to widen the code to read multiple shapes on bitmap?!
    This is going to be so useful!
     
  27. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Added code to the blog for setting the scale pivot (originally it was: 1 pixel in bitmap = 1 unit (m))

    Sure, just need to solve how to hide/erase already scanned objects..
    (basically floodfill the current object to black, after its done.. then just do a new scan until no shapes are left)

    Those extra objects would be submeshes then? (havent really used them before..)
     
  28. jamexist

    jamexist

    Joined:
    Mar 2, 2010
    Posts:
    11
    seems like a neat idea...

    No, there aren't submeshes in my case but they are as separate multiple objects. suppose that you have multiple shapes on your texture and you want every shape to be a unique gameobject all sitting beside each other as the reference texture.
     
  29. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Added new test version (2.0)

    - Improved UV's (still problems on the sides)
    - Better scanning and now it assigns vertices to outer edges of the pixels (earlier it was: pixel location = vertex location), now thin objects work better (and it looks better also)
    - Mesh extrude is now using unity procedural examples extrusion (can extrude in sections..if needed)
    - Pixel2Units-scale variable to set scale
    - Pivot point in better location
    - New gameObject is created (instead of building the mesh in the current object)

    Many other things to fix later..
    (and If someone has ideas how to fix the UV's on the sides, let me know : )

    I'll try the multiobject later also.. (not familiar with texture atlasing, if that would work for texturing then..(?))

    Screenshot:
    Original bitmap 16x16 (png)
    3D mesh views (using same image as texture)
     

    Attached Files:

  30. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    yay..after 3 days of testing random values and uv-offsets,
    finally got UV mapping to work..(atleast on most test objects)

    Adding the latest source download later this week..

    screenshot: bitmap and textured extrude mesh (viewed from back, fixed the inverted x axis already..)
     

    Attached Files:

  31. jamexist

    jamexist

    Joined:
    Mar 2, 2010
    Posts:
    11
    Again, nice job mgear, what is up with multiobjecting! :) Also random extrusion lengths on every single object would be a great option!
     
  32. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Made a completely new version from it, now the objects can have holes too.
    need to clean it up a bit before upload..(next week maybe)
    (And now it doesnt need the MeshExtrusion.cs anymore either)

    Multiobjects would be next thing to try,
    basically you can already do that by adjusting the "x,y" in for loops.
    but texturing doesnt work yet..

    screenshot (original bow png from minecraft)
     

    Attached Files:

  33. pattywac

    pattywac

    Joined:
    Feb 16, 2012
    Posts:
    4
  34. Bladesfist

    Bladesfist

    Joined:
    Jan 3, 2012
    Posts:
    107
    Nice work, Can I take your source and use it in one of my projects?
     
  35. vlano_

    vlano_

    Joined:
    Nov 9, 2017
    Posts:
    2
    Can I get an URL for your code ? I'm relly interested, this is just what i need for my game.
     
  36. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,445
    Aseemy likes this.
  37. vlano_

    vlano_

    Joined:
    Nov 9, 2017
    Posts:
    2
  38. Will_Croxford

    Will_Croxford

    Joined:
    Mar 7, 2018
    Posts:
    5
    If anybody else ends up here looking how to simply extrude any shape of 2D photo / sprite into 3D mesh for Unity 3D game (a photo of door in my case), try: http://www.chronosapien.com/blog/from-2d-to-3d-with-windows-10s-3d-builder using the free with Windows 10 app 3D Builder, simplest, quickest way I found. windows Paint 3D maybe you can, but Builder I found simpler for this use case, plus Paint3D lots of tutorials (by Windows!) which seem to gloss too quick over first steps. Obviously Blender would do better, but we're talking quick and dirty here ;-)
     
  39. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,076
    Yee hah! I'll definitely check out that blog.
    Thanks for posting dude.
     
  40. JadenJAllen

    JadenJAllen

    Joined:
    Feb 17, 2022
    Posts:
    15
    only a decade late but i recently wanted to see if i could do this exact thing through script just like minecraft and with about a day of work i got it fully functional, its not perfect as my code basically reads each pixel on the texture and creates a voxel there with the correct uv mapping, the issue is that im creating an entire voxel per pixel. I got it down to removing all tris inside of the mesh so only outside tris are being created but in the future i would like to reduce the vertices and tris by generating rectangles instead. Anyways if anyone needs the code, here it is. Note to get the model just call VoxelData.CreateItemObjectFromData()... Youll need to pass in a few variables such as a starting material, an item class isnt necessary just change it to ItemData instead and a transform for setting the position and parent of the newly created game object.

    Thanks to B3agz coding minecraft tutorials on generating voxels/ chunks

    Code (CSharp):
    1. [System.Serializable]
    2. public class ItemData
    3. {
    4.  
    5.     [Range(0f, 2f)] public float size = 0.5f;
    6.     [Range(0, 16)] public float thickness = 1;
    7.     public Vector3 renderOffset;
    8.     public Vector3 renderRotation;
    9.     public string typeId;
    10.     public Texture2D texture;
    11.  
    12.     public int maxStackSize;
    13.  
    14.     public bool hasDurability;
    15.     public int maxDurability;
    16.  
    17.     public int damage;
    18. }

    Code (CSharp):
    1. public static class VoxelData
    2. {
    3.  
    4.     public static Vector3[] voxelVerts (ItemData data) {
    5.  
    6.         Vector3[] verts = new Vector3[8] {
    7.         new Vector3(0.0f, 0.0f, 0.0f * data.thickness) * (data.size / data.texture.width),
    8.         new Vector3(1.0f, 0.0f, 0.0f * data.thickness) * (data.size / data.texture.width),
    9.         new Vector3(1.0f, 1.0f, 0.0f * data.thickness) * (data.size / data.texture.width),
    10.         new Vector3(0.0f, 1.0f, 0.0f * data.thickness) * (data.size / data.texture.width),
    11.         new Vector3(0.0f, 0.0f, 1.0f * data.thickness) * (data.size / data.texture.width),
    12.         new Vector3(1.0f, 0.0f, 1.0f * data.thickness) * (data.size / data.texture.width),
    13.         new Vector3(1.0f, 1.0f, 1.0f * data.thickness) * (data.size / data.texture.width),
    14.         new Vector3(0.0f, 1.0f, 1.0f * data.thickness) * (data.size / data.texture.width)
    15.         };
    16.         return verts;
    17.  
    18.     }
    19.  
    20.     public static readonly int[,] voxelTris = new int[6, 6] {
    21.         { 0,3,1,1,3,2 }, // Front face
    22.         { 5,6,4,4,6,7 }, // Back face
    23.         { 3,7,2,2,7,6 }, // Top face
    24.         { 1,5,0,0,5,4 }, // Bottom face
    25.         { 4,7,0,0,7,3 }, // Left Face
    26.         { 1,2,5,5,2,6 }, // Right Face
    27.     };
    28.     public static readonly Vector3[] faceChecks = new Vector3[6]
    29.     {
    30.         new Vector3(0,0,-1),
    31.         new Vector3(0,0,1),
    32.         new Vector3(0,1,0),
    33.         new Vector3(0,-1,0),
    34.         new Vector3(-1,0,0),
    35.         new Vector3(1,0,0)
    36.     };
    37.  
    38.     public static Vector2[] voxelUvs (Vector3 pos, Texture2D texture) {
    39.         Vector2[] _uvs = new Vector2[6]
    40.         {
    41.             new Vector2((pos.x + 0) / texture.width, (pos.y + 0) / texture.height),
    42.             new Vector2((pos.x + 0) / texture.width, (pos.y + 1) / texture.height),
    43.             new Vector2((pos.x + 1) / texture.width, (pos.y + 0) / texture.height),
    44.             new Vector2((pos.x + 1) / texture.width, (pos.y + 0) / texture.height),
    45.             new Vector2((pos.x + 0) / texture.width, (pos.y + 1) / texture.height),
    46.             new Vector2((pos.x + 1) / texture.width, (pos.y + 1) / texture.height)
    47.         };
    48.  
    49.         return _uvs;
    50.     }
    51.     public static Mesh CreateItemMesh(ItemData data)
    52.     {
    53.         List<Vector3> vertices = new List<Vector3>();
    54.         List<int> triangles = new List<int>();
    55.         List<Vector2> uvs = new List<Vector2>();
    56.  
    57.         bool[,] voxelMap = new bool[data.texture.width,data.texture.height];
    58.  
    59.         int vertexIndex = 0;
    60.         for (int y = 0; y < data.texture.height; y++)
    61.         {
    62.             for (int x = 0; x < data.texture.width; x++)
    63.             {
    64.                 Color color = data.texture.GetPixel(x, y);
    65.              
    66.                 if (color.a != 0)
    67.                 {
    68.                     voxelMap[x,y] = true;
    69.                 }
    70.                 else
    71.                 {
    72.                     voxelMap[x,y] = false;
    73.                 }
    74.             }
    75.         }
    76.  
    77.  
    78.         bool loadAll = false;
    79.         if (loadAll)
    80.         {
    81.             for (int y = 0; y < data.texture.height; y++)
    82.             {
    83.                 for (int x = 0; x < data.texture.width; x++)
    84.                 {
    85.                     Vector3 pos = new Vector3(x, y, 0);
    86.                     Color color = data.texture.GetPixel(x, y);
    87.  
    88.                     if (color.a != 0)
    89.                     {
    90.                         for (int p = 0; p < 6; p++)
    91.                         {
    92.                             for (int i = 0; i < 6; i++)
    93.                             {
    94.                                 Vector3[] voxelVerts = VoxelData.voxelVerts(data);
    95.                                 int triangleIndex = voxelTris[p, i];
    96.                                 vertices.Add(voxelVerts[triangleIndex] + (pos * (data.size / data.texture.width)));
    97.                                 triangles.Add(vertexIndex);
    98.  
    99.                                 Vector2[] _uvs = voxelUvs(pos, data.texture);
    100.                                 uvs.Add(_uvs[i]);
    101.                                 vertexIndex++;
    102.                             }
    103.  
    104.                         }
    105.                     }
    106.  
    107.                 }
    108.             }
    109.         }
    110.         else
    111.         {
    112.             for (int y = 0; y < data.texture.height; y++)
    113.             {
    114.                 for (int x = 0; x < data.texture.width; x++)
    115.                 {
    116.                     Vector3 pos = new Vector3(x, y, 0);
    117.                     Color color = data.texture.GetPixel(x, y);
    118.  
    119.                     if (color.a != 0)
    120.                     {
    121.                         for (int p = 0; p < 6; p++)
    122.                         {
    123.                             if (p == 0 || p == 1)
    124.                             {
    125.                                 for (int i = 0; i < 6; i++)
    126.                                 {
    127.                                     Vector3[] voxelVerts = VoxelData.voxelVerts(data);
    128.                                     int triangleIndex = voxelTris[p, i];
    129.                                     vertices.Add(voxelVerts[triangleIndex] + (pos * (data.size / data.texture.width)));
    130.                                     triangles.Add(vertexIndex);
    131.  
    132.                                     Vector2[] _uvs = voxelUvs(pos, data.texture);
    133.                                     uvs.Add(_uvs[i]);
    134.                                     vertexIndex++;
    135.                                 }
    136.                             }
    137.                             else
    138.                             {
    139.                                 if (!CheckVoxel(pos + faceChecks[p], voxelMap, data))
    140.                                 {
    141.                                     for (int i = 0; i < 6; i++)
    142.                                     {
    143.                                         Vector3[] voxelVerts = VoxelData.voxelVerts(data);
    144.                                         int triangleIndex = voxelTris[p, i];
    145.                                         vertices.Add(voxelVerts[triangleIndex] + (pos * (data.size / data.texture.width)));
    146.                                         triangles.Add(vertexIndex);
    147.  
    148.                                         Vector2[] _uvs = voxelUvs(pos, data.texture);
    149.                                         uvs.Add(_uvs[i]);
    150.                                         vertexIndex++;
    151.                                     }
    152.                                 }
    153.                             }
    154.  
    155.                         }
    156.                     }
    157.  
    158.                 }
    159.             }
    160.         }
    161.  
    162.  
    163.         Mesh mesh = new Mesh();
    164.         mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
    165.         mesh.vertices = vertices.ToArray();
    166.         Debug.Log(data.typeId + " { Vertice Count: " + vertices.Count + ", Triangle Count: " + triangles.Count / 3 + " }");
    167.         mesh.triangles = triangles.ToArray();
    168.         mesh.uv = uvs.ToArray();
    169.         mesh.RecalculateNormals();
    170.  
    171.         return mesh;
    172.     }
    173.     static bool CheckVoxel(Vector2 pos, bool[,] voxelMap, ItemData data)
    174.     {
    175.         int x = Mathf.FloorToInt(pos.x);
    176.         int y = Mathf.FloorToInt(pos.y);
    177.         if (x < 0 || x > data.texture.width - 1 || y < 0 || y > data.texture.height - 1)
    178.         {
    179.             return false;
    180.         }
    181.         return voxelMap[x, y];
    182.     }
    183.     public static GameObject CreateItemObjectFromData(Item item, Material mat, Transform parent)
    184.     {
    185.         GameObject _item = new GameObject(item.itemData.typeId);
    186.  
    187.         MeshFilter meshFilter = _item.AddComponent<MeshFilter>();
    188.         MeshRenderer meshRenderer = _item.AddComponent<MeshRenderer>();
    189.  
    190.         Material _mat = new Material(mat);
    191.  
    192.         _mat.mainTexture = item.itemData.texture;
    193.         meshRenderer.material = _mat;
    194.  
    195.         meshFilter.mesh = CreateItemMesh(item.itemData);
    196.  
    197.         _item.transform.parent = parent;
    198.         _item.transform.localPosition = item.itemData.renderOffset;
    199.         _item.transform.localEulerAngles = item.itemData.renderRotation;
    200.         _item.layer = 7;
    201.  
    202.         return _item;
    203.     }
    204.  
    205. }
     
    ParadoxSolutions and mgear like this.