2021年3月29日 星期一

從Blender裡萃取模組資料(11)

 從Blender裡萃取模組資料(11)

前言

  在之前的 從Blender裡萃取模組資料(9) 裡有示範如何萃取 Texture 的資料,但 Blender 2.8 以後的 Material 採取 Node 編輯的方式設定,所以該範例的方法已無法在  Blender 2.8 以後使用,這次就來研究如何萃取,在此把學習的過程做個紀錄。


內容

  在開始之前請先將 Material 調成以下

新增 Texture 給 Base Color


這次需要示範如何萃取 Image Texture 的資料,所以要新增一張圖並連結到"Base Color"。這次的範例會示範如何萃取連結到"Base Color"接口的 Image Texture,具體的範例如下

import bpy
import bmesh

tagMesh = bpy.data.meshes["Cube"]
#Create bmesh from mesh
tagBMesh = bmesh.new()
tagBMesh.from_mesh(tagMesh)

#
def find_node_by_name( srcNode , nodeName):
    if srcNode.name == nodeName:
        return srcNode
    tagNode = None
    for socket in srcNode.inputs:
        for link in socket.links:
            tagNode = find_node_by_name( link.from_node , nodeName )
            if tagNode != None:
                break
        if tagNode != None:
            break
    #
    return tagNode
#
def find_node_from_node_socket( srcNode , socketName , nodeName):
    tagSocket = srcNode.inputs.get( socketName )
    if tagSocket == None:
        return None
    tagNode = None
    for link in tagSocket.links:
        tagNode = find_node_by_name( link.from_node , nodeName )
        if tagNode != None:
            break
    #
    return tagNode
#Start extract
matList = tagMesh.materials

for mat in matList:
    print( 'material name:' , mat.name )
    outputNode = mat.node_tree.nodes.get( 'Material Output' )
    if outputNode != None:
        principledBSDFNode = find_node_by_name( outputNode , 'Principled BSDF' )
        if principledBSDFNode != None:
            imageNode = find_node_from_node_socket( principledBSDFNode , 'Base Color' , 'Image Texture' )
            if imageNode != None:
                print( 'Image name:' , imageNode.image.name)
                print( 'Image width: ', imageNode.image.size[0] )
                print( 'Image height: ', imageNode.image.size[1] )
                print( 'Image format: ', imageNode.image.file_format )
                print( 'Image path: ' , imageNode.image.filepath_from_user() )
                print( 'Image Node interpolation:' , imageNode.interpolation )
                print( 'Image Node projection:' , imageNode.projection )
                print( 'Image Node extension:' , imageNode.extension )
                print( 'Image source:' , imageNode.image.source )
                print( 'Image color space:' , imageNode.image.colorspace_settings.name )
            else:
                #Show default value
                socket = principledBSDFNode.inputs.get( 'Base Color' )
                for val in socket.default_value:
                    print( 'data:' , val )
  
#Free bmesh...
tagBMesh.free()


範例裡有兩個工具 Function ,分別為"find_node_by_name"與"find_node_from_node_socket",第一個是基於某個 Node 來從所有的輸入接口尋找目標 Node ,第二則是基於某個 Node 的指定接口來尋找目標 Node 。萃取的過程比想像中簡單,透過 Material 裡的"node_tree"來取得輸出的 Node (Material Output),接著透過"find_node_by_name"來尋找"Principled BSDF" Node ,用工具 Function 來尋找是因為不知道中間會過多少個 Node ,接著就透過"find_node_from_node_socket"從"Base Color"接口來尋找"Image Texture",範例在找到"Image Texture"時就取得 Node 的相關資料,當沒取得時就取得"Base Color"的顏色資料(當該接口沒有被連結時)。


  在取得"Base Color"的顏色資料時是透過"default_value",但官方的說明文件上沒有這個屬性,在 [ blender.stackexchange.com ] PyNodes API: transferring data between nodes with sockets 裡我才找到有這個屬性可以提取。這次範例的工具 Function 都只找出第一個目標 Node ,無法解決多個目標 Node 的狀況。由於 Material 採取 Node 編輯,但由於每個遊戲引擎的 Node 規格不太一樣,就算詳細萃取的每個 Node 的資料也很難可以匯出給其它的遊戲引擎,所以只提供這樣不完整的萃取方法,如果這樣不夠用以後在補新的。

 

參考資料

[ docs.blender.org ] Blender 2.92.0 Python API Documentation

[ blender.stackexchange.com ] PyNodes API: transferring data between nodes with sockets


相關文章

從Blender裡萃取模組資料(9)

2021年3月23日 星期二

從Blender裡萃取模組資料(10)

 從Blender裡萃取模組資料(10)

前言

  在先前的"從Blender裡萃取模組資料"系列文章中發現在萃取 Material 的時候沒有萃取對應的 Vertex ,也就是一個 Mesh 有多個 Material 時要如何萃取,在此做個紀錄。


內容

  先看以下範例

import bpy
import bmesh

tagMesh = bpy.data.meshes["Cube"]
#Create bmesh from mesh
tagBMesh = bmesh.new()
tagBMesh.from_mesh(tagMesh)

#Start extract
matList = tagMesh.materials

