367 lines
9.5 KiB
C#
367 lines
9.5 KiB
C#
|
|
using Godot;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
|
||
|
|
namespace Rokojori
|
||
|
|
{
|
||
|
|
[Tool]
|
||
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/FlareVFX.svg") ]
|
||
|
|
public partial class FlareLayer:Resource
|
||
|
|
{
|
||
|
|
[Export]
|
||
|
|
public string layerName = "";
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public bool solo = false;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public bool hide = false;
|
||
|
|
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float opacity = 1f;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public int numLayers = 1;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public FlareType flareType;
|
||
|
|
|
||
|
|
[ExportGroup("Color/Overwrite")]
|
||
|
|
[Export]
|
||
|
|
public Color overwriteColor = Colors.White;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float overwriteAmount = 0f;
|
||
|
|
|
||
|
|
[ExportGroup("Color")]
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float minHueRandom = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float maxHueRandom = 0;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public CurveTexture opacityCurvePerLayer = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public Color tint = Colors.White;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float hueShift = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float temparatureShift = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-100,100" )]
|
||
|
|
public float saturationShift = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-100,100" )]
|
||
|
|
public float lighntessShift = 0;
|
||
|
|
|
||
|
|
|
||
|
|
[ExportGroup("Size")]
|
||
|
|
[Export]
|
||
|
|
public float size = 1;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float sizeScale = 1;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float sizeXScale = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float sizeYScale = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,2" )]
|
||
|
|
public float worldSizeScale = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,2" )]
|
||
|
|
public float screenSizeScale = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float worldSize_vs_screenSize = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,2" )]
|
||
|
|
public float randomScaleMin = 1f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,2" )]
|
||
|
|
public float randomScaleMax = 1f;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public bool overwriteExtension = false;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "1,10" )]
|
||
|
|
public float extension = 1f;
|
||
|
|
|
||
|
|
|
||
|
|
[ExportGroup("ScreenOffset")]
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public Vector2 screenOffset = Vector2.Zero;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float screenOffsetStaticScale = 1f;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public Vector2 screenOffsetStaticDirection = Vector2.Zero;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "0,1" )]
|
||
|
|
public float screenOffsetLayerScale = 1f;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public Vector2 screenOffsetLayerDirection = Vector2.Zero;
|
||
|
|
|
||
|
|
[ExportGroup("Rotation")]
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float rotation = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float rotationOverX = 0;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float rotationOverY = 0f;
|
||
|
|
|
||
|
|
[Export( PropertyHint.Range, "-180,180" )]
|
||
|
|
public float rotationPerLayer = 0f;
|
||
|
|
|
||
|
|
[ExportGroup("Overwrites")]
|
||
|
|
[Export]
|
||
|
|
public FlareFading fading = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public FlareChromaticAberation chromaticAberation = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public FlareOcclusion occlusion = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public FlareBlendMode blendMode = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public FlareStencilMode stencilMode = null;
|
||
|
|
|
||
|
|
[Export]
|
||
|
|
public int renderPriority = 0;
|
||
|
|
|
||
|
|
|
||
|
|
public Data Create( FlareVFX vfx )
|
||
|
|
{
|
||
|
|
return new Data( vfx, this );
|
||
|
|
}
|
||
|
|
|
||
|
|
public class Data
|
||
|
|
{
|
||
|
|
public FlareLayer layer;
|
||
|
|
public FlareVFX vfx;
|
||
|
|
public MeshInstance3D meshInstance;
|
||
|
|
public ShaderMaterial material;
|
||
|
|
|
||
|
|
public FlareBlendMode.BlendModeType GetBlendMode()
|
||
|
|
{
|
||
|
|
return layer.blendMode != null ? layer.blendMode.blendMode : vfx.preset.blendMode;
|
||
|
|
}
|
||
|
|
|
||
|
|
public Data( FlareVFX vfx, FlareLayer layer )
|
||
|
|
{
|
||
|
|
this.vfx = vfx;
|
||
|
|
this.layer = layer;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void Update()
|
||
|
|
{
|
||
|
|
if ( meshInstance == null || layer.flareType == null )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
EnsureMesh();
|
||
|
|
EnsureMaterial();
|
||
|
|
|
||
|
|
if ( material == null )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
layer.flareType.ApplyShape( this );
|
||
|
|
|
||
|
|
|
||
|
|
ApplyColor();
|
||
|
|
ApplySize();
|
||
|
|
ApplyScreenOffset();
|
||
|
|
ApplyRotation();
|
||
|
|
ApplyFading();
|
||
|
|
ApplyChromaticAberation();
|
||
|
|
ApplyOcclusion();
|
||
|
|
|
||
|
|
material.RenderPriority = layer.renderPriority;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void EnsureMesh()
|
||
|
|
{
|
||
|
|
var arrayMesh = meshInstance.Mesh as ArrayMesh;
|
||
|
|
|
||
|
|
if ( arrayMesh != null && arrayMesh.SurfaceGetArrayLen( 0 ) == layer.numLayers * 4 )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var gen = new UnitBillboardQuadsGenerator();
|
||
|
|
gen.num = layer.numLayers;
|
||
|
|
meshInstance.Mesh = gen.Generate();
|
||
|
|
}
|
||
|
|
|
||
|
|
void EnsureMaterial()
|
||
|
|
{
|
||
|
|
var miMaterial = meshInstance.GetSurfaceOverrideMaterial( 0 ) as ShaderMaterial;
|
||
|
|
|
||
|
|
if ( material != null && miMaterial != null && miMaterial.Shader == layer.flareType.GetShader( this ) )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
material = layer.flareType.CreateMaterial( this );
|
||
|
|
meshInstance.SetSurfaceOverrideMaterial( 0, material );
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplyColor()
|
||
|
|
{
|
||
|
|
var preset = vfx.preset;
|
||
|
|
var color = preset.mainColor;
|
||
|
|
|
||
|
|
if ( layer.overwriteAmount > 0 )
|
||
|
|
{
|
||
|
|
color = color.Lerp( layer.overwriteColor, layer.overwriteAmount );
|
||
|
|
}
|
||
|
|
|
||
|
|
color *= layer.tint;
|
||
|
|
|
||
|
|
var scale = color.GetColorScale();
|
||
|
|
var hsl = color.ToHSL( scale );
|
||
|
|
|
||
|
|
hsl.h += layer.hueShift + preset.hueShift;
|
||
|
|
|
||
|
|
hsl.h = MathX.Repeat( hsl.h, 360f );
|
||
|
|
|
||
|
|
hsl.h = HSLColor.ShiftTemparatureOfHue( hsl.h, preset.temparatureShift + layer.temparatureShift );
|
||
|
|
hsl.s += ( layer.saturationShift + preset.saturationShift ) / 100f;
|
||
|
|
hsl.l += ( layer.lighntessShift + preset.lightnessShift ) / 100f;
|
||
|
|
|
||
|
|
hsl.ClampToLimits();
|
||
|
|
|
||
|
|
color = hsl.ToRGBA( scale );
|
||
|
|
|
||
|
|
// color = preset.mainColor;
|
||
|
|
BaseFlareShader.color.Set( material, color );
|
||
|
|
BaseFlareShader.opacity.Set( material, preset.opacity * layer.opacity );
|
||
|
|
BaseFlareShader.opacityCurve.Set( material, layer.opacityCurvePerLayer );
|
||
|
|
BaseFlareShader.minHueRandom.Set( material, layer.minHueRandom / 360f );
|
||
|
|
BaseFlareShader.maxHueRandom.Set( material, layer.maxHueRandom / 360f );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplySize()
|
||
|
|
{
|
||
|
|
var preset = vfx.preset;
|
||
|
|
var size = Vector2.One * preset.scale;
|
||
|
|
|
||
|
|
size *= layer.size * layer.sizeScale * new Vector2( layer.sizeXScale, layer.sizeYScale );
|
||
|
|
|
||
|
|
BaseFlareShader.sizeX.Set( material, size.X );
|
||
|
|
BaseFlareShader.sizeY.Set( material, size.Y );
|
||
|
|
|
||
|
|
BaseFlareShader.worldSizeScale.Set( material, layer.worldSizeScale );
|
||
|
|
BaseFlareShader.screenSizeScale.Set( material, layer.screenSizeScale );
|
||
|
|
BaseFlareShader.worldSizeVsScreenSize.Set( material, layer.worldSize_vs_screenSize );
|
||
|
|
|
||
|
|
BaseFlareShader.randomScaleMin.Set( material, layer.randomScaleMin );
|
||
|
|
BaseFlareShader.randomScaleMax.Set( material, layer.randomScaleMax );
|
||
|
|
|
||
|
|
|
||
|
|
BaseFlareShader.extension.Set( material, layer.overwriteExtension ? layer.extension : preset.extension );
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplyScreenOffset()
|
||
|
|
{
|
||
|
|
BaseFlareShader.screenOffset.Set( material, layer.screenOffset );
|
||
|
|
BaseFlareShader.screenOffsetScale.Set( material, layer.screenOffsetStaticDirection * layer.screenOffsetStaticScale );
|
||
|
|
BaseFlareShader.screenOffsetLayerSpread.Set( material, layer.screenOffsetLayerDirection * layer.screenOffsetLayerScale );
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplyRotation()
|
||
|
|
{
|
||
|
|
BaseFlareShader.rotation.Set( material, layer.rotation );
|
||
|
|
BaseFlareShader.rotationOverX.Set( material, layer.rotationOverX );
|
||
|
|
BaseFlareShader.rotationOverY.Set( material, layer.rotationOverY );
|
||
|
|
BaseFlareShader.rotationPerLayer.Set( material, layer.rotationPerLayer );
|
||
|
|
|
||
|
|
// BaseFlareShader.vertexRotation.Set( material, layer.vertexRotation );
|
||
|
|
// BaseFlareShader.vertexRotationOverX.Set( material, layer.vertexRotationOverX );
|
||
|
|
// BaseFlareShader.vertexRotationOverY.Set( material, layer.vertexRotationOverY );
|
||
|
|
// BaseFlareShader.vertexRotationPerLayer.Set( material, layer.vertexRotationPerLayer );
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplyFading()
|
||
|
|
{
|
||
|
|
var preset = vfx.preset;
|
||
|
|
var fading = preset.fading;
|
||
|
|
|
||
|
|
if ( layer.fading != null )
|
||
|
|
{
|
||
|
|
fading = layer.fading;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( fading == null )
|
||
|
|
{
|
||
|
|
BaseFlareShader.fadingMode.Set( material, 0 );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
fading.ApplyFading( this );
|
||
|
|
}
|
||
|
|
|
||
|
|
void ApplyChromaticAberation()
|
||
|
|
{
|
||
|
|
var preset = vfx.preset;
|
||
|
|
var chromaticAberation = preset.chromaticAberation;
|
||
|
|
|
||
|
|
if ( layer.chromaticAberation != null )
|
||
|
|
{
|
||
|
|
chromaticAberation = layer.chromaticAberation;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( chromaticAberation == null )
|
||
|
|
{
|
||
|
|
BaseFlareShader.chromaticAberationMode.Set( material, 0 );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
chromaticAberation.ApplyChromaticAberation( this );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void ApplyOcclusion()
|
||
|
|
{
|
||
|
|
var preset = vfx.preset;
|
||
|
|
var occlusion = preset.occlusion;
|
||
|
|
|
||
|
|
if ( layer.occlusion != null )
|
||
|
|
{
|
||
|
|
occlusion = layer.occlusion;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( occlusion == null )
|
||
|
|
{
|
||
|
|
BaseFlareShader.occlusionMode.Set( material, 0 );
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
occlusion.ApplyOcclusion( this );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|