Shader Generator/Stencil/Upgrade 4.5

This commit is contained in:
Josef 2025-09-17 10:25:03 +02:00
parent b69bca0309
commit 48eb111c45
151 changed files with 4691 additions and 628 deletions

View File

@ -8,47 +8,25 @@
[sub_resource type="Resource" id="Resource_jlvht"] [sub_resource type="Resource" id="Resource_jlvht"]
script = ExtResource("2_dx1wq") script = ExtResource("2_dx1wq")
key = 83 key = 83
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_75e6s"] [sub_resource type="Resource" id="Resource_75e6s"]
script = ExtResource("1_ikub8") script = ExtResource("1_ikub8")
sensors = [SubResource("Resource_jlvht")] sensors = [SubResource("Resource_jlvht")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_gmj7t"] [sub_resource type="Resource" id="Resource_gmj7t"]
script = ExtResource("3_1wc0w") script = ExtResource("3_1wc0w")
axis = 1 axis = 1
type = 0
continous = false
[sub_resource type="Resource" id="Resource_687xx"] [sub_resource type="Resource" id="Resource_687xx"]
script = ExtResource("4_wj7li") script = ExtResource("4_wj7li")
button = 12 button = 12
continous = false
[sub_resource type="Resource" id="Resource_unhue"] [sub_resource type="Resource" id="Resource_unhue"]
script = ExtResource("1_ikub8") script = ExtResource("1_ikub8")
sensors = [SubResource("Resource_gmj7t"), SubResource("Resource_687xx")] sensors = [SubResource("Resource_gmj7t"), SubResource("Resource_687xx")]
showOnlyVisibleIcons = true showOnlyVisibleIcons = true
numVisible = 1 numVisible = 1
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_ikub8") script = ExtResource("1_ikub8")
sensors = [SubResource("Resource_75e6s"), SubResource("Resource_unhue")] sensors = [SubResource("Resource_75e6s"), SubResource("Resource_unhue")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -7,41 +7,19 @@
[sub_resource type="Resource" id="Resource_1iwsh"] [sub_resource type="Resource" id="Resource_1iwsh"]
script = ExtResource("2_elgr4") script = ExtResource("2_elgr4")
key = 69 key = 69
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_jvxvp"] [sub_resource type="Resource" id="Resource_jvxvp"]
script = ExtResource("1_e8w3r") script = ExtResource("1_e8w3r")
sensors = [SubResource("Resource_1iwsh")] sensors = [SubResource("Resource_1iwsh")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_3ovg5"] [sub_resource type="Resource" id="Resource_3ovg5"]
script = ExtResource("3_pyik4") script = ExtResource("3_pyik4")
button = 10 button = 10
continous = false
[sub_resource type="Resource" id="Resource_yhdev"] [sub_resource type="Resource" id="Resource_yhdev"]
script = ExtResource("1_e8w3r") script = ExtResource("1_e8w3r")
sensors = [SubResource("Resource_3ovg5")] sensors = [SubResource("Resource_3ovg5")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_e8w3r") script = ExtResource("1_e8w3r")
sensors = [SubResource("Resource_jvxvp"), SubResource("Resource_yhdev")] sensors = [SubResource("Resource_jvxvp"), SubResource("Resource_yhdev")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -8,47 +8,26 @@
[sub_resource type="Resource" id="Resource_8h6fq"] [sub_resource type="Resource" id="Resource_8h6fq"]
script = ExtResource("2_rofew") script = ExtResource("2_rofew")
key = 87 key = 87
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_nj1ud"] [sub_resource type="Resource" id="Resource_nj1ud"]
script = ExtResource("1_r4ul7") script = ExtResource("1_r4ul7")
sensors = [SubResource("Resource_8h6fq")] sensors = [SubResource("Resource_8h6fq")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_mxixb"] [sub_resource type="Resource" id="Resource_mxixb"]
script = ExtResource("3_nh2m3") script = ExtResource("3_nh2m3")
axis = 1 axis = 1
type = 1 type = 1
continous = false
[sub_resource type="Resource" id="Resource_c1vyq"] [sub_resource type="Resource" id="Resource_c1vyq"]
script = ExtResource("3_dyhbp") script = ExtResource("3_dyhbp")
button = 11 button = 11
continous = false
[sub_resource type="Resource" id="Resource_vhtjx"] [sub_resource type="Resource" id="Resource_vhtjx"]
script = ExtResource("1_r4ul7") script = ExtResource("1_r4ul7")
sensors = [SubResource("Resource_mxixb"), SubResource("Resource_c1vyq")] sensors = [SubResource("Resource_mxixb"), SubResource("Resource_c1vyq")]
showOnlyVisibleIcons = true showOnlyVisibleIcons = true
numVisible = 1 numVisible = 1
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_r4ul7") script = ExtResource("1_r4ul7")
sensors = [SubResource("Resource_nj1ud"), SubResource("Resource_vhtjx")] sensors = [SubResource("Resource_nj1ud"), SubResource("Resource_vhtjx")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -8,47 +8,25 @@
[sub_resource type="Resource" id="Resource_jlvht"] [sub_resource type="Resource" id="Resource_jlvht"]
script = ExtResource("2_umtky") script = ExtResource("2_umtky")
key = 65 key = 65
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_qts7v"] [sub_resource type="Resource" id="Resource_qts7v"]
script = ExtResource("1_w0cyl") script = ExtResource("1_w0cyl")
sensors = [SubResource("Resource_jlvht")] sensors = [SubResource("Resource_jlvht")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_gmj7t"] [sub_resource type="Resource" id="Resource_gmj7t"]
script = ExtResource("3_ushvr") script = ExtResource("3_ushvr")
axis = 0
type = 1 type = 1
continous = false
[sub_resource type="Resource" id="Resource_687xx"] [sub_resource type="Resource" id="Resource_687xx"]
script = ExtResource("4_53tr6") script = ExtResource("4_53tr6")
button = 13 button = 13
continous = false
[sub_resource type="Resource" id="Resource_0hx40"] [sub_resource type="Resource" id="Resource_0hx40"]
script = ExtResource("1_w0cyl") script = ExtResource("1_w0cyl")
sensors = [SubResource("Resource_gmj7t"), SubResource("Resource_687xx")] sensors = [SubResource("Resource_gmj7t"), SubResource("Resource_687xx")]
showOnlyVisibleIcons = true showOnlyVisibleIcons = true
numVisible = 1 numVisible = 1
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_w0cyl") script = ExtResource("1_w0cyl")
sensors = [SubResource("Resource_qts7v"), SubResource("Resource_0hx40")] sensors = [SubResource("Resource_qts7v"), SubResource("Resource_0hx40")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -8,47 +8,24 @@
[sub_resource type="Resource" id="Resource_jlvht"] [sub_resource type="Resource" id="Resource_jlvht"]
script = ExtResource("2_prxyq") script = ExtResource("2_prxyq")
key = 68 key = 68
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_d1suo"] [sub_resource type="Resource" id="Resource_d1suo"]
script = ExtResource("1_vdwin") script = ExtResource("1_vdwin")
sensors = [SubResource("Resource_jlvht")] sensors = [SubResource("Resource_jlvht")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_c7ebh"] [sub_resource type="Resource" id="Resource_c7ebh"]
script = ExtResource("3_4antj") script = ExtResource("3_4antj")
axis = 0
type = 0
continous = false
[sub_resource type="Resource" id="Resource_md70b"] [sub_resource type="Resource" id="Resource_md70b"]
script = ExtResource("4_ucs5r") script = ExtResource("4_ucs5r")
button = 14 button = 14
continous = false
[sub_resource type="Resource" id="Resource_fhaor"] [sub_resource type="Resource" id="Resource_fhaor"]
script = ExtResource("1_vdwin") script = ExtResource("1_vdwin")
sensors = [SubResource("Resource_c7ebh"), SubResource("Resource_md70b")] sensors = [SubResource("Resource_c7ebh"), SubResource("Resource_md70b")]
showOnlyVisibleIcons = true showOnlyVisibleIcons = true
numVisible = 1 numVisible = 1
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_vdwin") script = ExtResource("1_vdwin")
sensors = [SubResource("Resource_d1suo"), SubResource("Resource_fhaor")] sensors = [SubResource("Resource_d1suo"), SubResource("Resource_fhaor")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -7,41 +7,21 @@
[sub_resource type="Resource" id="Resource_jt01w"] [sub_resource type="Resource" id="Resource_jt01w"]
script = ExtResource("2_g8pg7") script = ExtResource("2_g8pg7")
key = 81 key = 81
keyLocation = 0
ctrlHold = 2
altHold = 2
shiftHold = 2
modifiersMode = 0
continous = false
[sub_resource type="Resource" id="Resource_pqldp"] [sub_resource type="Resource" id="Resource_pqldp"]
script = ExtResource("1_5263n") script = ExtResource("1_5263n")
sensors = [SubResource("Resource_jt01w")] sensors = [SubResource("Resource_jt01w")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false
[sub_resource type="Resource" id="Resource_ivi7v"] [sub_resource type="Resource" id="Resource_ivi7v"]
script = ExtResource("3_ejsq1") script = ExtResource("3_ejsq1")
button = 9 button = 9
continous = false
[sub_resource type="Resource" id="Resource_0uxqa"] [sub_resource type="Resource" id="Resource_0uxqa"]
script = ExtResource("1_5263n") script = ExtResource("1_5263n")
sensors = [SubResource("Resource_ivi7v")] sensors = [SubResource("Resource_ivi7v")]
showOnlyVisibleIcons = true showOnlyVisibleIcons = true
numVisible = 1 numVisible = 1
inputIcons = []
useInputIconsFromSensors = true
continous = false
[resource] [resource]
script = ExtResource("1_5263n") script = ExtResource("1_5263n")
sensors = [SubResource("Resource_pqldp"), SubResource("Resource_0uxqa")] sensors = [SubResource("Resource_pqldp"), SubResource("Resource_0uxqa")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -7,14 +7,7 @@
[sub_resource type="Resource" id="Resource_rjqry"] [sub_resource type="Resource" id="Resource_rjqry"]
script = ExtResource("3_5t03r") script = ExtResource("3_5t03r")
axis = 5 axis = 5
type = 0
continous = false
[resource] [resource]
script = ExtResource("1_lnrk8") script = ExtResource("1_lnrk8")
sensors = [ExtResource("2_tuiuf"), SubResource("Resource_rjqry")] sensors = [ExtResource("2_tuiuf"), SubResource("Resource_rjqry")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

View File

@ -7,14 +7,7 @@
[sub_resource type="Resource" id="Resource_aybyw"] [sub_resource type="Resource" id="Resource_aybyw"]
script = ExtResource("3_pu70j") script = ExtResource("3_pu70j")
axis = 4 axis = 4
type = 0
continous = false
[resource] [resource]
script = ExtResource("1_w21si") script = ExtResource("1_w21si")
sensors = [ExtResource("2_dk7mn"), SubResource("Resource_aybyw")] sensors = [ExtResource("2_dk7mn"), SubResource("Resource_aybyw")]
showOnlyVisibleIcons = false
numVisible = 0
inputIcons = []
useInputIconsFromSensors = true
continous = false

77
Runtime/Graphs/Graph.cs Normal file
View File

@ -0,0 +1,77 @@
using System.Collections;
using System.Collections.Generic;
using System;
namespace Rokojori
{
public class Graph<N>:GraphWalker<N> where N:class
{
List<N> _nodes = [];
public Graph( List<N> nodes )
{
_nodes = nodes;
}
List<GraphConnection<N>> _connections = [];
MapList<N,N> _fromConnections = new MapList<N, N>();
MapList<N,N> _toConnections = new MapList<N, N>();
public void Connect( N from, N to )
{
var c = new GraphConnection<N>();
c.from = from;
c.to = to;
_connections.Add( c );
_toConnections.Add( from, to );
_fromConnections.Add( to, from );
}
public override int NumConnectedTo( N n )
{
if ( ! _toConnections.ContainsKey( n ) )
{
return 0;
}
return _toConnections[ n ].Count;
}
public override N GetConnectedTo( N n, int index )
{
if ( ! _toConnections.ContainsKey( n ) )
{
return null;
}
return _toConnections[ n ][ index ] ;
}
public override int NumConnectedFrom( N n )
{
if ( ! _fromConnections.ContainsKey( n ) )
{
return 0;
}
return _fromConnections[ n ].Count;
}
public override N GetConnectedFrom( N n, int index )
{
if ( ! _fromConnections.ContainsKey( n ) )
{
return null;
}
return _fromConnections[ n ][ index ] ;
}
public List<N> ComputeOrder()
{
return ComputeOrder( _nodes );
}
}
}

View File

@ -0,0 +1 @@
uid://bqgpm4jivtvau

View File

@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using System;
namespace Rokojori
{
public class GraphConnection<N> where N:class
{
public N from;
public N to;
}
}

View File

@ -0,0 +1 @@
uid://hloxykrb4wgx

View File

@ -85,5 +85,56 @@ namespace Rokojori
return false; return false;
} }
public List<N> ComputeOrder( List<N> nodes )
{
var processed = new HashSet<N>();
var unprocessed = nodes.Clone();
var order = new List<N>();
while ( unprocessed.Count > 0 )
{
var itemIndex = -1;
for ( int i = 0; itemIndex == -1 && i < unprocessed.Count; i++ )
{
if ( CanProcess( unprocessed[ i ], processed ) )
{
itemIndex = i;
}
}
if ( itemIndex == -1 )
{
order.AddRange( unprocessed );
return order;
}
var item = unprocessed[ itemIndex ];
unprocessed.RemoveAt( itemIndex );
processed.Add( item );
order.Add( item );
}
return order;
}
bool CanProcess( N n, HashSet<N> processed )
{
var dependencies = NumConnectedFrom( n );
for ( int i = 0 ; i < dependencies; i++ )
{
var connected = GetConnectedFrom( n, i );
if ( ! processed.Contains( connected ) )
{
return false;
}
}
return true;
}
} }
} }

View File

@ -22,6 +22,9 @@ namespace Rokojori
[Export] [Export]
public bool audioManager = true; public bool audioManager = true;
[Export]
public bool renderingManager = true;
[ExportGroup("Camera")] [ExportGroup("Camera")]
[Export] [Export]
@ -85,6 +88,11 @@ namespace Rokojori
{ {
root.CreateChild<AudioManager>( "Audio Manager" ); root.CreateChild<AudioManager>( "Audio Manager" );
} }
if ( renderingManager )
{
root.CreateChild<RenderingManager>( "Rendering Manager" );
}
} }
void CreateCamera( PresetContext context ) void CreateCamera( PresetContext context )

View File

@ -30,6 +30,9 @@ namespace Rokojori
[Export] [Export]
public float boundingBoxMaxY = 1; public float boundingBoxMaxY = 1;
[Export]
public bool extendBoundingBoxToMax = true;
public readonly EventProperty<__PlaneMeshType__> _type = new EventProperty<__PlaneMeshType__>(); public readonly EventProperty<__PlaneMeshType__> _type = new EventProperty<__PlaneMeshType__>();
[Export] [Export]
public __PlaneMeshType__ type { get => _type.value; set { _type.value = value; } } public __PlaneMeshType__ type { get => _type.value; set { _type.value = value; } }
@ -91,10 +94,20 @@ namespace Rokojori
if ( extendBoundingBox ) if ( extendBoundingBox )
{
if ( extendBoundingBoxToMax )
{
outputMesh.CustomAabb = Box3.Create( Vector3.One * -100000, Vector3.One * 100000 );
}
else
{ {
var extendedBounds = (Box3) outputMesh.Mesh.GetAabb(); var extendedBounds = (Box3) outputMesh.Mesh.GetAabb();
extendedBounds.EnsureYBounds( boundingBoxMinY, boundingBoxMaxY ); extendedBounds.EnsureYBounds( boundingBoxMinY, boundingBoxMaxY );
outputMesh.CustomAabb = extendedBounds; outputMesh.CustomAabb = extendedBounds;
}
} }
meshes[ i ] = outputMesh; meshes[ i ] = outputMesh;

View File

@ -269,10 +269,10 @@ namespace Rokojori
particles.CastShadow = renderLayer.data.GetShadows( renderLayer.subLayerIndex ) ? GeometryInstance3D.ShadowCastingSetting.On : GeometryInstance3D.ShadowCastingSetting.Off; particles.CastShadow = renderLayer.data.GetShadows( renderLayer.subLayerIndex ) ? GeometryInstance3D.ShadowCastingSetting.On : GeometryInstance3D.ShadowCastingSetting.Off;
processMaterial.positionVariance.Set( renderLayer.renderer.noise ); // processMaterial.positionVariance.Set( renderLayer.renderer.noise );
processMaterial.rotationVariance.Set( renderLayer.renderer.noise ); // processMaterial.rotationVariance.Set( renderLayer.renderer.noise );
processMaterial.scaleVariance.Set( renderLayer.renderer.noise ); // processMaterial.scaleVariance.Set( renderLayer.renderer.noise );
processMaterial.occupancyVariance.Set( renderLayer.renderer.noise ); // processMaterial.occupancyVariance.Set( renderLayer.renderer.noise );
renderLayer.gpuFoliageShaderMaterial = processMaterial; renderLayer.gpuFoliageShaderMaterial = processMaterial;

View File

@ -29,6 +29,9 @@ namespace Rokojori
[Export] [Export]
public FoliageTransparencyRenderMode transparencyRenderMode; public FoliageTransparencyRenderMode transparencyRenderMode;
[Export]
public FoliageTextureOverride[] textureOverrides = [];
public override void CreateFoliageOverideMaterial( FoliageRenderLayer foliageRenderLayer ) public override void CreateFoliageOverideMaterial( FoliageRenderLayer foliageRenderLayer )
{ {
var gpuParticles3D = foliageRenderLayer.gpuParticles3D; var gpuParticles3D = foliageRenderLayer.gpuParticles3D;
@ -63,6 +66,18 @@ namespace Rokojori
var standardMaterial = (StandardMaterial3D) material; var standardMaterial = (StandardMaterial3D) material;
transparencyRenderMode?.ApplyTransparencyMode( standardMaterial, foliageRenderLayer ); transparencyRenderMode?.ApplyTransparencyMode( standardMaterial, foliageRenderLayer );
textureOverrides.ForEach(
( to )=>
{
if ( to == null )
{
return;
}
to.Apply( material );
}
);
} }
public override Material GetOverrideMaterial(FoliageRenderLayer foliageRenderLayer) public override Material GetOverrideMaterial(FoliageRenderLayer foliageRenderLayer)

View File

@ -0,0 +1,203 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;
namespace Rokojori
{
/** <summary for="class FoliageTextureOverride">
<title>
Abstract archetype resource to create foliage texture overrides
</title>
<description>
</description>
</summary>
*/
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ]
public partial class FoliageTextureOverride:Resource
{
public enum OverrideTarget
{
Albedo,
Normal,
Roughness,
Metallic,
Occlusion,
Specular,
Emission
}
[Export]
public OverrideTarget target;
[Export]
public Texture2D texture2D;
[Export]
public bool assignValue = false;
[Export]
public Color color;
public void Apply( Material material )
{
if ( OverrideTarget.Albedo == target )
{
ApplyAlbedo( material );
}
else if ( OverrideTarget.Normal == target )
{
ApplyNormal( material );
}
else if ( OverrideTarget.Roughness == target )
{
ApplyRoughness( material );
}
else if ( OverrideTarget.Metallic == target )
{
ApplyMetallic( material );
}
else if ( OverrideTarget.Occlusion == target )
{
ApplyOcclusion( material );
}
else if ( OverrideTarget.Specular == target )
{
ApplySpecular( material );
}
else if ( OverrideTarget.Emission == target )
{
ApplyEmission( material );
}
}
void ApplyAlbedo( Material material )
{
if ( material is StandardMaterial3D sm )
{
if ( assignValue )
{
sm.AlbedoColor = color;
}
if ( texture2D != null )
{
sm.AlbedoTexture = texture2D;
}
}
}
void ApplyNormal( Material material )
{
if ( material is StandardMaterial3D sm )
{
sm.NormalEnabled = true;
if ( assignValue )
{
sm.NormalScale = color.R;
}
if ( texture2D != null )
{
sm.NormalTexture = texture2D;
}
}
}
void ApplyRoughness( Material material )
{
if ( material is StandardMaterial3D sm )
{
if ( assignValue )
{
sm.Roughness = color.R;
}
if ( texture2D != null )
{
sm.RoughnessTexture = texture2D;
}
}
}
void ApplyMetallic( Material material )
{
if ( material is StandardMaterial3D sm )
{
if ( assignValue )
{
sm.Metallic = color.R;
}
if ( texture2D != null )
{
sm.MetallicTexture = texture2D;
}
}
}
void ApplyOcclusion( Material material )
{
if ( material is StandardMaterial3D sm )
{
sm.AOEnabled = true;
if ( assignValue )
{
sm.AOLightAffect = color.R;
}
if ( texture2D != null )
{
sm.AOTexture = texture2D;
}
}
}
void ApplySpecular( Material material )
{
if ( material is StandardMaterial3D sm )
{
if ( assignValue )
{
sm.MetallicSpecular = color.R;
}
}
}
void ApplyEmission( Material material )
{
if ( material is StandardMaterial3D sm )
{
sm.EmissionEnabled = true;
if ( assignValue )
{
sm.EmissionIntensity = color.R;
}
if ( texture2D != null )
{
sm.EmissionTexture = texture2D;
}
}
}
}
}

View File

@ -137,6 +137,16 @@ namespace Rokojori
gpuFoliageShaderMaterial.hideStart.Set( hideStart ); gpuFoliageShaderMaterial.hideStart.Set( hideStart );
gpuFoliageShaderMaterial.hideOffset.Set( data.GetVisibilityFadeHidingOffset( subLayerIndex ) ); gpuFoliageShaderMaterial.hideOffset.Set( data.GetVisibilityFadeHidingOffset( subLayerIndex ) );
gpuFoliageShaderMaterial.mapCenter.Set( renderer.globalMapSizeXZ );
gpuFoliageShaderMaterial.mapSize.Set( renderer.globalMapSizeXZ );
gpuFoliageShaderMaterial.heightMap.Set( renderer.heightMap );
gpuFoliageShaderMaterial.minHeight.Set( renderer.minHeight );
gpuFoliageShaderMaterial.maxHeight.Set( renderer.maxHeight );
gpuFoliageShaderMaterial.coverageMap.Set( renderer.coverageMap );
gpuFoliageShaderMaterial.positionVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.positionVariance.Set( renderer.noise );
gpuFoliageShaderMaterial.rotationVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.rotationVariance.Set( renderer.noise );
gpuFoliageShaderMaterial.scaleVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.scaleVariance.Set( renderer.noise );

View File

@ -49,6 +49,43 @@ namespace Rokojori
[Export] [Export]
public Camera3D camera; public Camera3D camera;
[Export]
public Vector2 globalMapSizeXZ;
[Export]
public Vector2 globalMapCenterXZ;
[ExportGroup("Shared/Region")]
[Export]
public bool trimToRegion = false;
[Export]
public Vector2 regionSizeXZ;
[Export]
public Vector2 regionCenterXZ;
[ExportGroup("Shared")]
[Export]
public Texture2D heightMap;
[Export]
public float minHeight = 0;
[Export]
public float maxHeight = 100;
[Export]
public Texture2D normalMap;
[Export]
public Texture2D coverageMap;
[Export]
public Texture2D colorMap;
[Export] [Export]
public Texture2D noise; public Texture2D noise;

View File

@ -15,6 +15,10 @@ uniform vec3 positionOffset = vec3(0,0,0);
uniform vec2 positionUVScale = vec2( 1.0, 1.0 ); uniform vec2 positionUVScale = vec2( 1.0, 1.0 );
uniform vec2 positionUVOffset = vec2( 1.0, 1.0 ); uniform vec2 positionUVOffset = vec2( 1.0, 1.0 );
uniform float heightOffset = 0; uniform float heightOffset = 0;
uniform sampler2D heightMap;
uniform float minHeight = 0;
uniform float maxHeight = 100;
uniform sampler2D rotationVariance; uniform sampler2D rotationVariance;
uniform vec3 minRotation = vec3( 0, 0, 0 ); uniform vec3 minRotation = vec3( 0, 0, 0 );
@ -37,11 +41,14 @@ uniform float occupancyHideScale = 0.1;
uniform sampler2D occupancyVariance; uniform sampler2D occupancyVariance;
uniform vec2 occupancyUVScale = vec2( 1.0, 1.0 ); uniform vec2 occupancyUVScale = vec2( 1.0, 1.0 );
uniform vec2 occupancyUVOffset = vec2( 1.0, 1.0 ); uniform vec2 occupancyUVOffset = vec2( 1.0, 1.0 );
uniform bool discardFullyHidden = true;
uniform float hideStart = 40; uniform float hideStart = 40;
uniform float hideMax = 60; uniform float hideMax = 60;
uniform float hideOffset = -0.6; uniform float hideOffset = -0.6;
uniform sampler2D coverageMap;
uniform sampler2D colorMap;
uniform vec2 mapSize = vec2(1024,1024); uniform vec2 mapSize = vec2(1024,1024);
uniform vec2 mapCenter = vec2(0,0); uniform vec2 mapCenter = vec2(0,0);
@ -80,6 +87,8 @@ void process()
vec2 mapOffset = mapCenter - mapSize/2.0; vec2 mapOffset = mapCenter - mapSize/2.0;
vec2 uv = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize; vec2 uv = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize;
vec3 offset = (textureLod( positionVariance, tilingOffset( uv, positionUVScale, positionUVOffset ), 0 ).rgb - vec3(0.5,0.5,0.5) ) * maxPositionOffset; vec3 offset = (textureLod( positionVariance, tilingOffset( uv, positionUVScale, positionUVOffset ), 0 ).rgb - vec3(0.5,0.5,0.5) ) * maxPositionOffset;
position3D += offset + positionOffset; position3D += offset + positionOffset;
vec3 rotSampled = textureLod( rotationVariance, tilingOffset( uv, rotationUVScale, rotationUVOffset ), 0 ).rgb; vec3 rotSampled = textureLod( rotationVariance, tilingOffset( uv, rotationUVScale, rotationUVOffset ), 0 ).rgb;
@ -89,10 +98,19 @@ void process()
sca = sca * ( maxScale - minScale ) + minScale; sca = sca * ( maxScale - minScale ) + minScale;
vec2 uv2 = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize; vec2 uv2 = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize;
float sampledHeight = textureLod( heightMap, uv2, 0 ).r;
float occ = textureLod( occupancyVariance, tilingOffset( uv2, occupancyUVScale, occupancyUVOffset ), 0 ).r; float occ = textureLod( occupancyVariance, tilingOffset( uv2, occupancyUVScale, occupancyUVOffset ), 0 ).r;
float sampledCoverage = textureLod( coverageMap, uv2, 0 ).r;
occ = clamp( ( occ - occupancyTreshold ) * occupancyPower + occupancyTreshold, 0.0, 1.0 ); occ = clamp( ( occ - occupancyTreshold ) * occupancyPower + occupancyTreshold, 0.0, 1.0 );
sca *= mix( 1.0, occupancyHideScale , ( 1.0 - occ ) * occupancyAmount ); occ = 1.0 - occ;
position3D.y += ( 1.0 - occ ) * occupancyAmount * occupancyHideOffset;
occ = min( occ, 1.0 - sampledCoverage );
sca *= mix( 1.0, occupancyHideScale , occ * occupancyAmount );
position3D.y += occ * occupancyAmount * occupancyHideOffset;
position3D.y += mix( minHeight, maxHeight, sampledHeight );
TRANSFORM = TRS( position3D, rot, vec3( sca.x , sca.y, sca.z ) ); TRANSFORM = TRS( position3D, rot, vec3( sca.x , sca.y, sca.z ) );
} }

View File

@ -21,6 +21,9 @@ namespace Rokojori
public static readonly Vector2PropertyName positionUvScale = Vector2PropertyName.Create( "positionUVScale" ); public static readonly Vector2PropertyName positionUvScale = Vector2PropertyName.Create( "positionUVScale" );
public static readonly Vector2PropertyName positionUvOffset = Vector2PropertyName.Create( "positionUVOffset" ); public static readonly Vector2PropertyName positionUvOffset = Vector2PropertyName.Create( "positionUVOffset" );
public static readonly FloatPropertyName heightOffset = FloatPropertyName.Create( "heightOffset" ); public static readonly FloatPropertyName heightOffset = FloatPropertyName.Create( "heightOffset" );
public static readonly Texture2DPropertyName heightMap = Texture2DPropertyName.Create( "heightMap" );
public static readonly FloatPropertyName minHeight = FloatPropertyName.Create( "minHeight" );
public static readonly FloatPropertyName maxHeight = FloatPropertyName.Create( "maxHeight" );
public static readonly Texture2DPropertyName rotationVariance = Texture2DPropertyName.Create( "rotationVariance" ); public static readonly Texture2DPropertyName rotationVariance = Texture2DPropertyName.Create( "rotationVariance" );
public static readonly Vector3PropertyName minRotation = Vector3PropertyName.Create( "minRotation" ); public static readonly Vector3PropertyName minRotation = Vector3PropertyName.Create( "minRotation" );
public static readonly Vector3PropertyName maxRotation = Vector3PropertyName.Create( "maxRotation" ); public static readonly Vector3PropertyName maxRotation = Vector3PropertyName.Create( "maxRotation" );
@ -42,6 +45,7 @@ namespace Rokojori
public static readonly FloatPropertyName hideStart = FloatPropertyName.Create( "hideStart" ); public static readonly FloatPropertyName hideStart = FloatPropertyName.Create( "hideStart" );
public static readonly FloatPropertyName hideMax = FloatPropertyName.Create( "hideMax" ); public static readonly FloatPropertyName hideMax = FloatPropertyName.Create( "hideMax" );
public static readonly FloatPropertyName hideOffset = FloatPropertyName.Create( "hideOffset" ); public static readonly FloatPropertyName hideOffset = FloatPropertyName.Create( "hideOffset" );
public static readonly Texture2DPropertyName coverageMap = Texture2DPropertyName.Create( "coverageMap" );
public static readonly Vector2PropertyName mapSize = Vector2PropertyName.Create( "mapSize" ); public static readonly Vector2PropertyName mapSize = Vector2PropertyName.Create( "mapSize" );
public static readonly Vector2PropertyName mapCenter = Vector2PropertyName.Create( "mapCenter" ); public static readonly Vector2PropertyName mapCenter = Vector2PropertyName.Create( "mapCenter" );
@ -63,6 +67,9 @@ namespace Rokojori
public readonly CustomMaterialProperty<Vector2> positionUvScale; public readonly CustomMaterialProperty<Vector2> positionUvScale;
public readonly CustomMaterialProperty<Vector2> positionUvOffset; public readonly CustomMaterialProperty<Vector2> positionUvOffset;
public readonly CustomMaterialProperty<float> heightOffset; public readonly CustomMaterialProperty<float> heightOffset;
public readonly CustomMaterialProperty<Texture2D> heightMap;
public readonly CustomMaterialProperty<float> minHeight;
public readonly CustomMaterialProperty<float> maxHeight;
public readonly CustomMaterialProperty<Texture2D> rotationVariance; public readonly CustomMaterialProperty<Texture2D> rotationVariance;
public readonly CustomMaterialProperty<Vector3> minRotation; public readonly CustomMaterialProperty<Vector3> minRotation;
public readonly CustomMaterialProperty<Vector3> maxRotation; public readonly CustomMaterialProperty<Vector3> maxRotation;
@ -84,6 +91,7 @@ namespace Rokojori
public readonly CustomMaterialProperty<float> hideStart; public readonly CustomMaterialProperty<float> hideStart;
public readonly CustomMaterialProperty<float> hideMax; public readonly CustomMaterialProperty<float> hideMax;
public readonly CustomMaterialProperty<float> hideOffset; public readonly CustomMaterialProperty<float> hideOffset;
public readonly CustomMaterialProperty<Texture2D> coverageMap;
public readonly CustomMaterialProperty<Vector2> mapSize; public readonly CustomMaterialProperty<Vector2> mapSize;
public readonly CustomMaterialProperty<Vector2> mapCenter; public readonly CustomMaterialProperty<Vector2> mapCenter;
@ -102,6 +110,9 @@ namespace Rokojori
positionUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvScale ); positionUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvScale );
positionUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvOffset ); positionUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvOffset );
heightOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.heightOffset ); heightOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.heightOffset );
heightMap = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.heightMap );
minHeight = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.minHeight );
maxHeight = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.maxHeight );
rotationVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.rotationVariance ); rotationVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.rotationVariance );
minRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.minRotation ); minRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.minRotation );
maxRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.maxRotation ); maxRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.maxRotation );
@ -123,6 +134,7 @@ namespace Rokojori
hideStart = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideStart ); hideStart = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideStart );
hideMax = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideMax ); hideMax = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideMax );
hideOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideOffset ); hideOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideOffset );
coverageMap = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.coverageMap );
mapSize = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapSize ); mapSize = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapSize );
mapCenter = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapCenter ); mapCenter = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapCenter );
} }