for face in tagBMesh.faces:
    #Start extract face data
    print( 'material index:' , face.material_index )
    print( 'material name:' , matList[ face.material_index ].name)
  
#Free bmesh...
tagBMesh.free()


要萃取 Vertex 所屬的Material 可以透過 bmesh 來取得,加上先前 從Blender裡萃取模組資料(1) 裡的範例搭配使用就可以簡單地取得。要注意的是取得的資料"material.index",這是一個整數型態,而非名稱,所以是有順序性的,這個索引對應的陣列,這個對應的陣列是"mesh.materials",也就是範例的"matList",透過這個陣列加上"face.material_index"就可以完整萃取到對應資訊。


參考資料

[ docs.blender.org ] Blender 2.92.0 Python API Documentation


相關文章

從Blender裡萃取模組資料(9)

2021年3月17日 星期三

在 Blender 裡使用高面數模型製作 Normal map

 在 Blender 裡使用高面數模型製作 Normal map

前言

  在 Blender 2.7 時就支援用高面數模型製作 Normal map ,但不知是太久沒操作,在 2.9 時操作遽然失敗了!所以最近從新複習了一下這個操作,並在此做個紀錄。


內容

  在開始前先準備要使用的低面數模型,這裡使用的就是單純的 cube ,如下圖

低面數模型與 Shader 的設定狀況

圖中左側為低面數模型,其實是 Blender 預設的 cube 模型,右側為 Shader 的狀況,要新增一個 Texture node ,這個就是計算完的 Normal map ,在圖的"1"處,在圖中的"2"處,新增 Normap Map node ,圖中圈起來的地方要設定要使用哪一組 UV ,這裡選擇了預設的那一組。接著來看高面數的模型,如下圖 

高面數模型與 Shader 的設定狀況

高面數模型的上方有突起,前方有凹陷, Shader 使用的是預設的 Material ,這裡要注意高面數模型與低面數模型不要共用同一個 Material


  準備模型後就可以開始 Bake ,操作如下

設定 Render properties

選取高面數與低面數模型,選取前注意 3D View 不要處在 Edit Mode ,要在 Object Mode ,選取要注意有"順序性",先選高面數模型再選低面數模型,接著設定 Render properties ,點選圖中"2"處後,將 Render Engine 改成"cycles",接著往下找到 Bake 項目如下圖設定

設定 Bake 選項

選取 Bake Type 為 Normal ,也就是圖中的"1"處,接著選取 Selected to  Active ,並將 Extrusion 設為"0.5",最後按下"Bake"(圖中的"4"處)後就可以產生 Normal map 。範例產生的結果如下圖
範例產生的 Normal map

2021年3月8日 星期一

解決 Bevel 時產生的多餘 faces

 解決 Bevel 時產生的多餘 faces

前言

  最近使用 Blender 時發現 Bevel 的功能不太正常,以前都沒發現 Bevel 的結果其實有些小毛病,這裡提供解決的方法並做個紀錄。


內容

  在使用 Bevel 時為了不產生不正常的 faces ,所以會打開 Clamp Overlap ,如下圖

使用 Clamp Overlap 

但當完成後可以看到下圖

異常的 Edge

以前沒特別注意到中間 Overlap 的 edge 線條特別的粗,結果研究了一下發現那裡的 edge 有不正常的地方,如下圖

Clamp Overlap 處的 Edge 不正常的地方

如果揀選該處的 vertex 移動後就可以發現該處的不正常,這個問題如何解決呢?問題發生該處有一個兩兩頂點共點的 face , Bevel 工具提供了 Clamp Overlap 但卻不解決該處的不正常,可以用以下方法解決

解決的方法

由於該處有共點的狀況,必須先開啟 X-Ray 模式( alr + z ),開啟後再透過圈選的方式選擇該處的 vertex ,選完後用 Merge ( m ) 接著選取"By Distance"後就可以將該處的 face 移除。


解決 Radeon Software 與軟體的快捷鍵衝突的問題

解決 Radeon Software 與軟體的快捷鍵衝突的問題

前言

  最近使用 Blender 的時候發現按下某快捷鍵後會跳出 Radeon Software 的使用介面,所以就研究一下如何解決快捷鍵衝突的問題。


內容

  這次衝突的快捷鍵是" Alt + Z " 與" Alt + R ",這個衝突並不只發生在 Blender ,在任何軟體按下都有一樣的效果,所以修改 Blender 的快捷鍵並不是好方法,所以應改動 Radeon Software ,  Radeon Software  是 AMD 顯卡的軟體,可以透過它更新驅動程式或錄影,雖然可以直接翻安裝來解決問題,但以後要更新驅動程式就要自己手動操作,這也不是個好方法。有辦法關掉它嗎?答案是肯定的,如下圖

關閉 Radeon Software 的操作介面


這個功能的名稱遽然叫"遊戲中重疊",這個名稱估計是翻譯來的,所以我找了很久都沒找到,最後在 [ www.ptt.cc ] [請益] 怎麼讓AMD 2020版驅動不要跳出alt+r視窗 裡找到答案。


參考資料

[ www.ptt.cc ] [請益] 怎麼讓AMD 2020版驅動不要跳出alt+r視窗