유리에 검은 줄무늬

Nov 03 2020

저는 Blender를 처음 접하고 과학적 결과를 시각화하려고 노력하고 있습니다. 중심선의 더미 데이터를 생성 한 다음 보간에 베 지어 곡선을 사용했습니다. 그런 다음 베벨 (폴리 라인으로 정의 된 단순한 사각형)을 할당하고 3D 개체를 만들었습니다 (캡도 닫았습니다). 적어도 3D 개체 이길 바라며 채우기 기능도 사용해야하는지 잘 모르겠습니다.

그럼에도 불구하고 나는이 모든 것을 만들어 내고, 벽으로 물체를 둘러싸고 거기에 조명을 두는 환경에 두었습니다. 나는 유리와 같은 재료를 할당했습니다. 렌더링 (순환) 할 때 이미지에 이상한 검은 색 줄무늬가 나타나고 어떻게 수정해야할지 모르겠습니다. 아래에서 찾을 수있는 스크립트에 모든 것이 있습니다.

물론 솔루션이 Python 스크립트에 있지 않아도 상관 없습니다. 변환을 관리하겠습니다. 나는 그들이 나타나는 이유와 그것을 해결하는 방법을 이해하고 싶습니다.

import bpy
import numpy as np


# delete everything
print("\n\n\n\nNew run")
objs = [ob for ob in bpy.context.scene.objects]
bpy.ops.object.delete({"selected_objects": objs})
print("\n\n\n\n")

def dump(obj):
   for attr in dir(obj):
       if hasattr( obj, attr ):
           print( "obj.%s = %s" % (attr, getattr(obj, attr)))
           
def polyline_from(coords, name, closed):
    # create the Curve Datablock
    curvedata = bpy.data.curves.new(name, type='CURVE')
    curvedata.dimensions = '3D'
    
    # map coords to spline
    polyline = curvedata.splines.new('POLY')
    polyline.points.add(len(coords)-1)
    
    for i, coord in enumerate(coords):
        x,y = coord
        polyline.points[i].co = (x, y, 0, 1)
        
    if(closed):
        polyline.use_cyclic_u = True
  
    # create Object
    objectdata = bpy.data.objects.new(name+"Object", curvedata)

    return objectdata


def curve_from(coords, name, closed, res=10):
    # create the Curve Datablock
    curvedata = bpy.data.curves.new(name, type='CURVE')
    curvedata.dimensions = '3D'
    curvedata.resolution_u = res
    
    # map coords to spline
    spline = curvedata.splines.new('BEZIER')
    spline.bezier_points.add(len(coords)-1)
    
    for i, p in enumerate(spline.bezier_points):
        x,y,z = coords[i]
        p.co = (x, y, z)
        p.handle_left = (x, y, z)
        p.handle_right = (x, y, z)
        
        #Set automatic
        p.handle_right_type = 'AUTO'
        p.handle_left_type = 'AUTO'
        
    if(closed):
        spline.use_cyclic_u = True
    
    # create Object
    objectdata = bpy.data.objects.new(name+"Object", curvedata)

    return objectdata


# create scene
scene = bpy.context.scene
scene.world.color = (0,0,0)

# select render engine
scene.render.engine = 'CYCLES'

# Set render resolution
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080

# Generate fake data
def data(t):    
    x = np.linspace(0, 1, 10)
    y = 0*x
    z = x**2 * 0.2 * np.sin(t)
    return np.array([x, y, z]).T

centerline_points = data(0)

# Cross section
cross_section_points = 0.5*np.array([
    [-0.1,-0.1],
    [ 0.1,-0.1],
    [ 0.1, 0.1],
    [-0.1, 0.1]
])

centerline = curve_from(
    coords=centerline_points,
    name="Centerline",
    closed=False,
    res=13
)

cross_section = polyline_from(
    coords=cross_section_points,
    name="CrossSection",
    closed=True
)

# add bevel object
centerline.data.bevel_object = cross_section
centerline.data.use_fill_caps = True

# attach to scene and validate context
scene.collection.objects.link(centerline)

# clear all previous animation data
centerline.animation_data_clear()

# set first and last frame index
total_time = 2*np.pi # Animation should be 2*pi seconds long
fps = 10 # Frames per second (fps)
scene.frame_start = 0
scene.frame_end = int(total_time*fps)+1

# loop of frames and insert keyframes every 10th frame
keyframe_freq = 1
nlast = bpy.context.scene.frame_end
for n in range(nlast):
    t = total_time*n/nlast

    # Do computations
    new_points = data(t)

    # Check if n is a multiple of keyframe_freq
    if n%keyframe_freq == 0:
        # Set frame like this
        scene.frame_set(n)

        # Set current location like this
        for (i, p) in enumerate(centerline.data.splines.active.bezier_points):
            x,y,z = new_points[i]
            p.co = (x,y,z)
            p.keyframe_insert(data_path="co")
            p.handle_left = (x, y, z)
            p.keyframe_insert(data_path="handle_left")
            p.handle_right = (x, y, z)
            p.keyframe_insert(data_path="handle_right")