View File

@ -0,0 +1,108 @@
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Normals.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap_anisotropic, repeat_enable;
uniform ivec2 albedo_texture_size;
uniform float point_size : hint_range(0.1, 128.0, 0.1);
uniform float roughness : hint_range(0.0, 1.0);
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float specular : hint_range(0.0, 1.0, 0.01);
uniform float metallic : hint_range(0.0, 1.0, 0.01);
uniform sampler2D texture_normal : hint_roughness_normal, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float normal_scale : hint_range(-16.0, 16.0);
varying vec3 uv1_triplanar_pos;
uniform float uv1_blend_sharpness : hint_range(0.0, 150.0, 0.001);
varying vec3 uv1_power_normal;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
uniform vec2 mapSize = vec2(1024,1024);
uniform vec2 mapCenter = vec2(0,0);
uniform sampler2D heightMap;
uniform float minHeight = 0;
uniform float maxHeight = 0;
uniform float normalTexelSize = 0.1;
uniform float normalHeightSize = 1;
varying vec2 heightUV;
uniform float snapDistance: hint_range(5.0, 100.0) = 25;
void vertex()
{
vec3 quantizedCam = snapRounded( CAMERA_POSITION_WORLD, snapDistance );
quantizedCam.y = 0.0;
VERTEX += quantizedCam;
vec3 position3D = localToWorld( VERTEX, MODEL_MATRIX );
vec2 mapOffset = mapCenter - mapSize/2.0;
vec2 uv = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize;
heightUV = uv;
float sampledHeight = textureLod( heightMap, uv, 0 ).r;
position3D.y += mix( minHeight, maxHeight, sampledHeight );
VERTEX = worldToLocal( position3D, MODEL_MATRIX );
vec3 normal = MODEL_NORMAL_MATRIX * NORMAL;
TANGENT = vec3(0.0, 0.0, -1.0) * abs(normal.x);
TANGENT += vec3(1.0, 0.0, 0.0) * abs(normal.y);
TANGENT += vec3(1.0, 0.0, 0.0) * abs(normal.z);
TANGENT = inverse(MODEL_NORMAL_MATRIX) * normalize(TANGENT);
BINORMAL = vec3(0.0, 1.0, 0.0) * abs(normal.x);
BINORMAL += vec3(0.0, 0.0, -1.0) * abs(normal.y);
BINORMAL += vec3(0.0, 1.0, 0.0) * abs(normal.z);
BINORMAL = inverse(MODEL_NORMAL_MATRIX) * normalize(BINORMAL);
// UV1 Triplanar: Enabled (with World Triplanar)
uv1_power_normal = pow(abs(normal), vec3(uv1_blend_sharpness));
uv1_triplanar_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz * uv1_scale + uv1_offset;
uv1_power_normal /= dot(uv1_power_normal, vec3(1.0));
uv1_triplanar_pos *= vec3(1.0, -1.0, 1.0);
}
vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos)
{
vec4 samp = vec4(0.0);
samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;
samp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;
samp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;
return samp;
}
void fragment()
{
vec4 albedo_tex = triplanar_texture(texture_albedo, uv1_power_normal, uv1_triplanar_pos);
ALBEDO = albedo.rgb * albedo_tex.rgb;
float metallic_tex = dot(triplanar_texture(texture_metallic, uv1_power_normal, uv1_triplanar_pos), metallic_texture_channel);
METALLIC = metallic_tex * metallic;
SPECULAR = specular;
vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
float roughness_tex = dot(triplanar_texture(texture_roughness, uv1_power_normal, uv1_triplanar_pos), roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
vec3 worldNormal = computeNormalFromHeightMap( heightMap, heightUV, normalTexelSize, normalHeightSize );
NORMAL = worldToViewDirection( worldNormal, VIEW_MATRIX );
// Normal Map: Enabled
NORMAL_MAP = triplanar_texture(texture_normal, uv1_power_normal, uv1_triplanar_pos).rgb;
NORMAL_MAP_DEPTH = normal_scale;
}

View File

@ -0,0 +1 @@
uid://diw3ibat8rjxx

View File

@ -14,5 +14,24 @@ namespace Rokojori
{ {
[Export] [Export]
public RenderingManagerData data; public RenderingManagerData data;
public static int GetStencilReferenceIndex( StencilLayer stencilLayer )
{
if ( stencilLayer == null )
{
return -1;
}
var rm = Unique<RenderingManager>.Get();
if ( rm == null )
{
return stencilLayer.fallBackIndex;
}
var rmIndex = rm.data.stencilLayers.IndexOf( stencilLayer );
return rmIndex == -1 ? stencilLayer.fallBackIndex : ( rmIndex + 1 );
}
} }
} }

