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

148 lines
3.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GrabTexture2:Action
{
[Export]
public SubViewport viewport;
[Export]
public Texture2D target;
[Export]
public MeshInstance3D meshInstance3D;
[Export( PropertyHint.Range, "0,1" ) ]
public float intensity;
[Export( PropertyHint.Range, "0,100" ) ]
public float noise;
[Export( PropertyHint.Range, "1,100" ) ]
public float kernelOffset;
[Export( PropertyHint.Range, "1,50" ) ]
public float kernelRadius;
[ExportToolButton( "Grab Texture")]
public Callable GrabButton => Callable.From(
() =>
{
Grab();
}
);
async void Grab()
{
var updateMode = viewport.RenderTargetUpdateMode;
if ( updateMode != SubViewport.UpdateMode.Always )
{
viewport.RenderTargetUpdateMode = SubViewport.UpdateMode.Always;
await this.RequestNextFrame();
viewport.RenderTargetUpdateMode = updateMode;
}
var viewPortFormat = RDTextureFormats.GetDataFormat( viewport );
var viewPortData = viewport.GetTexture().GetImage().GetData();
var viewPortSize = viewport.Size;
this.LogInfo( "Creating context" );
var ctx = RDContext.Local();
ctx.computeSize = viewPortSize;
ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose );
this.LogInfo( "Creating textures" );
var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) );
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
inputTexture.SetData( viewPortData );
this.LogInfo( "Creating graph" );
var graph = CreateGraph( ctx, inputTexture, outputTexture );
this.LogInfo( "Process graph" );
graph.ProcessForView();
ctx.SubmitAndSync();
var width = inputTexture.width;
var height = inputTexture.height;
var format = inputTexture.imageFormat;
var data = inputTexture.GetData();
ctx.SubmitAndSync();
await this.RequestNextFrame();
this.LogInfo( "Copying texture" );
var image = Image.CreateFromData( width, height, false, format, data );
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) );
target = buffer.CreateImageTexture();
var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride;
material3D.AlbedoTexture = target;
ctx.CleanUp();
await this.RequestNextFrame();
}
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot )
{
var graph = new RDGraph( ctx );
var viewTexture = CEG_BufferTexture.From( graph, it );
var bufferTexture = CEG_BufferTexture.From( graph, ot );
var copy = new CEG_Copy( graph );
var blur = new RD_BoxBlur( graph );
graph.InitializeNodes();
copy.SetTextureSlotInputs( viewTexture, bufferTexture );
blur.SetTextureSlotInputs( copy.output, copy.input );
graph.SetProcessOrder(
viewTexture, bufferTexture,
copy, blur
);
blur.constants.Set(
intensity,
noise,
kernelOffset,
kernelRadius
);
ctx.Verbose( "Radial Blur constants:", blur.constants.size );
return graph;
}
}
}