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

130 lines
3.5 KiB
C#
Raw Normal View History

2025-01-03 12:09:23 +00:00
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
public class MultiBakeModeOctahedral:MultiBakeModeImplementation
{
public readonly string octahedralShader = "res://addons/rokojori_action_library/External/Imposter/materials/shaders/ImpostorShader.gdshader";
public override MultiBaker.BakeMode GetBakeMode()
{
return MultiBaker.BakeMode.Octahedral;
}
public override int GetNumViews()
{
var views = multiBaker.octahedralSides * multiBaker.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", mb.octahedralFullSphere );
material.SetShaderParameter( "imposterFrames", Vector2.One * mb.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 CreateBakes()
{
var fov = multiBaker.GetCameraFOV();
var distance = multiBaker.GetCameraDistance();
var outputScale = multiBaker.GetOutputScale();
var _bakers = multiBaker.bakers;
var mb = multiBaker;
_bakers.ForEach(
b =>
{
b.useCustomFOV = true;
b.customFOV = fov;
b.useCustomDistance = true;
b.customDistance = distance;
b.rotationMode = Baker.RotationMode.Quaternion;
}
);
var numTextures = GetNumViews();
var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures );
var toOP = 1f / ( mb.octahedralSides - 1 );
var index = 0;
for ( int x = 0; x < mb.octahedralSides; x++ )
{
for ( int y = 0; y < mb.octahedralSides; y++ )
{
var inverseX = ( mb.octahedralSides - 1 ) - x;
var inverseY = ( mb.octahedralSides - 1 ) - y;
var octahedralPosition = new Vector2( y, inverseX ) * toOP;
var normal = OctahedralMapping.Map( octahedralPosition, mb.octahedralFullSphere );
_bakers[ index ].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);
}
}
}