View File

@ -14,5 +14,9 @@ namespace Rokojori
{ {
[Export] [Export]
public RenderingPriority[] renderingPriorities; public RenderingPriority[] renderingPriorities;
[Export]
public StencilLayer[] stencilLayers;
} }
} }

View File

@ -0,0 +1,18 @@
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class StencilLayer:Resource
{
[Export]
public int fallBackIndex = 0;
}
}

View File

@ -0,0 +1 @@
uid://bsd5qj85xsio4

View File

@ -46,8 +46,6 @@ button = 5
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_m53ti"), SubResource("Resource_a3cu1")] icons = [SubResource("Resource_m53ti"), SubResource("Resource_a3cu1")]
texture = ExtResource("3_pm2rw") texture = ExtResource("3_pm2rw")
widthScale = 1.0
orderMode = 2
isUpperCase = false isUpperCase = false
fontSizeScale = 0.0 fontSizeScale = 0.0
@ -63,8 +61,6 @@ button = 14
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_xbpgk"), SubResource("Resource_laa4d")] icons = [SubResource("Resource_xbpgk"), SubResource("Resource_laa4d")]
texture = ExtResource("5_ycc70") texture = ExtResource("5_ycc70")
widthScale = 1.0
orderMode = 2
isUpperCase = false isUpperCase = false
fontSizeScale = 0.0 fontSizeScale = 0.0
@ -80,33 +76,24 @@ button = 12
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_4mvgb"), SubResource("Resource_l8cwl")] icons = [SubResource("Resource_4mvgb"), SubResource("Resource_l8cwl")]
texture = ExtResource("6_6nxcf") texture = ExtResource("6_6nxcf")
widthScale = 1.0
orderMode = 2
isUpperCase = false isUpperCase = false
fontSizeScale = 0.0 fontSizeScale = 0.0
[sub_resource type="Resource" id="Resource_8bcch"] [sub_resource type="Resource" id="Resource_8bcch"]
script = ExtResource("7_y0txw") script = ExtResource("7_y0txw")
axis = 0
type = 0
[sub_resource type="Resource" id="Resource_rlnb1"] [sub_resource type="Resource" id="Resource_rlnb1"]
script = ExtResource("7_y0txw") script = ExtResource("7_y0txw")
axis = 0
type = 1 type = 1
[sub_resource type="Resource" id="Resource_fmatu"] [sub_resource type="Resource" id="Resource_fmatu"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "L" en = "L"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_tqg5p"] [sub_resource type="Resource" id="Resource_tqg5p"]
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_8bcch"), SubResource("Resource_rlnb1")] icons = [SubResource("Resource_8bcch"), SubResource("Resource_rlnb1")]
texture = ExtResource("9_eeamd") texture = ExtResource("9_eeamd")
widthScale = 1.0
orderMode = 2
label = SubResource("Resource_fmatu") label = SubResource("Resource_fmatu")
isUpperCase = false isUpperCase = false
fontSizeScale = 0.8 fontSizeScale = 0.8
@ -119,28 +106,21 @@ type = 1
[sub_resource type="Resource" id="Resource_vjbhe"] [sub_resource type="Resource" id="Resource_vjbhe"]
script = ExtResource("7_y0txw") script = ExtResource("7_y0txw")
axis = 1 axis = 1
type = 0
[sub_resource type="Resource" id="Resource_q8dch"] [sub_resource type="Resource" id="Resource_q8dch"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "L" en = "L"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_3oyc0"] [sub_resource type="Resource" id="Resource_3oyc0"]
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_vi3u1"), SubResource("Resource_vjbhe")] icons = [SubResource("Resource_vi3u1"), SubResource("Resource_vjbhe")]
texture = ExtResource("10_3i85w") texture = ExtResource("10_3i85w")
widthScale = 1.0
orderMode = 2
label = SubResource("Resource_q8dch") label = SubResource("Resource_q8dch")
isUpperCase = true
fontSizeScale = 0.8 fontSizeScale = 0.8
[sub_resource type="Resource" id="Resource_wd2xx"] [sub_resource type="Resource" id="Resource_wd2xx"]
script = ExtResource("7_y0txw") script = ExtResource("7_y0txw")
axis = 2 axis = 2
type = 0
[sub_resource type="Resource" id="Resource_h3a17"] [sub_resource type="Resource" id="Resource_h3a17"]
script = ExtResource("7_y0txw") script = ExtResource("7_y0txw")
@ -150,15 +130,11 @@ type = 1
[sub_resource type="Resource" id="Resource_07ljj"] [sub_resource type="Resource" id="Resource_07ljj"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "R" en = "R"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_c6gt5"] [sub_resource type="Resource" id="Resource_c6gt5"]
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_wd2xx"), SubResource("Resource_h3a17")] icons = [SubResource("Resource_wd2xx"), SubResource("Resource_h3a17")]
texture = ExtResource("9_eeamd") texture = ExtResource("9_eeamd")
widthScale = 1.0
orderMode = 2
label = SubResource("Resource_07ljj") label = SubResource("Resource_07ljj")
isUpperCase = false isUpperCase = false
fontSizeScale = 0.8 fontSizeScale = 0.8
@ -171,17 +147,12 @@ type = 1
[sub_resource type="Resource" id="Resource_4ro5i"] [sub_resource type="Resource" id="Resource_4ro5i"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "R" en = "R"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_812y6"] [sub_resource type="Resource" id="Resource_812y6"]
script = ExtResource("2_g15ft") script = ExtResource("2_g15ft")
icons = [SubResource("Resource_qmgk3"), SubResource("Resource_vjbhe")] icons = [SubResource("Resource_qmgk3"), SubResource("Resource_vjbhe")]
texture = ExtResource("10_3i85w") texture = ExtResource("10_3i85w")
widthScale = 1.0
orderMode = 2
label = SubResource("Resource_4ro5i") label = SubResource("Resource_4ro5i")
isUpperCase = true
fontSizeScale = 0.8 fontSizeScale = 0.8
[sub_resource type="Resource" id="Resource_udrbd"] [sub_resource type="Resource" id="Resource_udrbd"]
@ -192,39 +163,20 @@ combined = [SubResource("Resource_xpfqu"), SubResource("Resource_28c0y"), SubRes
script = ExtResource("5_sn8hr") script = ExtResource("5_sn8hr")
backgroundTexture = ExtResource("5_amgur") backgroundTexture = ExtResource("5_amgur")
directionUpTexture = ExtResource("6_0hfff") directionUpTexture = ExtResource("6_0hfff")
directionalOffset = 0.0
fontSizeScale = 1.0
isUpperCase = true
[sub_resource type="Resource" id="Resource_40bf3"] [sub_resource type="Resource" id="Resource_40bf3"]
script = ExtResource("2_4sutq") script = ExtResource("2_4sutq")
value = 0.7 value = 0.7
unit = "em" unit = "em"
isAnimated = false
animationDuration = 0.0
animationOffset = 0.0
[sub_resource type="Resource" id="Resource_xrtll"] [sub_resource type="Resource" id="Resource_xrtll"]
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("10_q44jo") backgroundTexture = ExtResource("10_q44jo")
widthScale = 1.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = false hasLabel = false
borderLeft = 0.0
borderRight = 0.0
borderTop = 0.0
borderBottom = 0.0
[sub_resource type="Resource" id="Resource_nkgsq"] [sub_resource type="Resource" id="Resource_nkgsq"]
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("12_mf3bj") backgroundTexture = ExtResource("12_mf3bj")
widthScale = 1.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = true
borderLeft = 40.0 borderLeft = 40.0
borderRight = 40.0 borderRight = 40.0
borderTop = 40.0 borderTop = 40.0
@ -236,8 +188,6 @@ backgroundTexture = ExtResource("12_mf3bj")
widthScale = 2.0 widthScale = 2.0
fontSizeScale = 0.7 fontSizeScale = 0.7
fontSizeCharacterMultiply = 1.0 fontSizeCharacterMultiply = 1.0
fontIsUpperCase = true
hasLabel = true
borderLeft = 40.0 borderLeft = 40.0
borderRight = 40.0 borderRight = 40.0
borderTop = 40.0 borderTop = 40.0
@ -249,56 +199,27 @@ rightIndicatorTexture = ExtResource("13_ijjqw")
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("14_6vom6") backgroundTexture = ExtResource("14_6vom6")
widthScale = 2.0 widthScale = 2.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = false hasLabel = false
borderLeft = 0.0
borderRight = 0.0
borderTop = 0.0
borderBottom = 0.0
[sub_resource type="Resource" id="Resource_qt31g"] [sub_resource type="Resource" id="Resource_qt31g"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "L" en = "L"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_4s1kq"] [sub_resource type="Resource" id="Resource_4s1kq"]
script = ExtResource("5_sn8hr") script = ExtResource("5_sn8hr")
backgroundTexture = ExtResource("18_amimm") backgroundTexture = ExtResource("18_amimm")
directionUpTexture = ExtResource("20_r1y6a") directionUpTexture = ExtResource("20_r1y6a")
directionalOffset = 0.0
label = SubResource("Resource_qt31g") label = SubResource("Resource_qt31g")
fontSizeScale = 0.8 fontSizeScale = 0.8
isUpperCase = true
buttonPressTexture = ExtResource("19_7x4g0") buttonPressTexture = ExtResource("19_7x4g0")
[sub_resource type="Resource" id="Resource_dr7bt"] [sub_resource type="Resource" id="Resource_dr7bt"]
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("13_omll7") backgroundTexture = ExtResource("13_omll7")
widthScale = 1.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = true
borderLeft = 0.0
borderRight = 0.0
borderTop = 0.0
borderBottom = 0.0
[sub_resource type="Resource" id="Resource_2rh0g"] [sub_resource type="Resource" id="Resource_2rh0g"]
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("14_n68qo") backgroundTexture = ExtResource("14_n68qo")
widthScale = 1.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = true
borderLeft = 0.0
borderRight = 0.0
borderTop = 0.0
borderBottom = 0.0
[sub_resource type="Resource" id="Resource_34cgw"] [sub_resource type="Resource" id="Resource_34cgw"]
script = ExtResource("5_a3fep") script = ExtResource("5_a3fep")
@ -311,31 +232,18 @@ wheelDownTexture = ExtResource("6_qyc6e")
[sub_resource type="Resource" id="Resource_5ywoi"] [sub_resource type="Resource" id="Resource_5ywoi"]
script = ExtResource("20_55eoq") script = ExtResource("20_55eoq")
en = "R" en = "R"
entries = []
context = ""
[sub_resource type="Resource" id="Resource_jl0ql"] [sub_resource type="Resource" id="Resource_jl0ql"]
script = ExtResource("5_sn8hr") script = ExtResource("5_sn8hr")
backgroundTexture = ExtResource("18_amimm") backgroundTexture = ExtResource("18_amimm")
directionUpTexture = ExtResource("20_r1y6a") directionUpTexture = ExtResource("20_r1y6a")
directionalOffset = 0.0
label = SubResource("Resource_5ywoi") label = SubResource("Resource_5ywoi")
fontSizeScale = 0.8 fontSizeScale = 0.8
isUpperCase = true
buttonPressTexture = ExtResource("19_7x4g0") buttonPressTexture = ExtResource("19_7x4g0")
[sub_resource type="Resource" id="Resource_b5rf1"] [sub_resource type="Resource" id="Resource_b5rf1"]
script = ExtResource("1_64knt") script = ExtResource("1_64knt")
backgroundTexture = ExtResource("21_hcyk3") backgroundTexture = ExtResource("21_hcyk3")
widthScale = 1.0
fontSizeScale = 1.0
fontSizeCharacterMultiply = 0.9
fontIsUpperCase = true
hasLabel = true
borderLeft = 0.0
borderRight = 0.0
borderTop = 0.0
borderBottom = 0.0
[resource] [resource]
script = ExtResource("1_urlfx") script = ExtResource("1_urlfx")
@ -353,4 +261,3 @@ digitalPad = SubResource("Resource_s3w6q")
leftJoystick = SubResource("Resource_4s1kq") leftJoystick = SubResource("Resource_4s1kq")
rightJoystick = SubResource("Resource_jl0ql") rightJoystick = SubResource("Resource_jl0ql")
combinedInputs = SubResource("Resource_udrbd") combinedInputs = SubResource("Resource_udrbd")
locales = []

View File

@ -0,0 +1,184 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public class ShaderCode
{
public string variantName = "";
public ShaderPhase phase;
public bool sortableCode = false;
public List<ShaderCodeVariableOccurance> variableOccurances = new List<ShaderCodeVariableOccurance>();
protected virtual string _GetCode( ShaderGenerationContext context )
{
return "";
}
public string GetCode( ShaderGenerationContext context )
{
return _GetCode( context );
}
public void ResolveVariableOccurances( ShaderGenerationContext context )
{
var code = GetCode( context );
var lexed = GDShaderLexer.Lex( code );
var index = lexed.CreateIndex();
var relevantVariables = ShaderCodeVariable.DefaultVariables.Map( v => v.variableName ).CreateSet();
var foundVariables = lexed.Filter( le => le.Is( LexerMatcherLibrary.CwordMatcher ) && relevantVariables.Contains( le.match ) );
var mapped = new Dictionary<ShaderCodeVariableOccurance,LexerEvent>();
foundVariables.ForEach(
( w )=>
{
var nextTokenResult = LexerEvent.Find( lexed, index[ w ],
( le ) =>
{
if ( le.Is( LexerMatcherLibrary.OperatorMatcher ) )
{
return LexerEvent.FindResultType.Found;
}
if ( le.IsAnyOf( LexerMatcherLibrary.Ignore ) )
{
return LexerEvent.FindResultType.KeepSearching;
}
return LexerEvent.FindResultType.NotFound;
}
);
if ( LexerEvent.FindResultType.NotFound == nextTokenResult.type )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Read( w.match ) );
}
else
{
var token = lexed[ nextTokenResult.index ];
if ( token.match == "=" )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Assignment( w.match ) );
}
else if ( token.MatchIsAny( "++", "--", "+=", "-=", "*=", "/=" ) )
{
variableOccurances.Add( ShaderCodeVariableOccurance.Modification( w.match ) );
}
else
{
variableOccurances.Add( ShaderCodeVariableOccurance.Read( w.match ) );
}
}
mapped[ variableOccurances.Last() ] = w;
}
);
variableOccurances.ForEach(
( vo )=>
{
var lineInfo = mapped[ vo ].GetLineInfo( code );
RJLog.Log( vo.type, ":", vo.variable.variableName, " >> ", lineInfo );
}
);
}
}
public class StringShaderCode:ShaderCode
{
public string code = "";
public StringShaderCode( string code )
{
this.code = code;
}
protected override string _GetCode( ShaderGenerationContext context )
{
return code;
}
public static StringShaderCode FromLines( List<string> code, bool addBreaks = true )
{
return new StringShaderCode( code.Join( addBreaks ? "\n" : "" ) );
}
}
public class BuiltInTextureShaderCode:ShaderCode
{
public enum TextureType
{
Screen,
Depth,
NormalRoughness
}
public TextureType textureType => _textureType;
TextureType _textureType;
public static BuiltInTextureShaderCode Screen
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.Screen;
return sc;
}
}
public static BuiltInTextureShaderCode Depth
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.Depth;
return sc;
}
}
public static BuiltInTextureShaderCode NormalRoughness
{
get
{
var sc = new BuiltInTextureShaderCode();
sc._textureType = TextureType.NormalRoughness;
return sc;
}
}
public ShaderCode GetBuiltInCode()
{
if ( _textureType == TextureType.Screen )
{
return new StringShaderCode( ShaderGenerationModule.ScreenTextureUniform().LineBreak() );
}
if ( _textureType == TextureType.Depth )
{
return new StringShaderCode( ShaderGenerationModule.DepthTextureUniform().LineBreak() );
}
if ( _textureType == TextureType.NormalRoughness )
{
return new StringShaderCode( ShaderGenerationModule.NormalRoughnessTextureUniform().LineBreak() );
}
return null;
}
}
}

