How do you avoid weird artifacts while baking normals?

The polycount as in the number of polygons doubles, yes, but since it’s just turned quads into triangles, it should still take the same amount of video memory, so it’s all good.

And I said nothing about decimating. I just want you to export as triangles to make sure there is no difference between how Substance and Blender will split the quads. Because any discrepancy here can and will ruin a bake every time.

False alarm, I must have duplicated the mesh accidentaly, not you.

  1. The slimy look was caused by sampling the normalmap as Color instead of Non-Color_Data.

  2. The best technique to get a clean bake on hard surface models is to have a minimal bevel (1 segment) on the low-poly, then edit the normals in a way that the orientation of the normals is decided by large faces around it. Blender 2.80 has the Weigted Normal Modifier to do this, for Blender 2.79 this addon can be used to do the same: Weighted Normals Calculator. This technique requires high-poly to low-poly baking, not baking from multires. The problem is that Cycles has a bug that prevents baking correctly with custom normals, but Blender Internal could do it.

  3. A baking cage can also help if there are opposing faces close to each other but I think this particular model doesn’t need that but who knows. At least it’s clear that those artifacts are not caused by the lack of a cage. The problem with that is that Blender Internal can’t bake with a cage.

  4. So to get both techniques to work together you have to bake in a program that can bake with a cage using custom normals. The easiest way to do this from Blender is using the [Addon] GYAZ Handplane Baker Bridge addon that makes it possible to the bake with Handplane Baker, a small program that bakes from highpoly to lowpoly, from within Blender, never leaving it.

  5. Alternatively, you can model the gun using hard edges and use the bevel shader in 2.80 or 2.79 (unstable version) to do the bevel. This is the fastest workflow but can only be used with thin bevels since it’s only a shading effect. This shader can be baked down to a normalmap without any problem. There’s one requirement: all hard edges must have a seam, otherwise the baked normalmap will come out wrong. Whether it’s for you, it depends on how you want to use this model, if it’s for a game, this technique is more than good enough. Although, if you need very close shots with photorealistic results, it may not be convincing enough.

  6. Another thing to try is to bake an object space normalmap, this could have better results since tangent space normalmaps are relative to the normals of the low-poly mesh while object space normalmaps flat-out override them. The catch is that every software uses different axes for forward, upward… like in Blender +Z is up, -Y is forward; in Unreal +Z is up, +X is forward, in Unity Y is up… so the channels need to be swizzled to match the axes of the target application.

helluvamesh, dude, thank you. I see why you’re Hellvamesh now. I appreciate the help and the time you took to write all that. I am going to try it as soon as I get the chance. The Non-Color data was a stupid rookie mistake I made while preparing the file for the forum, so just ignore that, the original file has it right.

Do you think that edge loops affect the process in the slightest?

I was able to bake a quite good OBJECT-SPACE normalmap with the Handplane Baker. This should be possible with with Blender too, but no matter what I tried I just couldn’t get it to work. Cycles always rendered the OS normalmap it baked wrong.

.

Gun_object_space_normalmap.blend (1.7 MB)

There are still small artifacts but I guess those could be eliminated by using a baking cage. Also, I found intertwined UVs at multiple places.

What does this mean? Intertwined UV’s?

Badly layed out, self-collapsed uvs.

k%C3%A9p

Is there a way to detect those? Like some kind of “select messed up UV’s” kinda menu option?

Run this script in edit mode.

"""RUN IN MESH EDIT MODE TO SELECT MIRRORED UVS"""

import bpy, bmesh
import numpy as np

    
obj = bpy.context.object
mesh = obj.data
uv_maps = mesh.uv_layers

if len(uv_maps) > 0:    
    
    bm = bmesh.from_edit_mesh(mesh)
    
    uv_layer = bm.loops.layers.uv[uv_maps.active_index]    
    
    bpy.ops.uv.select_all(action='DESELECT')

    for face in bm.faces:
        uvs = [tuple(loop[uv_layer].uv) for loop in face.loops]
        x, y = zip (*uvs)
        # is vert order ccw?
        if 0.5 * np.array(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))) > 0:
            if not bpy.context.scene.tool_settings.use_uv_select_sync:
                for uv in [loop[uv_layer] for loop in face.loops]:
                    uv.select = True
            face.select = True                                   
    
    bmesh.update_edit_mesh(mesh, False)

DUDE, thank you so much, man, I really appreciate the time you took to do this! :bowing_man:t2: