Spaces:
Runtime error
Runtime error
| """Material properties, conforming to the glTF 2.0 standards as specified in | |
| https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-material | |
| and | |
| https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness | |
| Author: Matthew Matl | |
| """ | |
| import abc | |
| import numpy as np | |
| import six | |
| from .constants import TexFlags | |
| from .utils import format_color_vector, format_texture_source | |
| from .texture import Texture | |
| class Material(object): | |
| """Base for standard glTF 2.0 materials. | |
| Parameters | |
| ---------- | |
| name : str, optional | |
| The user-defined name of this object. | |
| normalTexture : (n,n,3) float or :class:`Texture`, optional | |
| A tangent space normal map. The texture contains RGB components in | |
| linear space. Each texel represents the XYZ components of a normal | |
| vector in tangent space. Red [0 to 255] maps to X [-1 to 1]. Green | |
| [0 to 255] maps to Y [-1 to 1]. Blue [128 to 255] maps to Z | |
| [1/255 to 1]. The normal vectors use OpenGL conventions where +X is | |
| right and +Y is up. +Z points toward the viewer. | |
| occlusionTexture : (n,n,1) float or :class:`Texture`, optional | |
| The occlusion map texture. The occlusion values are sampled from the R | |
| channel. Higher values indicate areas that should receive full indirect | |
| lighting and lower values indicate no indirect lighting. These values | |
| are linear. If other channels are present (GBA), they are ignored for | |
| occlusion calculations. | |
| emissiveTexture : (n,n,3) float or :class:`Texture`, optional | |
| The emissive map controls the color and intensity of the light being | |
| emitted by the material. This texture contains RGB components in sRGB | |
| color space. If a fourth component (A) is present, it is ignored. | |
| emissiveFactor : (3,) float, optional | |
| The RGB components of the emissive color of the material. These values | |
| are linear. If an emissiveTexture is specified, this value is | |
| multiplied with the texel values. | |
| alphaMode : str, optional | |
| The material's alpha rendering mode enumeration specifying the | |
| interpretation of the alpha value of the main factor and texture. | |
| Allowed Values: | |
| - `"OPAQUE"` The alpha value is ignored and the rendered output is | |
| fully opaque. | |
| - `"MASK"` The rendered output is either fully opaque or fully | |
| transparent depending on the alpha value and the specified alpha | |
| cutoff value. | |
| - `"BLEND"` The alpha value is used to composite the source and | |
| destination areas. The rendered output is combined with the | |
| background using the normal painting operation (i.e. the Porter | |
| and Duff over operator). | |
| alphaCutoff : float, optional | |
| Specifies the cutoff threshold when in MASK mode. If the alpha value is | |
| greater than or equal to this value then it is rendered as fully | |
| opaque, otherwise, it is rendered as fully transparent. | |
| A value greater than 1.0 will render the entire material as fully | |
| transparent. This value is ignored for other modes. | |
| doubleSided : bool, optional | |
| Specifies whether the material is double sided. When this value is | |
| false, back-face culling is enabled. When this value is true, | |
| back-face culling is disabled and double sided lighting is enabled. | |
| smooth : bool, optional | |
| If True, the material is rendered smoothly by using only one normal | |
| per vertex and face indexing. | |
| wireframe : bool, optional | |
| If True, the material is rendered in wireframe mode. | |
| """ | |
| def __init__(self, | |
| name=None, | |
| normalTexture=None, | |
| occlusionTexture=None, | |
| emissiveTexture=None, | |
| emissiveFactor=None, | |
| alphaMode=None, | |
| alphaCutoff=None, | |
| doubleSided=False, | |
| smooth=True, | |
| wireframe=False): | |
| # Set defaults | |
| if alphaMode is None: | |
| alphaMode = 'OPAQUE' | |
| if alphaCutoff is None: | |
| alphaCutoff = 0.5 | |
| if emissiveFactor is None: | |
| emissiveFactor = np.zeros(3).astype(np.float32) | |
| self.name = name | |
| self.normalTexture = normalTexture | |
| self.occlusionTexture = occlusionTexture | |
| self.emissiveTexture = emissiveTexture | |
| self.emissiveFactor = emissiveFactor | |
| self.alphaMode = alphaMode | |
| self.alphaCutoff = alphaCutoff | |
| self.doubleSided = doubleSided | |
| self.smooth = smooth | |
| self.wireframe = wireframe | |
| self._tex_flags = None | |
| def name(self): | |
| """str : The user-defined name of this object. | |
| """ | |
| return self._name | |
| def name(self, value): | |
| if value is not None: | |
| value = str(value) | |
| self._name = value | |
| def normalTexture(self): | |
| """(n,n,3) float or :class:`Texture` : The tangent-space normal map. | |
| """ | |
| return self._normalTexture | |
| def normalTexture(self, value): | |
| # TODO TMP | |
| self._normalTexture = self._format_texture(value, 'RGB') | |
| self._tex_flags = None | |
| def occlusionTexture(self): | |
| """(n,n,1) float or :class:`Texture` : The ambient occlusion map. | |
| """ | |
| return self._occlusionTexture | |
| def occlusionTexture(self, value): | |
| self._occlusionTexture = self._format_texture(value, 'R') | |
| self._tex_flags = None | |
| def emissiveTexture(self): | |
| """(n,n,3) float or :class:`Texture` : The emission map. | |
| """ | |
| return self._emissiveTexture | |
| def emissiveTexture(self, value): | |
| self._emissiveTexture = self._format_texture(value, 'RGB') | |
| self._tex_flags = None | |
| def emissiveFactor(self): | |
| """(3,) float : Base multiplier for emission colors. | |
| """ | |
| return self._emissiveFactor | |
| def emissiveFactor(self, value): | |
| if value is None: | |
| value = np.zeros(3) | |
| self._emissiveFactor = format_color_vector(value, 3) | |
| def alphaMode(self): | |
| """str : The mode for blending. | |
| """ | |
| return self._alphaMode | |
| def alphaMode(self, value): | |
| if value not in set(['OPAQUE', 'MASK', 'BLEND']): | |
| raise ValueError('Invalid alpha mode {}'.format(value)) | |
| self._alphaMode = value | |
| def alphaCutoff(self): | |
| """float : The cutoff threshold in MASK mode. | |
| """ | |
| return self._alphaCutoff | |
| def alphaCutoff(self, value): | |
| if value < 0 or value > 1: | |
| raise ValueError('Alpha cutoff must be in range [0,1]') | |
| self._alphaCutoff = float(value) | |
| def doubleSided(self): | |
| """bool : Whether the material is double-sided. | |
| """ | |
| return self._doubleSided | |
| def doubleSided(self, value): | |
| if not isinstance(value, bool): | |
| raise TypeError('Double sided must be a boolean value') | |
| self._doubleSided = value | |
| def smooth(self): | |
| """bool : Whether to render the mesh smoothly by | |
| interpolating vertex normals. | |
| """ | |
| return self._smooth | |
| def smooth(self, value): | |
| if not isinstance(value, bool): | |
| raise TypeError('Double sided must be a boolean value') | |
| self._smooth = value | |
| def wireframe(self): | |
| """bool : Whether to render the mesh in wireframe mode. | |
| """ | |
| return self._wireframe | |
| def wireframe(self, value): | |
| if not isinstance(value, bool): | |
| raise TypeError('Wireframe must be a boolean value') | |
| self._wireframe = value | |
| def is_transparent(self): | |
| """bool : If True, the object is partially transparent. | |
| """ | |
| return self._compute_transparency() | |
| def tex_flags(self): | |
| """int : Texture availability flags. | |
| """ | |
| if self._tex_flags is None: | |
| self._tex_flags = self._compute_tex_flags() | |
| return self._tex_flags | |
| def textures(self): | |
| """list of :class:`Texture` : The textures associated with this | |
| material. | |
| """ | |
| return self._compute_textures() | |
| def _compute_transparency(self): | |
| return False | |
| def _compute_tex_flags(self): | |
| tex_flags = TexFlags.NONE | |
| if self.normalTexture is not None: | |
| tex_flags |= TexFlags.NORMAL | |
| if self.occlusionTexture is not None: | |
| tex_flags |= TexFlags.OCCLUSION | |
| if self.emissiveTexture is not None: | |
| tex_flags |= TexFlags.EMISSIVE | |
| return tex_flags | |
| def _compute_textures(self): | |
| all_textures = [ | |
| self.normalTexture, self.occlusionTexture, self.emissiveTexture | |
| ] | |
| textures = set([t for t in all_textures if t is not None]) | |
| return textures | |
| def _format_texture(self, texture, target_channels='RGB'): | |
| """Format a texture as a float32 np array. | |
| """ | |
| if isinstance(texture, Texture) or texture is None: | |
| return texture | |
| else: | |
| source = format_texture_source(texture, target_channels) | |
| return Texture(source=source, source_channels=target_channels) | |
| class MetallicRoughnessMaterial(Material): | |
| """A material based on the metallic-roughness material model from | |
| Physically-Based Rendering (PBR) methodology. | |
| Parameters | |
| ---------- | |
| name : str, optional | |
| The user-defined name of this object. | |
| normalTexture : (n,n,3) float or :class:`Texture`, optional | |
| A tangent space normal map. The texture contains RGB components in | |
| linear space. Each texel represents the XYZ components of a normal | |
| vector in tangent space. Red [0 to 255] maps to X [-1 to 1]. Green | |
| [0 to 255] maps to Y [-1 to 1]. Blue [128 to 255] maps to Z | |
| [1/255 to 1]. The normal vectors use OpenGL conventions where +X is | |
| right and +Y is up. +Z points toward the viewer. | |
| occlusionTexture : (n,n,1) float or :class:`Texture`, optional | |
| The occlusion map texture. The occlusion values are sampled from the R | |
| channel. Higher values indicate areas that should receive full indirect | |
| lighting and lower values indicate no indirect lighting. These values | |
| are linear. If other channels are present (GBA), they are ignored for | |
| occlusion calculations. | |
| emissiveTexture : (n,n,3) float or :class:`Texture`, optional | |
| The emissive map controls the color and intensity of the light being | |
| emitted by the material. This texture contains RGB components in sRGB | |
| color space. If a fourth component (A) is present, it is ignored. | |
| emissiveFactor : (3,) float, optional | |
| The RGB components of the emissive color of the material. These values | |
| are linear. If an emissiveTexture is specified, this value is | |
| multiplied with the texel values. | |
| alphaMode : str, optional | |
| The material's alpha rendering mode enumeration specifying the | |
| interpretation of the alpha value of the main factor and texture. | |
| Allowed Values: | |
| - `"OPAQUE"` The alpha value is ignored and the rendered output is | |
| fully opaque. | |
| - `"MASK"` The rendered output is either fully opaque or fully | |
| transparent depending on the alpha value and the specified alpha | |
| cutoff value. | |
| - `"BLEND"` The alpha value is used to composite the source and | |
| destination areas. The rendered output is combined with the | |
| background using the normal painting operation (i.e. the Porter | |
| and Duff over operator). | |
| alphaCutoff : float, optional | |
| Specifies the cutoff threshold when in MASK mode. If the alpha value is | |
| greater than or equal to this value then it is rendered as fully | |
| opaque, otherwise, it is rendered as fully transparent. | |
| A value greater than 1.0 will render the entire material as fully | |
| transparent. This value is ignored for other modes. | |
| doubleSided : bool, optional | |
| Specifies whether the material is double sided. When this value is | |
| false, back-face culling is enabled. When this value is true, | |
| back-face culling is disabled and double sided lighting is enabled. | |
| smooth : bool, optional | |
| If True, the material is rendered smoothly by using only one normal | |
| per vertex and face indexing. | |
| wireframe : bool, optional | |
| If True, the material is rendered in wireframe mode. | |
| baseColorFactor : (4,) float, optional | |
| The RGBA components of the base color of the material. The fourth | |
| component (A) is the alpha coverage of the material. The alphaMode | |
| property specifies how alpha is interpreted. These values are linear. | |
| If a baseColorTexture is specified, this value is multiplied with the | |
| texel values. | |
| baseColorTexture : (n,n,4) float or :class:`Texture`, optional | |
| The base color texture. This texture contains RGB(A) components in sRGB | |
| color space. The first three components (RGB) specify the base color of | |
| the material. If the fourth component (A) is present, it represents the | |
| alpha coverage of the material. Otherwise, an alpha of 1.0 is assumed. | |
| The alphaMode property specifies how alpha is interpreted. | |
| The stored texels must not be premultiplied. | |
| metallicFactor : float | |
| The metalness of the material. A value of 1.0 means the material is a | |
| metal. A value of 0.0 means the material is a dielectric. Values in | |
| between are for blending between metals and dielectrics such as dirty | |
| metallic surfaces. This value is linear. If a metallicRoughnessTexture | |
| is specified, this value is multiplied with the metallic texel values. | |
| roughnessFactor : float | |
| The roughness of the material. A value of 1.0 means the material is | |
| completely rough. A value of 0.0 means the material is completely | |
| smooth. This value is linear. If a metallicRoughnessTexture is | |
| specified, this value is multiplied with the roughness texel values. | |
| metallicRoughnessTexture : (n,n,2) float or :class:`Texture`, optional | |
| The metallic-roughness texture. The metalness values are sampled from | |
| the B channel. The roughness values are sampled from the G channel. | |
| These values are linear. If other channels are present (R or A), they | |
| are ignored for metallic-roughness calculations. | |
| """ | |
| def __init__(self, | |
| name=None, | |
| normalTexture=None, | |
| occlusionTexture=None, | |
| emissiveTexture=None, | |
| emissiveFactor=None, | |
| alphaMode=None, | |
| alphaCutoff=None, | |
| doubleSided=False, | |
| smooth=True, | |
| wireframe=False, | |
| baseColorFactor=None, | |
| baseColorTexture=None, | |
| metallicFactor=1.0, | |
| roughnessFactor=1.0, | |
| metallicRoughnessTexture=None): | |
| super(MetallicRoughnessMaterial, self).__init__( | |
| name=name, | |
| normalTexture=normalTexture, | |
| occlusionTexture=occlusionTexture, | |
| emissiveTexture=emissiveTexture, | |
| emissiveFactor=emissiveFactor, | |
| alphaMode=alphaMode, | |
| alphaCutoff=alphaCutoff, | |
| doubleSided=doubleSided, | |
| smooth=smooth, | |
| wireframe=wireframe | |
| ) | |
| # Set defaults | |
| if baseColorFactor is None: | |
| baseColorFactor = np.ones(4).astype(np.float32) | |
| self.baseColorFactor = baseColorFactor | |
| self.baseColorTexture = baseColorTexture | |
| self.metallicFactor = metallicFactor | |
| self.roughnessFactor = roughnessFactor | |
| self.metallicRoughnessTexture = metallicRoughnessTexture | |
| def baseColorFactor(self): | |
| """(4,) float or :class:`Texture` : The RGBA base color multiplier. | |
| """ | |
| return self._baseColorFactor | |
| def baseColorFactor(self, value): | |
| if value is None: | |
| value = np.ones(4) | |
| self._baseColorFactor = format_color_vector(value, 4) | |
| def baseColorTexture(self): | |
| """(n,n,4) float or :class:`Texture` : The diffuse texture. | |
| """ | |
| return self._baseColorTexture | |
| def baseColorTexture(self, value): | |
| self._baseColorTexture = self._format_texture(value, 'RGBA') | |
| self._tex_flags = None | |
| def metallicFactor(self): | |
| """float : The metalness of the material. | |
| """ | |
| return self._metallicFactor | |
| def metallicFactor(self, value): | |
| if value is None: | |
| value = 1.0 | |
| if value < 0 or value > 1: | |
| raise ValueError('Metallic factor must be in range [0,1]') | |
| self._metallicFactor = float(value) | |
| def roughnessFactor(self): | |
| """float : The roughness of the material. | |
| """ | |
| return self.RoughnessFactor | |
| def roughnessFactor(self, value): | |
| if value is None: | |
| value = 1.0 | |
| if value < 0 or value > 1: | |
| raise ValueError('Roughness factor must be in range [0,1]') | |
| self.RoughnessFactor = float(value) | |
| def metallicRoughnessTexture(self): | |
| """(n,n,2) float or :class:`Texture` : The metallic-roughness texture. | |
| """ | |
| return self._metallicRoughnessTexture | |
| def metallicRoughnessTexture(self, value): | |
| self._metallicRoughnessTexture = self._format_texture(value, 'GB') | |
| self._tex_flags = None | |
| def _compute_tex_flags(self): | |
| tex_flags = super(MetallicRoughnessMaterial, self)._compute_tex_flags() | |
| if self.baseColorTexture is not None: | |
| tex_flags |= TexFlags.BASE_COLOR | |
| if self.metallicRoughnessTexture is not None: | |
| tex_flags |= TexFlags.METALLIC_ROUGHNESS | |
| return tex_flags | |
| def _compute_transparency(self): | |
| if self.alphaMode == 'OPAQUE': | |
| return False | |
| cutoff = self.alphaCutoff | |
| if self.alphaMode == 'BLEND': | |
| cutoff = 1.0 | |
| if self.baseColorFactor[3] < cutoff: | |
| return True | |
| if (self.baseColorTexture is not None and | |
| self.baseColorTexture.is_transparent(cutoff)): | |
| return True | |
| return False | |
| def _compute_textures(self): | |
| textures = super(MetallicRoughnessMaterial, self)._compute_textures() | |
| all_textures = [self.baseColorTexture, self.metallicRoughnessTexture] | |
| all_textures = {t for t in all_textures if t is not None} | |
| textures |= all_textures | |
| return textures | |
| class SpecularGlossinessMaterial(Material): | |
| """A material based on the specular-glossiness material model from | |
| Physically-Based Rendering (PBR) methodology. | |
| Parameters | |
| ---------- | |
| name : str, optional | |
| The user-defined name of this object. | |
| normalTexture : (n,n,3) float or :class:`Texture`, optional | |
| A tangent space normal map. The texture contains RGB components in | |
| linear space. Each texel represents the XYZ components of a normal | |
| vector in tangent space. Red [0 to 255] maps to X [-1 to 1]. Green | |
| [0 to 255] maps to Y [-1 to 1]. Blue [128 to 255] maps to Z | |
| [1/255 to 1]. The normal vectors use OpenGL conventions where +X is | |
| right and +Y is up. +Z points toward the viewer. | |
| occlusionTexture : (n,n,1) float or :class:`Texture`, optional | |
| The occlusion map texture. The occlusion values are sampled from the R | |
| channel. Higher values indicate areas that should receive full indirect | |
| lighting and lower values indicate no indirect lighting. These values | |
| are linear. If other channels are present (GBA), they are ignored for | |
| occlusion calculations. | |
| emissiveTexture : (n,n,3) float or :class:`Texture`, optional | |
| The emissive map controls the color and intensity of the light being | |
| emitted by the material. This texture contains RGB components in sRGB | |
| color space. If a fourth component (A) is present, it is ignored. | |
| emissiveFactor : (3,) float, optional | |
| The RGB components of the emissive color of the material. These values | |
| are linear. If an emissiveTexture is specified, this value is | |
| multiplied with the texel values. | |
| alphaMode : str, optional | |
| The material's alpha rendering mode enumeration specifying the | |
| interpretation of the alpha value of the main factor and texture. | |
| Allowed Values: | |
| - `"OPAQUE"` The alpha value is ignored and the rendered output is | |
| fully opaque. | |
| - `"MASK"` The rendered output is either fully opaque or fully | |
| transparent depending on the alpha value and the specified alpha | |
| cutoff value. | |
| - `"BLEND"` The alpha value is used to composite the source and | |
| destination areas. The rendered output is combined with the | |
| background using the normal painting operation (i.e. the Porter | |
| and Duff over operator). | |
| alphaCutoff : float, optional | |
| Specifies the cutoff threshold when in MASK mode. If the alpha value is | |
| greater than or equal to this value then it is rendered as fully | |
| opaque, otherwise, it is rendered as fully transparent. | |
| A value greater than 1.0 will render the entire material as fully | |
| transparent. This value is ignored for other modes. | |
| doubleSided : bool, optional | |
| Specifies whether the material is double sided. When this value is | |
| false, back-face culling is enabled. When this value is true, | |
| back-face culling is disabled and double sided lighting is enabled. | |
| smooth : bool, optional | |
| If True, the material is rendered smoothly by using only one normal | |
| per vertex and face indexing. | |
| wireframe : bool, optional | |
| If True, the material is rendered in wireframe mode. | |
| diffuseFactor : (4,) float | |
| The RGBA components of the reflected diffuse color of the material. | |
| Metals have a diffuse value of [0.0, 0.0, 0.0]. The fourth component | |
| (A) is the opacity of the material. The values are linear. | |
| diffuseTexture : (n,n,4) float or :class:`Texture`, optional | |
| The diffuse texture. This texture contains RGB(A) components of the | |
| reflected diffuse color of the material in sRGB color space. If the | |
| fourth component (A) is present, it represents the alpha coverage of | |
| the material. Otherwise, an alpha of 1.0 is assumed. | |
| The alphaMode property specifies how alpha is interpreted. | |
| The stored texels must not be premultiplied. | |
| specularFactor : (3,) float | |
| The specular RGB color of the material. This value is linear. | |
| glossinessFactor : float | |
| The glossiness or smoothness of the material. A value of 1.0 means the | |
| material has full glossiness or is perfectly smooth. A value of 0.0 | |
| means the material has no glossiness or is perfectly rough. This value | |
| is linear. | |
| specularGlossinessTexture : (n,n,4) or :class:`Texture`, optional | |
| The specular-glossiness texture is a RGBA texture, containing the | |
| specular color (RGB) in sRGB space and the glossiness value (A) in | |
| linear space. | |
| """ | |
| def __init__(self, | |
| name=None, | |
| normalTexture=None, | |
| occlusionTexture=None, | |
| emissiveTexture=None, | |
| emissiveFactor=None, | |
| alphaMode=None, | |
| alphaCutoff=None, | |
| doubleSided=False, | |
| smooth=True, | |
| wireframe=False, | |
| diffuseFactor=None, | |
| diffuseTexture=None, | |
| specularFactor=None, | |
| glossinessFactor=1.0, | |
| specularGlossinessTexture=None): | |
| super(SpecularGlossinessMaterial, self).__init__( | |
| name=name, | |
| normalTexture=normalTexture, | |
| occlusionTexture=occlusionTexture, | |
| emissiveTexture=emissiveTexture, | |
| emissiveFactor=emissiveFactor, | |
| alphaMode=alphaMode, | |
| alphaCutoff=alphaCutoff, | |
| doubleSided=doubleSided, | |
| smooth=smooth, | |
| wireframe=wireframe | |
| ) | |
| # Set defaults | |
| if diffuseFactor is None: | |
| diffuseFactor = np.ones(4).astype(np.float32) | |
| if specularFactor is None: | |
| specularFactor = np.ones(3).astype(np.float32) | |
| self.diffuseFactor = diffuseFactor | |
| self.diffuseTexture = diffuseTexture | |
| self.specularFactor = specularFactor | |
| self.glossinessFactor = glossinessFactor | |
| self.specularGlossinessTexture = specularGlossinessTexture | |
| def diffuseFactor(self): | |
| """(4,) float : The diffuse base color. | |
| """ | |
| return self._diffuseFactor | |
| def diffuseFactor(self, value): | |
| self._diffuseFactor = format_color_vector(value, 4) | |
| def diffuseTexture(self): | |
| """(n,n,4) float or :class:`Texture` : The diffuse map. | |
| """ | |
| return self._diffuseTexture | |
| def diffuseTexture(self, value): | |
| self._diffuseTexture = self._format_texture(value, 'RGBA') | |
| self._tex_flags = None | |
| def specularFactor(self): | |
| """(3,) float : The specular color of the material. | |
| """ | |
| return self._specularFactor | |
| def specularFactor(self, value): | |
| self._specularFactor = format_color_vector(value, 3) | |
| def glossinessFactor(self): | |
| """float : The glossiness of the material. | |
| """ | |
| return self.glossinessFactor | |
| def glossinessFactor(self, value): | |
| if value < 0 or value > 1: | |
| raise ValueError('glossiness factor must be in range [0,1]') | |
| self._glossinessFactor = float(value) | |
| def specularGlossinessTexture(self): | |
| """(n,n,4) or :class:`Texture` : The specular-glossiness texture. | |
| """ | |
| return self._specularGlossinessTexture | |
| def specularGlossinessTexture(self, value): | |
| self._specularGlossinessTexture = self._format_texture(value, 'GB') | |
| self._tex_flags = None | |
| def _compute_tex_flags(self): | |
| flags = super(SpecularGlossinessMaterial, self)._compute_tex_flags() | |
| if self.diffuseTexture is not None: | |
| flags |= TexFlags.DIFFUSE | |
| if self.specularGlossinessTexture is not None: | |
| flags |= TexFlags.SPECULAR_GLOSSINESS | |
| return flags | |
| def _compute_transparency(self): | |
| if self.alphaMode == 'OPAQUE': | |
| return False | |
| cutoff = self.alphaCutoff | |
| if self.alphaMode == 'BLEND': | |
| cutoff = 1.0 | |
| if self.diffuseFactor[3] < cutoff: | |
| return True | |
| if (self.diffuseTexture is not None and | |
| self.diffuseTexture.is_transparent(cutoff)): | |
| return True | |
| return False | |
| def _compute_textures(self): | |
| textures = super(SpecularGlossinessMaterial, self)._compute_textures() | |
| all_textures = [self.diffuseTexture, self.specularGlossinessTexture] | |
| all_textures = {t for t in all_textures if t is not None} | |
| textures |= all_textures | |
| return textures | |