View File

@ -0,0 +1,20 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public enum ShaderCodeStage
{
Vertex,
Fragment,
Light
}
public static class ShaderCodeStages
{
public static readonly List<ShaderCodeStage> Spatial =
[ ShaderCodeStage.Vertex, ShaderCodeStage.Fragment, ShaderCodeStage.Light ];
}
}

View File

@ -0,0 +1 @@
uid://be11x132nwd1y

View File

@ -0,0 +1,67 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public class ShaderCodeVariable
{
public static readonly ShaderCodeVariable VERTEX = new ShaderCodeVariable( "VERTEX", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable NORMAL = new ShaderCodeVariable( "NORMAL", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable UV = new ShaderCodeVariable( "UV", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable ALBEDO = new ShaderCodeVariable( "ALBEDO", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable ALPHA = new ShaderCodeVariable( "ALPHA", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable NORMAL_MAP = new ShaderCodeVariable( "NORMAL_MAP", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable NORMAL_MAP_DEPTH = new ShaderCodeVariable( "NORMAL_MAP_DEPTH", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable AO = new ShaderCodeVariable( "AO", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable ROUGHNESS = new ShaderCodeVariable( "ROUGHNESS", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable METALLIC = new ShaderCodeVariable( "METALLIC", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable SPECULAR = new ShaderCodeVariable( "SPECULAR", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable EMISSION = new ShaderCodeVariable( "EMISSION", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable BACKLIGHT = new ShaderCodeVariable( "BACKLIGHT", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable SSS_STRENGTH = new ShaderCodeVariable( "SSS_STRENGTH", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable SSS_TRANSMITTANCE_COLOR = new ShaderCodeVariable( "SSS_TRANSMITTANCE_COLOR", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable SSS_TRANSMITTANCE_DEPTH = new ShaderCodeVariable( "SSS_TRANSMITTANCE_DEPTH", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable SSS_TRANSMITTANCE_BOOST = new ShaderCodeVariable( "SSS_TRANSMITTANCE_BOOST", ShaderCodeStages.Spatial, true );
public static readonly ShaderCodeVariable MODEL_MATRIX = new ShaderCodeVariable( "MODEL_MATRIX", ShaderCodeStages.Spatial, true );
public static readonly List<ShaderCodeVariable> DefaultVariables =
[
VERTEX, NORMAL, UV,
ALBEDO, ALPHA,
NORMAL_MAP, NORMAL_MAP_DEPTH,
AO, ROUGHNESS, METALLIC, SPECULAR,
EMISSION, BACKLIGHT, SSS_STRENGTH,
SSS_TRANSMITTANCE_COLOR, SSS_TRANSMITTANCE_DEPTH, SSS_TRANSMITTANCE_BOOST,
MODEL_MATRIX
];
string _variableName;
public string variableName => _variableName;
bool _builtIn = false;
public bool builtIn => _builtIn;
List<ShaderCodeStage> _stages = new List<ShaderCodeStage>();
public List<ShaderCodeStage> stages => _stages;
public ShaderCodeVariable( string name, List<ShaderCodeStage> stages, bool builtIn = false )
{
_variableName = name;
_stages = stages;
_builtIn = builtIn;
}
}
}

View File

@ -0,0 +1 @@
uid://bb6q3uj0c5kj0

View File

@ -0,0 +1,47 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
public enum ShaderCodeVariableOccuranceType
{
Read,
Assignment, // =
Modification // ++, --, +=, *=
}
public class ShaderCodeVariableOccurance
{
public ShaderCodeVariableOccuranceType type;
public ShaderCodeVariable variable;
public static ShaderCodeVariableOccurance AsType( string name, ShaderCodeVariableOccuranceType type )
{
var variable = new ShaderCodeVariable( name, ShaderCodeStages.Spatial );
var occurance = new ShaderCodeVariableOccurance();
occurance.variable = variable;
occurance.type = type;
return occurance;
}
public static ShaderCodeVariableOccurance Read( string name )
{
return AsType( name, ShaderCodeVariableOccuranceType.Read );
}
public static ShaderCodeVariableOccurance Assignment( string name )
{
return AsType( name, ShaderCodeVariableOccuranceType.Assignment );
}
public static ShaderCodeVariableOccurance Modification( string name )
{
return AsType( name, ShaderCodeVariableOccuranceType.Modification );
}
}
}

View File

@ -0,0 +1 @@
uid://xnpahk8cgkye

View File

@ -8,15 +8,24 @@ namespace Rokojori
{ {
public ShaderPhase phase; public ShaderPhase phase;
public List<ShaderVariant> variants = new List<ShaderVariant>(); public List<ShaderVariant> variants = new List<ShaderVariant>();
public bool IsPhase( ShaderPhase phase )
{
return phase == this.phase;
}
public bool isIncludesPhase => IsPhase( ShaderPhase.Includes );
public bool isVariablesPhase => IsPhase( ShaderPhase.Variables );
public bool isVertexPhase => IsPhase( ShaderPhase.Vertex );
public bool isFragmentPhase => IsPhase( ShaderPhase.Fragment );
public ShaderGenerationContext() public ShaderGenerationContext()
{ {
variants.Add( new ShaderVariant() ); variants.Add( new ShaderVariant() );
} }
public void Add( List<ShaderCode> code ) public void AddVariants( List<ShaderVariant> code )
{ {
if ( code == null || code.Count == 0 ) if ( code == null || code.Count == 0 )
{ {

View File

@ -0,0 +1,297 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.VisualBasic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public abstract partial class ShaderGenerationModule:Resource
{
public bool sortableCode = true;
public virtual bool CodeIsSortable( ShaderPhase phase )
{
return sortableCode;
}
public virtual List<string> GetVariantNames()
{
return new List<string>(){ "" };
}
public virtual List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
return new List<ShaderVariant>(){};
}
public static ShaderVariant ToVariant( params ShaderCode[] code )
{
var variant = new ShaderVariant();
variant.shaderCode = code.ToList();
return variant;
}
public static List<ShaderVariant> ToVariants( params ShaderCode[] code )
{
return [ ToVariant( code ) ];
}
public string GetShaderCacheData()
{
var shaderHash = "";
var name = "[ " + GetType().FullName + " ]";
var exportedTuples = ReflectionHelper.GetExportedMembersAsJSON( this );
exportedTuples.Sort();
shaderHash = name + " { " + ( exportedTuples.Map( t => $"\"{t.Item1}\":{t.Item2}" ).Join( ", " ) ) + " } ";
return shaderHash.Replace( "\n", "" );
}
public string GetShaderCacheHash()
{
var name = GetType().Name.Substring( 0, 3 ).ToLower();
var exportedTuples = ReflectionHelper.GetExportedMembersAsJSON( this );
exportedTuples.Sort();
var allAtts = " { " + ( exportedTuples.Map( t => $"\"{t.Item1}\":{t.Item2}" ).Join( ", " ) ) + " } ";
return name + "." + allAtts.Length;
}
public static List<ShaderCode> IncludeFromLibrary( string path )
{
return ToCode( "#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/" + path + ".gdshaderinc\"\n" );
}
public static List<ShaderCode> IncludeTransformLibrary(){ return IncludeFromLibrary( "Transform" ); }
public static List<ShaderCode> IncludeDepthLibrary(){ return IncludeFromLibrary( "Depth" ); }
public static List<ShaderCode> IncludeCamerasLibrary(){ return IncludeFromLibrary( "Cameras" ); }
public static List<ShaderCode> IncludeNoiseLibrary(){ return IncludeFromLibrary( "Noise" ); }
public static List<ShaderCode> IncludeDitheringLibrary(){ return IncludeFromLibrary( "Dithering" ); }
public static List<ShaderCode> IncludeSDFLibrary(){ return IncludeFromLibrary( "SDF" ); }
public static List<ShaderCode> IncludeMathLibrary(){ return IncludeFromLibrary( "Math" ); }
public static List<ShaderCode> IncludeLightLibrary(){ return IncludeFromLibrary( "Light" ); }
public static ShaderVariant ToVariant( List<ShaderCode> code )
{
var variant = new ShaderVariant();
variant.shaderCode = code;
return variant;
}
public static List<ShaderVariant> ToVariants( List<ShaderCode> code )
{
return [ ToVariant( code ) ];
}
public static List<ShaderVariant> ToVariants( params string[] values )
{
return ToVariants( ToCode( values ) );
}
public static List<ShaderCode> ToCode( params string[] values )
{
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
}
public static List<ShaderCode> ToCode( string value )
{
return Lists.From( (ShaderCode)new StringShaderCode( value ) );
}
public List<ShaderCode> AsUniformGroup( string name, string value )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var blockCode = value.Indent( " ", false );
var code =
@$"
// [ {wideName} ]
group_uniforms {name};
{blockCode}
group_uniforms;
";
return ToCode( code.Indent( "" ) );
}
public List<ShaderCode> AsUniformGroup( string name, List<ShaderCode> code )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var codeBefore =
@$"
// [ {wideName} ]
group_uniforms {name};
";
var codeAfter =
@$"
group_uniforms;
";
return Lists.From( ToCode( codeBefore.Indent("") ), code, ToCode( codeAfter.Indent("") ) );
}
public List<ShaderCode> StartUniformGroup( string name )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var codeBefore =
@$"
// [ {wideName} ]
group_uniforms {name};
";
return ToCode( codeBefore.Indent("") );
}
public List<ShaderCode> EndUniformGroup()
{
var codeAfter =
@$"
group_uniforms;
";
return ToCode( codeAfter.Indent("") );
}
public static List<ShaderCode> ToInnerBlock( string name, string block )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var blockCode = block.Indent( " ", false );
var code =
@$"
// [ {wideName} ]
{blockCode}
";
return ToCode( code.Indent( " " ) );
}
public static List<ShaderCode> ToCode( List<string> values )
{
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
}
public static string Uniform( Vector2Property property )
{
var name = property.propertyName.propertyName;
var x = property.value.X._G();
var y = property.value.Y._G();
return @$"uniform vec2 {name} = vec2( {x}, {y});";
}
public static string Uniform( string name, float value )
{
return @$"uniform float {name} = {value._G()};";
}
public static string Uniform01( string name, float value )
{
return Uniform( name, value, 0, 1 );
}
public static string Uniform( string name, float value, float min, float max )
{
var mi = min._G();
var ma = max._G();
var v = value._G();
return @$"uniform float {name}:hint_range( {mi}, {ma}) = {v};";
}
public static string UniformSampler( string name, string hints )
{
return @$"uniform sampler2D {name}:{hints};";
}
public static string Uniform( string name, Color color )
{
var r = color.R._G();
var g = color.G._G();
var b = color.B._G();
var a = color.A._G();
return @$"uniform vec4 {name}:source_color = vec4( {r}, {g}, {b}, {a});";
}
public static string Uniform( string name, Vector3 vec )
{
var x = vec.X._G();
var y = vec.Y._G();
var z = vec.Z._G();
return @$"uniform vec3 {name} = vec3( {x}, {y}, {z});";
}
public static string Varying( string type, string name )
{
return @$"varying {type} {name};";
}
public static string VaryingFloat( string name ){ return Varying( "float", name ); }
public static string VaryingVec2( string name ){ return Varying( "vec2", name ); }
public static string VaryingVec3( string name ){ return Varying( "vec3", name ); }
public static string VaryingVec4( string name ){ return Varying( "vec4", name ); }
public static string Uniform( string name, Vector4 vec )
{
var x = vec.X._G();
var y = vec.Y._G();
var z = vec.Z._G();
var w = vec.W._G();
return @$"uniform vec4 {name} = vec4( {x}, {y}, {z}, {w});";
}
public static string DepthTextureUniform()
{
return UniformSampler( "depthTexture", "hint_depth_texture, repeat_disable, filter_nearest" );
}
public static string ScreenTextureUniform()
{
return UniformSampler( "screenTexture", "hint_screen_texture, repeat_disable, filter_linear" );
}
public static string NormalRoughnessTextureUniform()
{
return UniformSampler( "normalRoughness", "hint_normal_roughness_texture, repeat_disable, filter_linear" );
}
}
}

View File

@ -29,6 +29,9 @@ namespace Rokojori
[Export] [Export]
public bool sendGodotUpdateMessage = false; public bool sendGodotUpdateMessage = false;
[Export]
public int numVariants = -1;
public virtual List<ShaderPhase> GetPhases() public virtual List<ShaderPhase> GetPhases()
{ {
return new List<ShaderPhase>(); return new List<ShaderPhase>();
@ -41,11 +44,13 @@ namespace Rokojori
public virtual ShaderGenerationContext GenerateShaderVariants() public virtual ShaderGenerationContext GenerateShaderVariants()
{ {
numVariants = 0;
var context = new ShaderGenerationContext(); var context = new ShaderGenerationContext();
var phases = GetPhases(); var phases = GetPhases();
this.LogInfo( context.variants ); // this.LogInfo( context.variants );
phases.ForEach( phases.ForEach(
( phase )=> ( phase )=>
@ -54,7 +59,7 @@ namespace Rokojori
var modules = GetShaderGenerationModules( phase ); var modules = GetShaderGenerationModules( phase );
this.LogInfo( "PHASE", phase, ">>", context.variants, "MODS:", modules == null ? "-" : ( modules.Map( m => m.GetType().Name ) )); // this.LogInfo( "PHASE", phase, ">>", context.variants, "MODS:", modules == null ? "-" : ( modules.Map( m => m.GetType().Name ) ));
if ( modules == null ) if ( modules == null )
{ {
@ -64,16 +69,29 @@ namespace Rokojori
modules.ForEach( modules.ForEach(
( m )=> ( m )=>
{ {
var code = m.GetCode( context ); var variants = m.GetVariants( context );
this.LogInfo( phase, m.GetType().Name, code ); if ( variants == null )
if ( code == null )
{ {
return; return;
} }
context.Add( code ); variants.ForEach(
c =>
{
c.shaderCode.ForEach(
cs =>
{
cs.phase = phase;
cs.sortableCode = m.CodeIsSortable( phase );
}
);
}
);
this.LogInfo( phase, m.GetType().Name, ">>", variants.Count );
context.AddVariants( variants );
} }
); );
} }
@ -87,8 +105,12 @@ namespace Rokojori
public void UpdateShader() public void UpdateShader()
{ {
numVariants = 0;
var context = GenerateShaderVariants(); var context = GenerateShaderVariants();
this.LogInfo( "Created variants:", context.variants );
numVariants = context.variants.Count;
// this.LogInfo( "Created variants:", context.variants );
var first = true; var first = true;
@ -102,7 +124,7 @@ namespace Rokojori
absolutePath = ProjectSettings.GlobalizePath( path ); absolutePath = ProjectSettings.GlobalizePath( path );
} }
this.LogInfo( shaderCode ); // this.LogInfo( shaderCode );
var filePath = FilePath.Join( absolutePath, shaderName + variant.variantName + ".gdshader" ); var filePath = FilePath.Join( absolutePath, shaderName + variant.variantName + ".gdshader" );
FilesSync.SaveUTF8( filePath, shaderCode ); FilesSync.SaveUTF8( filePath, shaderCode );

View File

@ -9,6 +9,7 @@ namespace Rokojori
[GlobalClass] [GlobalClass]
public partial class ShaderRawModule:ShaderGenerationModule public partial class ShaderRawModule:ShaderGenerationModule
{ {
[Export] [Export]
public string value; public string value;
@ -20,6 +21,8 @@ namespace Rokojori
public ShaderRawModule( string value, ShaderPhase? phase = null ) public ShaderRawModule( string value, ShaderPhase? phase = null )
{ {
sortableCode = false;
if ( phase != null ) if ( phase != null )
{ {
phase = (ShaderPhase) phase; phase = (ShaderPhase) phase;
@ -33,14 +36,14 @@ namespace Rokojori
this.value = value; this.value = value;
} }
public override List<ShaderCode> GetCode( ShaderGenerationContext context ) public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{ {
if ( matchPhase && context.phase != phase ) if ( matchPhase && context.phase != phase )
{ {
return null; return null;
} }
return Lists.From( (ShaderCode) new StringShaderCode( value ) ); return ToVariants( ToCode( value ) );
} }
} }
} }

View File

@ -0,0 +1,293 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public class ShaderVariant
{
public string variantName = "";
public List<ShaderCode> shaderCode = [];
public string GetCode( ShaderGenerationContext context )
{
ResolveVariableOccurances( context );
var cleanedUpCode = RemoveDuplicateIncludes( shaderCode, context );
var hasScreen = false;
var hasDepth = false;
var hasNormalRoughness = false;
cleanedUpCode = cleanedUpCode.Filter(
( c )=>
{
if ( c is BuiltInTextureShaderCode bsc )
{
if ( BuiltInTextureShaderCode.TextureType.Screen == bsc.textureType )
{
hasScreen = true;
}
if ( BuiltInTextureShaderCode.TextureType.Depth == bsc.textureType )
{
hasDepth = true;
}
if ( BuiltInTextureShaderCode.TextureType.NormalRoughness == bsc.textureType )
{
hasNormalRoughness = true;
}
return false;
}
return true;
}
);
var insertionIndex = cleanedUpCode.FindIndex(
( c )=>
{
return c.GetCode( context ).Contains( "group_uniforms" );
}
);
if ( hasNormalRoughness )
{
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
cleanedUpCode.Insert( insertionIndex, BuiltInTextureShaderCode.NormalRoughness.GetBuiltInCode() );
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
}
if ( hasDepth )
{
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
cleanedUpCode.Insert( insertionIndex, BuiltInTextureShaderCode.Depth.GetBuiltInCode() );
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
}
if ( hasScreen )
{
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
cleanedUpCode.Insert( insertionIndex, BuiltInTextureShaderCode.Screen.GetBuiltInCode() );
cleanedUpCode.Insert( insertionIndex, ShaderGenerationModule.ToCode( "\n" )[ 0 ] );
}
var blocks = GetCodeBlocks( cleanedUpCode );
var sortedCode = new List<ShaderCode>();
blocks.ForEach(
( b )=>
{
if ( ! b[ 0 ].sortableCode )
{
sortedCode.AddRange( b );
return;
}
sortedCode.AddRange( SortBlock( b ) );
}
);
return sortedCode.Map( s => s.GetCode( context ) ).Join( "" );
}
void ResolveVariableOccurances( ShaderGenerationContext context )
{
shaderCode.ForEach( s => s.ResolveVariableOccurances( context ) );
}
List<List<ShaderCode>> GetCodeBlocks( List<ShaderCode> shaderCode )
{
var blocks = new List<List<ShaderCode>>();
List<ShaderCode> currentBlock = null;
for ( int i = 0; i < shaderCode.Count; i++ )
{
if ( ! shaderCode[ i ].sortableCode ||
currentBlock != null && currentBlock[ 0 ].phase != shaderCode[ i ].phase )
{
if ( currentBlock != null && currentBlock.Count > 0 )
{
blocks.Add( currentBlock );
}
currentBlock = null;
if ( ! shaderCode[ i ].sortableCode )
{
blocks.Add( [ shaderCode[ i ] ] );
continue;
}
}
if ( currentBlock == null )
{
currentBlock = new List<ShaderCode>();
}
currentBlock.Add( shaderCode[ i ] );
}
if ( currentBlock != null )
{
blocks.Add( currentBlock );
}
return blocks;
}
List<ShaderCode> RemoveDuplicateIncludes( List<ShaderCode> shaderCode, ShaderGenerationContext context )
{
var cleanedUp = new List<ShaderCode>();
var includes = new HashSet<string>();
var includeStart = "#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/";
shaderCode.ForEach(
( sc )=>
{
var code = sc.GetCode( context );
if ( ! code.Contains( includeStart ) )
{
cleanedUp.Add( sc );
return;
}
var include = code.GetInnerMatch( includeStart, ".gdshaderinc" );
if ( include != null && includes.Contains( include ) )
{
return;
}
cleanedUp.Add( sc );
if ( include != null )
{
includes.Add( include );
}
}
);
return cleanedUp;
}
List<ShaderCode> SortBlock( List<ShaderCode> blockShaderCode )
{
var g = new Graph<ShaderCode>( blockShaderCode );
var reads = new MapList<string,ShaderCode>();
var assignments = new MapList<string,ShaderCode>();
var modifications = new MapList<string,ShaderCode>();
blockShaderCode.ForEach(
( sc )=>
{
sc.variableOccurances.ForEach(
( occ )=>
{
if ( ShaderCodeVariableOccuranceType.Read == occ.type )
{
reads.Add( occ.variable.variableName, sc );
}
if ( ShaderCodeVariableOccuranceType.Assignment == occ.type )
{
assignments.Add( occ.variable.variableName, sc );
}
if ( ShaderCodeVariableOccuranceType.Modification == occ.type )
{
modifications.Add( occ.variable.variableName, sc );
}
}
);
}
);
blockShaderCode.ForEach(
( s ) =>
{
s.variableOccurances.ForEach(
( occ )=>
{
if ( ShaderCodeVariableOccuranceType.Assignment == occ.type )
{
return;
}
if ( ! assignments.ContainsKey( occ.variable.variableName ) )
{
return;
}
var assigningCodes = assignments[ occ.variable.variableName ];
assigningCodes.ForEach( sc => g.Connect( sc, s ) );
RJLog.Log( "Set dependency:", s, occ.variable.variableName );
}
);
}
);
return g.ComputeOrder();
}
public ShaderVariant Extend( ShaderCode shaderCode )
{
var variant = new ShaderVariant();
variant.variantName = variantName + shaderCode.variantName;
variant.shaderCode = this.shaderCode.Clone();
variant.shaderCode.Add( shaderCode );
return variant;
}
public ShaderVariant Extend( ShaderVariant shaderVariant )
{
var extendedVariant = new ShaderVariant();
extendedVariant.variantName = variantName + shaderVariant.variantName;
extendedVariant.shaderCode = shaderCode.Clone();
extendedVariant.shaderCode.AddRange( shaderVariant.shaderCode );
return extendedVariant;
}
public static List<ShaderVariant> CombineVariants( List<ShaderVariant> before, List<ShaderVariant> addition )
{
if ( before == null || before.Count == 0 )
{
return addition;
}
if ( addition == null || addition.Count == 0 )
{
return before;
}
return Lists.Combine( before, addition, ( a, b ) => a.Extend( b ) );
}
}
}

View File

@ -1,51 +0,0 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public class ShaderCodeImports
{
public string importPath;
}
public class ShaderCodeVariable
{
public string variableName;
}
public class ShaderCode
{
public string variantName = "";
public List<ShaderCodeImports> imports = [];
public List<ShaderCodeVariable> variables = [];
protected virtual string _GetCode( ShaderGenerationContext context )
{
return "";
}
public string GetCode( ShaderGenerationContext context )
{
return _GetCode( context );
}
}
public class StringShaderCode:ShaderCode
{
public string code = "";
public StringShaderCode( string code )
{
this.code = code;
}
protected override string _GetCode( ShaderGenerationContext context )
{
return code;
}
}
}

View File

@ -1,138 +0,0 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.VisualBasic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class ShaderGenerationModule:Resource
{
public virtual List<string> GetVariantNames()
{
return new List<string>(){ "" };
}
public virtual List<ShaderCode> GetCode( ShaderGenerationContext context )
{
return new List<ShaderCode>(){};
}
public List<ShaderCode> ToCode( params string[] values )
{
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
}
public List<ShaderCode> ToCode( string value )
{
return Lists.From( (ShaderCode)new StringShaderCode( value ) );
}
public List<ShaderCode> AsUniformGroup( string name, string value )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var blockCode = value.Indent( " ", false );
var code =
@$"
// [ {wideName} ]
group_uniforms {name};
{blockCode}
group_uniforms;
";
return ToCode( code.Indent( "" ) );
}
public List<ShaderCode> ToInnerBlock( string name, string block )
{
var wideName = RegexUtility.UpperCaseAndWide( name );
var blockCode = block.Indent( " ", false );
var code =
@$"
// [ {wideName} ]
{blockCode}
";
return ToCode( code.Indent( " " ) );
}
public List<ShaderCode> ToCode( List<string> values )
{
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
}
public string Uniform( Vector2Property property )
{
var name = property.propertyName.propertyName;
var x = property.value.X._G();
var y = property.value.Y._G();
return @$"uniform vec2 {name} = vec2( {x}, {y});";
}
public string Uniform( string name, float value )
{
return @$"uniform float {name} = {value._G()};";
}
public string Uniform01( string name, float value )
{
return Uniform( name, value, 0, 1 );
}
public string Uniform( string name, float value, float min, float max )
{
var mi = min._G();
var ma = max._G();
var v = value._G();
return @$"uniform float {name}:hint_range( {mi}, {ma}) = {v};";
}
public string UniformSampler( string name, string hints )
{
return @$"uniform sampler2D {name}:{hints};";
}
public string Uniform( string name, Color color )
{
var r = color.R._G();
var g = color.G._G();
var b = color.B._G();
var a = color.A._G();
return @$"uniform vec4 {name}:source_color = vec4( {r}, {g}, {b}, {a});";
}
public string Uniform( string name, Vector3 vec )
{
var x = vec.X._G();
var y = vec.Y._G();
var z = vec.Z._G();
return @$"uniform vec3 {name} = vec3( {x}, {y}, {z});";
}
public string Uniform( string name, Vector4 vec )
{
var x = vec.X._G();
var y = vec.Y._G();
var z = vec.Z._G();
var w = vec.W._G();
return @$"uniform vec4 {name} = vec4( {x}, {y}, {z}, {w});";
}
}
}

View File

@ -1,29 +0,0 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public class ShaderVariant
{
public string variantName = "";
public List<ShaderCode> shaderCode = [];
public string GetCode( ShaderGenerationContext context )
{
return shaderCode.Map( s => s.GetCode( context ) ).Join( "" );
}
public ShaderVariant Extend( ShaderCode shaderCode )
{
var variant = new ShaderVariant();
variant.variantName = variantName + shaderCode.variantName;
variant.shaderCode = this.shaderCode.Clone();
variant.shaderCode.Add( shaderCode );
return variant;
}
}
}

View File

@ -10,12 +10,14 @@ namespace Rokojori
{ {
public AlbedoModule() public AlbedoModule()
{ {
_type = TextureChannelType.RGBA;
_domainName = "albedo"; _domainName = "albedo";
_domainScaleName = "albedo"; _domainScaleName = "albedo";
_domainValueName = "albedo";
_target = "ALBEDO";
_srgb = true; _srgb = true;
_type = TextureChannelType.RGB;
scaleType = TextureChannelType.RGB;
} }
[Export] [Export]
@ -27,18 +29,58 @@ namespace Rokojori
[Export] [Export]
public bool srgb = true; public bool srgb = true;
[Export]
public bool writeAlpha = true;
[Export] [Export]
public bool repeat = true; public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export] [Export]
public TextureDefault textureDefault = TextureDefault.White; public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues() public override void GrabValues()
{ {
domainMode = useTint ? DomainMode.Texture_Scale : DomainMode.Texture; _domainMode = useTint ? DomainMode.Texture_Scale : DomainMode.Texture;
_textureFilter = filter; _textureFilter = filter;
_srgb = srgb; _srgb = srgb;
_repeat = repeat; _repeat = repeat;
_textureDefault = textureDefault; _textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
} }
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
var variants = base.GetVariants( context );
if ( ! writeAlpha || ShaderPhase.Fragment != context.phase )
{
return variants;
}
var value = GetSampledName() + ".a" ;
if ( useTint )
{
value += " * albedo.a";
}
var assignment = " ALPHA *= " + value + ";\n\n";
return ShaderVariant.CombineVariants( variants, ToVariants( ToCode( assignment ) ) );
}
} }
} }

View File

@ -0,0 +1,55 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public enum AlphaFadeMode
{
___,
Alpha,
NoiseDitherDiscard
}
public static class AlphaFade
{
public static List<ShaderCode> Includes( string variableName, AlphaFadeMode mode )
{
if ( AlphaFadeMode.NoiseDitherDiscard != mode )
{
return null;
}
return ShaderGenerationModule.IncludeNoiseLibrary();
}
public static string Fragment( string variableName, AlphaFadeMode mode )
{
if ( AlphaFadeMode.Alpha == mode )
{
return " ALPHA *= " + variableName + ";\n";
}
if ( AlphaFadeMode.NoiseDitherDiscard == mode )
{
var code =
$@"
if ( ditherDiscard( {variableName}, FRAGCOORD ) )
{{
discard;
}}
";
return code.Indent( " ");
}
return null;
}
}
}

View File

@ -0,0 +1 @@
uid://biah4fyd5aa4o

View File

@ -0,0 +1,53 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class AlphaModule:TextureModule
{
public AlphaModule()
{
_domainName = "alpha";
_domainScaleName = "alpha";
_domainOffsetName = "alphaOffset";
_domainValueName = "alpha";
_target = "ALPHA";
_type = TextureChannelType.ONE;
_channelSource = TextureChannelSource.R;
domainScaleDefault = 1f;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public DomainMode domainMode = DomainMode.Texture_Scale;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = domainMode;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
}
}

View File

@ -0,0 +1 @@
uid://8a10in76h56n

View File

@ -0,0 +1,84 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class BacklightModule:TextureModule
{
public BacklightModule()
{
_domainName = "backlight";
_domainScaleName = "backlight";
_domainValueName = "backlight";
_target = "BACKLIGHT";
_srgb = true;
_type = TextureChannelType.RGB;
scaleType = TextureChannelType.RGB;
scaleColor = Colors.Black;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public bool useTint = true;
[Export]
public bool feedAlbedoIntoBacklight = true;
[Export]
public bool srgb = true;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = useTint ? DomainMode.Texture_Scale : DomainMode.Texture;
_textureFilter = filter;
_srgb = srgb;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
public override string AddVariables()
{
if ( ! feedAlbedoIntoBacklight )
{
return "";
}
return "\n" + Uniform01( "backlightFromAlbedo", 0.0f );
}
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
var variants = base.GetVariants( context );
if ( ! feedAlbedoIntoBacklight || ShaderPhase.Fragment != context.phase )
{
return variants;
}
var backlightAssignment = " BACKLIGHT += backlightFromAlbedo * ALBEDO;\n\n";
return ShaderVariant.CombineVariants( variants, ToVariants( ToCode( backlightAssignment ) ) );
}
}
}

View File

@ -0,0 +1 @@
uid://bhqel20k1ky16

View File

@ -0,0 +1,68 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class EmissionModule:TextureModule
{
public EmissionModule()
{
_domainName = "emission";
_domainScaleName = "emission";
_domainIntensityName = "emissionIntensity";
_domainValueName = "emission";
_target = "EMISSION";
_srgb = true;
_type = TextureChannelType.RGB;
scaleType = TextureChannelType.RGB;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
public enum EmissionMode
{
Texture,
Texture_Tint,
Texture_Tint_Intensity
}
[Export]
public EmissionMode mode = EmissionMode.Texture_Tint_Intensity;
[Export]
public bool srgb = true;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.Black;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = EmissionMode.Texture == mode ? DomainMode.Texture :
EmissionMode.Texture_Tint == mode ? DomainMode.Texture_Scale :
DomainMode.Texture_Scale_Intensity;
_textureFilter = filter;
_srgb = srgb;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
}
}

View File

@ -0,0 +1 @@
uid://dobmqsid1agkj

View File

@ -0,0 +1,84 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class CameraDistanceFading:FadingModifier
{
public enum Mode
{
Near_Camera,
Far_Camera
}
[Export]
public Mode mode;
public override bool IsSameType( FadingModifier modifier )
{
if ( modifier is CameraDistanceFading cdf )
{
return cdf.mode == mode;
}
return false;
}
public override List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
bool isNear = mode == Mode.Near_Camera;
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeNoiseLibrary().Concat( IncludeCamerasLibrary() );
}
var fadeOutVariable = isNear ? "nearCameraFadeOutDistance" : "farCameraFadeOutDistance";
var fadeInVariable = isNear ? "nearCameraFadeInDistance" : "farCameraFadeInDistance";
fadeOutVariable += suffix;
fadeInVariable += suffix;
if ( context.isVariablesPhase )
{
if ( isNear )
{
var nearFadeOutDistance = Uniform( fadeOutVariable, 0.0f, 0.1f, 5000 ).LineBreak();
var nearFadeInDistance = Uniform( fadeInVariable, 0.0f, 0.5f, 5000 ).LineBreak();
return ToCode( nearFadeOutDistance, nearFadeInDistance );
}
else
{
var farFadeInDistance = Uniform( fadeInVariable, 0.0f, 0.1f, 5000 ).LineBreak();
var farFadeOutDistance = Uniform( fadeOutVariable, 0.0f, 0.5f, 5000 ).LineBreak();
return ToCode( farFadeInDistance, farFadeOutDistance );
}
}
if ( context.isFragmentPhase )
{
var prefix = isNear ? "near" : "far";
var variable = $"{prefix}CameraDistanceFadeAlpha{suffix}";
var code = $"float {variable} = cameraDistanceFade( VERTEX, {fadeOutVariable}, {fadeInVariable});\n";
return ToCode( code.Indent( " ") ).Concat( ToCode( AlphaFade.Fragment( variable, alphaFadeMode ) ) );
}
return [];
}
}
}

View File

@ -0,0 +1 @@
uid://cvcdfjgoog384

View File

@ -0,0 +1,55 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class DepthPromixityFading:FadingModifier
{
public override List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeDepthLibrary();
}
if ( context.isVariablesPhase )
{
var depthProximityFadeDistanceUniform = Uniform( "depthProximityFadeDistance" + suffix, 0.2f, 0, 1000 ).LineBreak();
var list = new List<ShaderCode>()
{
BuiltInTextureShaderCode.Depth,
ToCode( depthProximityFadeDistanceUniform )
};
return list;
}
if ( context.isFragmentPhase )
{
var code =
$@"
float depthProximityAlpha{suffix} = getDepthProximityAlpha( depthTexture,
SCREEN_UV, INV_PROJECTION_MATRIX,
VERTEX.z, depthProximityFadeDistance{suffix}
);
";
return ToCode( code.Indent( " " ) ).Concat( ToCode( AlphaFade.Fragment( "depthProximityAlpha" + suffix, alphaFadeMode ) ) );
}
return [];
}
}
}

View File

@ -0,0 +1 @@
uid://ip3xwmcn077l

View File

@ -0,0 +1,50 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public abstract partial class FadingModifier:ShaderGenerationModule
{
[Export]
public AlphaFadeMode alphaFadeMode = AlphaFadeMode.___;
[Export]
public bool createUniformGroup = false;
public abstract List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentAlphaFadeMode );
public virtual bool IsSameType( FadingModifier modifier )
{
return modifier.GetType() == GetType();
}
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
return ToVariants( GetFadingCode( context, -1, alphaFadeMode ) );
}
public string GetSuffix( int offsetIndex )
{
return offsetIndex <= 0 ? "" : ( "_" + ( offsetIndex + 1 ) );
}
public AlphaFadeMode GetFadeMode( AlphaFadeMode parent )
{
if ( AlphaFadeMode.___ != alphaFadeMode )
{
return alphaFadeMode;
}
if ( AlphaFadeMode.___ != parent )
{
return parent;
}
return AlphaFadeMode.Alpha;
}
}
}

