rj-action-library/Runtime/Procedural/Baking/SetBakingMaterials.cs

150 lines
4.3 KiB
C#
Raw Normal View History

2024-12-01 17:07:41 +00:00
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
[Tool]
[GlobalClass]
2025-01-03 12:09:23 +00:00
public partial class SetBakingMaterials:Node
2024-12-01 17:07:41 +00:00
{
[Export]
public Node targetContainer;
[Export]
public BakingMaterialMode mode;
2025-01-03 12:09:23 +00:00
MapList<VisualInstance3D,Material> _originalMaterials;
public void SetTarget( Node targetContainer )
2024-12-01 17:07:41 +00:00
{
2025-01-03 12:09:23 +00:00
_originalMaterials = new MapList<VisualInstance3D, Material>();
this.targetContainer = targetContainer;
2024-12-01 17:07:41 +00:00
Nodes.ForEach<VisualInstance3D>( targetContainer,
( v )=>
{
2025-01-03 12:09:23 +00:00
_originalMaterials[ v ] = Materials.GetAll<Material>( v );
2024-12-01 17:07:41 +00:00
}
);
}
2025-01-03 12:09:23 +00:00
public void ApplyBakingMaterials( float distance, float radius )
{
Nodes.ForEach<VisualInstance3D>( targetContainer,
( v )=>
{
SetMaterial( v, distance, radius );
}
);
}
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
FloatPropertyName centerDistance = FloatPropertyName.Create( "centerDistance");
FloatPropertyName rangeDistance = FloatPropertyName.Create( "rangeDistance");
void SetMaterial( VisualInstance3D v, float distance, float radius )
2024-12-01 17:07:41 +00:00
{
2025-01-03 12:09:23 +00:00
var materials = _originalMaterials[ v ];
if ( BakingMaterialMode.Preview != mode )
2024-12-01 17:07:41 +00:00
{
2025-01-03 12:09:23 +00:00
materials = CreateBakingMaterials( materials );
2024-12-01 17:07:41 +00:00
}
2025-01-03 12:09:23 +00:00
if ( BakingMaterialMode.Depth == mode )
{
materials.ForEach(
m =>
{
centerDistance.Set( m, distance );
rangeDistance.Set( m, radius );
}
);
}
Materials.Set( v, materials );
}
List<Material> CreateBakingMaterials( List<Material> materials )
{
return Lists.Map( materials, m => CreateBakingMaterial( m ) );
}
Material CreateBakingMaterial( Material originalMaterial )
{
var bakingMaterial = LoadBakingMaterialForMode().Duplicate( true ) as Material;
var materialTransfer = GetBakingMaterialTransfer();
this.LogInfo( mode, materialTransfer, originalMaterial, bakingMaterial );
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
materialTransfer.Transfer( originalMaterial, bakingMaterial );
return bakingMaterial;
2024-12-01 17:07:41 +00:00
}
2025-01-03 12:09:23 +00:00
static readonly string transferPaths = "res://addons/rokojori_action_library/Runtime/Procedural/Baking/BakingMaterials/";
MaterialTransfer GetBakingMaterialTransfer()
2024-12-01 17:07:41 +00:00
{
switch ( mode )
{
2025-01-03 12:09:23 +00:00
case BakingMaterialMode.Albedo: return Load<MaterialTransfer>( transferPaths + "Albedo/Albedo Transfer.tres" );
case BakingMaterialMode.Normals: return Load<MaterialTransfer>( transferPaths + "Normal/Normal Transfer.tres" );
case BakingMaterialMode.ORM: return Load<MaterialTransfer>( transferPaths + "ORM/ORM Transfer.tres" );
case BakingMaterialMode.Depth: return Load<MaterialTransfer>( transferPaths + "Depth/Depth Transfer.tres" );
}
return null;
}
2024-12-01 17:07:41 +00:00
2025-01-03 12:09:23 +00:00
public static readonly string materialsPath = "res://addons/rokojori_action_library/External/Imposter/materials/";
public static readonly string depthMapPath = "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Baking/DepthMap.material";
public Material LoadBakingMaterialForMode()
{
switch ( mode )
{
case BakingMaterialMode.Albedo: return Load<Material>( materialsPath + "albedo_material.material" );
case BakingMaterialMode.Normals: return Load<Material>( materialsPath + "normal_baker.material" );
case BakingMaterialMode.ORM: return Load<Material>( materialsPath + "orm_baker.material" );
case BakingMaterialMode.Depth: return Load<Material>( depthMapPath );
2024-12-01 17:07:41 +00:00
}
return null;
}
2025-01-03 12:09:23 +00:00
static Dictionary<string,Resource> _cachedResources = new Dictionary<string, Resource>();
static R Load<R>( string resourcePath ) where R:Resource
{
RJLog.Log( "Loading", resourcePath );
if ( ! _cachedResources.ContainsKey( resourcePath ) )
{
_cachedResources[ resourcePath ] = ResourceLoader.Load( resourcePath );
RJLog.Log( "Loaded", resourcePath, _cachedResources[ resourcePath ] );
if ( _cachedResources[ resourcePath ] == null )
{
RJLog.Error( "Resource not found:", resourcePath );
}
}
return _cachedResources[ resourcePath ] as R;
}
2024-12-01 17:07:41 +00:00
}
}