rj-action-library/Runtime/Procedural/Baking/MultiBaker/Octahedral_Baker.cs

131 lines
3.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Octahedral_Baker:_XX_MultiBakeMode
{
public static readonly string octahedralShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
[Export]
public int octahedralSides = 4;
[Export]
public bool octahedralFullSphere = false;
public override int GetNumViews()
{
var views = octahedralSides * octahedralSides;
return views;
}
public override void CreateMaterial( bool preview )
{
var mb = multiBaker;
var material = new ShaderMaterial();
material.Shader = ResourceLoader.Load( octahedralShader ) as Shader;
material.SetShaderParameter( "isFullSphere", octahedralFullSphere );
material.SetShaderParameter( "imposterFrames", Vector2.One * octahedralSides );
Materials.Set( mb.X_outputMesh, material );
}
public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture )
{
var mb = multiBaker;
mb.CacheTexture( mode, texture );
var material = Materials.Get<ShaderMaterial>( mb.X_outputMesh );
if ( material == null )
{
RJLog.Log( "Not the right material on mesh!" );
return;
}
if ( BakingMaterialMode.Albedo == mode || BakingMaterialMode.Preview == mode )
{
material.SetShaderParameter( "imposterTextureAlbedo", texture );
}
else if ( BakingMaterialMode.Normals == mode )
{
material.SetShaderParameter( "imposterTextureNormal", texture );
}
else if ( BakingMaterialMode.ORM == mode )
{
material.SetShaderParameter( "imposterTextureOrm", texture );
}
else if ( BakingMaterialMode.Depth == mode )
{
material.SetShaderParameter( "imposterTextureDepth", texture );
}
}
public override void CreateBakers()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
bk =>
{
var vs = bk.viewSettings;
vs.fovDistance = Manual_BakingFDSettings.Create( fov, distance );
vs.rotationMode = BakingViewSettings.RotationMode.Quaternion;
}
);
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
var toOP = 1f / ( octahedralSides - 1 );
var index = 0;
for ( int x = 0; x < octahedralSides; x++ )
{
for ( int y = 0; y < octahedralSides; y++ )
{
var inverseX = ( octahedralSides - 1 ) - x;
var inverseY = ( octahedralSides - 1 ) - y;
var octahedralPosition = new Vector2( y, inverseX ) * toOP;
var normal = OctahedralMapping.Map( octahedralPosition, octahedralFullSphere );
_bakers[ index ].viewSettings.rotationQuaternion = Math3D.LookRotation( normal, true ).Normalized().Inverse();
index ++;
}
}
var qm = new QuadMesh();
mb.X_outputMesh.Mesh = qm;
var magicScale = 0.75f;
mb.X_outputMesh.Scale = Vector3.One * ( outputScale / mb.cameraZoom * magicScale);
}
}
}