View File

@ -0,0 +1 @@
uid://btwbxenq2cgyb

View File

@ -0,0 +1,81 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FadingModule:ShaderGenerationModule
{
[Export]
public AlphaFadeMode alphaFadeMode = AlphaFadeMode.NoiseDitherDiscard;
[Export]
public FadingModifier[] fadingModifiers = [];
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
if ( fadingModifiers == null )
{
return null ;
}
var list = fadingModifiers.ToList().FilterNulls();
if ( list.Count == 0 )
{
return null;
}
var shaderCode = new List<ShaderCode>();
if ( ShaderPhase.Includes == context.phase )
{
shaderCode.Add( IncludeNoiseLibrary() );
}
list.ForEach(
( fm )=>
{
var fIndex = list.Filter( l => l.IsSameType( fm ) ).IndexOf( fm );
var fCode = fm.GetFadingCode( context, fIndex, alphaFadeMode );
if ( fCode == null )
{
return;
}
if ( ShaderPhase.Variables == context.phase && fm.createUniformGroup )
{
shaderCode.Add( EndUniformGroup() );
fCode = AsUniformGroup( fm.GetType().Name + fm.GetSuffix( fIndex ), fCode );
}
shaderCode.Add( fCode );
if ( ShaderPhase.Variables == context.phase && fm.createUniformGroup )
{
shaderCode.Add( StartUniformGroup( "Fading") );
}
}
);
if ( ShaderPhase.Variables == context.phase )
{
shaderCode = AsUniformGroup( "Fading", shaderCode );
}
return ToVariants( shaderCode );
}
}
}

