Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
#
|
|
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
|
|
|
|
# <pep8 compliant>
|
|
|
|
|
|
|
|
import bpy
|
|
|
|
from mathutils import Vector
|
|
|
|
|
|
|
|
__all__ = (
|
|
|
|
"PrincipledBSDFWrapper",
|
2018-10-01 08:42:58 +10:00
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
def _set_check(func):
|
|
|
|
from functools import wraps
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@wraps(func)
|
|
|
|
def wrapper(self, *args, **kwargs):
|
|
|
|
if self.is_readonly:
|
|
|
|
assert(not "Trying to set value to read-only shader!")
|
|
|
|
return
|
|
|
|
return func(self, *args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
|
|
|
class ShaderWrapper():
|
|
|
|
"""
|
|
|
|
Base class with minimal common ground for all types of shader interfaces we may want/need to implement.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# The two mandatory nodes any children class should support.
|
|
|
|
NODES_LIST = (
|
|
|
|
"node_out",
|
|
|
|
|
|
|
|
"_node_texcoords",
|
2018-10-01 08:42:58 +10:00
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
__slots__ = (
|
|
|
|
"is_readonly",
|
|
|
|
"material",
|
|
|
|
"_textures",
|
|
|
|
"_grid_locations",
|
2018-10-01 08:42:58 +10:00
|
|
|
) + NODES_LIST
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
_col_size = 300
|
|
|
|
_row_size = 300
|
|
|
|
|
|
|
|
def _grid_to_location(self, x, y, dst_node=None, ref_node=None):
|
|
|
|
if ref_node is not None: # x and y are relative to this node location.
|
|
|
|
nx = round(ref_node.location.x / self._col_size)
|
|
|
|
ny = round(ref_node.location.y / self._row_size)
|
|
|
|
x += nx
|
|
|
|
y += ny
|
|
|
|
loc = None
|
|
|
|
while True:
|
|
|
|
loc = (x * self._col_size, y * self._row_size)
|
|
|
|
if loc not in self._grid_locations:
|
|
|
|
break
|
|
|
|
loc = (x * self._col_size, (y - 1) * self._row_size)
|
|
|
|
if loc not in self._grid_locations:
|
|
|
|
break
|
|
|
|
loc = (x * self._col_size, (y - 2) * self._row_size)
|
|
|
|
if loc not in self._grid_locations:
|
|
|
|
break
|
|
|
|
x -= 1
|
|
|
|
self._grid_locations.add(loc)
|
|
|
|
if dst_node is not None:
|
|
|
|
dst_node.location = loc
|
|
|
|
dst_node.width = min(dst_node.width, self._col_size - 20)
|
|
|
|
return loc
|
|
|
|
|
|
|
|
def __init__(self, material, is_readonly=True):
|
|
|
|
self.is_readonly = is_readonly
|
|
|
|
self.material = material
|
|
|
|
self.update()
|
|
|
|
|
|
|
|
def update(self): # Should be re-implemented by children classes...
|
|
|
|
for node in self.NODES_LIST:
|
|
|
|
setattr(self, node, None)
|
|
|
|
self._textures = {}
|
|
|
|
self._grid_locations = set()
|
|
|
|
|
|
|
|
def use_nodes_get(self):
|
|
|
|
return self.material.use_nodes
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def use_nodes_set(self, val):
|
|
|
|
self.material.use_nodes = val
|
|
|
|
self.update()
|
|
|
|
use_nodes = property(use_nodes_get, use_nodes_set)
|
|
|
|
|
|
|
|
def node_texcoords_get(self):
|
|
|
|
if not self.use_nodes:
|
|
|
|
return None
|
|
|
|
if self._node_texcoords is None:
|
|
|
|
for n in self.material.node_tree.nodes:
|
|
|
|
if n.bl_idname == 'ShaderNodeTexCoord':
|
|
|
|
self._node_texcoords = n
|
|
|
|
self._grid_to_location(0, 0, ref_node=n)
|
|
|
|
break
|
|
|
|
if self._node_texcoords is None and not self.is_readonly:
|
|
|
|
tree = self.material.node_tree
|
|
|
|
nodes = tree.nodes
|
|
|
|
links = tree.links
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
node_texcoords = nodes.new(type='ShaderNodeTexCoord')
|
|
|
|
node_texcoords.label = "Texture Coords"
|
|
|
|
self._grid_to_location(-5, 1, dst_node=node_texcoords)
|
|
|
|
self._node_texcoords = node_texcoords
|
|
|
|
return self._node_texcoords
|
|
|
|
node_texcoords = property(node_texcoords_get)
|
|
|
|
|
|
|
|
|
|
|
|
class PrincipledBSDFWrapper(ShaderWrapper):
|
|
|
|
"""
|
|
|
|
Hard coded shader setup, based in Principled BSDF.
|
|
|
|
Should cover most common cases on import, and gives a basic nodal shaders support for export.
|
|
|
|
Supports basic: diffuse/spec/reflect/transparency/normal, with texturing.
|
|
|
|
"""
|
|
|
|
NODES_LIST = (
|
|
|
|
"node_out",
|
|
|
|
"node_principled_bsdf",
|
|
|
|
|
|
|
|
"_node_normalmap",
|
|
|
|
"_node_texcoords",
|
2018-10-01 08:42:58 +10:00
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
__slots__ = (
|
|
|
|
"is_readonly",
|
|
|
|
"material",
|
2018-10-01 08:42:58 +10:00
|
|
|
) + NODES_LIST
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
NODES_LIST = ShaderWrapper.NODES_LIST + NODES_LIST
|
|
|
|
|
|
|
|
def __init__(self, material, is_readonly=True):
|
|
|
|
super(PrincipledBSDFWrapper, self).__init__(material, is_readonly)
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
super(PrincipledBSDFWrapper, self).update()
|
|
|
|
|
|
|
|
if not self.use_nodes:
|
|
|
|
return
|
|
|
|
|
|
|
|
tree = self.material.node_tree
|
|
|
|
|
|
|
|
nodes = tree.nodes
|
|
|
|
links = tree.links
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Main output and shader.
|
|
|
|
node_out = None
|
|
|
|
node_principled = None
|
|
|
|
for n in nodes:
|
|
|
|
if n.bl_idname == 'ShaderNodeOutputMaterial' and n.inputs[0].is_linked:
|
|
|
|
node_out = n
|
|
|
|
node_principled = n.inputs[0].links[0].from_node
|
|
|
|
elif n.bl_idname == 'ShaderNodeBsdfPrincipled' and n.outputs[0].is_linked:
|
|
|
|
node_principled = n
|
|
|
|
for lnk in n.outputs[0].links:
|
|
|
|
node_out = lnk.to_node
|
|
|
|
if node_out.bl_idname == 'ShaderNodeOutputMaterial':
|
|
|
|
break
|
2018-10-01 08:42:58 +10:00
|
|
|
if (
|
|
|
|
node_out is not None and node_principled is not None and
|
|
|
|
node_out.bl_idname == 'ShaderNodeOutputMaterial' and
|
|
|
|
node_principled.bl_idname == 'ShaderNodeBsdfPrincipled'
|
|
|
|
):
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
break
|
|
|
|
node_out = node_principled = None # Could not find a valid pair, let's try again
|
|
|
|
|
|
|
|
if node_out is not None:
|
|
|
|
self._grid_to_location(0, 0, ref_node=node_out)
|
|
|
|
elif not self.is_readonly:
|
|
|
|
node_out = nodes.new(type='ShaderNodeOutputMaterial')
|
|
|
|
node_out.label = "Material Out"
|
|
|
|
node_out.target = 'ALL'
|
|
|
|
self._grid_to_location(1, 1, dst_node=node_out)
|
|
|
|
self.node_out = node_out
|
|
|
|
|
|
|
|
if node_principled is not None:
|
|
|
|
self._grid_to_location(0, 0, ref_node=node_principled)
|
|
|
|
elif not self.is_readonly:
|
|
|
|
node_principled = nodes.new(type='ShaderNodeBsdfPrincipled')
|
|
|
|
node_principled.label = "Principled BSDF"
|
|
|
|
self._grid_to_location(0, 1, dst_node=node_principled)
|
|
|
|
# Link
|
|
|
|
links.new(node_principled.outputs["BSDF"], self.node_out.inputs["Surface"])
|
|
|
|
self.node_principled_bsdf = node_principled
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Normal Map, lazy initialization...
|
|
|
|
self._node_normalmap = None
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Tex Coords, lazy initialization...
|
|
|
|
self._node_texcoords = None
|
|
|
|
|
|
|
|
def node_normalmap_get(self):
|
|
|
|
if not self.use_nodes:
|
|
|
|
return None
|
|
|
|
if self._node_normalmap is None and self.node_principled_bsdf is not None:
|
|
|
|
node_principled = self.node_principled_bsdf
|
|
|
|
if node_principled.inputs["Normal"].is_linked:
|
|
|
|
node_normalmap = node_principled.inputs["Normal"].links[0].from_node
|
|
|
|
if node_normalmap.bl_idname == 'ShaderNodeNormalMap':
|
|
|
|
self._node_normalmap = node_normalmap
|
|
|
|
self._grid_to_location(0, 0, ref_node=node_normalmap)
|
|
|
|
if self._node_normalmap is None and not self.is_readonly:
|
|
|
|
node_normalmap = nodes.new(type='ShaderNodeNormalMap')
|
|
|
|
node_normalmap.label = "Normal/Map"
|
|
|
|
self._grid_to_location(-1, -2, dst_node=node_normalmap, ref_node=node_principled)
|
|
|
|
# Link
|
|
|
|
links.new(node_normalmap.outputs["Normal"], node_principled.inputs["Normal"])
|
|
|
|
return self._node_normalmap
|
|
|
|
node_normalmap = property(node_normalmap_get)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Diffuse.
|
|
|
|
|
|
|
|
def diffuse_color_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return self.material.diffuse_color
|
|
|
|
return self.node_principled_bsdf.inputs["Base Color"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def diffuse_color_set(self, color):
|
|
|
|
self.material.diffuse_color = color
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Base Color"].default_value = color
|
|
|
|
diffuse_color = property(diffuse_color_get, diffuse_color_set)
|
|
|
|
|
|
|
|
def diffuse_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["Base Color"],
|
|
|
|
grid_row_diff=1,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
diffuse_texture = property(diffuse_texture_get)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Specular.
|
|
|
|
|
|
|
|
def specular_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return self.material.specular_intensity
|
|
|
|
return self.node_principled_bsdf.inputs["Specular"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def specular_set(self, value):
|
|
|
|
self.material.specular_intensity = value
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Specular"].default_value = value
|
|
|
|
specular = property(specular_get, specular_set)
|
|
|
|
|
|
|
|
def specular_tint_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return 0.0
|
|
|
|
return self.node_principled_bsdf.inputs["Specular Tint"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def specular_tint_set(self, value):
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Specular Tint"].default_value = value
|
|
|
|
specular_tint = property(specular_tint_get, specular_tint_set)
|
|
|
|
|
|
|
|
# Will only be used as gray-scale one...
|
|
|
|
def specular_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["Specular"],
|
|
|
|
grid_row_diff=0,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
specular_texture = property(specular_texture_get)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Roughness (also sort of inverse of specular hardness...).
|
|
|
|
|
|
|
|
def roughness_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return self.material.roughness
|
|
|
|
return self.node_principled_bsdf.inputs["Roughness"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def roughness_set(self, value):
|
|
|
|
self.material.roughness = value
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Roughness"].default_value = value
|
|
|
|
roughness = property(roughness_get, roughness_set)
|
|
|
|
|
|
|
|
# Will only be used as gray-scale one...
|
|
|
|
def roughness_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["Roughness"],
|
|
|
|
grid_row_diff=0,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
roughness_texture = property(roughness_texture_get)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Metallic (a.k.a reflection, mirror).
|
|
|
|
|
|
|
|
def metallic_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return self.material.metallic
|
|
|
|
return self.node_principled_bsdf.inputs["Metallic"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def metallic_set(self, value):
|
|
|
|
self.material.metallic = value
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Metallic"].default_value = value
|
|
|
|
metallic = property(metallic_get, metallic_set)
|
|
|
|
|
|
|
|
# Will only be used as gray-scale one...
|
|
|
|
def metallic_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["Metallic"],
|
|
|
|
grid_row_diff=0,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
metallic_texture = property(metallic_texture_get)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Transparency settings.
|
|
|
|
|
|
|
|
def ior_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return 1.0
|
|
|
|
return self.node_principled_bsdf.inputs["IOR"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def ior_set(self, value):
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["IOR"].default_value = value
|
|
|
|
ior = property(ior_get, ior_set)
|
|
|
|
|
|
|
|
# Will only be used as gray-scale one...
|
|
|
|
def ior_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["IOR"],
|
|
|
|
grid_row_diff=-1,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
ior_texture = property(ior_texture_get)
|
|
|
|
|
|
|
|
def transmission_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return 0.0
|
|
|
|
return self.node_principled_bsdf.inputs["Transmission"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def transmission_set(self, value):
|
|
|
|
if self.use_nodes and self.node_principled_bsdf is not None:
|
|
|
|
self.node_principled_bsdf.inputs["Transmission"].default_value = value
|
|
|
|
transmission = property(transmission_get, transmission_set)
|
|
|
|
|
|
|
|
# Will only be used as gray-scale one...
|
|
|
|
def transmission_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_principled_bsdf is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_principled_bsdf,
|
|
|
|
self.node_principled_bsdf.inputs["Transmission"],
|
|
|
|
grid_row_diff=-1,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
transmission_texture = property(transmission_texture_get)
|
|
|
|
|
|
|
|
# TODO: Do we need more complex handling for alpha (allowing masking and such)?
|
|
|
|
# Would need extra mixing nodes onto Base Color maybe, or even its own shading chain...
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Normal map.
|
|
|
|
|
|
|
|
def normalmap_strength_get(self):
|
|
|
|
if not self.use_nodes or self.node_normalmap is None:
|
|
|
|
return 0.0
|
|
|
|
return self.node_normalmap.inputs["Strength"].default_value
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def normalmap_strength_set(self, value):
|
|
|
|
if self.use_nodes and self.node_normalmap is not None:
|
|
|
|
self.node_normalmap.inputs["Strength"].default_value = value
|
|
|
|
normalmap_strength = property(normalmap_strength_get, normalmap_strength_set)
|
|
|
|
|
|
|
|
def normalmap_texture_get(self):
|
|
|
|
if not self.use_nodes or self.node_normalmap is None:
|
|
|
|
return None
|
2018-10-01 08:42:58 +10:00
|
|
|
return ShaderImageTextureWrapper(
|
|
|
|
self, self.node_normalmap,
|
|
|
|
self.node_normalmap.inputs["Color"],
|
|
|
|
grid_row_diff=-2,
|
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
normalmap_texture = property(normalmap_texture_get)
|
|
|
|
|
|
|
|
|
|
|
|
class ShaderImageTextureWrapper():
|
|
|
|
"""
|
|
|
|
Generic 'image texture'-like wrapper, handling image node, some mapping (texture coordinates transformations),
|
|
|
|
and texture coordinates source.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Note: this class assumes we are using nodes, otherwise it should never be used...
|
|
|
|
|
|
|
|
NODES_LIST = (
|
|
|
|
"node_dst",
|
|
|
|
"socket_dst",
|
|
|
|
|
|
|
|
"_node_image",
|
|
|
|
"_node_mapping",
|
2018-10-01 08:42:58 +10:00
|
|
|
)
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
__slots__ = (
|
|
|
|
"owner_shader",
|
|
|
|
"is_readonly",
|
|
|
|
"grid_row_diff",
|
|
|
|
"use_alpha",
|
2018-10-01 08:42:58 +10:00
|
|
|
) + NODES_LIST
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
|
|
|
|
def __new__(cls, owner_shader: ShaderWrapper, node_dst, socket_dst, *args, **kwargs):
|
|
|
|
instance = owner_shader._textures.get((node_dst, socket_dst), None)
|
|
|
|
if instance is not None:
|
|
|
|
return instance
|
|
|
|
instance = super(ShaderImageTextureWrapper, cls).__new__(cls)
|
|
|
|
owner_shader._textures[(node_dst, socket_dst)] = instance
|
|
|
|
return instance
|
|
|
|
|
|
|
|
def __init__(self, owner_shader: ShaderWrapper, node_dst, socket_dst, grid_row_diff=0, use_alpha=False):
|
|
|
|
self.owner_shader = owner_shader
|
|
|
|
self.is_readonly = owner_shader.is_readonly
|
|
|
|
self.node_dst = node_dst
|
|
|
|
self.socket_dst = socket_dst
|
|
|
|
self.grid_row_diff = grid_row_diff
|
|
|
|
self.use_alpha = use_alpha
|
|
|
|
|
|
|
|
self._node_image = None
|
|
|
|
self._node_mapping = None
|
|
|
|
|
|
|
|
tree = node_dst.id_data
|
|
|
|
nodes = tree.nodes
|
|
|
|
links = tree.links
|
|
|
|
|
|
|
|
if socket_dst.is_linked:
|
|
|
|
self._node_image = socket_dst.links[0].from_node
|
|
|
|
|
|
|
|
if self.node_image is not None:
|
|
|
|
socket_dst = self.node_image.inputs["Vector"]
|
|
|
|
if socket_dst.is_linked:
|
|
|
|
from_node = socket_dst.links[0].from_node
|
|
|
|
if from_node.bl_idname == 'ShaderNodeMapping':
|
|
|
|
self._node_mapping = from_node
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Image.
|
|
|
|
|
|
|
|
def node_image_get(self):
|
|
|
|
if self._node_image is None:
|
|
|
|
if self.socket_dst.is_linked:
|
|
|
|
node_image = self.socket_dst.links[0].from_node
|
|
|
|
if node_image.bl_idname == 'ShaderNodeTexImage':
|
|
|
|
self._node_image = node_image
|
|
|
|
self.owner_shader._grid_to_location(0, 0, ref_node=node_image)
|
|
|
|
if self._node_image is None and not self.is_readonly:
|
|
|
|
tree = self.owner_shader.material.node_tree
|
|
|
|
|
|
|
|
node_image = tree.nodes.new(type='ShaderNodeTexImage')
|
|
|
|
self.owner_shader._grid_to_location(-1, 0 + self.grid_row_diff, dst_node=node_image, ref_node=self.node_dst)
|
|
|
|
|
|
|
|
tree.links.new(node_image.outputs["Alpha" if self.use_alpha else "Color"], self.socket_dst)
|
|
|
|
|
|
|
|
self._node_image = node_image
|
|
|
|
return self._node_image
|
|
|
|
node_image = property(node_image_get)
|
|
|
|
|
|
|
|
def image_get(self):
|
|
|
|
return self.node_image.image if self.node_image is not None else None
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def image_set(self, image):
|
|
|
|
self.node_image.image = image
|
|
|
|
image = property(image_get, image_set)
|
|
|
|
|
|
|
|
def projection_get(self):
|
|
|
|
return self.node_image.projection if self.node_image is not None else 'FLAT'
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def projection_set(self, projection):
|
|
|
|
self.node_image.projection = projection
|
|
|
|
projection = property(projection_get, projection_set)
|
|
|
|
|
|
|
|
def texcoords_get(self):
|
|
|
|
if self.node_image is not None:
|
|
|
|
socket = (self.node_mapping if self._node_mapping is not None else self.node_image).inputs["Vector"]
|
|
|
|
if socket.is_linked:
|
|
|
|
return socket.links[0].from_socket.name
|
|
|
|
return 'UV'
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def texcoords_set(self, texcoords):
|
|
|
|
tree = self.node_image.id_data
|
|
|
|
links = tree.links
|
|
|
|
node_dst = self.node_mapping if self._node_mapping is not None else self.node_image
|
|
|
|
socket_src = self.owner_shader.node_texcoords.outputs[texcoords]
|
|
|
|
links.new(socket_src, node_dst.inputs["Vector"])
|
|
|
|
texcoords = property(texcoords_get, texcoords_set)
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
# Mapping.
|
|
|
|
|
|
|
|
def node_mapping_get(self):
|
|
|
|
if self._node_mapping is None:
|
|
|
|
if self.node_image is None:
|
|
|
|
return None
|
|
|
|
if self.node_image.inputs["Vector"].is_linked:
|
|
|
|
node_mapping = self.node_image.inputs["Vector"].links[0].from_node
|
|
|
|
if node_mapping.bl_idname == 'ShaderNodeMapping':
|
|
|
|
self._node_mapping = node_mapping
|
|
|
|
self.owner_shader._grid_to_location(0, 0 + self.grid_row_diff, ref_node=node_mapping)
|
|
|
|
if self._node_mapping is None and not self.is_readonly:
|
|
|
|
# Find potential existing link into image's Vector input.
|
|
|
|
socket_dst = self.node_image.inputs["Vector"]
|
|
|
|
socket_src = socket_dst.links[0].from_socket if socket_dst.is_linked else None
|
|
|
|
|
|
|
|
tree = self.owner_shader.material.node_tree
|
|
|
|
node_mapping = tree.nodes.new(type='ShaderNodeMapping')
|
|
|
|
node_mapping.vector_type = 'TEXTURE'
|
|
|
|
self.owner_shader._grid_to_location(-1, 0, dst_node=node_mapping, ref_node=self.node_image)
|
|
|
|
|
|
|
|
# link mapping -> image node
|
|
|
|
tree.links.new(node_mapping.outputs["Vector"], socket_dst)
|
|
|
|
# And if already existing, re-link texcoords -> mapping
|
|
|
|
if socket_src is not None:
|
|
|
|
tree.links.new(socket_src, node_mapping.inputs["Vector"])
|
|
|
|
|
|
|
|
self._node_mapping = node_mapping
|
|
|
|
return self._node_mapping
|
|
|
|
node_mapping = property(node_mapping_get)
|
|
|
|
|
|
|
|
def translation_get(self):
|
|
|
|
return self.node_mapping.translation if self.node_mapping is not None else Vector((0.0, 0.0, 0.0))
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def translation_set(self, translation):
|
|
|
|
self.node_mapping.translation = translation
|
|
|
|
translation = property(translation_get, translation_set)
|
|
|
|
|
|
|
|
def rotation_get(self):
|
|
|
|
return self.node_mapping.rotation if self.node_mapping is not None else Vector((0.0, 0.0, 0.0))
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def rotation_set(self, rotation):
|
|
|
|
self.node_mapping.rotation = rotation
|
|
|
|
rotation = property(rotation_get, rotation_set)
|
|
|
|
|
|
|
|
def scale_get(self):
|
|
|
|
return self.node_mapping.scale if self.node_mapping is not None else Vector((1.0, 1.0, 1.0))
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def scale_set(self, scale):
|
|
|
|
self.node_mapping.scale = scale
|
|
|
|
scale = property(scale_get, scale_set)
|
|
|
|
|
|
|
|
def use_min_get(self):
|
|
|
|
return self.node_mapping.use_min if self_mapping.node is not None else False
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def use_min_set(self, use_min):
|
|
|
|
self.node_mapping.use_min = use_min
|
|
|
|
use_min = property(use_min_get, use_min_set)
|
|
|
|
|
|
|
|
def use_max_get(self):
|
|
|
|
return self.node_mapping.use_max if self_mapping.node is not None else False
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def use_max_set(self, use_max):
|
|
|
|
self.node_mapping.use_max = use_max
|
|
|
|
use_max = property(use_max_get, use_max_set)
|
|
|
|
|
|
|
|
def min_get(self):
|
|
|
|
return self.node_mapping.min if self.node_mapping is not None else Vector((0.0, 0.0, 0.0))
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def min_set(self, min):
|
|
|
|
self.node_mapping.min = min
|
|
|
|
min = property(min_get, min_set)
|
|
|
|
|
|
|
|
def max_get(self):
|
|
|
|
return self.node_mapping.max if self.node_mapping is not None else Vector((0.0, 0.0, 0.0))
|
2018-10-01 08:42:58 +10:00
|
|
|
|
Python IO: Initial nodal shader support for import AND export.
That new bpy_extras' node_shader_utils module is remotely based on
existing addons' cycles_shader_compat module. It has some key
differences though:
- It is based on Principled shader, instead of the noodle combination
of half a dozen simpler shaders.
- It does not do any value conversion (like e.g. clamping, which was
only suited for FBX). Any conversion/adaptation is to be done
by each IO add-on.
- It extensively uses accessors to offer:
- Easy read/write of values, hiding all the hairy noodly nodes
(principled shader helps a lot here).
- lazy creation of most nodes on accessing (when generating a
material), which avoids getting unused nodes in final shader.
- We only use Principled BSDF so far though, which means some features
supported by previous system are not yet implemented in new one.
Note that, even though we support 'exporting' side of things, this will
only work for a very specific (and basic) kind of shader. This will have
to be clearly explained in end-user documentation.
Also, that code has had some basic testing, but most certainly needs a
lot more refinement.
As proof-of-concept, OBJ IO script will be updated to use that new
system after that commit.
2018-09-27 22:03:30 +02:00
|
|
|
@_set_check
|
|
|
|
def max_set(self, max):
|
|
|
|
self.node_mapping.max = max
|
|
|
|
max = property(max_get, max_set)
|