2
$\begingroup$

I'm working on a Minecraft themed map, and have a ton cubes. Some cubes require 3 materials (a top texture, bottom texture, and sides texture). When I apply the top and bottom materials, it applies it correctly. However, when I apply the side material, it looks distorted and smeared, and only appears correctly when viewing it from the Renderer Viewport (rather than the Material Viewport).

Material View:

enter image description here

Rendered View:

enter image description here

Is there a way to fix it, without resorting to UV mapping?

$\endgroup$
  • $\begingroup$ Is scale applied? If it is, then the only thing I can think to do is to UV Unwrap, but instead of taking the time to do it manually, and creating seams, you can just project from cube. $\endgroup$ – J. A. Streich May 13 '15 at 17:28
  • $\begingroup$ @J.A.Streich It's already set to cube projection. That's what makes it work in rendered view, but it's not appearing correctly in material view. $\endgroup$ – Mr. Smith May 13 '15 at 17:39
  • 1
    $\begingroup$ Why are you avoiding UVs? That will give you total control on the texture mapping. Unwrapping a cube takes 2 minutes to learn: youtube.com/watch?v=e_dTES_CCbY another way to do it is blender.stackexchange.com/a/27351/1853 $\endgroup$ – cegaton May 13 '15 at 17:40
  • $\begingroup$ @cegaton Overkill, and overhead; I don't need that much control, and with several thousand of these cubes being on the map, I'm worried about performance implications. Infact, with the manner in which I merge cubes (to remove hidden faces and duplicate verticies), UV mapping is likely far more difficult than you're imagining. $\endgroup$ – Mr. Smith May 13 '15 at 17:49
4
$\begingroup$

I am not optimistic that there is a way to "solve" this without using UV maps.

If it is any encouragement, understand that many people before you have converted minecraft data into 3D data sets: http://www.purplefrog.com/~thoth/minecraft-webgl/two.html ; and they used UVs.

I can't remember why I wrote this, but it is python code that makes up a UV map based on the position of the vertices relative to whichever of the XY, YZ, or XZ planes they are most aligned with.

Here's a copy inline:

import bpy
import bmesh
from math import *
from mathutils import *

def set_uvs_for_face(bm, fi, uv_layer):
    face = bm.faces[fi]
    normal = face.normal
    dx=abs(normal[0])
    dy=abs(normal[1])
    dz=abs(normal[2])

    if (dz > dx):
        u = Vector([1,0,0])
        if (dz>dy):
            v = Vector([0,1,0])
        else:
            v = Vector([0,0,1])
    else:
        v = Vector([0,0,1])
        if dx>dy:
            u = Vector([0,1,0])
        else:
            u = Vector([1,0,0])
    for i in range(len(face.loops)):
        l = face.loops[i]
        l[uv_layer].uv = [ u.dot(l.vert.co),
                           v.dot(l.vert.co)]

def set_uvs(mesh, name=None):

    if name is None:
        if 0<len(mesh.uv_textures):
            uv = mesh.uv_textures[0]
        else:
            uv = mesh.uv_textures.new("cubic")
    else:
        uv = mesh.uv_textures.get(name)
        if uv is None:
            uv = mesh.uv_textures.new(name)

    bm = bmesh.new()
    bm.from_mesh(mesh)

    uv_layer = bm.loops.layers.uv[uv.name]

    for fi in range(len(bm.faces)):
        set_uvs_for_face(bm, fi, uv_layer)

    bm.to_mesh(mesh)

#
#
#

mode = bpy.context.mode
if 'OBJECT' != mode:
    bpy.ops.object.mode_set(mode='OBJECT')

obj = bpy.context.active_object
set_uvs(obj.data)

if 'OBJECT' != mode:
    bpy.ops.object.mode_set(mode = mode)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.