Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gltf2_blender_gather_materials_pbr_metallic_roughness.py « exp « blender « io_scene_gltf2 - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3e18dbad95707cd43c00fa955647e74505e5fbbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2021 The glTF-Blender-IO authors.

import bpy

from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.blender.exp import gltf2_blender_gather_texture_info, gltf2_blender_search_node_tree
from io_scene_gltf2.blender.exp import gltf2_blender_get
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions


@cached
def gather_material_pbr_metallic_roughness(blender_material, orm_texture, export_settings):
    if not __filter_pbr_material(blender_material, export_settings):
        return None

    material = gltf2_io.MaterialPBRMetallicRoughness(
        base_color_factor=__gather_base_color_factor(blender_material, export_settings),
        base_color_texture=__gather_base_color_texture(blender_material, export_settings),
        extensions=__gather_extensions(blender_material, export_settings),
        extras=__gather_extras(blender_material, export_settings),
        metallic_factor=__gather_metallic_factor(blender_material, export_settings),
        metallic_roughness_texture=__gather_metallic_roughness_texture(blender_material, orm_texture, export_settings),
        roughness_factor=__gather_roughness_factor(blender_material, export_settings)
    )

    export_user_extensions('gather_material_pbr_metallic_roughness_hook', export_settings, material, blender_material, orm_texture)

    return material


def __filter_pbr_material(blender_material, export_settings):
    return True


def __gather_base_color_factor(blender_material, export_settings):
    if not blender_material.use_nodes:
        return [*blender_material.diffuse_color[:3], 1.0]

    rgb, alpha = None, None

    alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")
    if isinstance(alpha_socket, bpy.types.NodeSocket):
        if export_settings['gltf_image_format'] != "NONE":
            alpha = gltf2_blender_get.get_factor_from_socket(alpha_socket, kind='VALUE')
        else:
            alpha = gltf2_blender_get.get_const_from_default_value_socket(alpha_socket, kind='VALUE')

    base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColorFactor")
    if isinstance(base_color_socket, bpy.types.NodeSocket):
        if export_settings['gltf_image_format'] != "NONE":
            rgb = gltf2_blender_get.get_factor_from_socket(base_color_socket, kind='RGB')
        else:
            rgb = gltf2_blender_get.get_const_from_default_value_socket(base_color_socket, kind='RGB')

    if rgb is None: rgb = [1.0, 1.0, 1.0]
    if alpha is None: alpha = 1.0

    rgba = [*rgb, alpha]

    if rgba == [1, 1, 1, 1]: return None
    return rgba


def __gather_base_color_texture(blender_material, export_settings):
    base_color_socket = gltf2_blender_get.get_socket(blender_material, "Base Color")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket(blender_material, "BaseColor")
    if base_color_socket is None:
        base_color_socket = gltf2_blender_get.get_socket_old(blender_material, "BaseColor")

    alpha_socket = gltf2_blender_get.get_socket(blender_material, "Alpha")

    # keep sockets that have some texture : color and/or alpha
    inputs = tuple(
        socket for socket in [base_color_socket, alpha_socket]
        if socket is not None and __has_image_node_from_socket(socket)
    )
    if not inputs:
        return None

    return gltf2_blender_gather_texture_info.gather_texture_info(inputs[0], inputs, export_settings)


def __gather_extensions(blender_material, export_settings):
    return None


def __gather_extras(blender_material, export_settings):
    return None


def __gather_metallic_factor(blender_material, export_settings):
    if not blender_material.use_nodes:
        return blender_material.metallic

    metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic")
    if metallic_socket is None:
        metallic_socket = gltf2_blender_get.get_socket_old(blender_material, "MetallicFactor")
    if isinstance(metallic_socket, bpy.types.NodeSocket):
        fac = gltf2_blender_get.get_factor_from_socket(metallic_socket, kind='VALUE')
        return fac if fac != 1 else None
    return None


def __gather_metallic_roughness_texture(blender_material, orm_texture, export_settings):
    metallic_socket = gltf2_blender_get.get_socket(blender_material, "Metallic")
    roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness")

    hasMetal = metallic_socket is not None and __has_image_node_from_socket(metallic_socket)
    hasRough = roughness_socket is not None and __has_image_node_from_socket(roughness_socket)

    if not hasMetal and not hasRough:
        metallic_roughness = gltf2_blender_get.get_socket_old(blender_material, "MetallicRoughness")
        if metallic_roughness is None or not __has_image_node_from_socket(metallic_roughness):
            return None
        texture_input = (metallic_roughness,)
    elif not hasMetal:
        texture_input = (roughness_socket,)
    elif not hasRough:
        texture_input = (metallic_socket,)
    else:
        texture_input = (metallic_socket, roughness_socket)

    return gltf2_blender_gather_texture_info.gather_texture_info(
        texture_input[0],
        orm_texture or texture_input,
        export_settings,
    )


def __gather_roughness_factor(blender_material, export_settings):
    if not blender_material.use_nodes:
        return blender_material.roughness

    roughness_socket = gltf2_blender_get.get_socket(blender_material, "Roughness")
    if roughness_socket is None:
        roughness_socket = gltf2_blender_get.get_socket_old(blender_material, "RoughnessFactor")
    if isinstance(roughness_socket, bpy.types.NodeSocket):
        fac = gltf2_blender_get.get_factor_from_socket(roughness_socket, kind='VALUE')
        return fac if fac != 1 else None
    return None

def __has_image_node_from_socket(socket):
    result = gltf2_blender_search_node_tree.from_socket(
        socket,
        gltf2_blender_search_node_tree.FilterByType(bpy.types.ShaderNodeTexImage))
    if not result:
        return False
    return True