View File

@ -0,0 +1 @@
uid://bqk5po80nylsk

View File

@ -0,0 +1,128 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FresnelFading:FadingModifier
{
[Export]
public bool advancedControls = true;
public override bool IsSameType( FadingModifier modifier )
{
if ( modifier is FresnelFading ff )
{
return ff.advancedControls == advancedControls;
}
return false;
}
public override List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
if ( advancedControls )
{
return GetFadingCodeAdvanced( context, offsetIndex, parentFadeMode );
}
else
{
return GetFadingCodeSimple( context, offsetIndex, parentFadeMode );
}
return null;
}
public List<ShaderCode> GetFadingCodeSimple( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeLightLibrary().Concat( IncludeMathLibrary() );
}
if ( context.isVariablesPhase )
{
var code =
$@"
uniform float fresnelFadingPower{suffix} = 1.0f;
uniform bool fresnelFadingInverse{suffix} = false;
";
return ToCode( code.Indent( " " ) );
}
if ( context.isFragmentPhase )
{
var code =
$@"
float fresnelFadingAlpha{suffix} = clamp01( fresnelNormalizedFromView( NORMAL, fresnelFadingPower{suffix} ) );
if ( ! fresnelFadingInverse{suffix} )
{{ fresnelFadingAlpha{suffix} = 1.0 - fresnelFadingAlpha{suffix}; }}
";
return ToCode( code.Indent( " " ) ).Concat( ToCode( AlphaFade.Fragment( "fresnelFadingAlpha" + suffix, alphaFadeMode ) ) );
}
return [];
}
public List<ShaderCode> GetFadingCodeAdvanced( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeLightLibrary();
}
if ( context.isVariablesPhase )
{
var code =
$@"
uniform float advancedFresnelFadingZOffset{suffix} = 0.0f;
uniform float advancedFresnelFadingPower{suffix} = 1.0f;
uniform float advancedFresnelFadingPostScale{suffix} = 1.0f;
uniform float advancedFresnelFadingPostOffset{suffix} = 0.0f;
uniform bool advancedFresnelFadingInverse = false;
";
return ToCode( code.Indent( "" ) );
}
if ( context.isFragmentPhase )
{
var code =
$@"
float advancedFresnelFadingAlpha{suffix} = clamp01( fresnelNormalizedFromViewAdvanced( NORMAL,
advancedFresnelFadingZOffset{suffix},
advancedFresnelFadingPower{suffix},
advancedFresnelFadingPostScale{suffix},
advancedFresnelFadingPostOffset{suffix}
) );
if ( ! advancedFresnelFadingInverse{suffix} )
{{ advancedFresnelFadingAlpha{suffix} = 1.0 - advancedFresnelFadingAlpha{suffix}; }}
";
return ToCode( code.Indent( " " ) ).Concat( ToCode( AlphaFade.Fragment( "advancedFresnelFadingAlpha" + suffix, alphaFadeMode ) ) );
}
return [];
}
}
}

