556 lines
19 KiB
C#
556 lines
19 KiB
C#
|
|
using System.Diagnostics;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using Godot;
|
|
|
|
|
|
namespace Rokojori.Reallusion
|
|
{
|
|
public class CCMaterialInfo:CCImportFileBase
|
|
{
|
|
|
|
public string name;
|
|
|
|
|
|
public CCJSONProperty<string> materialType = new CCJSONProperty<string>( "Material Type" );
|
|
public CCJSONProperty<int> multiUVIndex = new CCJSONProperty<int>( "MultiUV Index" );
|
|
public CCJSONProperty<string> nodeType = new CCJSONProperty<string>( "Node Type" );
|
|
public CCJSONProperty<bool> twoSide = new CCJSONProperty<bool>( "Two Side" );
|
|
public CCJSONProperty<List<float>> diffuseColor = new CCJSONProperty<List<float>>( "Diffuse Color" );
|
|
public CCJSONProperty<List<float>> ambientColor = new CCJSONProperty<List<float>>( "Ambient Color" );
|
|
public CCJSONProperty<List<float>> specularColor = new CCJSONProperty<List<float>>( "Specular Color" );
|
|
public CCJSONProperty<float> opacity = new CCJSONProperty<float>( "Opacity" );
|
|
public CCJSONProperty<float> selfIllumination = new CCJSONProperty<float>( "Self Illumination" );
|
|
public CCJSONProperty<float> specular = new CCJSONProperty<float>( "Specular" );
|
|
public CCJSONProperty<float> glossiness = new CCJSONProperty<float>( "Glossiness" );
|
|
|
|
public CCJSONProperty<List<CCTextureInfo>> textures = new CCJSONProperty<List<CCTextureInfo>>( "Textures" );
|
|
|
|
public CCJSONProperty<CCCustomShader> customShader = new CCJSONProperty<CCCustomShader>( "Custom Shader" );
|
|
|
|
public CCJSONProperty<CCSubsurfaceScatter> subsurfaceScatter = new CCJSONProperty<CCSubsurfaceScatter>( "Subsurface Scatter" );
|
|
|
|
public CCMaterialInfo( CCImportFile ccImportFile, string name ):base( ccImportFile )
|
|
{
|
|
this.name = name;
|
|
|
|
textures.SetReader(
|
|
( data ) =>
|
|
{
|
|
var list = new List<CCTextureInfo>();
|
|
var obj = data.AsObject();
|
|
|
|
Info( "Reading textures:", obj.keys );
|
|
|
|
obj.keys.ForEach(
|
|
k =>
|
|
{
|
|
var ti = CCTextureInfo.Create( importFile, k, obj.Get( k ) );
|
|
Info( "Adding texture for material", name, ti.name, ti.texturePath.value );
|
|
list.Add( ti );
|
|
}
|
|
);
|
|
|
|
|
|
return list;
|
|
}
|
|
);
|
|
|
|
customShader.SetReader(
|
|
( data ) =>
|
|
{
|
|
var shaderName = data.AsObject().Get( "Shader Name" ).stringValue;
|
|
var cs = new CCCustomShader( importFile, shaderName );
|
|
|
|
Info( "Found Shader", shaderName );
|
|
|
|
cs.ReadFrom( data.AsObject() );
|
|
|
|
return cs;
|
|
|
|
}
|
|
);
|
|
|
|
subsurfaceScatter.SetReader(
|
|
( data ) =>
|
|
{
|
|
var ss = new CCSubsurfaceScatter( importFile );
|
|
|
|
ss.ReadFrom( data.AsObject() );
|
|
|
|
return ss;
|
|
|
|
}
|
|
);
|
|
}
|
|
|
|
public void ReadFrom( JSONObject root )
|
|
{
|
|
materialType.Read( root );
|
|
multiUVIndex.Read( root );
|
|
nodeType.Read( root );
|
|
twoSide.Read( root );
|
|
diffuseColor.Read( root );
|
|
ambientColor.Read( root );
|
|
specularColor.Read( root );
|
|
opacity.Read( root );
|
|
selfIllumination.Read( root );
|
|
textures.Read( root );
|
|
customShader.Read( root );
|
|
subsurfaceScatter.Read( root );
|
|
}
|
|
|
|
public bool IsCustomShader( string shaderName )
|
|
{
|
|
return customShader.exists && customShader.value.name == shaderName;
|
|
}
|
|
|
|
public Material CreateMaterial( CCMaterialSettings settings )
|
|
{
|
|
RJLog.Log( "Custom Shader", customShader.exists ? customShader.value.name : "none" );
|
|
|
|
if ( settings.materialType.shaderType == CCMaterialType.CCShaderType.RLHair )
|
|
{
|
|
return CreateHairMaterial( settings );
|
|
}
|
|
|
|
if ( settings.materialType.shaderType == CCMaterialType.CCShaderType.RLEyeOcclusion )
|
|
{
|
|
return CreateEyeOcclusionMaterial( settings );
|
|
}
|
|
|
|
if ( settings.materialType.shaderType == CCMaterialType.CCShaderType.RLEye )
|
|
{
|
|
return CreateEyeMaterial( settings );
|
|
}
|
|
|
|
|
|
if (
|
|
settings.materialType.shaderType == CCMaterialType.CCShaderType.RLSkin ||
|
|
settings.materialType.shaderType == CCMaterialType.CCShaderType.RLHead
|
|
)
|
|
{
|
|
|
|
return CreateSkinMaterial( settings );
|
|
}
|
|
|
|
if ( HasOpacityTexture() )
|
|
{
|
|
return CreateOpacityMaterial( settings );
|
|
}
|
|
|
|
|
|
return CreatePBRMaterial( settings );
|
|
}
|
|
|
|
|
|
public Color GetAlbedoColor( float gamma )
|
|
{
|
|
var a = opacity.GetOr( 1.0f );
|
|
var color = ColorX.From( diffuseColor.GetOr( new List<float>{ 255, 255, 255, 255 } ), 255 );
|
|
color.A *= a;
|
|
|
|
color = color.Gamma( gamma );
|
|
|
|
return color;
|
|
}
|
|
|
|
public bool HasOpacityTexture()
|
|
{
|
|
if ( textures.exists )
|
|
{
|
|
var opacityTexture = textures.value.Find( t => t.name == CCTextureInfo.Opacity );
|
|
return opacityTexture != null;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool IsTransparent()
|
|
{
|
|
return HasOpacityTexture() || GetAlbedoColor( 1.0f ).A < 1.0f;
|
|
}
|
|
|
|
|
|
public CCMaterialType GetMaterialType()
|
|
{
|
|
var materialType = new CCMaterialType();
|
|
|
|
materialType.shaderType = CCMaterialType.CCShaderType.PBR;
|
|
|
|
if ( customShader.exists )
|
|
{
|
|
materialType.shaderType = ReflectionHelper.StringToEnum( customShader.value.name, CCMaterialType.CCShaderType.Unknown );
|
|
}
|
|
|
|
return materialType;
|
|
}
|
|
|
|
|
|
public StandardMaterial3D CreatePBRMaterial( CCMaterialSettings settings, bool skin = false )
|
|
{
|
|
var material = new StandardMaterial3D();
|
|
|
|
material.CullMode = twoSide.GetOr( false ) ? BaseMaterial3D.CullModeEnum.Disabled : BaseMaterial3D.CullModeEnum.Back;
|
|
|
|
material.Metallic = 1.0f;
|
|
material.AlbedoColor = GetAlbedoColor( settings.configuration.gammaForAlbedoColor );
|
|
material.Transparency = IsTransparent() ? BaseMaterial3D.TransparencyEnum.Alpha : BaseMaterial3D.TransparencyEnum.Disabled;
|
|
material.MetallicSpecular = skin ? 0.0f : 0.5f;
|
|
|
|
|
|
if ( skin && subsurfaceScatter.exists)
|
|
{
|
|
material.SubsurfScatterEnabled = true;
|
|
material.SubsurfScatterStrength = subsurfaceScatter.value.radius.value / 3.0f;
|
|
material.SubsurfScatterSkinMode = true;
|
|
}
|
|
|
|
if ( ! textures.exists )
|
|
{
|
|
return material;
|
|
}
|
|
|
|
textures.value.ForEach(
|
|
( t ) =>
|
|
{
|
|
if ( t.isBaseColor )
|
|
{
|
|
material.AlbedoTexture = t.GetTexture();
|
|
var uv1Scale = t.tiling.GetOr( new List<float>(){ 1, 1 } );
|
|
var uv1Offset = t.offset.GetOr( new List<float>(){ 0, 0 } );
|
|
material.Uv1Scale = new Vector3( uv1Scale[ 0 ], uv1Scale[ 1 ], 1 );
|
|
material.Uv1Offset = new Vector3( uv1Offset[ 0 ], uv1Offset[ 1 ], 1 );
|
|
}
|
|
else if ( t.isNormal )
|
|
{
|
|
material.NormalTexture = t.GetTexture();
|
|
material.NormalEnabled = true;
|
|
}
|
|
else if ( t.isRoughness )
|
|
{
|
|
material.RoughnessTexture = t.GetTexture();
|
|
material.RoughnessTextureChannel = BaseMaterial3D.TextureChannel.Red;
|
|
}
|
|
else if ( t.isMetallic )
|
|
{
|
|
material.MetallicTexture = t.GetTexture();
|
|
material.MetallicTextureChannel = BaseMaterial3D.TextureChannel.Red;
|
|
}
|
|
else if ( t.isGlow )
|
|
{
|
|
material.EmissionEnabled = true;
|
|
material.EmissionTexture = t.GetTexture();
|
|
}
|
|
else if ( t.isAO )
|
|
{
|
|
material.AOEnabled = true;
|
|
material.AOTexture = t.GetTexture();
|
|
material.AOTextureChannel = BaseMaterial3D.TextureChannel.Red;
|
|
}
|
|
}
|
|
);
|
|
|
|
return material;
|
|
}
|
|
|
|
public ShaderMaterial CreateEyeOcclusionMaterial( CCMaterialSettings settings )
|
|
{
|
|
var eyeOcclusionMaterial = new CCEyeOcclusionMaterial();
|
|
|
|
eyeOcclusionMaterial.shadowTopColor.Set(
|
|
ColorX.From( customShader.value.shadowTopColor.value, 255.0f )
|
|
);
|
|
|
|
eyeOcclusionMaterial.shadowBottomColor.Set(
|
|
ColorX.From( customShader.value.shadowBottomColor.value, 255.0f )
|
|
);
|
|
|
|
return eyeOcclusionMaterial;
|
|
}
|
|
|
|
public ShaderMaterial CreateEyeMaterial( CCMaterialSettings settings )
|
|
{
|
|
var eyeMaterial = new CCEyeMaterial();
|
|
|
|
textures.value.ForEach(
|
|
( t ) =>
|
|
{
|
|
if ( t.isBaseColor )
|
|
{
|
|
eyeMaterial.textureAlbedo.Set( t.GetTexture() );
|
|
|
|
}
|
|
}
|
|
);
|
|
|
|
eyeMaterial.textureNormal.Set( customShader.value.GetIrisNormal() );
|
|
|
|
return eyeMaterial;
|
|
}
|
|
|
|
public ShaderMaterial CreateSkinMaterial( CCMaterialSettings settings )
|
|
{
|
|
var skinMaterial = new CCSkinMaterial();
|
|
CustomMaterial outputMaterial = skinMaterial;
|
|
|
|
if ( settings.configuration.transmissiveSkin )
|
|
{
|
|
outputMaterial = new CCSkinTransmissiveMaterial();
|
|
}
|
|
|
|
if ( settings.configuration.applyAlbedoNoise )
|
|
{
|
|
var skinScale = 2.0f;
|
|
|
|
if ( name.EndsWith( "Head" ) )
|
|
{
|
|
skinScale = 1.0f;
|
|
}
|
|
else if ( name.EndsWith( "Body" ) )
|
|
{
|
|
skinScale = 5.0f;
|
|
}
|
|
|
|
|
|
skinMaterial.albedoNoiseUvScale.AssignFor( outputMaterial, skinScale );
|
|
skinMaterial.albedoNoiseOffset.AssignFor( outputMaterial, settings.configuration.albedoNoiseBrightness );
|
|
skinMaterial.albedoNoise.AssignFor( outputMaterial, settings.configuration.albedoNoiseAmount );
|
|
skinMaterial.textureAlbedoNoise.AssignFor( outputMaterial, settings.configuration.skinAlbedoNoise );
|
|
}
|
|
|
|
skinMaterial.albedo.AssignFor( outputMaterial, GetAlbedoColor( settings.configuration.gammaForAlbedoColor ) );
|
|
skinMaterial.specular.AssignFor( outputMaterial, 0.5f );
|
|
|
|
|
|
var tiling = customShader.value.GetFloatVariable( "MicroNormal Tiling", 20f );
|
|
skinMaterial.uv1Scale.AssignFor( outputMaterial, Vector3.One );
|
|
skinMaterial.uv2Scale.AssignFor( outputMaterial, Vector3.One * tiling );
|
|
|
|
skinMaterial.microNormalTexture.AssignFor( outputMaterial, customShader.value.GetMicroNormal() );
|
|
skinMaterial.microNormalMaskTexture.AssignFor( outputMaterial, customShader.value.GetMicroNormalMask() );
|
|
skinMaterial.microNormalScale.AssignFor( outputMaterial, customShader.value.GetFloatVariable( "MicroNormal Strength", 0.5f ) );
|
|
|
|
if ( outputMaterial is CCSkinTransmissiveMaterial st )
|
|
{
|
|
st.textureSubsurfaceTransmittance.Set( customShader.value.GetTransmisionMap() );
|
|
}
|
|
// skinMaterial.textureSubsurfaceTransmittance.Set( customShader.value.GetTransmisionMap() );
|
|
skinMaterial.textureSpecular.AssignFor( outputMaterial, customShader.value.GetSpecularMask() );
|
|
skinMaterial.textureSubsurfaceScattering.AssignFor( outputMaterial, customShader.value.GetSSSMap() );
|
|
|
|
textures.value.ForEach(
|
|
( t ) =>
|
|
{
|
|
if ( t.isBaseColor )
|
|
{
|
|
skinMaterial.textureAlbedo.AssignFor( outputMaterial, t.GetTexture() );
|
|
|
|
var uv1Scale = t.tiling.GetOr( new List<float>(){ 1, 1 } );
|
|
var uv1Offset = t.offset.GetOr( new List<float>(){ 0, 0 } );
|
|
|
|
skinMaterial.uv1Scale.AssignFor( outputMaterial, new Vector3( uv1Scale[ 0 ], uv1Scale[ 1 ], 1 ) );
|
|
skinMaterial.uv1Offset.AssignFor( outputMaterial, new Vector3( uv1Offset[ 0 ], uv1Offset[ 1 ], 1 ) );
|
|
}
|
|
else if ( t.isNormal )
|
|
{
|
|
skinMaterial.textureNormal.AssignFor( outputMaterial, t.GetTexture() );
|
|
}
|
|
else if ( t.isRoughness )
|
|
{
|
|
skinMaterial.textureRoughness.AssignFor( outputMaterial, t.GetTexture() );
|
|
}
|
|
else if ( t.isAO )
|
|
{
|
|
skinMaterial.textureAmbientOcclusion.AssignFor( outputMaterial, t.GetTexture() );
|
|
}
|
|
}
|
|
);
|
|
|
|
return outputMaterial;
|
|
|
|
}
|
|
|
|
public ShaderMaterial CreateOpacityMaterial( CCMaterialSettings settings )
|
|
{
|
|
var opacityMaterial = new CCPBROpacityMaterial();
|
|
|
|
opacityMaterial.albedo.Set( GetAlbedoColor( settings.configuration.gammaForAlbedoColor ) );
|
|
opacityMaterial.specular.Set( 0.0f );
|
|
opacityMaterial.opacity.Set( opacity.GetOr( 1 ) );
|
|
opacityMaterial.uv1Scale.Set( Vector3.One );
|
|
opacityMaterial.uv2Scale.Set( Vector3.One );
|
|
|
|
textures.value.ForEach(
|
|
( t ) =>
|
|
{
|
|
if ( t.isBaseColor )
|
|
{
|
|
opacityMaterial.textureAlbedo.Set( t.GetTexture() );
|
|
|
|
var uv1Scale = t.tiling.GetOr( new List<float>(){ 1, 1 } );
|
|
var uv1Offset = t.offset.GetOr( new List<float>(){ 0, 0 } );
|
|
|
|
opacityMaterial.uv1Scale.Set( new Vector3( uv1Scale[ 0 ], uv1Scale[ 1 ], 1 ) );
|
|
opacityMaterial.uv1Offset.Set( new Vector3( uv1Offset[ 0 ], uv1Offset[ 1 ], 1 ) );
|
|
}
|
|
if ( t.isOpacity )
|
|
{
|
|
opacityMaterial.textureOpacity.Set( t.GetTexture() );
|
|
}
|
|
else if ( t.isNormal )
|
|
{
|
|
opacityMaterial.textureNormal.Set( t.GetTexture() );
|
|
}
|
|
else if ( t.isRoughness )
|
|
{
|
|
opacityMaterial.textureRoughness.Set( t.GetTexture() );
|
|
}
|
|
else if ( t.isMetallic )
|
|
{
|
|
opacityMaterial.textureMetallic.Set( t.GetTexture() );
|
|
opacityMaterial.metallicTextureChannel.Set( new Vector4( 1, 0, 0, 0 ) );
|
|
}
|
|
else if ( t.isAO )
|
|
{
|
|
opacityMaterial.textureAmbientOcclusion.Set( t.GetTexture() );
|
|
opacityMaterial.aoTextureChannel.Set( new Vector4( 1, 0, 0, 0 ) );
|
|
}
|
|
}
|
|
);
|
|
|
|
return opacityMaterial;
|
|
}
|
|
|
|
public ShaderMaterial CreateHairMaterial( CCMaterialSettings settings )
|
|
{
|
|
|
|
|
|
var scissorMaterial = new CCHairScissorMaterial();
|
|
var alphaMaterial = new CCHairAlphaMaterial();
|
|
var alphaBackMaterial = new CCHairAlphaBackMaterial();
|
|
|
|
|
|
scissorMaterial.NextPass = alphaBackMaterial;
|
|
alphaBackMaterial.NextPass = alphaMaterial;
|
|
|
|
alphaBackMaterial.RenderPriority = settings.materialRenderPriorityIndexBack;
|
|
alphaMaterial.RenderPriority = settings.materialRenderPriorityIndexFront;
|
|
|
|
var m = new List<CustomMaterial>(){ scissorMaterial, alphaMaterial, alphaBackMaterial };
|
|
|
|
var mat = scissorMaterial;
|
|
|
|
CustomMaterial outputMaterial = scissorMaterial;
|
|
|
|
var opacityScale = 1.0f;
|
|
|
|
if ( CCImportConfiguration.HairShaderMode.Alpha_Only == settings.configuration.hairShaderMode )
|
|
{
|
|
var hairMaterial = new CCHairMaterial();
|
|
hairMaterial.RenderPriority = settings.materialRenderPriorityIndexBack;
|
|
outputMaterial = hairMaterial;
|
|
m = new List<CustomMaterial>(){ hairMaterial };
|
|
opacityScale = 1.5f;
|
|
}
|
|
else if ( CCImportConfiguration.HairShaderMode.Shadow_Scissor_AlphaBack_AlphaFront == settings.configuration.hairShaderMode )
|
|
{
|
|
scissorMaterial.NextPass = null;
|
|
|
|
var shadowMaterial = new CCHairShadowMaterial();
|
|
shadowMaterial.RenderPriority = -2;
|
|
var hairMaterial = new CCHairScissorMaterial();
|
|
|
|
outputMaterial = shadowMaterial;
|
|
shadowMaterial.NextPass = hairMaterial;
|
|
hairMaterial.NextPass = alphaBackMaterial;
|
|
|
|
m = new List<CustomMaterial>(){ shadowMaterial, hairMaterial, alphaMaterial, alphaBackMaterial };
|
|
opacityScale = 1f;
|
|
}
|
|
|
|
mat.naturalColors.AssignFor( m, settings.configuration.naturalColors );
|
|
mat.maximumHighlightAmount.AssignFor( m, settings.configuration.maximumHighlightAmount );
|
|
|
|
mat.opacityGamma.AssignFor( m, settings.configuration.GetHairOpacityGamma( settings.meshName, settings.materialIndex ) );
|
|
|
|
mat.flowMap.AssignFor( m, customShader.value.GetHairFlowMap() );
|
|
mat.rootMap.AssignFor( m, customShader.value.GetHairRootMap() );
|
|
mat.idMap.AssignFor( m, customShader.value.GetHairIDMap() );
|
|
|
|
mat.anisotropyRatio.AssignFor( m, settings.configuration.anisotropicRatio );
|
|
|
|
mat.vertexGreyToColor.AssignFor( m, customShader.value.GetColorVariable( "VertexGrayToColor", 255f, false ) );
|
|
mat.vertexColorStrength.AssignFor( m, customShader.value.GetFloatVariable( "VertexColorStrength" ) );
|
|
mat.diffuseStrength.AssignFor( m, customShader.value.GetFloatVariable( "Diffuse Strength" ) );
|
|
mat.baseColorMapStrength.AssignFor( m, customShader.value.GetFloatVariable( "BaseColorMapStrength" ) );
|
|
|
|
mat.strandRootColor.AssignFor( m, customShader.value.GetColorVariable( "RootColor", 255f, false ) );
|
|
mat.strandRootStrength.AssignFor( m, customShader.value.GetFloatVariable( "RootColorStrength" ) );
|
|
|
|
mat.strandEndColor.AssignFor( m, customShader.value.GetColorVariable( "TipColor", 255f, false ) );
|
|
mat.strandEndStrength.AssignFor( m, customShader.value.GetFloatVariable( "TipColorStrength" ) );
|
|
|
|
mat.highlightAColor.AssignFor( m, customShader.value.GetColorVariable( "_1st Dye Color", 255, false ) );
|
|
mat.highlightAStrength.AssignFor( m, customShader.value.GetFloatVariable( "_1st Dye Strength" ) );
|
|
mat.highlightARange.AssignFor( m,
|
|
customShader.value.GetColorVariable( "_1st Dye Distribution from Grayscale", 255, false ).ToVector3()
|
|
);
|
|
mat.highlightAOverlapEnd.AssignFor( m, customShader.value.GetFloatVariable( "Mask 1st Dye by RootMap" ) );
|
|
mat.highlightAInvert.AssignFor( m, customShader.value.GetFloatVariable( "Invert 1st Dye RootMap Mask" ) );
|
|
|
|
mat.highlightBColor.AssignFor( m, customShader.value.GetColorVariable( "_2nd Dye Color", 255, false ) );
|
|
mat.highlightBStrength.AssignFor( m, customShader.value.GetFloatVariable( "_2nd Dye Strength" ) );
|
|
mat.highlightBRange.AssignFor( m,
|
|
customShader.value.GetColorVariable( "_2nd Dye Distribution from Grayscale", 255, false ).ToVector3()
|
|
);
|
|
mat.highlightBOverlapEnd.AssignFor( m, customShader.value.GetFloatVariable( "Mask 2nd Dye by RootMap" ) );
|
|
mat.highlightBInvert.AssignFor( m, customShader.value.GetFloatVariable( "Invert 2nd Dye RootMap Mask" ) );
|
|
|
|
|
|
mat.albedo.AssignFor( m, GetAlbedoColor( settings.configuration.gammaForAlbedoColor ) );
|
|
// mat.specular.AssignFor( m, 0.5f );
|
|
mat.opacity.AssignFor( m, opacity.GetOr( 1 ) * opacityScale );
|
|
mat.blendAmount.AssignFor( m, 0f );
|
|
|
|
mat.roughnessOffset.AssignFor( m, settings.configuration.roughnessOffset );
|
|
mat.metallicOffset.AssignFor( m, settings.configuration.metallicOffset );
|
|
|
|
textures.value.ForEach(
|
|
( t ) =>
|
|
{
|
|
if ( t.isBaseColor )
|
|
{
|
|
mat.textureAlbedo.AssignFor( m, t.GetTexture() );
|
|
}
|
|
if ( t.isOpacity )
|
|
{
|
|
mat.textureOpacity.AssignFor( m, t.GetTexture() );
|
|
}
|
|
else if ( t.isRoughness )
|
|
{
|
|
mat.textureRoughness.AssignFor( m, t.GetTexture() );
|
|
}
|
|
else if ( t.isMetallic )
|
|
{
|
|
mat.textureMetallic.AssignFor( m, t.GetTexture() );
|
|
}
|
|
else if ( t.isAO )
|
|
{
|
|
mat.textureAmbientOcclusion.AssignFor( m, t.GetTexture() );
|
|
}
|
|
else if ( t.isBlend )
|
|
{
|
|
mat.textureBlend.AssignFor( m, t.GetTexture() );
|
|
mat.blendAmount.AssignFor( m, t.strength.GetOr( 0f ) / 100f ) ;
|
|
}
|
|
}
|
|
);
|
|
|
|
return outputMaterial;
|
|
}
|
|
|
|
}
|
|
} |