def _create_layered(self, dson_material, sg_node): """ Create and return the material. If this is a blended metallic/plastic material, create both materials and combine them with a layeredShader. """ # These flags apply to all textures on this material. self.set_tiles( self.channels.get('Horizontal Tiles', 1), self.channels.get('Vertical Tiles', 1), self.channels.get('Horizontal Offset', 0), self.channels.get('Vertical Offset', 0)) # If we're not in Metallicity mode, just create a regular single-layer shader. base_mixing = self.channels['Base Mixing'] if base_mixing != 0: material = self._create_glossy_or_weighted(dson_material, sg_node) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) return material # We're in Metallicity mode. If the metallicity value is a constant 0 or 1, then also create a # regular single-layer shader. This is the most common case for this mode. metallic_weight = self.get_texture_with_color(self.images.get('Metallic Weight'), self.channels['Metallic Weight'], mode='alpha') if metallic_weight in (0, 1): material = self._create_metallic(dson_material, sg_node, metallic_weight == 1) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) return material # We're in metallicity mode, and we have a mix of metallicity and platic. These two use # very different mixing modes (the mixing order is different between the layers). Do this # by creating a material for 0 metallicity and 1 metallicity, then combining them with # a layeredShader. This is slower, but most materials don't use this. # # Multiply the transparency of this layer by metallic_weight. metallic_material = self._create_metallic(dson_material, sg_node, metallic=True, top_weight=metallic_weight) pm.rename(metallic_material, 'Mat_Arnold_Metal_%s' % mh.cleanup_node_name(self.name)) # This layer is underneath metallic, so set its weight to 1. plastic_material = self._create_metallic(dson_material, sg_node, metallic=False, top_weight=1) pm.rename(plastic_material, 'Mat_Arnold_Plastic_%s' % mh.cleanup_node_name(self.name)) material = pm.shadingNode('layeredShader', asShader=True) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) metallic_material.attr('outColor').connect(material.attr('inputs[0].color')) metallic_material.attr('outTransparency').connect(material.attr('inputs[0].transparency')) plastic_material.attr('outColor').connect(material.attr('inputs[1].color')) plastic_material.attr('outTransparency').connect(material.attr('inputs[1].transparency')) return material
def create(self, dson_material, sg_node): self.material = pm.shadingNode('lambert', asShader=True) pm.rename(self.material, 'Mat_Viewport_%s' % mh.cleanup_node_name(self.name)) self.material.attr('diffuse').set(1) material_type = self._get_dson_material_type(dson_material) self.set_attr_to_texture_with_color(self.material.attr('color'), self.images.get('diffuse'), self.channels['diffuse'], nodeName=self.name) if material_type == 'studio/material/uber_iray': # Refraction isn't really opacity, but we'll approximate it that way in the viewport. refraction_opacity = self.get_texture_with_alpha( self.images.get('Refraction Weight'), self.channels['Refraction Weight'], zero_is_invisible=True) transparency = self.get_texture_with_alpha( self.images.get('Cutout Opacity'), self.channels['Cutout Opacity']) # "Transparency" is a terrible way to represent opacity, because instead of just multiplying # values to combine them, you have to do 1-((1-t1)*(1-t2)). That gives an ugly shader. # Cutout opacity and refraction are used for very different types of materials and I've never # seen them used together, so we cheat here and just add them. transparency = mh.math_op('add', transparency, refraction_opacity) else: transparency = self.get_texture_with_alpha( self.images.get('transparency'), self.channels['transparency']) # If transparency is constant, don't let it be 0. Clamp it to 0.5, so it's not completely # invisible in the viewport. In the real materials there are usually other things causing # it to be visible, like reflections or refraction. Hack: don't do this for certain eye # materials, or it'll wash out eyes. allow_completely_transparent_shaders = [ 'EyeMoisture', 'Cornea', ] allow_completely_transparent = any( s in str(dson_material) for s in allow_completely_transparent_shaders) if not isinstance(transparency, pm.PyNode) and not allow_completely_transparent: transparency = min(transparency, 0.5) mh.set_or_connect(self.material.attr('transparency'), transparency) # Connect the material. Force this connection, so if it's already connected to lambert1 # we'll override it. self.material.attr('outColor').connect(sg_node.attr('surfaceShader'), f=True)
def create(self, dson_material, sg_node): super(MaterialPlastic, self).create(dson_material, sg_node) material = pm.shadingNode('aiStandard', asShader=True) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) # Don't apply transparency if there's no texture and transparency is 1 (transparency is really alpha). if self.channels['transparency'] < 1 or self.images.get('transparency'): self.set_attr_to_transparency(material.attr('opacity'), self.images.get('transparency'), self.channels['transparency'], zero_is_invisible=True) self.uses_transparency = True # Bump # Daz has a positive and negative bump value. That's odd and I'm not sure if anyone actually uses this. # This isn't used for now. bump_negative = self.channels['bump_min'] bump_positive = self.channels['bump_max'] bump_scale = abs(bump_positive - bump_negative) if bump_scale > 0: self._set_normal_map(material, bump_texture=self.images.get('bump'), bump_scale=bump_scale * 0.5) # # reflectionStrength = self.channels['Reflection Strength'] # # if reflectionStrength > 0: # # pass # # Specular (XXX untested) specular_strength = self.channels.get('specular_strength', 0) if specular_strength > 0: mh.set_or_connect(material.attr('Ks'), specular_strength) # We currently ignore any glossiness map. You can set one, but Iray seems to ignore it. # self.set_attr_to_roughness_from_glossiness(self.images.get('glossiness'), self.channels['glossiness'], spec_layer.node.attr('roughness')) self.set_attr_to_roughness_from_glossiness(None, self.channels['glossiness'], material.attr('specularRoughness')) self.set_attr_to_texture_with_color(material.attr('KsColor'), self.images.get('specular'), self.channels['specular']) # Diffuse color. We don't currently implement textures for diffuse strength. self.set_attr_to_texture_with_color(material.attr('color'), self.images.get('diffuse'), self.channels['diffuse']) self.set_attr_to_texture_with_color(material.attr('Kd'), self.images.get('diffuse_strength'), self.channels['diffuse_strength'], mode='r') # Unimplemented: ambient/ambient_strength, reflection/reflection_strength, refraction/refraction_strength/ior, # displacement/displacement_min/displacement_max, normal, u_offset/u_scale/v_offset/v_scale self._post_create(sg_node, material)
def create(self, dson_material, sg_node): super(MaterialDazShader, self).create(dson_material, sg_node) material = pm.shadingNode('aiStandard', asShader=True) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) diffuse_weight = 1 # Bump: if self.channels['Bump Active']: # XXX: Normal maps? self._set_normal_map(material, bump_texture=self.images.get('Bump Strength'), bump_scale=self.channels.get('Bump Strength', 0) * 0.025) if self.channels['Opacity Active'] and (self.channels['transparency'] < 1 or self.images.get('transparency')): self.set_attr_to_transparency(material.attr('opacity'), self.images.get('transparency'), self.channels['transparency'], zero_is_invisible=True) self.uses_transparency = True # Specular (Primary) if self.channels['Specular Active']: self.set_attr_to_texture_with_color(material.attr('KsColor'), self.images.get('Specular Color'), self.channels['Specular Color']) self.set_attr_to_roughness_from_glossiness(self.images.get('Glossiness'), self.channels['Glossiness'], material.attr('specularRoughness')) specular_strength = self.channels['Specular Strength'] # diffuse_weight = mh.math_op('sub', diffuse_weight, specular_strength) mh.set_or_connect(material.attr('Ks'), specular_strength) # Diffuse if self.channels['Diffuse Active'] and self.channels['Diffuse Strength'] > 0: self.set_attr_to_texture_with_color(material.attr('color'), self.images.get('diffuse'), self.channels['diffuse']) diffuse_weight = mh.math_op('mult', diffuse_weight, self.channels['Diffuse Strength']) mh.set_or_connect(material.attr('Kd'), diffuse_weight) self.set_attr_to_texture_with_color(material.attr('diffuseRoughness'), self.images.get('Diffuse Roughness'), self.channels['Diffuse Roughness'], mode='alpha') self._post_create(sg_node, material)
def create(self, dson_material, sg_node): super(MaterialDazBrick, self).create(dson_material, sg_node) material = pm.shadingNode('aiStandard', asShader=True) pm.rename(material, 'Mat_Arnold_%s' % mh.cleanup_node_name(self.name)) # Don't apply transparency if there's no texture and transparency is 1 (transparency is really alpha). if self.channels['transparency'] < 1 or self.images.get('transparency'): self.set_attr_to_transparency(material.attr('opacity'), self.images.get('transparency'), self.channels['transparency'], zero_is_invisible=True) self.uses_transparency = True # Normals: # # This material has a positive and negative bump value. That's odd and I'm not sure if anyone actually uses this. bump_negative = self.channels.get('Negative Bump', 0) bump_positive = self.channels.get('Positive Bump', 0) bump_scale = abs(bump_positive - bump_negative) bump_scale = mh.math_op('mult', bump_scale, self.channels['Bump Strength']) self._set_normal_map(material, normal_texture=self.images.get('Normal Map'), bump_texture=self.images.get('Bump Strength'), bump_scale=bump_scale*0.5) # # reflectionStrength = self.channels['Reflection Strength'] # # if reflectionStrength > 0: # # pass # Specular 1. specularStrength = self.channels.get('Specular Strength', 0) if specularStrength > 0: # XXX: calibrate material.attr('Ks').set(specularStrength * 0.075) # We currently ignore any glossiness map. You can set one, but Iray seems to ignore it. # self.set_attr_to_roughness_from_glossiness(self.images.get('Glossiness'), self.channels['Glossiness'], material.attr('specularRoughness')) self.set_attr_to_roughness_from_glossiness(None, self.channels['Glossiness'], material.attr('specularRoughness')) self.set_attr_to_texture_with_color(material.attr('KsColor'), self.images.get('Specular Color'), self.channels['Specular Color']) # # # Specular 2. This is a phong specular. This isn't very well tested. # specular2Strength = self.channels['value222'] # if specular2Strength > 0: # pass # This material allows Diffuse Strength to be greater than 1, but aiStandard doesn't, # so apply diffuse strength as part of the diffuse color instead. #diffuse_color = util.srgb_vector_to_linear(self.channels['diffuse']) #diffuse_color = mh.math_op('mult', diffuse_color, self.channels['Diffuse Strength']) #diffuse_texture_node = self.find_or_create_texture(path=self.images.get('diffuse')) #if diffuse_texture_node is not None: # diffuse_color = mh.math_op('mult', diffuse_color, diffuse_texture_node.attr('outColor')) #mh.set_or_connect(material.attr('color'), diffuse_color) #mh.set_or_connect(material.attr('Kd'), 1) diffuse_color = self.get_texture_with_color(self.images.get('diffuse'), self.channels['diffuse']) mh.set_or_connect(material.attr('color'), diffuse_color) # Note that the diffuse strength isn't quite the same as a multiplier to the diffuse color, # since it's a layering weight and affected by other material layers. diffuse_strength = self.get_texture_with_color(self.images.get('Diffuse Strength'), self.channels['Diffuse Strength'], mode='alpha') if not isinstance(diffuse_strength, pm.PyNode): diffuse_strength = min(diffuse_strength, 1) mh.set_or_connect(material.attr('Kd'), diffuse_strength) # Subsurface # # "value23" is "Subsurface Off - On". # "Ambient Strength" is "Subsurface Strength" (huh?). # "Ambient Color" is "Subsurface Color" # Multiply these together to get the SSS weight, and to see if we need to set up SSS at # all. "Subsurface Off - On" is probably 0 or 1 most of the time. # # This material's scatter is very different from ours, so we don't really try to emulate # it. We just set up basic texture maps if available, so it's easier to turn it on manually. scatter_weight = self._scatter_weight() # If we have an ambient color (which is actually Subsurface Color), connect it to SSS color. # Otherwise, connect the diffuse color, since it's the usually what you want if you're turning # on simple SSS. self.set_attr_to_texture_with_color(material.attr('KsssColor'), self.images.get('Ambient Color'), [1,1,1]) # Set a reasonable default for skin SSS. This won't be used unless SSS is actually weighted on. material.attr('sssRadius').set((1, 0.5, 0.25)) # XXX: Not implemented: ambient, displacement, opacity, reflection, shadows, tiling, velvet self._post_create(sg_node, material)