View File

@ -0,0 +1 @@
uid://dpkfvftsk23we

View File

@ -0,0 +1,229 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LineFading:FadingModifier
{
public enum Mode
{
World,
WorldPoint_To_Camera,
Screen
}
[Export]
public Mode mode;
public override bool IsSameType( FadingModifier modifier )
{
if ( modifier is LineFading lf )
{
return lf.mode == mode;
}
return false;
}
public override List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeTransformLibrary().Concat( IncludeFromLibrary( "Line3" ) ).Concat( IncludeSDFLibrary() );
}
if ( context.isVariablesPhase )
{
if ( Mode.Screen == mode )
{
List<string> variables =
[
Uniform( "screenLineDistanceFadeWorldPositionA" + suffix, Vector3.Zero ),
Uniform( "screenLineDistanceFadeWorldPositionB" + suffix, Vector3.One ),
VaryingVec3( "screenLineDistanceFadeScreenPositionA" + suffix ),
VaryingVec3( "screenLineDistanceFadeScreenPositionB" + suffix ),
Uniform( "screenLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "screenLineDistanceFadeOuterRadius" + suffix, 0.15f ),
VaryingVec2( "screenLineDistanceViewportRatio" + suffix )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
else if ( Mode.World == mode )
{
List<string> variables =
[
Uniform( "worldLineDistanceFadeWorldPositionA" + suffix, Vector3.Zero ),
Uniform( "worldLineDistanceFadeWorldPositionB" + suffix, Vector3.One ),
VaryingVec3( "worldLineDistanceFadeViewPositionA" + suffix ),
VaryingVec3( "worldLineDistanceFadeViewPositionB" + suffix ),
Uniform( "worldLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "worldLineDistanceFadeOuterRadius" + suffix, 0.15f )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
List<string> variables =
[
Uniform( "worldCameraLineDistanceFadeWorldPosition" + suffix, Vector3.Zero ),
VaryingVec3( "worldCameraLineDistanceFadeViewPosition" + suffix ),
Uniform( "worldCameraLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "worldCameraLineDistanceFadeOuterRadius" + suffix, 0.15f )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
}
if ( context.isVertexPhase )
{
if ( Mode.Screen == mode )
{
var code =
$@"
screenLineDistanceFadeScreenPositionA{suffix} = vec3( worldToScreen( screenLineDistanceFadeWorldPositionA{suffix}, VIEW_MATRIX, PROJECTION_MATRIX ), 0.0 );
screenLineDistanceFadeScreenPositionB{suffix} = vec3( worldToScreen( screenLineDistanceFadeWorldPositionB{suffix}, VIEW_MATRIX, PROJECTION_MATRIX ), 0.0 );
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.World == mode )
{
var code =
$@"
worldLineDistanceFadeViewPositionA{suffix} = worldToView( worldLineDistanceFadeWorldPositionA{suffix}, VIEW_MATRIX );
worldLineDistanceFadeViewPositionB{suffix} = worldToView( worldLineDistanceFadeWorldPositionB{suffix}, VIEW_MATRIX );
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
var code =
$@"
worldCameraLineDistanceFadeViewPosition{suffix} = worldToView( worldCameraLineDistanceFadeWorldPosition{suffix}, VIEW_MATRIX );
";
return ToCode( code.Indent( " ") );
}
}
if ( context.isFragmentPhase )
{
if ( Mode.Screen == mode )
{
var fadeVariable = "screenLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
vec2 screenRatioMultiply = VIEWPORT_SIZE;
if ( screenRatioMultiply.x > screenRatioMultiply.y )
{{
screenRatioMultiply /= VIEWPORT_SIZE.x;
}}
else
{{
screenRatioMultiply /= VIEWPORT_SIZE.y;
}}
vec2 screenVertex = viewToScreen( VERTEX, PROJECTION_MATRIX ) * screenRatioMultiply;
Line3 screenLineDistanceFadeLine3;
screenLineDistanceFadeLine3.start = screenLineDistanceFadeScreenPositionA{suffix} * vec3( screenRatioMultiply, 1.0 );
screenLineDistanceFadeLine3.end = screenLineDistanceFadeScreenPositionB{suffix} * vec3( screenRatioMultiply, 1.0 );
float screenLineDistanceFadeDistance = Line3_getDistance( screenLineDistanceFadeLine3, vec3( screenVertex, 0.0 ) );
float {fadeVariable} = clamp( smoothstep( screenLineDistanceFadeInnerRadius{suffix}, screenLineDistanceFadeOuterRadius{suffix}, screenLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.World == mode )
{
var fadeVariable = "worldLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
Line3 worldLineDistanceFadeLine3;
worldLineDistanceFadeLine3.start = worldLineDistanceFadeViewPositionA{suffix};
worldLineDistanceFadeLine3.end = worldLineDistanceFadeViewPositionB{suffix};
float worldLineDistanceFadeDistance = Line3_getDistance( worldLineDistanceFadeLine3, VERTEX );
float {fadeVariable} = clamp( smoothstep( worldLineDistanceFadeInnerRadius{suffix}, worldLineDistanceFadeOuterRadius{suffix}, worldLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
var fadeVariable = "worldLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
float worldLineDistanceFadeDistance = sdRoundCone( VERTEX, vec3( 0.0, 0.0, 0.0), worldCameraLineDistanceFadeViewPosition{suffix}, 0, worldCameraLineDistanceFadeInnerRadius );
float {fadeVariable} = clamp( smoothstep( 0, ( worldCameraLineDistanceFadeOuterRadius{suffix} - worldCameraLineDistanceFadeInnerRadius{suffix} ), worldLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
}
return [];
}
}
}

View File

@ -0,0 +1 @@
uid://biqus8elamaeo

View File

@ -0,0 +1,24 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public abstract partial class GeometryModifier:ShaderGenerationModule
{
public virtual bool IsSameType( GeometryModifier modifier )
{
return modifier.GetType() == GetType();
}
public abstract List<ShaderCode> GetGeometryCode( ShaderGenerationContext context, int offsetIndex );
public string GetSuffix( int offsetIndex )
{
return offsetIndex <= 0 ? "" : ( "_" + ( offsetIndex + 1 ) );
}
}
}

View File

@ -0,0 +1,38 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GeometryModule:ShaderGenerationModule
{
[Export]
public GeometryModifier[] modifiers = [];
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
var list = new List<ShaderCode>();
var allModifiers = Lists.From( modifiers ).FilterNulls();
allModifiers.ForEach(
( m )=>
{
var offsetIndex = allModifiers.Filter( l => l.IsSameType( m ) ).IndexOf( m );
var geometryCode = m.GetGeometryCode( context, offsetIndex );
if ( geometryCode == null )
{
return;
}
list.AddRange( geometryCode );
}
);
return ToVariants( list );
}
}
}

View File

@ -0,0 +1,198 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GeometryNormalOffset:GeometryModifier
{
public enum Mode
{
Object,
World
}
[Export]
public Mode mode;
[ExportGroup("Texture")]
[Export]
public bool textureScaleEnabled = false;
[Export]
public string textureUVChannel = "UV";
[Export]
public bool textureRepeat = true;
[Export]
public TextureModule.TextureFilter textureFilter = TextureModule.TextureFilter.Linear_MipMap_Anisotropic;
public override bool IsSameType( GeometryModifier modifier )
{
if ( modifier is GeometryNormalOffset no )
{
return no.mode == mode;
}
return false;
}
public override List<ShaderCode> GetGeometryCode( ShaderGenerationContext context, int offsetIndex )
{
if ( Mode.Object == mode )
{
return ObjectNormal( context, offsetIndex );
}
else if ( Mode.World == mode )
{
return WorldNormal( context, offsetIndex );
}
return null;
}
List<ShaderCode> ObjectNormal( ShaderGenerationContext context, int offsetIndex )
{
var suffix = GetSuffix( offsetIndex );
if ( ShaderPhase.Variables == context.phase )
{
var hints = new List<string>();
hints.Add( "hint_default_white" );
hints.Add( textureRepeat ? "repeat_enable" : "repeat_disable" );
hints.Add( "filter_" + ( textureFilter + "" ).ToLower() );
var sampler = UniformSampler( $"objectNormalOffsetTexture{suffix}", hints.Join( ", " ) );
if ( ! textureScaleEnabled )
{
sampler = "";
}
return AsUniformGroup( $"ObjectNormalOffset{suffix}",
$@"
uniform float objectNormalOffset{suffix} = 0.1;
{sampler}
"
);
}
if ( ShaderPhase.Vertex == context.phase )
{
var samplerMultply =
$@"
float sampledObjectNormalOffset{suffix} = texture( objectNormalOffsetTexture{suffix}, {textureUVChannel} ).r;
objectNormalOffsetAmount{suffix} *= sampledObjectNormalOffset{suffix};
";
if ( ! textureScaleEnabled )
{
samplerMultply = "";
}
return ToInnerBlock( $"ObjectNormalOffset{suffix}",
$@"
{{
float objectNormalOffsetAmount{suffix} = objectNormalOffset{suffix};
{samplerMultply}
VERTEX += NORMAL * objectNormalOffsetAmount{suffix};
}}
"
);
}
return null;
}
List<ShaderCode> WorldNormal( ShaderGenerationContext context, int offsetIndex )
{
var suffix = GetSuffix( offsetIndex );
if ( ShaderPhase.Includes == context.phase )
{
return IncludeTransformLibrary();
}
else if ( ShaderPhase.Variables == context.phase )
{
var hints = new List<string>();
hints.Add( "hint_default_white" );
hints.Add( textureRepeat ? "repeat_enable" : "repeat_disable" );
hints.Add( "filter_" + ( textureFilter + "" ).ToLower() );
var sampler = UniformSampler( $"worldNormalOffsetTexture{suffix}", hints.Join( ", " ) );
if ( ! textureScaleEnabled )
{
sampler = "";
}
return AsUniformGroup( $"WorldNormalOffset{suffix}",
$@"
uniform float worldNormalOffsetScale{suffix} = 1.0;
uniform float worldNormalWorldOffset{suffix} = 0.1;
uniform float worldNormalViewOffset{suffix} = 0.1;
uniform float worldNormalScaleType{suffix}:hint_range( 0.0, 1.0 ) = 1.0;
{sampler}
"
);
}
if ( ShaderPhase.Vertex == context.phase )
{
var samplerMultply =
$@"
float sampledWorldNormalOffset{suffix} = texture( worldNormalOffsetTexture{suffix}, {textureUVChannel} ).r;
worldNormalOffsetAmount{suffix} *= sampledWorldNormalOffset{suffix};
";
if ( ! textureScaleEnabled )
{
samplerMultply = "";
}
return ToInnerBlock( $"WorldNormalOffset{suffix}",
$@"
{{
float vertexDistance = length( localToWorld( VERTEX, MODEL_MATRIX ) - CAMERA_POSITION_WORLD );
float worldNormalOffsetAmount{suffix} = mix( worldNormalWorldOffset{suffix}, vertexDistance * worldNormalViewOffset{suffix}, worldNormalScaleType{suffix} );
{samplerMultply}
vec3 worldNormal = localToWorldDirection( NORMAL, MODEL_MATRIX ) * worldNormalOffsetAmount{suffix} * worldNormalOffsetScale{suffix};
vec3 localNormal = worldToLocalDirection( worldNormal, MODEL_MATRIX );
VERTEX += localNormal;
}}
"
);
}
return null;
}
}
}

View File

@ -0,0 +1 @@
uid://j4aagrd2fmce

View File

@ -0,0 +1,63 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GeometryTerrainOffset:GeometryModifier
{
public override List<ShaderCode> GetGeometryCode( ShaderGenerationContext context, int offsetIndex )
{
if ( offsetIndex != 0 )
{
throw new System.Exception( "Unique component, can't be used multiple times");
}
if ( ShaderPhase.Includes == context.phase )
{
return IncludeFromLibrary( "Terrain" );
}
if ( ShaderPhase.Variables == context.phase )
{
return AsUniformGroup( "Terrain",
@"
uniform sampler2D terrainHeightMap;
uniform vec2 terrainCenterXZ = vec2( 0.0, 0.0 );
uniform vec2 terrainSizeXZ = vec2( 100.0, 100.0 );
uniform float terrainMinHeight = 0.0;
uniform float terrainMaxHeight = 100.0;
"
);
}
if ( ShaderPhase.Vertex == context.phase )
{
return ToInnerBlock( "Terrain",
@"
addTerrainOffset(
MODEL_MATRIX,
VERTEX,
terrainHeightMap,
terrainCenterXZ,
terrainSizeXZ,
terrainMinHeight,
terrainMaxHeight
);
"
);
}
return null;
}
}
}

View File

@ -0,0 +1 @@
uid://cmby3d8ou6e30

View File

@ -1,15 +1,14 @@
using Godot; using Godot;
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
using System;
namespace Rokojori namespace Rokojori
{ {
[Tool] [Tool]
[GlobalClass] [GlobalClass]
public partial class VertexWind:VertexModifier public partial class GeometryWind:GeometryModifier
{ {
[Export]
public bool enabled = true;
[Export] [Export]
public bool sampleAngleFromNoise = true; public bool sampleAngleFromNoise = true;
@ -18,11 +17,16 @@ namespace Rokojori
public bool heightCompensation = true; public bool heightCompensation = true;
public override List<ShaderCode> GetCode( ShaderGenerationContext context ) public override List<ShaderCode> GetGeometryCode( ShaderGenerationContext context, int offsetIndex )
{ {
if ( offsetIndex != 0 )
{
throw new Exception( "Unique component, can't be used multiple times");
}
if ( ShaderPhase.Includes == context.phase ) if ( ShaderPhase.Includes == context.phase )
{ {
return ToCode( "#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/Wind.gdshaderinc\"" ); return IncludeFromLibrary( "Wind" );
} }
if ( ShaderPhase.Variables == context.phase ) if ( ShaderPhase.Variables == context.phase )
@ -30,16 +34,20 @@ namespace Rokojori
return AsUniformGroup( "Wind", return AsUniformGroup( "Wind",
@" @"
uniform float windStrength = 0; uniform float windStrength = 0;
uniform vec2 windSpeed = vec2(1,1); uniform vec2 windSpeed = vec2(1,1);
uniform float windScale = 1; uniform float windScale = 0.1;
uniform sampler2D windNoise; uniform sampler2D windNoise;
uniform vec2 windNoiseAngleOffset; uniform vec2 windNoiseAngleOffset;
uniform vec2 windNoiseStrengthOffset = vec2( 0.1234, 0.56789 ); uniform vec2 windNoiseStrengthOffset;
uniform float windStart = 0; uniform float windStart = 0;
uniform float windEnd = 1; uniform float windEnd = 1;
uniform float windWeightCurve:hint_range(0,1) = 0.5f; uniform float windWeightCurve:hint_range(0,1) = 0.5f;
uniform float windHeightCompensation :hint_range(0,1) = 0.5f; uniform float windHeightCompensation :hint_range(0,1) = 0.5f;
uniform float windNormalBending :hint_range(0,1) = 0.1f;
uniform float windOcclusionAmount = 0;
varying float vertexWindAO;
" "
); );
@ -52,9 +60,16 @@ namespace Rokojori
return ToInnerBlock( "Wind", return ToInnerBlock( "Wind",
@" @"
applyWind(
TIME, MODEL_MATRIX, VERTEX,
float cachedVertexWindAO = 0.0;
applyWind(
TIME,
MODEL_MATRIX,
VERTEX,
NORMAL,
cachedVertexWindAO,
windOcclusionAmount,
windStrength, windStrength,
windSpeed, windSpeed,
windScale, windScale,
@ -64,11 +79,20 @@ namespace Rokojori
windStart, windStart,
windEnd, windEnd,
windWeightCurve, windWeightCurve,
windHeightCompensation windHeightCompensation,
windNormalBending
); );
vertexWindAO = cachedVertexWindAO;
" "
); ) ;
}
if ( ShaderPhase.Fragment == context.phase )
{
return ToCode( "AO *= vertexWindAO;".Indent( " " ).LineBreaks() );
} }
return null; return null;

View File

@ -0,0 +1,53 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class MetallicModule:TextureModule
{
public MetallicModule()
{
_domainName = "metallic";
_domainScaleName = "metallic";
_domainOffsetName = "metallicOffset";
_domainValueName = "metallic";
_target = "METALLIC";
_type = TextureChannelType.ONE;
_channelSource = TextureChannelSource.B;
domainScaleDefault = 0;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public DomainMode domainMode = DomainMode.Texture_Scale_Offset;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = domainMode;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
}
}

View File

@ -0,0 +1 @@
uid://n0gi67ntpq0y

View File

@ -0,0 +1,58 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class NormalMapModule:TextureModule
{
public NormalMapModule()
{
_type = TextureChannelType.RGB;
_domainName = "normal";
_domainScaleName = "normalStrength";
_domainValueName = "normal";
_target = "NORMAL_MAP";
_scaleTarget = "NORMAL_MAP_DEPTH";
_normal = true;
_type = TextureChannelType.RGB;
scaleType = TextureChannelType.SCALAR;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public bool useStrength = true;
[Export]
public float maximumStrength = 5;
[Export]
public bool allowNegativeStrength = false;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
public override void GrabValues()
{
_domainMode = useStrength ? DomainMode.Texture_Scale : DomainMode.Texture;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
domainScaleMax = Mathf.Abs( maximumStrength );
domainScaleMin = allowNegativeStrength ? -Mathf.Abs( maximumStrength ) : 0;
}
}
}

View File

@ -0,0 +1 @@
uid://tl4qfoxysj06

View File

@ -0,0 +1,53 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class OcclusionModule:TextureModule
{
public OcclusionModule()
{
_domainName = "occlusion";
_domainScaleName = "occlusion";
_domainOffsetName = "occlusionOffset";
_domainValueName = "occlusion";
_target = "AO";
_type = TextureChannelType.ONE;
_channelSource = TextureChannelSource.R;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public DomainMode domainMode = DomainMode.Texture_Scale_Offset;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = domainMode;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
}
}

View File

@ -0,0 +1 @@
uid://dnikyu81333q8

View File

@ -0,0 +1,57 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class RoughnessModule:TextureModule
{
public RoughnessModule()
{
_domainName = "roughness";
_domainScaleName = "roughness";
_domainOffsetName = "roughnessOffset";
_domainValueName = "roughness";
_target = "ROUGHNESS";
_type = TextureChannelType.ONE;
_channelSource = TextureChannelSource.G;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public DomainMode domainMode = DomainMode.Texture_Scale_Offset;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
[Export]
public bool clamp = true;
public override void GrabValues()
{
_domainMode = domainMode;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
_clamp = clamp;
}
}
}

View File

@ -0,0 +1 @@
uid://dew0uayffwxwk

View File

@ -32,7 +32,7 @@ namespace Rokojori
[Export] [Export]
public bool wireFrameMode = false; public bool wireFrameMode = false;
public override List<ShaderCode> GetCode( ShaderGenerationContext context ) public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{ {
if ( ShaderPhase.RenderMode != context.phase ) if ( ShaderPhase.RenderMode != context.phase )
{ {
@ -91,7 +91,7 @@ namespace Rokojori
value = RegexUtility.Replace( value, @"\,\s*$", "" ); value = RegexUtility.Replace( value, @"\,\s*$", "" );
return Lists.From( (ShaderCode) new StringShaderCode( value ) ); return ToVariants( ToCode( value ) ) ;
} }
} }

View File

@ -0,0 +1,249 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class SpatialShaderData:Resource
{
[ExportGroup("Presets/Starters")]
[ExportToolButton("PBR Starter")]
public Callable pbrStarterButton => Callable.From( ()=>{ PBR_Starter(); } );
[ExportToolButton("PBR Alpha Starter")]
public Callable pbrAlphaStarterButton => Callable.From( ()=>{ PBR_Alpha_Starter(); } );
[ExportToolButton("PBR Emissive Starter")]
public Callable pbrEmissiveStarterButton => Callable.From( ()=>{ PBR_Emissive_Starter(); } );
[ExportToolButton("PBR Luminance Starter")]
public Callable pbrLuminanceStarterButton => Callable.From( ()=>{ PBR_Luminance_Starter(); } );
[ExportToolButton("PBR All Starter")]
public Callable pbrAllStarterButton => Callable.From( ()=>{ PBR_All_Starter(); } );
[ExportToolButton("Unshaded Starter")]
public Callable unshadedStarterButton => Callable.From( ()=>{ Unshaded_Starter(); } );
[ExportGroup("Modules")]
[Export]
public TransparencyModule transparency = new TransparencyModule();
[Export]
public ShadingModule shading = new ShadingModule();
[Export]
public StencilModule stencil = null;
[Export]
public GeometryModule geometry = new GeometryModule();
[Export]
public UVModule uv = new UVModule();
[Export]
public AlbedoModule albedo = new AlbedoModule();
[Export]
public AlphaModule alpha = null;
[Export]
public FadingModule fading = null;
[Export]
public NormalMapModule normalMap = null;
[Export]
public RoughnessModule roughness = null;
[Export]
public MetallicModule metallic = null;
[Export]
public SpecularModule specular = null;
[Export]
public OcclusionModule occlusion = null;
[Export]
public EmissionModule emission = null;
[Export]
public BacklightModule backlight = null;
[Export]
public SubsurfaceScatteringModule subsurfaceScattering = null;
public void PBR_All_Starter()
{
transparency = new TransparencyModule();
shading = new ShadingModule();
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = null;
fading = null;
normalMap = new NormalMapModule();
roughness = new RoughnessModule();
metallic = new MetallicModule();
specular = new SpecularModule();
specular.domainMode = TextureModule.DomainMode.Value;
occlusion = new OcclusionModule();
emission = new EmissionModule();
backlight = new BacklightModule();
subsurfaceScattering = new SubsurfaceScatteringModule();
}
public void PBR_Luminance_Starter()
{
transparency = new TransparencyModule();
shading = new ShadingModule();
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = null;
fading = null;
normalMap = new NormalMapModule();
roughness = new RoughnessModule();
metallic = new MetallicModule();
specular = new SpecularModule();
specular.domainMode = TextureModule.DomainMode.Value;
occlusion = new OcclusionModule();
emission = null;
backlight = new BacklightModule();
subsurfaceScattering = new SubsurfaceScatteringModule();
}
public void PBR_Starter()
{
transparency = new TransparencyModule();
shading = new ShadingModule();
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = null;
fading = null;
normalMap = new NormalMapModule();
roughness = new RoughnessModule();
metallic = new MetallicModule();
specular = new SpecularModule();
specular.domainMode = TextureModule.DomainMode.Value;
occlusion = new OcclusionModule();
emission = null;
backlight = null;
subsurfaceScattering = null;
}
public void PBR_Emissive_Starter()
{
transparency = new TransparencyModule();
shading = new ShadingModule();
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = null;
fading = null;
normalMap = new NormalMapModule();
roughness = new RoughnessModule();
metallic = new MetallicModule();
specular = new SpecularModule();
specular.domainMode = TextureModule.DomainMode.Value;
occlusion = new OcclusionModule();
emission = new EmissionModule();
backlight = null;
subsurfaceScattering = null;
}
public void PBR_Alpha_Starter()
{
transparency = new TransparencyModule();
transparency.transparency = BaseMaterial3D.TransparencyEnum.Alpha;
shading = new ShadingModule();
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = new AlphaModule();
fading = null;
normalMap = new NormalMapModule();
roughness = new RoughnessModule();
metallic = new MetallicModule();
specular = new SpecularModule();
specular.domainMode = TextureModule.DomainMode.Value;
occlusion = new OcclusionModule();
emission = null;
backlight = null;
subsurfaceScattering = null;
}
public void Unshaded_Starter()
{
transparency = new TransparencyModule();
transparency.transparency = BaseMaterial3D.TransparencyEnum.Alpha;
shading = new ShadingModule();
shading.shadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded;
stencil = null;
geometry = new GeometryModule();
uv = new UVModule();
albedo = new AlbedoModule();
alpha = new AlphaModule();
fading = null;
normalMap = null;
roughness = null;
metallic = null;
specular = null;
occlusion = null;
emission = null;
backlight = null;
subsurfaceScattering = null;
}
}
}

View File

@ -0,0 +1 @@
uid://bakspsqw7d0hn

View File

@ -9,20 +9,7 @@ namespace Rokojori
public partial class SpatialShaderGenerator:ShaderGenerator public partial class SpatialShaderGenerator:ShaderGenerator
{ {
[Export] [Export]
public TransparencyModule transparency = new TransparencyModule(); public SpatialShaderData data = new SpatialShaderData();
[Export]
public ShadingModule shading = new ShadingModule();
[Export]
public VertexModule vertex = new VertexModule();
[Export]
public UVModule uv = new UVModule();
[Export]
public AlbedoModule albedo = new AlbedoModule();
public override List<ShaderPhase> GetPhases() public override List<ShaderPhase> GetPhases()
{ {
@ -39,38 +26,97 @@ namespace Rokojori
}; };
} }
public string RokojoriInfo()
{
var allModules = GetAllModules();
var hashValues = allModules.Map( a => a.GetShaderCacheHash() );
hashValues.Sort();
var hash = hashValues.Join( "-" );
var allInfos = allModules.Map( a => a.GetShaderCacheData() );
return $"// Rokojori Shader @{hash}: \n/*\n" + allInfos.Join( "\n" ) + "\n*/\n";
}
List<ShaderGenerationModule> GetAllModules()
{
return GetHeaderModules().Concat( GetMainModules() );
}
List<ShaderGenerationModule> GetHeaderModules()
{
List<ShaderGenerationModule> list = [
data.transparency,
data.shading,
data.stencil
];
return list.FilterNulls();
}
List<ShaderGenerationModule> GetMainModules()
{
List<ShaderGenerationModule> list = [
data.geometry,
data.uv,
data.albedo,
data.alpha,
data.fading,
data.normalMap,
data.occlusion,
data.roughness,
data.metallic,
data.specular,
data.emission,
data.backlight,
data.subsurfaceScattering
];
return list.FilterNulls();
}
public override List<ShaderGenerationModule> GetShaderGenerationModules( ShaderPhase phase ) public override List<ShaderGenerationModule> GetShaderGenerationModules( ShaderPhase phase )
{ {
if ( ShaderPhase.Header == phase ) if ( ShaderPhase.Header == phase )
{ {
var info = RokojoriInfo();
return return
[ [
new ShaderRawModule( "\n\nshader_type spatial;\n" ) new ShaderRawModule( "\n\nshader_type spatial;\n" ),
new ShaderRawModule( $"\n{info}\n")
]; ];
} }
if ( ShaderPhase.RenderMode == phase ) if ( ShaderPhase.RenderMode == phase )
{ {
return List<ShaderGenerationModule> modules =
[ [
new ShaderRawModule( "render_mode " ), new ShaderRawModule( "render_mode " ),
transparency, data.transparency,
new ShaderRawModule( ", " ), new ShaderRawModule( ", " ),
shading, data.shading,
new ShaderRawModule( ";\n\n" ), new ShaderRawModule( ";\n" ),
]; ];
if ( data.stencil != null )
{
modules.Add( new ShaderRawModule( data.stencil.ToShaderCode() + "\n" ) );
} }
modules.Add( new ShaderRawModule( "\n" ) );
return modules;
}
var mainModules = GetMainModules();
if ( ShaderPhase.Includes == phase || ShaderPhase.Variables == phase || ShaderPhase.Functions == phase ) if ( ShaderPhase.Includes == phase || ShaderPhase.Variables == phase || ShaderPhase.Functions == phase )
{ {
return List<ShaderGenerationModule> preModules = [
[ data.transparency,
transparency, data.shading ]
shading, ;
vertex,
uv, return preModules.Concat( mainModules );
albedo
];
} }
if ( ShaderPhase.Vertex == phase ) if ( ShaderPhase.Vertex == phase )
@ -79,10 +125,7 @@ namespace Rokojori
{ {
new ShaderRawModule( "\nvoid vertex()\n{\n\n" ) new ShaderRawModule( "\nvoid vertex()\n{\n\n" )
} }
.Concat .Concat( mainModules )
(
uv, vertex, albedo
)
.Concat .Concat
( (
new ShaderRawModule( "\n}\n" ) new ShaderRawModule( "\n}\n" )
@ -95,10 +138,7 @@ namespace Rokojori
{ {
new ShaderRawModule( "\nvoid fragment()\n{\n\n" ) new ShaderRawModule( "\nvoid fragment()\n{\n\n" )
} }
.Concat .Concat( mainModules )
(
uv, vertex, albedo
)
.Concat .Concat
( (
new ShaderRawModule( "\n}\n" ) new ShaderRawModule( "\n}\n" )

View File

@ -0,0 +1,53 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class SpecularModule:TextureModule
{
public SpecularModule()
{
_domainName = "specular";
_domainScaleName = "specular";
_domainOffsetName = "specularOffset";
_domainValueName = "specular";
_target = "SPECULAR";
_type = TextureChannelType.ONE;
_channelSource = TextureChannelSource.G;
}
[Export]
public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;
[Export]
public DomainMode domainMode = DomainMode.Texture_Scale_Offset;
[Export]
public bool repeat = true;
[Export]
public string uvChannel = "UV";
[Export]
public TextureDefault textureDefault = TextureDefault.White;
[Export]
public AssignmentType assignmentType = AssignmentType.Set;
public override void GrabValues()
{
_domainMode = domainMode;
_textureFilter = filter;
_repeat = repeat;
_textureDefault = textureDefault;
_uvChannel = uvChannel;
_assignmentType = assignmentType;
}
}
}

View File

@ -0,0 +1 @@
uid://c7bmbvoc57ebo

View File

@ -0,0 +1,17 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class StencilBaseReference:StencilReference
{
public override int GetReferenceIndex()
{
return 0;
}
}
}

Some files were not shown because too many files have changed in this diff Show More