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
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018-2022 The glTF-Blender-IO authors.
import bpy
from io_scene_gltf2.io.com.gltf2_io_extensions import Extension
from io_scene_gltf2.blender.exp import gltf2_blender_get
from io_scene_gltf2.io.com.gltf2_io_constants import GLTF_IOR
from io_scene_gltf2.blender.com.gltf2_blender_default import BLENDER_SPECULAR, BLENDER_SPECULAR_TINT
from io_scene_gltf2.blender.exp import gltf2_blender_gather_texture_info
def export_original_specular(blender_material, export_settings):
specular_extension = {}
original_specular_socket = gltf2_blender_get.get_socket_old(blender_material, 'Specular')
original_specularcolor_socket = gltf2_blender_get.get_socket_old(blender_material, 'Specular Color')
if original_specular_socket is None or original_specularcolor_socket is None:
return None, None
specular_non_linked = isinstance(original_specular_socket, bpy.types.NodeSocket) and not original_specular_socket.is_linked
specularcolor_non_linked = isinstance(original_specularcolor_socket, bpy.types.NodeSocket) and not original_specularcolor_socket.is_linked
use_actives_uvmaps = []
if specular_non_linked is True:
fac = original_specular_socket.default_value
if fac != 1.0:
specular_extension['specularFactor'] = fac
else:
# Factor
fac = gltf2_blender_get.get_factor_from_socket(original_specular_socket, kind='VALUE')
if fac is not None and fac != 1.0:
specular_extension['specularFactor'] = fac
# Texture
if gltf2_blender_get.has_image_node_from_socket(original_specular_socket):
original_specular_texture, original_specular_use_active_uvmap, _ = gltf2_blender_gather_texture_info.gather_texture_info(
original_specular_socket,
(original_specular_socket,),
export_settings,
)
specular_extension['specularTexture'] = original_specular_texture
if original_specular_use_active_uvmap:
use_actives_uvmaps.append("specularTexture")
if specularcolor_non_linked is True:
color = original_specularcolor_socket.default_value[:3]
if color != [1.0, 1.0, 1.0]:
specular_extension['specularColorFactor'] = color
else:
# Factor
fac = gltf2_blender_get.get_factor_from_socket(original_specularcolor_socket, kind='RGB')
if fac is not None and fac != [1.0, 1.0, 1.0]:
specular_extension['specularColorFactor'] = fac
# Texture
if gltf2_blender_get.has_image_node_from_socket(original_specularcolor_socket):
original_specularcolor_texture, original_specularcolor_use_active_uvmap, _ = gltf2_blender_gather_texture_info.gather_texture_info(
original_specularcolor_socket,
(original_specularcolor_socket,),
export_settings,
)
specular_extension['specularColorTexture'] = original_specularcolor_texture
if original_specularcolor_use_active_uvmap:
use_actives_uvmaps.append("specularColorTexture")
return Extension('KHR_materials_specular', specular_extension, False), use_actives_uvmaps
def export_specular(blender_material, export_settings):
if export_settings['gltf_original_specular'] is True:
return export_original_specular(blender_material, export_settings)
specular_extension = {}
specular_ext_enabled = False
specular_socket = gltf2_blender_get.get_socket(blender_material, 'Specular')
specular_tint_socket = gltf2_blender_get.get_socket(blender_material, 'Specular Tint')
base_color_socket = gltf2_blender_get.get_socket(blender_material, 'Base Color')
transmission_socket = gltf2_blender_get.get_socket(blender_material, 'Transmission')
ior_socket = gltf2_blender_get.get_socket(blender_material, 'IOR')
if base_color_socket is None:
return None, None
# TODOExt replace by __has_image_node_from_socket calls
specular_not_linked = isinstance(specular_socket, bpy.types.NodeSocket) and not specular_socket.is_linked
specular_tint_not_linked = isinstance(specular_tint_socket, bpy.types.NodeSocket) and not specular_tint_socket.is_linked
base_color_not_linked = isinstance(base_color_socket, bpy.types.NodeSocket) and not base_color_socket.is_linked
transmission_not_linked = isinstance(transmission_socket, bpy.types.NodeSocket) and not transmission_socket.is_linked
ior_not_linked = isinstance(ior_socket, bpy.types.NodeSocket) and not ior_socket.is_linked
specular = specular_socket.default_value if specular_not_linked else None
specular_tint = specular_tint_socket.default_value if specular_tint_not_linked else None
transmission = transmission_socket.default_value if transmission_not_linked else None
ior = ior_socket.default_value if ior_not_linked else GLTF_IOR # textures not supported #TODOExt add warning?
base_color = base_color_socket.default_value[0:3]
no_texture = (transmission_not_linked and specular_not_linked and specular_tint_not_linked and
(specular_tint == 0.0 or (specular_tint != 0.0 and base_color_not_linked)))
use_actives_uvmaps = []
if no_texture:
if specular != BLENDER_SPECULAR or specular_tint != BLENDER_SPECULAR_TINT:
import numpy as np
# See https://gist.github.com/proog128/d627c692a6bbe584d66789a5a6437a33
specular_ext_enabled = True
def normalize(c):
luminance = lambda c: 0.3 * c[0] + 0.6 * c[1] + 0.1 * c[2]
assert(len(c) == 3)
l = luminance(c)
if l == 0:
return np.array(c)
return np.array([c[0] / l, c[1] / l, c[2] / l])
f0_from_ior = ((ior - 1)/(ior + 1))**2
tint_strength = (1 - specular_tint) + normalize(base_color) * specular_tint
specular_color = (1 - transmission) * (1 / f0_from_ior) * 0.08 * specular * tint_strength + transmission * tint_strength
specular_extension['specularColorFactor'] = list(specular_color)
else:
if specular_not_linked and specular == BLENDER_SPECULAR and specular_tint_not_linked and specular_tint == BLENDER_SPECULAR_TINT:
return None, None
# Trying to identify cases where exporting a texture will not be needed
if specular_not_linked and transmission_not_linked and \
specular == 0.0 and transmission == 0.0:
specular_extension['specularColorFactor'] = [0.0, 0.0, 0.0]
return specular_extension, []
# There will be a texture, with a complex calculation (no direct channel mapping)
sockets = (specular_socket, specular_tint_socket, base_color_socket, transmission_socket, ior_socket)
# Set primary socket having a texture
primary_socket = specular_socket
if specular_not_linked:
primary_socket = specular_tint_socket
if specular_tint_not_linked:
primary_socket = base_color_socket
if base_color_not_linked:
primary_socket = transmission_socket
specularColorTexture, use_active_uvmap, specularColorFactor = gltf2_blender_gather_texture_info.gather_texture_info(
primary_socket,
sockets,
export_settings,
filter_type='ANY')
if specularColorTexture is None:
return None, None
if use_active_uvmap:
use_actives_uvmaps.append("specularColorTexture")
specular_ext_enabled = True
specular_extension['specularColorTexture'] = specularColorTexture
if specularColorFactor is not None:
specular_extension['specularColorFactor'] = specularColorFactor
specular_extension = Extension('KHR_materials_specular', specular_extension, False) if specular_ext_enabled else None
return specular_extension, use_actives_uvmaps
|