# create material
material = bpy.data.materials.new("Material")
centerline.active_material = material
material.use_nodes = True
material.node_tree.links.remove(material.node_tree.links[0])
material.node_tree.nodes.remove(material.node_tree.nodes['Principled BSDF'])

glass_node = material.node_tree.nodes.new("ShaderNodeBsdfGlass")
glass_node.inputs["Color"].default_value = (0.0, 0.8, 1.0, 1.0)
glass_node.inputs["Roughness"].default_value = 0.1
material.node_tree.links.new(material.node_tree.nodes["Material Output"].inputs["Surface"], glass_node.outputs["BSDF"])

# create plane
minx = -0.1
maxx = 1.1
miny = -0.25
maxy = 0.25
minz = -0.25
maxz = 0.25
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,0.0,minz), rotation=(0.0,0.0,0.0))
basez1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,0.0,15), rotation=(0.0,0.0,0.0))
basez2 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,-15,0.0), rotation=(-np.pi/2,0.0,0.0))
basey1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,15,0.0), rotation=(np.pi/2,0.0,0.0))
basey2 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(-15,0.0,0.0), rotation=(0.0,-np.pi/2,0.0))
basex1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(15,0.0,0.0), rotation=(0.0,np.pi/2,0.0))
basex2 = bpy.context.active_object

# create material
base_material = bpy.data.materials.new("BaseMaterial")
base_material.use_nodes = True

base_bsdf = base_material.node_tree.nodes["Principled BSDF"]

texture_image = base_material.node_tree.nodes.new('ShaderNodeTexImage')
texture_path = "/Users/jantomec/Downloads/fabric_pattern_05_8k_png/fabric_pattern_05_rough_8k.png"
texture_image.image = bpy.data.images.load(texture_path)
texture_image.texture_mapping.scale = (10,10,10)
base_material.node_tree.links.new(base_bsdf.inputs['Base Color'], texture_image.outputs['Color'])

basez1.active_material = base_material
basez2.active_material = base_material
basey1.active_material = base_material
basey2.active_material = base_material
basex1.active_material = base_material
basex2.active_material = base_material

# add light
# create light datablock, set attributes
light_data = bpy.data.lights.new(name="light_2.80", type='POINT')
light_data.energy = 10000
light_data.cycles.samples = 4

# create new object with our light datablock
light_object = bpy.data.objects.new(name="Light", object_data=light_data)
light_object.location = (7,-10,10)

# link light object
bpy.context.collection.objects.link(light_object)


# add camera
camera_data = bpy.data.cameras.new(name='Camera')
camera_object = bpy.data.objects.new('Camera', camera_data)
bpy.context.scene.collection.objects.link(camera_object)

# Set camera fov in degrees
camera_object.data.angle = 35*np.pi/180.0

# Set camera rotation in euler angles
xc = 1.3
yc = -3.0
zc = 0.75
midpoint = [(minx+maxx)/2, (miny+maxy)/2, (minz+maxz)/2]
camera_object.rotation_mode = 'XZY'
camera_object.rotation_euler[0] = np.pi/2
camera_object.rotation_euler[2] = np.arctan2(xc - midpoint[0], -(yc - midpoint[1]))
camera_object.rotation_euler[0] = np.pi/2 - np.arctan2(zc, np.sqrt((xc - midpoint[0])**2 * (yc-midpoint[1])**2)) + 0.07

# Set camera translation
camera_object.location = (xc, yc, zc)

답변

3 lemon Nov 03 2020 at 18:42

모양 가장자리를 약간 부드럽게하여 수정할 수 있습니다.

이 경우 수행하려면 다음을 수행하십시오.

Bevel 오브젝트 반전 (마치 마지막 모양이 반전 된 법선이있는 것처럼) :

#Reversed indices to make the final shape correctly oriented
cross_section_points = 0.5*np.array([
    [-0.1, 0.1],
    [ 0.1, 0.1],
    [ 0.1,-0.1],
    [-0.1,-0.1]
])

"중심선"오브젝트에 베벨 수정자를 추가합니다.

# Bevel modifier
bevel_modifier = centerline.modifiers.new("Bevel", "BEVEL")
bevel_modifier.width = 0.005
bevel_modifier.segments = 3
bevel_modifier.limit_method = 'ANGLE'

참고 : 먼저 이것은 화선이고 (?)이어야합니다. 그러나 이것은 여기서 작동하지 않습니다 .