Update Texture Combiner
This commit is contained in:
parent
1c06a1f4d0
commit
a413d6d31e
|
@ -24,6 +24,10 @@ namespace Rokojori
|
|||
public static float pmR( this Color c ) => c.AlphaMultipliedR();
|
||||
public static float pmG( this Color c ) => c.AlphaMultipliedG();
|
||||
public static float pmB( this Color c ) => c.AlphaMultipliedB();
|
||||
public static Color PreMultiply( this Color c )
|
||||
{
|
||||
return new Color( c.pmR(), c.pmG(), c.pmB(), c.A );
|
||||
}
|
||||
|
||||
static float Clamp( float f )
|
||||
{
|
||||
|
@ -54,6 +58,16 @@ namespace Rokojori
|
|||
return new Color( r, g, b, 1 ) / a;
|
||||
}
|
||||
|
||||
public static Color PreMultipliedRGBBlendMode( Color bottom, Color top, System.Func<Color,Color,float, Color> blending )
|
||||
{
|
||||
var fade = ( 1f - top.A );
|
||||
var a = top.A + bottom.A * fade;
|
||||
|
||||
var rgb = blending( bottom.PreMultiply(), top.PreMultiply(), fade );
|
||||
|
||||
return new Color( rgb.R, rgb.G, rgb.B, 1 ) / a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Color BlendMultiply( Color bottom, Color top )
|
||||
|
@ -106,6 +120,36 @@ namespace Rokojori
|
|||
);
|
||||
}
|
||||
|
||||
public static Color BlendColor( Color bottom, Color top )
|
||||
{
|
||||
var hslA = HSLColor.FromRGBA( bottom );
|
||||
var hslB = HSLColor.FromRGBA( top );
|
||||
|
||||
var combined = bottom.A == 0 ? bottom : (Color)( new HSLColor( hslB.h, hslB.s, hslA.l, top.A ) );
|
||||
|
||||
return ColorX.Blend( bottom, combined );
|
||||
}
|
||||
|
||||
public static Color BlendHue( Color bottom, Color top )
|
||||
{
|
||||
var hslA = HSLColor.FromRGBA( bottom );
|
||||
var hslB = HSLColor.FromRGBA( top );
|
||||
|
||||
var combined = new HSLColor( hslB.h, hslA.s, hslA.l, bottom.A );
|
||||
|
||||
return ColorX.Lerp( bottom, combined, top.A );
|
||||
}
|
||||
|
||||
public static Color BlendSaturation( Color bottom, Color top )
|
||||
{
|
||||
var hslA = HSLColor.FromRGBA( bottom );
|
||||
var hslB = HSLColor.FromRGBA( top );
|
||||
|
||||
var combined = new HSLColor( hslB.h, hslA.s, hslA.l, bottom.A );
|
||||
|
||||
return ColorX.Lerp( bottom, combined, top.A );
|
||||
}
|
||||
|
||||
public static Color BlendAdd( Color bottom, Color top )
|
||||
{
|
||||
return PreMultipliedSingleComponentBlendMode( bottom, top,
|
||||
|
|
|
@ -287,6 +287,11 @@ namespace Rokojori
|
|||
return SafeIndex( index, elements.Count, wrap );
|
||||
}
|
||||
|
||||
public static int SafeIndex<T>( int index, T[] elements, bool wrap = false )
|
||||
{
|
||||
return SafeIndex( index, elements.Length, wrap );
|
||||
}
|
||||
|
||||
public static int SafeIndex( int index, int maxElements, bool wrap = false )
|
||||
{
|
||||
if ( wrap )
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ]
|
||||
public partial class BillboardTree:Node3D
|
||||
{
|
||||
float _startHeight = 2;
|
||||
[Export]
|
||||
public float startHeight
|
||||
{
|
||||
get => _startHeight;
|
||||
set { _startHeight = value; }
|
||||
}
|
||||
|
||||
float _endHeight = 7;
|
||||
[Export]
|
||||
public float endHeight
|
||||
{
|
||||
get => _endHeight;
|
||||
set { _endHeight = value; }
|
||||
}
|
||||
|
||||
[Export]
|
||||
public Curve radiusShape;
|
||||
|
||||
[Export]
|
||||
public MeshInstance3D leavesMesh;
|
||||
|
||||
[Export]
|
||||
public Material leavesMaterial;
|
||||
|
||||
[Export]
|
||||
public int numRows = 5;
|
||||
|
||||
[Export]
|
||||
public Curve rowDensity = MathX.Curve( 0.2f, 0.8f );
|
||||
|
||||
[Export]
|
||||
public Curve leavesSize = MathX.Curve( 0.2f, 0.8f );
|
||||
|
||||
[Export]
|
||||
public Curve leavesRotation = MathX.Curve( 0f, 360f );
|
||||
|
||||
[Export]
|
||||
public int seed = 2000;
|
||||
|
||||
|
||||
MeshGeometry mg;
|
||||
RandomEngine random;
|
||||
|
||||
|
||||
[Export]
|
||||
public bool update = false;
|
||||
|
||||
[Export]
|
||||
public bool updateAlways = false;
|
||||
|
||||
|
||||
public override void _Process( double d )
|
||||
{
|
||||
if ( ! ( updateAlways || update ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
update = false;
|
||||
|
||||
Generate();
|
||||
}
|
||||
|
||||
void Generate()
|
||||
{
|
||||
if ( leavesMesh == null )
|
||||
{
|
||||
leavesMesh = this.CreateChild<MeshInstance3D>( "Leaves" );
|
||||
}
|
||||
|
||||
mg = new MeshGeometry();
|
||||
random = LCG.WithSeed( seed );
|
||||
|
||||
|
||||
for ( int i = 0; i < numRows; i++ )
|
||||
{
|
||||
CreateRow( i );
|
||||
}
|
||||
|
||||
|
||||
leavesMesh.Mesh = mg.GenerateMesh();
|
||||
|
||||
Materials.Set( leavesMesh, leavesMaterial );
|
||||
}
|
||||
|
||||
void CreateRow( int rowIndex )
|
||||
{
|
||||
|
||||
var rowNormalized = rowIndex / (float) ( numRows - 1 );
|
||||
var rowRadius = radiusShape.Sample( rowNormalized );
|
||||
var rowDensityValue = random.Sample( rowDensity );
|
||||
var numLeaves = Mathf.Ceil( rowRadius / rowDensityValue );
|
||||
|
||||
var rowAngleOffset = random.Range( 0, 360f );
|
||||
|
||||
//this.LogInfo( "index:", rowIndex, "leaves:", numLeaves );
|
||||
|
||||
for ( int i = 0; i < numLeaves; i++ )
|
||||
{
|
||||
var size = random.Sample( leavesSize );
|
||||
var leave = MeshGeometry.BillboardQuad( size );
|
||||
|
||||
var angle = 360f * i / ( (float) numLeaves ) + rowAngleOffset;
|
||||
|
||||
|
||||
|
||||
var position = Math3D.OnCircleXZ( MathX.DegreesToRadians * angle ) * rowRadius;
|
||||
position.Y = Mathf.Lerp( startHeight, endHeight, rowNormalized );
|
||||
|
||||
var rotation = random.Sample( leavesRotation );
|
||||
//this.LogInfo( "index:", rowIndex, "leaves:", numLeaves, i, "size/angle", size, "/", angle, "pos:", position.X, position.Z );
|
||||
|
||||
leave.ApplyTransform( position, Math3D.RotateZ( MathX.DegreesToRadians * rotation ), Vector3.One );
|
||||
|
||||
var normal = position - new Vector3( 0, ( startHeight + endHeight ) / 2f, 0);
|
||||
normal = normal.Normalized();
|
||||
|
||||
this.LogInfo( "index:", rowIndex, "leaves:", numLeaves, i, normal );
|
||||
|
||||
mg.Add( leave );
|
||||
mg.NormalsLookAt( normal, 1 );
|
||||
|
||||
var clone = leave.Clone();
|
||||
clone.FlipNormalDirection();
|
||||
clone.NormalsLookAt( normal, 1 );
|
||||
|
||||
mg.Add( clone );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ uniform float ao_light_affect : hint_range(0.0, 1.0, 0.01);
|
|||
uniform vec3 uv1_scale;
|
||||
uniform vec3 uv1_offset;
|
||||
|
||||
uniform bool windEnabled = false;
|
||||
uniform float windStrength = 0;
|
||||
uniform vec2 windSpeed = vec2(1,1);
|
||||
uniform float windScale = 1;
|
||||
|
@ -40,22 +41,27 @@ uniform float windEnd = 1;
|
|||
uniform float windWeightCurve:hint_range(0,1) = 0.5f;
|
||||
uniform float windHeightCompensation :hint_range(0,1) = 0.5f;
|
||||
|
||||
|
||||
void vertex()
|
||||
{
|
||||
UV = UV * uv1_scale.xy + uv1_offset.xy;
|
||||
|
||||
if ( windEnabled )
|
||||
{
|
||||
float windAmount = normalizeToRange01( VERTEX.y, windStart, windEnd );
|
||||
float rawWindAmount = windAmount;
|
||||
windAmount = mix( windAmount, windAmount * windAmount, windWeightCurve );
|
||||
vec3 worldVertex = localToWorld( VERTEX, MODEL_MATRIX ).xyz;
|
||||
vec2 windUV = TIME * windSpeed + worldVertex.xz * windScale;
|
||||
float angle = texture( windNoise, windUV + windNoiseAngleOffset).r * PI * 2.0;
|
||||
float strength = texture( windNoise, windUV + windNoiseStrengthOffset ).r * windStrength;
|
||||
vec2 circle = onCircle( angle ) * strength;
|
||||
VERTEX = worldToLocal( worldVertex + vec3( circle.x, 0, circle.y ) * windAmount, MODEL_MATRIX );
|
||||
float minY = min( VERTEX.y, 0 ); // VERTEX.y = mix( VERTEX.y, max( 0, VERTEX.y - strength * windAmount), windHeightCompensation * 2.0f );
|
||||
VERTEX.y = mix( VERTEX.y, max( minY, VERTEX.y - strength * windAmount), windHeightCompensation * 4.0f );
|
||||
|
||||
}
|
||||
|
||||
float windAmount = normalizeToRange01( VERTEX.y, windStart, windEnd );
|
||||
float rawWindAmount = windAmount;
|
||||
windAmount = mix( windAmount, windAmount * windAmount, windWeightCurve );
|
||||
vec3 worldVertex = localToWorld( VERTEX, MODEL_MATRIX ).xyz;
|
||||
vec2 windUV = TIME * windSpeed + worldVertex.xz * windScale;
|
||||
float angle = texture( windNoise, windUV + windNoiseAngleOffset).r * PI * 2.0;
|
||||
float strength = texture( windNoise, windUV + windNoiseStrengthOffset ).r * windStrength;
|
||||
vec2 circle = onCircle( angle ) * strength;
|
||||
VERTEX = worldToLocal( worldVertex + vec3( circle.x, 0, circle.y ) * windAmount, MODEL_MATRIX );
|
||||
float minY = min( VERTEX.y, 0 );
|
||||
// VERTEX.y = mix( VERTEX.y, max( 0, VERTEX.y - strength * windAmount), windHeightCompensation * 2.0f );
|
||||
VERTEX.y = mix( VERTEX.y, max( minY, VERTEX.y - strength * windAmount), windHeightCompensation * 4.0f );
|
||||
}
|
||||
|
||||
void fragment()
|
||||
|
@ -65,6 +71,7 @@ void fragment()
|
|||
vec4 albedo_tex = texture(texture_albedo, base_uv);
|
||||
ALBEDO = albedo.rgb * albedo_tex.rgb;
|
||||
|
||||
|
||||
float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
|
||||
METALLIC = metallic_tex * metallic;
|
||||
SPECULAR = specular;
|
||||
|
@ -75,6 +82,7 @@ void fragment()
|
|||
|
||||
NORMAL_MAP = texture(texture_normal, base_uv).rgb;
|
||||
NORMAL_MAP_DEPTH = normal_scale;
|
||||
|
||||
|
||||
AO = dot(texture(texture_ambient_occlusion, base_uv), ao_texture_channel);
|
||||
AO_LIGHT_AFFECT = ao_light_affect;
|
||||
|
|
|
@ -158,6 +158,15 @@ namespace Rokojori
|
|||
}
|
||||
}
|
||||
|
||||
public void NormalsLookAt( Vector3 point, float amount )
|
||||
{
|
||||
for ( int i = 0; i < normals.Count; i++ )
|
||||
{
|
||||
var direction = ( vertices[ i ] - point ).Normalized();
|
||||
normals[ i ] = Math3D.BlendNormals( normals[ i ], direction, amount );
|
||||
}
|
||||
}
|
||||
|
||||
public void BlendNormals( Vector3 direction, float amount )
|
||||
{
|
||||
if ( amount <= 0 )
|
||||
|
@ -504,7 +513,7 @@ namespace Rokojori
|
|||
normals[ i ] = -normals[ i ];
|
||||
}
|
||||
|
||||
for ( int i =0 ; i < indices.Count; i += 3 )
|
||||
for ( int i = 0 ; i < indices.Count; i += 3 )
|
||||
{
|
||||
var b = indices[ i ];
|
||||
indices[ i ] = indices[ i + 2 ];
|
||||
|
|
|
@ -20,6 +20,9 @@ namespace Rokojori
|
|||
[Export]
|
||||
public bool refreshNode3D = false;
|
||||
|
||||
[Export]
|
||||
public bool getMeshInstanceChild = false;
|
||||
|
||||
[Export]
|
||||
public bool useInstancing = false;
|
||||
|
||||
|
@ -36,7 +39,15 @@ namespace Rokojori
|
|||
{
|
||||
refreshNode3D = false;
|
||||
_cachedNode3DScene = new PackedScene();
|
||||
_cachedNode3DScene.Pack( node3D );
|
||||
|
||||
var node = node3D;
|
||||
|
||||
if ( getMeshInstanceChild )
|
||||
{
|
||||
node = Nodes.GetAnyChild<MeshInstance3D>( node );
|
||||
}
|
||||
|
||||
_cachedNode3DScene.Pack( node );
|
||||
}
|
||||
|
||||
return _cachedNode3DScene;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Rokojori
|
|||
public Vector2 offset = Vector2.Zero;
|
||||
|
||||
[Export]
|
||||
public bool updateTexture;
|
||||
public bool updateTexture = true;
|
||||
|
||||
TextureCombinerBuffer textureBuffer;
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace Rokojori
|
|||
|
||||
time = await Async.WaitIfExceeded( time );
|
||||
}
|
||||
|
||||
|
||||
|
||||
for ( int i = 0; i < processingRect.processingWidth; i++ )
|
||||
{
|
||||
|
|
|
@ -28,6 +28,8 @@ namespace Rokojori
|
|||
set { if ( ! value ) return; CreateTexture(); }
|
||||
}
|
||||
|
||||
[Export]
|
||||
public bool autoCreate = false;
|
||||
|
||||
[Export]
|
||||
public TextureCombinerStack layerStack;
|
||||
|
@ -40,11 +42,33 @@ namespace Rokojori
|
|||
|
||||
[ExportGroup( "Processing Settings")]
|
||||
[Export]
|
||||
bool _creatingTexture = false;
|
||||
public bool _creatingTexture = false;
|
||||
|
||||
[Export]
|
||||
int _blockSize = 512;
|
||||
|
||||
public void UpdateProgressTexture()
|
||||
{
|
||||
var size = 64;
|
||||
var hRatio = width / (float)height;
|
||||
var oProgress = Mathf.Min( 1, _progress * _progress + 0.2f );
|
||||
var waitImage = Image.CreateEmpty( size, Mathf.Max( 1, Mathf.RoundToInt( size / hRatio ) ), false, Image.Format.Rgba8 );
|
||||
waitImage.Fill( new HSLColor( oProgress * 120, 1f, 0.3f ) );
|
||||
|
||||
var progressI = size * _progress;
|
||||
|
||||
for ( int i = 0; i < progressI; i++ )
|
||||
{
|
||||
waitImage.SetPixel( i, waitImage.GetHeight() / 2 - 2, new Color( 1, 1, 1 ) );
|
||||
waitImage.SetPixel( ( size - 1 ) - i, waitImage.GetHeight() / 2 + 2, new Color( 1, 1, 1 ) );
|
||||
}
|
||||
|
||||
|
||||
textureOutput = ImageTexture.CreateFromImage( waitImage );
|
||||
}
|
||||
|
||||
float _progress = 0;
|
||||
|
||||
async void CreateTexture()
|
||||
{
|
||||
if ( _creatingTexture )
|
||||
|
@ -52,12 +76,16 @@ namespace Rokojori
|
|||
return;
|
||||
}
|
||||
|
||||
var hRatio = width / (float)height;
|
||||
/*var hRatio = width / (float)height;
|
||||
var waitImage = Image.CreateEmpty( 32, Mathf.Max( 1, Mathf.RoundToInt( 32 / hRatio ) ), false, Image.Format.Rgba8 );
|
||||
waitImage.Fill( new Color( 1, 0, 1 ));
|
||||
|
||||
textureOutput = ImageTexture.CreateFromImage( waitImage );
|
||||
*/
|
||||
|
||||
UpdateProgressTexture();
|
||||
|
||||
|
||||
|
||||
_creatingTexture = true;
|
||||
|
||||
|
@ -71,6 +99,8 @@ namespace Rokojori
|
|||
|
||||
var first = true;
|
||||
|
||||
var pNormalizer = 1f / ( layerStack.layers.Length - 2 );
|
||||
|
||||
for ( int i = 0; i < layerStack.layers.Length; i++ )
|
||||
{
|
||||
var layerIndex = ( layerStack.layers.Length - 1 ) - i;
|
||||
|
@ -81,8 +111,15 @@ namespace Rokojori
|
|||
continue;
|
||||
}
|
||||
|
||||
_progress = Mathf.Min( 1, i * pNormalizer );
|
||||
UpdateProgressTexture();
|
||||
|
||||
await ProcessLayer( layer, context );
|
||||
|
||||
|
||||
_progress = Mathf.Min( 1, ( i + 0.5f ) * pNormalizer );
|
||||
UpdateProgressTexture();
|
||||
|
||||
if ( first )
|
||||
{
|
||||
var b = inputBuffer;
|
||||
|
@ -96,8 +133,10 @@ namespace Rokojori
|
|||
await BlendLayer( layer, context );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
var image = Image.CreateEmpty( width, height, createMipmaps, Image.Format.Rgba8 );
|
||||
inputBuffer.CopyTo( 0, 0, 0, 0, width, height, image );
|
||||
image.GenerateMipmaps();
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace Rokojori
|
|||
Screen,
|
||||
Overlay,
|
||||
HardLight,
|
||||
SoftLight
|
||||
SoftLight,
|
||||
Color,
|
||||
Hue
|
||||
}
|
||||
|
||||
public class TextureCombinerBlendModeAlgorithm
|
||||
|
@ -52,6 +54,14 @@ namespace Rokojori
|
|||
{
|
||||
BlendMode( ColorX.BlendSoftLight, x, y, w, h, topOpacity, bottom, top, output );
|
||||
}
|
||||
else if ( TextureCombinerBlendMode.Color == blendMode )
|
||||
{
|
||||
BlendMode( ColorX.BlendColor, x, y, w, h, topOpacity, bottom, top, output );
|
||||
}
|
||||
else if ( TextureCombinerBlendMode.Hue == blendMode )
|
||||
{
|
||||
BlendMode( ColorX.BlendHue, x, y, w, h, topOpacity, bottom, top, output );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,6 +126,14 @@ namespace Rokojori
|
|||
{
|
||||
BlendModeMasked( ColorX.BlendSoftLight, x, y, w, h, topOpacity, mask, bottom, top, output );
|
||||
}
|
||||
else if ( TextureCombinerBlendMode.Color == blendMode )
|
||||
{
|
||||
BlendModeMasked( ColorX.BlendColor, x, y, w, h, topOpacity, mask, bottom, top, output );
|
||||
}
|
||||
else if ( TextureCombinerBlendMode.Hue == blendMode )
|
||||
{
|
||||
BlendModeMasked( ColorX.BlendHue, x, y, w, h, topOpacity, mask, bottom, top, output );
|
||||
}
|
||||
}
|
||||
|
||||
static void BlendModeMasked( System.Func<Color,Color,Color> blender, int x, int y, int w, int h, float topOpacity,
|
||||
|
|
|
@ -56,11 +56,12 @@ namespace Rokojori
|
|||
|
||||
public void CopyFrom( Image image, int sourceX, int sourceY, int ownX, int ownY, int w, int h )
|
||||
{
|
||||
|
||||
for ( int i = 0; i < w; i++ )
|
||||
{
|
||||
for ( int j = 0; j < h; j++ )
|
||||
{
|
||||
var sourcePixel = image.GetPixel( sourceX + i, sourceY + j );
|
||||
var sourcePixel = image == null ? new Color( 0, 0, 0 ) : image.GetPixel( sourceX + i, sourceY + j );
|
||||
|
||||
SetAt( ownX + i, ownY + j, sourcePixel );
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class TextureCombinerRunner:Node
|
||||
{
|
||||
[Export]
|
||||
public TextureCombiner[] combiners;
|
||||
|
||||
[Export]
|
||||
public bool run = false;
|
||||
|
||||
[Export]
|
||||
public int processIndex = 1;
|
||||
|
||||
[Export]
|
||||
public bool waitForFinish = false;
|
||||
|
||||
|
||||
public override void _Process( double delta )
|
||||
{
|
||||
if ( ! run || combiners == null || combiners.Length == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < combiners.Length; i++ )
|
||||
{
|
||||
if ( combiners[ i ] == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processIndex = Mathf.Clamp( processIndex, 0, combiners.Length -1 );
|
||||
|
||||
|
||||
if ( combiners[ processIndex ]._creatingTexture || ! combiners[ processIndex ].autoCreate )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( waitForFinish )
|
||||
{
|
||||
processIndex = MathX.SafeIndex( processIndex + 1, combiners, true );
|
||||
}
|
||||
|
||||
waitForFinish = ! waitForFinish;
|
||||
combiners[ processIndex ].create = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,17 @@ vec3 applyMatrix( vec3 v, mat4 m )
|
|||
return ( m * vec4( v, 1.0 ) ).xyz;
|
||||
}
|
||||
|
||||
vec3 applyMatrixWithTranslation( vec3 v, mat4 m )
|
||||
{
|
||||
mat4 mw = m;
|
||||
mw[ 3 ][ 0 ] = 0.0;
|
||||
mw[ 3 ][ 1 ] = 0.0;
|
||||
mw[ 3 ][ 2 ] = 0.0;
|
||||
mw[ 3 ][ 3 ] = 1.0;
|
||||
|
||||
return ( mw * vec4( v, 1.0 ) ).xyz;
|
||||
}
|
||||
|
||||
vec3 localToWorld( vec3 _VERTEX, mat4 _MODEL_MATRIX )
|
||||
{
|
||||
return ( _MODEL_MATRIX * vec4( _VERTEX, 1.0 ) ).xyz;
|
||||
|
@ -25,6 +36,18 @@ vec3 worldToLocal( vec3 _VERTEX, mat4 _MODEL_MATRIX )
|
|||
return ( inverse( _MODEL_MATRIX ) * vec4( _VERTEX, 1.0 ) ).xyz;
|
||||
}
|
||||
|
||||
vec3 worldToLocalDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX )
|
||||
{
|
||||
mat4 mw = inverse( _MODEL_MATRIX );
|
||||
mw[ 3 ][ 0 ] = 0.0;
|
||||
mw[ 3 ][ 1 ] = 0.0;
|
||||
mw[ 3 ][ 2 ] = 0.0;
|
||||
mw[ 3 ][ 3 ] = 1.0;
|
||||
|
||||
return ( mw * vec4( _VERTEX, 1.0 ) ).xyz;
|
||||
}
|
||||
|
||||
|
||||
vec3 extractScale( mat3 _MODEL_NORMAL_MATRIX )
|
||||
{
|
||||
mat3 m = _MODEL_NORMAL_MATRIX;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[gd_resource type="Resource" script_class="Texture2DPropertyName" load_steps=2 format=3 uid="uid://bvj5d6q0g1d0w"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Properties/Texture2DPropertyName.cs" id="1_s8dyc"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_s8dyc")
|
||||
propertyName = "texture_albedo"
|
|
@ -0,0 +1,28 @@
|
|||
using Godot;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class Vector2IPropertyName : ShaderPropertyName
|
||||
{
|
||||
public void Set( Material material, Vector2I value )
|
||||
{
|
||||
_Set( material, value );
|
||||
}
|
||||
|
||||
public Vector2I Get( Material material )
|
||||
{
|
||||
return _Get( material, Vector2I.Zero );
|
||||
}
|
||||
|
||||
public static Vector2IPropertyName Create( string name )
|
||||
{
|
||||
var p = new Vector2IPropertyName();
|
||||
p.propertyName = name;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
[gd_resource type="ShaderMaterial" load_steps=5 format=3 uid="uid://c7og674edrsy2"]
|
||||
|
||||
[ext_resource type="Shader" path="res://addons/rokojori_action_library/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboard.gdshader" id="1_yfe48"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_cxr4k"]
|
||||
colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1)
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_vt5xb"]
|
||||
frequency = 0.0902
|
||||
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_ew55x"]
|
||||
seamless = true
|
||||
color_ramp = SubResource("Gradient_cxr4k")
|
||||
noise = SubResource("FastNoiseLite_vt5xb")
|
||||
|
||||
[resource]
|
||||
render_priority = 0
|
||||
shader = ExtResource("1_yfe48")
|
||||
shader_parameter/size = 0.3
|
||||
shader_parameter/randomPosition = 0.0
|
||||
shader_parameter/albedo = Color(1, 1, 1, 1)
|
||||
shader_parameter/rotation = 3.22
|
||||
shader_parameter/rotationNoiseAmount = 2.445
|
||||
shader_parameter/rotationNoiseScale = 0.95
|
||||
shader_parameter/normalBlendAmount = 0.548
|
||||
shader_parameter/normalBlendDirection = Vector3(0, 1, 0)
|
||||
shader_parameter/roughness = 1.0
|
||||
shader_parameter/metalness = 1.0
|
||||
shader_parameter/specular = 1.0
|
||||
shader_parameter/alpha_scissor_threshold = 0.176
|
||||
shader_parameter/alpha_antialiasing_edge = 0.09
|
||||
shader_parameter/albedo_texture_size = null
|
||||
shader_parameter/ao_texture_channel = null
|
||||
shader_parameter/ao_light_affect = 0.62
|
||||
shader_parameter/yMapStart = null
|
||||
shader_parameter/yMapEnd = null
|
||||
shader_parameter/yMapNoiseAmount = null
|
||||
shader_parameter/yMapNoiseScale = null
|
||||
shader_parameter/discardNoiseScale = 1.0
|
||||
shader_parameter/discardThreshold = 1.0
|
||||
shader_parameter/fresnelNormalSource = 0.5
|
||||
shader_parameter/fresnelColor = null
|
||||
shader_parameter/fresnelSharpness = 1.0
|
||||
shader_parameter/fresnelScale = 1.0
|
||||
shader_parameter/windAmount = 1.0
|
||||
shader_parameter/windSpeed = Vector2(0.1, 0.1)
|
||||
shader_parameter/windNoiseScale = 1.0
|
||||
shader_parameter/windStart = 0.0
|
||||
shader_parameter/windEnd = 1.0
|
||||
shader_parameter/texture_albedo = SubResource("NoiseTexture2D_ew55x")
|
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -8,6 +8,8 @@ render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_sc
|
|||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Light.gdshaderinc"
|
||||
|
||||
uniform float size = 1;
|
||||
uniform float sizeMin = 1;
|
||||
uniform float sizeMax = 1;
|
||||
uniform float randomPosition;
|
||||
uniform vec4 albedo : source_color;
|
||||
uniform float rotation : hint_range(0,6.28) = 0;
|
||||
|
@ -69,15 +71,16 @@ void vertex()
|
|||
float px = perlinPolar( NORMAL.yz );
|
||||
float pz = perlinPolar( NORMAL.xy );
|
||||
float filter = perlin( vec2( px, pz ) * discardNoiseScale );
|
||||
|
||||
|
||||
|
||||
float scaleMix = perlin3D( vec3( nrx, nry, nrz ) ) ;
|
||||
float randomScale = mix( sizeMin, sizeMax, scaleMix );
|
||||
discardValue = filter;
|
||||
|
||||
vec3 worldOffset = billboardWorldOffset( UV, INV_VIEW_MATRIX, MODEL_MATRIX );
|
||||
|
||||
vec3 originalVertex = VERTEX;
|
||||
|
||||
VERTEX = VERTEX + worldOffset * size + vec3( nrx, nry, nrz ) * randomPosition;
|
||||
VERTEX = VERTEX + worldOffset * size * randomScale + vec3( nrx, nry, nrz ) * randomPosition;
|
||||
VERTEX = VERTEX + yWindAmount * vec3( windDirection.x, 0, windDirection.y );
|
||||
|
||||
vec3 vertexNormal = originalVertex; vertexNormal.y = 0.0; vertexNormal = normalize( vertexNormal );
|
|
@ -0,0 +1,136 @@
|
|||
using Godot;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
// Generated by ShaderClassGenerator
|
||||
|
||||
public class QuadBillboardShader
|
||||
{
|
||||
public static readonly CachedResource<Shader> shader = new CachedResource<Shader>(
|
||||
"res://addons/rokojori_action_library/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboard.gdshader"
|
||||
);
|
||||
|
||||
public static readonly FloatPropertyName size = FloatPropertyName.Create( "size" );
|
||||
public static readonly FloatPropertyName randomPosition = FloatPropertyName.Create( "randomPosition" );
|
||||
public static readonly ColorPropertyName albedo = ColorPropertyName.Create( "albedo" );
|
||||
public static readonly FloatPropertyName rotation = FloatPropertyName.Create( "rotation" );
|
||||
public static readonly FloatPropertyName rotationNoiseAmount = FloatPropertyName.Create( "rotationNoiseAmount" );
|
||||
public static readonly FloatPropertyName rotationNoiseScale = FloatPropertyName.Create( "rotationNoiseScale" );
|
||||
public static readonly FloatPropertyName normalBlendAmount = FloatPropertyName.Create( "normalBlendAmount" );
|
||||
public static readonly Vector3PropertyName normalBlendDirection = Vector3PropertyName.Create( "normalBlendDirection" );
|
||||
public static readonly FloatPropertyName roughness = FloatPropertyName.Create( "roughness" );
|
||||
public static readonly FloatPropertyName metalness = FloatPropertyName.Create( "metalness" );
|
||||
public static readonly FloatPropertyName specular = FloatPropertyName.Create( "specular" );
|
||||
public static readonly FloatPropertyName alphaScissorThreshold = FloatPropertyName.Create( "alpha_scissor_threshold" );
|
||||
public static readonly FloatPropertyName alphaAntialiasingEdge = FloatPropertyName.Create( "alpha_antialiasing_edge" );
|
||||
public static readonly Vector2IPropertyName albedoTextureSize = Vector2IPropertyName.Create( "albedo_texture_size" );
|
||||
public static readonly Vector4PropertyName aoTextureChannel = Vector4PropertyName.Create( "ao_texture_channel" );
|
||||
public static readonly FloatPropertyName aoLightAffect = FloatPropertyName.Create( "ao_light_affect" );
|
||||
public static readonly FloatPropertyName yMapStart = FloatPropertyName.Create( "yMapStart" );
|
||||
public static readonly FloatPropertyName yMapEnd = FloatPropertyName.Create( "yMapEnd" );
|
||||
public static readonly FloatPropertyName yMapNoiseAmount = FloatPropertyName.Create( "yMapNoiseAmount" );
|
||||
public static readonly FloatPropertyName yMapNoiseScale = FloatPropertyName.Create( "yMapNoiseScale" );
|
||||
public static readonly FloatPropertyName discardNoiseScale = FloatPropertyName.Create( "discardNoiseScale" );
|
||||
public static readonly FloatPropertyName discardThreshold = FloatPropertyName.Create( "discardThreshold" );
|
||||
public static readonly FloatPropertyName fresnelNormalSource = FloatPropertyName.Create( "fresnelNormalSource" );
|
||||
public static readonly ColorPropertyName fresnelColor = ColorPropertyName.Create( "fresnelColor" );
|
||||
public static readonly FloatPropertyName fresnelSharpness = FloatPropertyName.Create( "fresnelSharpness" );
|
||||
public static readonly FloatPropertyName fresnelScale = FloatPropertyName.Create( "fresnelScale" );
|
||||
public static readonly FloatPropertyName windAmount = FloatPropertyName.Create( "windAmount" );
|
||||
public static readonly Vector2PropertyName windSpeed = Vector2PropertyName.Create( "windSpeed" );
|
||||
public static readonly FloatPropertyName windNoiseScale = FloatPropertyName.Create( "windNoiseScale" );
|
||||
public static readonly FloatPropertyName windStart = FloatPropertyName.Create( "windStart" );
|
||||
public static readonly FloatPropertyName windEnd = FloatPropertyName.Create( "windEnd" );
|
||||
public static readonly Texture2DPropertyName textureAlbedo = Texture2DPropertyName.Create( "texture_albedo" );
|
||||
public static readonly Texture2DPropertyName textureNormals = Texture2DPropertyName.Create( "texture_normals" );
|
||||
public static readonly Texture2DPropertyName textureAmbientOcclusion = Texture2DPropertyName.Create( "texture_ambient_occlusion" );
|
||||
public static readonly Texture2DPropertyName textureYMapGradient = Texture2DPropertyName.Create( "texture_yMapGradient" );
|
||||
|
||||
}
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class QuadBillboardMaterial:CustomMaterial
|
||||
{
|
||||
|
||||
|
||||
public readonly CustomMaterialProperty<float> size;
|
||||
public readonly CustomMaterialProperty<float> randomPosition;
|
||||
public readonly CustomMaterialProperty<Color> albedo;
|
||||
public readonly CustomMaterialProperty<float> rotation;
|
||||
public readonly CustomMaterialProperty<float> rotationNoiseAmount;
|
||||
public readonly CustomMaterialProperty<float> rotationNoiseScale;
|
||||
public readonly CustomMaterialProperty<float> normalBlendAmount;
|
||||
public readonly CustomMaterialProperty<Vector3> normalBlendDirection;
|
||||
public readonly CustomMaterialProperty<float> roughness;
|
||||
public readonly CustomMaterialProperty<float> metalness;
|
||||
public readonly CustomMaterialProperty<float> specular;
|
||||
public readonly CustomMaterialProperty<float> alphaScissorThreshold;
|
||||
public readonly CustomMaterialProperty<float> alphaAntialiasingEdge;
|
||||
public readonly CustomMaterialProperty<Vector2I> albedoTextureSize;
|
||||
public readonly CustomMaterialProperty<Vector4> aoTextureChannel;
|
||||
public readonly CustomMaterialProperty<float> aoLightAffect;
|
||||
public readonly CustomMaterialProperty<float> yMapStart;
|
||||
public readonly CustomMaterialProperty<float> yMapEnd;
|
||||
public readonly CustomMaterialProperty<float> yMapNoiseAmount;
|
||||
public readonly CustomMaterialProperty<float> yMapNoiseScale;
|
||||
public readonly CustomMaterialProperty<float> discardNoiseScale;
|
||||
public readonly CustomMaterialProperty<float> discardThreshold;
|
||||
public readonly CustomMaterialProperty<float> fresnelNormalSource;
|
||||
public readonly CustomMaterialProperty<Color> fresnelColor;
|
||||
public readonly CustomMaterialProperty<float> fresnelSharpness;
|
||||
public readonly CustomMaterialProperty<float> fresnelScale;
|
||||
public readonly CustomMaterialProperty<float> windAmount;
|
||||
public readonly CustomMaterialProperty<Vector2> windSpeed;
|
||||
public readonly CustomMaterialProperty<float> windNoiseScale;
|
||||
public readonly CustomMaterialProperty<float> windStart;
|
||||
public readonly CustomMaterialProperty<float> windEnd;
|
||||
public readonly CustomMaterialProperty<Texture2D> textureAlbedo;
|
||||
public readonly CustomMaterialProperty<Texture2D> textureNormals;
|
||||
public readonly CustomMaterialProperty<Texture2D> textureAmbientOcclusion;
|
||||
public readonly CustomMaterialProperty<Texture2D> textureYMapGradient;
|
||||
|
||||
public QuadBillboardMaterial()
|
||||
{
|
||||
Shader = QuadBillboardShader.shader.Get();
|
||||
|
||||
size = new CustomMaterialProperty<float>( this, QuadBillboardShader.size );
|
||||
randomPosition = new CustomMaterialProperty<float>( this, QuadBillboardShader.randomPosition );
|
||||
albedo = new CustomMaterialProperty<Color>( this, QuadBillboardShader.albedo );
|
||||
rotation = new CustomMaterialProperty<float>( this, QuadBillboardShader.rotation );
|
||||
rotationNoiseAmount = new CustomMaterialProperty<float>( this, QuadBillboardShader.rotationNoiseAmount );
|
||||
rotationNoiseScale = new CustomMaterialProperty<float>( this, QuadBillboardShader.rotationNoiseScale );
|
||||
normalBlendAmount = new CustomMaterialProperty<float>( this, QuadBillboardShader.normalBlendAmount );
|
||||
normalBlendDirection = new CustomMaterialProperty<Vector3>( this, QuadBillboardShader.normalBlendDirection );
|
||||
roughness = new CustomMaterialProperty<float>( this, QuadBillboardShader.roughness );
|
||||
metalness = new CustomMaterialProperty<float>( this, QuadBillboardShader.metalness );
|
||||
specular = new CustomMaterialProperty<float>( this, QuadBillboardShader.specular );
|
||||
alphaScissorThreshold = new CustomMaterialProperty<float>( this, QuadBillboardShader.alphaScissorThreshold );
|
||||
alphaAntialiasingEdge = new CustomMaterialProperty<float>( this, QuadBillboardShader.alphaAntialiasingEdge );
|
||||
albedoTextureSize = new CustomMaterialProperty<Vector2I>( this, QuadBillboardShader.albedoTextureSize );
|
||||
aoTextureChannel = new CustomMaterialProperty<Vector4>( this, QuadBillboardShader.aoTextureChannel );
|
||||
aoLightAffect = new CustomMaterialProperty<float>( this, QuadBillboardShader.aoLightAffect );
|
||||
yMapStart = new CustomMaterialProperty<float>( this, QuadBillboardShader.yMapStart );
|
||||
yMapEnd = new CustomMaterialProperty<float>( this, QuadBillboardShader.yMapEnd );
|
||||
yMapNoiseAmount = new CustomMaterialProperty<float>( this, QuadBillboardShader.yMapNoiseAmount );
|
||||
yMapNoiseScale = new CustomMaterialProperty<float>( this, QuadBillboardShader.yMapNoiseScale );
|
||||
discardNoiseScale = new CustomMaterialProperty<float>( this, QuadBillboardShader.discardNoiseScale );
|
||||
discardThreshold = new CustomMaterialProperty<float>( this, QuadBillboardShader.discardThreshold );
|
||||
fresnelNormalSource = new CustomMaterialProperty<float>( this, QuadBillboardShader.fresnelNormalSource );
|
||||
fresnelColor = new CustomMaterialProperty<Color>( this, QuadBillboardShader.fresnelColor );
|
||||
fresnelSharpness = new CustomMaterialProperty<float>( this, QuadBillboardShader.fresnelSharpness );
|
||||
fresnelScale = new CustomMaterialProperty<float>( this, QuadBillboardShader.fresnelScale );
|
||||
windAmount = new CustomMaterialProperty<float>( this, QuadBillboardShader.windAmount );
|
||||
windSpeed = new CustomMaterialProperty<Vector2>( this, QuadBillboardShader.windSpeed );
|
||||
windNoiseScale = new CustomMaterialProperty<float>( this, QuadBillboardShader.windNoiseScale );
|
||||
windStart = new CustomMaterialProperty<float>( this, QuadBillboardShader.windStart );
|
||||
windEnd = new CustomMaterialProperty<float>( this, QuadBillboardShader.windEnd );
|
||||
textureAlbedo = new CustomMaterialProperty<Texture2D>( this, QuadBillboardShader.textureAlbedo );
|
||||
textureNormals = new CustomMaterialProperty<Texture2D>( this, QuadBillboardShader.textureNormals );
|
||||
textureAmbientOcclusion = new CustomMaterialProperty<Texture2D>( this, QuadBillboardShader.textureAmbientOcclusion );
|
||||
textureYMapGradient = new CustomMaterialProperty<Texture2D>( this, QuadBillboardShader.textureYMapGradient );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue