diff --git a/External/Imposter/materials/normal_baker.gdshader b/External/Imposter/materials/normal_baker.gdshader index 1c53860..60f23e4 100644 --- a/External/Imposter/materials/normal_baker.gdshader +++ b/External/Imposter/materials/normal_baker.gdshader @@ -1,22 +1,38 @@ shader_type spatial; -render_mode blend_mix,depth_draw_opaque,cull_disabled,diffuse_burley,specular_schlick_ggx; +render_mode blend_mix,depth_draw_opaque,cull_disabled, unshaded; + +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc" + uniform vec4 albedo_color : source_color; uniform sampler2D albedo_texture : source_color; uniform sampler2D normal_texture : source_color; uniform bool use_normalmap = false; +uniform bool uncompressNormalMap = true; uniform bool use_alpha_texture = false; +uniform bool useCustomNormals = true; uniform float alpha_scissor_threshold : hint_range(0,1); -uniform float normal_scale : hint_range(-5,5); +uniform float normal_scale : hint_range(-5,5) = 1; -uniform vec3 uv1_scale; +uniform vec3 uv1_scale = vec3( 1, 1, 1 ); uniform vec3 uv1_offset; +varying vec3 vertexNormal; +varying vec3 vertexTangent; +varying vec3 vertexBinormal; + +uniform float binormalMix:hint_range(0,1); void vertex() { UV = UV * uv1_scale.xy + uv1_offset.xy; + vertexNormal = localToViewDirection( NORMAL, MODELVIEW_NORMAL_MATRIX ); + vertexTangent = localToViewDirection( TANGENT, MODELVIEW_NORMAL_MATRIX ); + vertexBinormal = cross( vertexNormal, vertexTangent ); + //NORMAL = localToViewDirection( NORMAL, MODELVIEW_NORMAL_MATRIX ); } void fragment() @@ -24,18 +40,41 @@ void fragment() vec2 base_uv = UV; vec4 albedo = texture( albedo_texture, base_uv ) * albedo_color; vec4 normal_tex = texture( normal_texture, base_uv ); + vec3 RENDER_NORMAL = useCustomNormals ? vertexNormal : NORMAL; + + if ( ! useCustomNormals && ! FRONT_FACING ) + { + RENDER_NORMAL = - RENDER_NORMAL; + } + //ALBEDO = mix( vertexNormal, NORMAL, normalMix ); // 0.5 + -1.0 == -1.0 + 0.5 //ALBEDO = vec3(1.0 - NORMAL.y, 1.0 - NORMAL.x, - NORMAL.z)* 0.5; if ( use_normalmap ) { vec3 normalmap; - normalmap.xy = normal_tex.xy * 2.0 - 1.0; - normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); - NORMAL = normalize(mix(NORMAL, TANGENT * normalmap.x + BINORMAL * normalmap.y + NORMAL * normalmap.z, normal_scale)); + + if ( uncompressNormalMap ) + { + normalmap.xy = normal_tex.xy * 2.0 - 1.0; + normalmap.z = sqrt( max( 0.0, 1.0 - dot( normalmap.xy, normalmap.xy ) ) ); + } + else + { + normalmap = normal_tex.xyz * 2.0 - 1.0; + } + + vec3 textureNormal = vertexTangent * normalmap.x + + vertexBinormal * normalmap.y + + vertexNormal * normalmap.z; + + + RENDER_NORMAL = normalize( mix( RENDER_NORMAL, textureNormal, normal_scale ) ); + //NORMAL = textureNormal; } - - - ALBEDO = vec3( -NORMAL.x, NORMAL.y, -NORMAL.z) * 0.5 + 0.5; + + + vec3 rn = vec3( RENDER_NORMAL.x, RENDER_NORMAL.y, RENDER_NORMAL.z ) * 0.5 + 0.5; + ALBEDO = rn; if ( use_alpha_texture ) { diff --git a/Runtime/Procedural/Baking/Baker.cs b/Runtime/Procedural/Baking/Baker.cs index dfd30f9..d69c402 100644 --- a/Runtime/Procedural/Baking/Baker.cs +++ b/Runtime/Procedural/Baking/Baker.cs @@ -12,8 +12,8 @@ namespace Rokojori public partial class Baker:Node { - [ExportToolButton( "Update")] - public Callable BakeButton => Callable.From( () => Bake() ); + [ExportToolButton( "Apply Camera Settings")] + public Callable ApplyCamerySettingsButton => Callable.From( () => ApplyCameraSettings() ); [Export] public bool updateAlways = false; @@ -77,11 +77,11 @@ namespace Rokojori return; } - Bake(); + ApplyCameraSettings(); } - public void Bake() + public void ApplyCameraSettings() { if ( viewport == null || target == null || camera == null ) { @@ -91,6 +91,12 @@ namespace Rokojori if ( autoTargetPivot ) { Box3 box = target.GetWorldBounds(); + + if ( box == null ) + { + return; + } + targetPivot = new Vector3( 0, -box.center.Y, 0 ); } diff --git a/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs b/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs new file mode 100644 index 0000000..632a0ff --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs @@ -0,0 +1,72 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class BakingOutput:Resource + { + [Export] + public BakingTarget bakingTarget; + + [Export] + public Texture2D bakedTexture; + + public static BakingOutput With( BakingTargetType type, Texture2D texture2D ) + { + var bo = new BakingOutput(); + bo.bakingTarget = new BakingTarget(); + bo.bakingTarget.type = type; + bo.bakedTexture = texture2D; + + return bo; + } + + public static BakingOutput Lit( Texture2D texture2D = null ) + { + return With( BakingTargetType.Lit, texture2D ); + } + + public static BakingOutput Albedo( Texture2D texture2D = null ) + { + return With( BakingTargetType.Albedo, texture2D ); + } + + + public static BakingOutput Normals( Texture2D texture2D = null ) + { + return With( BakingTargetType.Normals, texture2D ); + } + + public static BakingOutput Depth( Texture2D texture2D = null ) + { + return With( BakingTargetType.Depth, texture2D ); + } + + public static BakingOutput UV( Texture2D texture2D = null ) + { + return With( BakingTargetType.UV, texture2D ); + } + + public static BakingOutput ORM( Texture2D texture2D = null ) + { + return With( BakingTargetType.ORM, texture2D ); + } + + public bool IsType( BakingTargetType type, string customType = null ) + { + if ( type == BakingTargetType.Custom && bakingTarget.type == type ) + { + return bakingTarget.customType == customType; + } + + return type == bakingTarget.type; + } + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs.uid new file mode 100644 index 0000000..ceb0a7a --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/BakingOutput.cs.uid @@ -0,0 +1 @@ +uid://b75n4nbcvnu4c diff --git a/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs b/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs new file mode 100644 index 0000000..3624619 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs @@ -0,0 +1,35 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + public enum BakingTargetType + { + Albedo, + Normals, + Depth, + UV, + Lit, + Occlusion, + Roughness, + Metallic, + ORM, + Custom + } + + [Tool] + [GlobalClass] + public partial class BakingTarget:Resource + { + [Export] + public BakingTargetType type; + + [Export] + public string customType; + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs.uid new file mode 100644 index 0000000..8de0ab7 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/BakingTarget.cs.uid @@ -0,0 +1 @@ +uid://63mge3pjf5ir diff --git a/Runtime/Procedural/Baking/BakingMaterials/Normal/Normal Transfer.tres b/Runtime/Procedural/Baking/BakingMaterials/Normal/Normal Transfer.tres index bb42fd2..02bd6ad 100644 --- a/Runtime/Procedural/Baking/BakingMaterials/Normal/Normal Transfer.tres +++ b/Runtime/Procedural/Baking/BakingMaterials/Normal/Normal Transfer.tres @@ -1,6 +1,6 @@ [gd_resource type="Resource" script_class="MaterialTransfer" load_steps=3 format=3 uid="uid://h2ypphdx3inw"] -[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/MaterialTransfer.cs" id="1_0hco5"] +[ext_resource type="Script" uid="uid://drbmjiqfk51c3" path="res://addons/rokojori_action_library/Runtime/Shading/Materials/MaterialTransfer.cs" id="1_0hco5"] [ext_resource type="Resource" uid="uid://dgyihly620ymm" path="res://addons/rokojori_action_library/Runtime/Procedural/Baking/BakingMaterials/Normal/Normal From Standard.tres" id="2_cufcd"] [resource] diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs new file mode 100644 index 0000000..93e6573 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class LitBaker:_XX_MultiTextureBaker + { + [Export] + public LitBakingPass litBakingPass = new LitBakingPass(); + + protected override void _IntitializePasses() + { + _SetPasses( litBakingPass ); + } + + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs.uid new file mode 100644 index 0000000..86fa51b --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/Lit/LitBaker.cs.uid @@ -0,0 +1 @@ +uid://dn2fffnlg8wac diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs new file mode 100644 index 0000000..0cda7ed --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs @@ -0,0 +1,50 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class PBRBaker:_XX_MultiTextureBaker + { + [Export] + public AlbedoBakingPass albedoBakingPass = new AlbedoBakingPass(); + + [Export] + public NormalsBakingPass normalsBakingPass = new NormalsBakingPass(); + + [Export] + public ORMBakingPass ormBakingPass = new ORMBakingPass(); + + [Export] + public DepthBakingPass depthBakingPass = new DepthBakingPass(); + + [Export] + public UVBakingPass uvBakingPass = new UVBakingPass(); + + [Export] + public LitBakingPass litBakingPass = new LitBakingPass(); + + + protected override void _IntitializePasses() + { + _SetPasses( + albedoBakingPass, + normalsBakingPass, + ormBakingPass, + depthBakingPass, + uvBakingPass, + litBakingPass + ); + + litBakingPass.isEnabled = false; + depthBakingPass.isEnabled = false; + uvBakingPass.isEnabled = false; + } + + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs.uid new file mode 100644 index 0000000..68d7941 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Bakers/PBR/PBRBaker.cs.uid @@ -0,0 +1 @@ +uid://rojkq3fjdrvf diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs new file mode 100644 index 0000000..9a7807a --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs @@ -0,0 +1,105 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class AlbedoBakingPass: _XX_BakingPass + { + public AlbedoBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.Albedo() ]; + } + + protected override bool KeepsOriginalState() + { + return false; + } + + protected override bool KeepsCompositors() + { + return true; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.Albedo ); + + SetMaterial(); + + await multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( true, true ); + + Set( BakingTargetType.Albedo, texture ); + + return; + } + + public void SetMaterial() + { + Dictionary materials = new Dictionary(); + + Nodes.ForEach( multiBaker.X_bakingTargetContainer, + ( n )=> + { + SetMaterial( n, materials ); + } + ); + } + + void SetMaterial( Node3D n, Dictionary materials ) + { + var material = Materials.Get( n ); + + if ( material == null ) + { + n.LogInfo( "No material found" ); + return; + } + + if ( ! materials.ContainsKey( material ) ) + { + var appliedMaterial = new StandardMaterial3D(); + + if ( material is StandardMaterial3D sm ) + { + n.LogInfo( "StandardMaterial3D found" ); + + appliedMaterial.AlbedoColor = sm.AlbedoColor; + appliedMaterial.AlbedoTexture = sm.AlbedoTexture; + + appliedMaterial.Uv1Scale = sm.Uv1Scale; + appliedMaterial.Uv1Offset = sm.Uv1Offset; + + + appliedMaterial.Transparency = sm.Transparency; + appliedMaterial.AlphaScissorThreshold = sm.AlphaScissorThreshold; + appliedMaterial.AlphaAntialiasingMode = sm.AlphaAntialiasingMode; + appliedMaterial.AlphaAntialiasingEdge = sm.AlphaAntialiasingEdge; + + appliedMaterial.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded; + } + else + { + n.LogInfo( "No StandardMaterial3D found", material.GetType().Name ); + } + + + materials[ material ] = appliedMaterial; + } + + + Materials.Set( n, materials[ material ] ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs.uid new file mode 100644 index 0000000..015f443 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/AlbedoBakingPass.cs.uid @@ -0,0 +1 @@ +uid://0sm8nqqyogth diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs new file mode 100644 index 0000000..b80451e --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs @@ -0,0 +1,52 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class DepthBakingPass: _XX_BakingPass + { + public DepthBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.Depth() ]; + } + + protected override bool KeepsOriginalState() + { + return true; + } + + protected override bool KeepsCompositors() + { + return false; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.Depth ); + + multiBaker.AddCompositorEffect( new DepthViewEffect() ); + + await multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( true, false ); + + Set( BakingTargetType.Depth, texture ); + + return; + } + + void EnsureBakingOutputs() + { + bakingOutputs = [ BakingOutput.Lit() ]; + } + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs.uid new file mode 100644 index 0000000..c630a23 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/DepthBakingPass.cs.uid @@ -0,0 +1 @@ +uid://dqk8nmdbotxhc diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs new file mode 100644 index 0000000..cfaf631 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs @@ -0,0 +1,50 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class LitBakingPass: _XX_BakingPass + { + public LitBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.Lit() ]; + } + + protected override bool KeepsOriginalState() + { + return true; + } + + protected override bool KeepsCompositors() + { + return true; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.Lit ); + + await textureBaker.multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( true, true ); + + Set( BakingTargetType.Lit, texture ); + + return; + } + + void EnsureBakingOutputs() + { + bakingOutputs = [ BakingOutput.Lit() ]; + } + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs.uid new file mode 100644 index 0000000..319741c --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/LitBakingPass.cs.uid @@ -0,0 +1 @@ +uid://oqmyrtxqtk2x diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs new file mode 100644 index 0000000..6dda28a --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs @@ -0,0 +1,114 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class NormalsBakingPass: _XX_BakingPass + { + public NormalsBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.Normals() ]; + } + + protected override bool KeepsOriginalState() + { + return false; + } + + protected override bool KeepsCompositors() + { + return true; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.Normals ); + + SetNormalMaterial(); + + await multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( false, false ); + + Set( BakingTargetType.Normals, texture ); + + return; + } + + public void SetNormalMaterial() + { + Dictionary materials = new Dictionary(); + + Nodes.ForEach( multiBaker.X_bakingTargetContainer, + ( n )=> + { + SetMaterial( n, materials ); + } + ); + } + + + public static readonly CachedResource shader = new CachedResource( + "res://addons/rokojori_action_library/External/Imposter/materials/normal_baker.gdshader" + ); + + void SetMaterial( Node3D n, Dictionary materials ) + { + var material = Materials.Get( n ); + + if ( material == null ) + { + n.LogInfo( "No material found" ); + return; + } + + if ( ! materials.ContainsKey( material ) ) + { + var appliedMaterial = new ShaderMaterial(); + appliedMaterial.Shader = shader.Get(); + + + appliedMaterial.SetShaderParameter( "use_alpha_texture", true ); + + if ( material is StandardMaterial3D sm ) + { + n.LogInfo( "StandardMaterial3D found" ); + + appliedMaterial.SetShaderParameter( "use_normalmap", sm.NormalTexture != null ); + appliedMaterial.SetShaderParameter( "normal_texture", sm.NormalTexture ); + appliedMaterial.SetShaderParameter( "normal_scale", sm.NormalScale ); + + appliedMaterial.SetShaderParameter( "albedo_texture", sm.AlbedoTexture ); + appliedMaterial.SetShaderParameter( "albedo_color", sm.AlbedoColor ); + appliedMaterial.SetShaderParameter( "alpha_scissor_threshold", sm.AlphaScissorThreshold ); + + appliedMaterial.SetShaderParameter( "uv1_scale", sm.Uv1Scale ); + appliedMaterial.SetShaderParameter( "uv1_offset", sm.Uv1Offset ); + + appliedMaterial.SetShaderParameter( "uncompressNormalMap", false ); + appliedMaterial.SetShaderParameter( "useCustomNormals", true ); + } + else + { + n.LogInfo( "No StandardMaterial3D found", material.GetType().Name ); + } + + + materials[ material ] = appliedMaterial; + } + + + Materials.Set( n, materials[ material ] ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs.uid new file mode 100644 index 0000000..940a449 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/NormalsBakingPass.cs.uid @@ -0,0 +1 @@ +uid://dwmwibrf8rfux diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs new file mode 100644 index 0000000..ccfec61 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs @@ -0,0 +1,143 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class ORMBakingPass: _XX_BakingPass + { + public ORMBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.ORM() ]; + } + + protected override bool KeepsOriginalState() + { + return false; + } + + protected override bool KeepsCompositors() + { + return true; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.ORM ); + + SetMaterial(); + + await multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( false, false ); + + Set( BakingTargetType.ORM, texture ); + + return; + } + + public void SetMaterial() + { + Dictionary materials = new Dictionary(); + + Nodes.ForEach( multiBaker.X_bakingTargetContainer, + ( n )=> + { + SetMaterial( n, materials ); + } + ); + } + + + public static readonly CachedResource shader = new CachedResource( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader" + ); + + void SetChannel( string channel, ShaderMaterial material, Texture2D texture2D, int index ) + { + material.SetShaderParameter( "channelTexture" + channel, texture2D ); + material.SetShaderParameter( "gamma" + channel, 1.0f ); + + + var projection = Projection.Zero; + + if ( texture2D != null ) + { + projection[ index ] = new Vector4( + index == 0 ? 1:0, + index == 1 ? 1:0, + index == 2 ? 1:0, + 1 + ); + } + + + + + + material.SetShaderParameter( "colorMatrix" + channel, projection ); + } + + void SetMaterial( Node3D n, Dictionary materials ) + { + var material = Materials.Get( n ); + + if ( material == null ) + { + n.LogInfo( "No material found" ); + return; + } + + if ( ! materials.ContainsKey( material ) ) + { + var appliedMaterial = new ShaderMaterial(); + appliedMaterial.Shader = shader.Get(); + + if ( material is StandardMaterial3D sm ) + { + n.LogInfo( "StandardMaterial3D found" ); + + SetChannel( "A", appliedMaterial, sm.AOTexture, 0 ); + SetChannel( "B", appliedMaterial, sm.RoughnessTexture, 1 ); + SetChannel( "C", appliedMaterial, sm.MetallicTexture, 2 ); + + appliedMaterial.SetShaderParameter( "uv1_scale", sm.Uv1Scale ); + appliedMaterial.SetShaderParameter( "uv1_offset", sm.Uv1Offset ); + + // appliedMaterial.SetShaderParameter( "use_normalmap", sm.NormalTexture != null ); + // appliedMaterial.SetShaderParameter( "normal_texture", sm.NormalTexture ); + // appliedMaterial.SetShaderParameter( "normal_scale", sm.NormalScale ); + + // appliedMaterial.SetShaderParameter( "albedo_texture", sm.AlbedoTexture ); + // appliedMaterial.SetShaderParameter( "albedo_color", sm.AlbedoColor ); + // appliedMaterial.SetShaderParameter( "alpha_scissor_threshold", sm.AlphaScissorThreshold ); + + // appliedMaterial.SetShaderParameter( "uv1_scale", sm.Uv1Scale ); + // appliedMaterial.SetShaderParameter( "uv1_offset", sm.Uv1Offset ); + + // appliedMaterial.SetShaderParameter( "uncompressNormalMap", false ); + // appliedMaterial.SetShaderParameter( "useCustomNormals", true ); + } + else + { + n.LogInfo( "No StandardMaterial3D found", material.GetType().Name ); + } + + + materials[ material ] = appliedMaterial; + } + + + Materials.Set( n, materials[ material ] ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs.uid new file mode 100644 index 0000000..1804502 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/ORMBakingPass.cs.uid @@ -0,0 +1 @@ +uid://wtsyw4idd6nb diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs new file mode 100644 index 0000000..a330094 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs @@ -0,0 +1,101 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class UVBakingPass: _XX_BakingPass + { + public UVBakingPass():base(){} + + protected override void CreateBakingOutputs() + { + bakingOutputs = [ BakingOutput.UV() ]; + } + + protected override bool KeepsOriginalState() + { + return false; + } + + protected override bool KeepsCompositors() + { + return true; + } + + protected override async Task _Bake() + { + Clear( BakingTargetType.UV ); + + SetMaterial(); + + await multiBaker.RequestNextFrame(); + + var texture = await GrabDilatedTexture( false, false ); + + Set( BakingTargetType.UV, texture ); + + return; + } + + public void SetMaterial() + { + Dictionary materials = new Dictionary(); + + Nodes.ForEach( multiBaker.X_bakingTargetContainer, + ( n )=> + { + SetMaterial( n, materials ); + } + ); + } + + public static readonly CachedResource shader = new CachedResource( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Baking/UVBaker.gdshader" + ); + + + void SetMaterial( Node3D n, Dictionary materials ) + { + var material = Materials.Get( n ); + + if ( material == null ) + { + n.LogInfo( "No material found" ); + return; + } + + if ( ! materials.ContainsKey( material ) ) + { + var appliedMaterial = new ShaderMaterial(); + appliedMaterial.Shader = shader.Get(); + + if ( material is StandardMaterial3D sm ) + { + n.LogInfo( "StandardMaterial3D found" ); + + appliedMaterial.SetShaderParameter( "uv1_scale", sm.Uv1Scale ); + appliedMaterial.SetShaderParameter( "uv1_offset", sm.Uv1Offset ); + + } + else + { + n.LogInfo( "No StandardMaterial3D found", material.GetType().Name ); + } + + + materials[ material ] = appliedMaterial; + } + + + Materials.Set( n, materials[ material ] ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs.uid new file mode 100644 index 0000000..2e17a6e --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/TextureBakers/Passes/UVBakingPass.cs.uid @@ -0,0 +1 @@ +uid://dwrqxwtundxgk diff --git a/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs b/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs new file mode 100644 index 0000000..7f10e3f --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs @@ -0,0 +1,168 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; +using System.Runtime.CompilerServices; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class _XX_BakingPass:Resource + { + [Export] + public bool isEnabled = true; + + public _XX_BakingPass() + { + CreateBakingOutputs(); + } + + protected virtual bool KeepsOriginalState() + { + return false; + } + + protected virtual bool KeepsCompositors() + { + return false; + } + + protected virtual void CreateBakingOutputs() + { + + } + + protected virtual async Task _Bake() + { + return; + } + + + public async Task Bake() + { + if ( bakingOutputs == null || bakingOutputs.Length == 0 ) + { + CreateBakingOutputs(); + } + + await _Bake(); + + if ( ! KeepsOriginalState() ) + { + textureBaker.multiBaker.SetTargetDirty(); + } + + if ( ! KeepsCompositors() ) + { + textureBaker.multiBaker.SetCompositorsDirty(); + } + + return; + } + + public async Task GrabDilatedTexture( bool srgb, bool alpha, bool mipmaps = true ) + { + var texture = await textureBaker.multiBaker.GrabDilatedTexture( srgb, alpha, mipmaps ); + return texture; + } + + public _XX_MultiTextureBaker textureBaker; + + public MultiBaker multiBaker => textureBaker.multiBaker; + + [Export] + public BakingOutput[] bakingOutputs = []; + + public static Texture2D Get( List<_XX_BakingPass> passes, params BakingTargetType[] bakingTargetType ) + { + for ( int i = 0 ; i < bakingTargetType.Length; i++ ) + { + var t = Get( passes, bakingTargetType[ i ] ); + + if ( t != null ) + { + return t; + } + } + + return null; + } + + protected void Clear( BakingTargetType type, string customType = null ) + { + Set( type, customType, null ); + } + + protected void Set( BakingTargetType type, Texture2D texture2D ) + { + var index = Array.Find( bakingOutputs, b => b.IsType( type, null ) ); + + if ( index == null ) + { + return; + } + + index.bakedTexture = texture2D; + } + + protected void Set( BakingTargetType type, string customType, Texture2D texture2D ) + { + var index = Array.Find( bakingOutputs, b => b.IsType( type, customType ) ); + + if ( index == null ) + { + return; + } + + index.bakedTexture = texture2D; + } + + public static Texture2D Get( List<_XX_BakingPass> passes, string customType = null ) + { + return Get( passes, BakingTargetType.Custom, customType ); + } + + public static Texture2D Get( List<_XX_BakingPass> passes, BakingTargetType bakingTargetType, string customType = null ) + { + + var pass = passes.Find( p => p.ContainsBakingOutput( bakingTargetType ) ); + + if ( pass == null ) + { + return null; + } + + var output = Array.Find( pass.bakingOutputs, p => p.IsType( bakingTargetType, customType ) ); + + if ( output == null ) + { + return null; + } + + return output.bakedTexture; + } + + + public bool ContainsBakingOutput( BakingTargetType bakingTargetType, string customType = null ) + { + for ( int i = 0; i < bakingOutputs.Length; i++ ) + { + if ( bakingOutputs[ i ].bakingTarget.type == bakingTargetType ) + { + if ( bakingTargetType == BakingTargetType.Custom ) + { + return customType == bakingOutputs[ i ].bakingTarget.customType; + } + + return true; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs.uid new file mode 100644 index 0000000..0090b04 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/_XX_BakingPass.cs.uid @@ -0,0 +1 @@ +uid://du0r1hyfhie6j diff --git a/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs b/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs new file mode 100644 index 0000000..b797cc9 --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs @@ -0,0 +1,48 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; +using System.Threading.Tasks; + + + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class _XX_MultiTextureBaker:Resource + { + protected MultiBaker _multiBaker; + public MultiBaker multiBaker => _multiBaker; + + protected List<_XX_BakingPass> _passes; + + protected void _SetPasses( params _XX_BakingPass[] passes ) + { + _passes = [.. passes]; + + _passes.ForEach( p => p.textureBaker = this ); + } + + protected virtual void _IntitializePasses() + { + + } + + + public List<_XX_BakingPass> GetPasses( MultiBaker multiBaker ) + { + _multiBaker = multiBaker; + + if ( _passes != null ) + { + return Lists.Filter( _passes, p => p.isEnabled ); + } + + _IntitializePasses(); + + return Lists.Filter( _passes, p => p.isEnabled ); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs.uid b/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs.uid new file mode 100644 index 0000000..2257e1e --- /dev/null +++ b/Runtime/Procedural/Baking/BakingMaterials/_XX_MultiTextureBaker.cs.uid @@ -0,0 +1 @@ +uid://dtpu1n5h6j61t diff --git a/Runtime/Procedural/Baking/MultiBaker/CrossBraces_Baker.cs b/Runtime/Procedural/Baking/MultiBaker/CrossBraces_Baker.cs index 17f842e..817cbc4 100644 --- a/Runtime/Procedural/Baking/MultiBaker/CrossBraces_Baker.cs +++ b/Runtime/Procedural/Baking/MultiBaker/CrossBraces_Baker.cs @@ -49,7 +49,7 @@ namespace Rokojori var outputScale = multiBaker.GetOutputScale(); RJLog.Log( "outputScale", outputScale ); - var _bakers = multiBaker.bakers; + var _bakers = multiBaker.bakerCameras; var mb = multiBaker; diff --git a/Runtime/Procedural/Baking/MultiBaker/Cylinder_Baker.cs b/Runtime/Procedural/Baking/MultiBaker/Cylinder_Baker.cs index 0eaa76b..bc1ae50 100644 --- a/Runtime/Procedural/Baking/MultiBaker/Cylinder_Baker.cs +++ b/Runtime/Procedural/Baking/MultiBaker/Cylinder_Baker.cs @@ -53,11 +53,11 @@ namespace Rokojori var distance = multiBaker.GetCameraDistance(); var outputScale = multiBaker.GetOutputScale(); - var _bakers = multiBaker.bakers; + var bakerCameras = multiBaker.bakerCameras; var mb = multiBaker; - _bakers.ForEach( + bakerCameras.ForEach( bk => { var vs = bk.viewSettings; @@ -75,13 +75,13 @@ namespace Rokojori if ( cylinderTop ) { - _bakers[ index ].viewSettings.yaw = 0; - _bakers[ index ].viewSettings.pitch = 90f; + bakerCameras[ index ].viewSettings.yaw = 0; + bakerCameras[ index ].viewSettings.pitch = 90f; var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true ); var q = new MeshGeometry(); - q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); + q.AddQuad( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); if ( cylinderTopOffset != 0 ) @@ -103,13 +103,13 @@ namespace Rokojori if ( cylinderBottom ) { - _bakers[ index ].viewSettings.yaw = 0; - _bakers[ index ].viewSettings.pitch = -90f; + bakerCameras[ index ].viewSettings.yaw = 0; + bakerCameras[ index ].viewSettings.pitch = -90f; var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true ); var q = new MeshGeometry(); - q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); + q.AddQuad( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); if ( cylinderBottomOffset != 0 ) { @@ -132,18 +132,18 @@ namespace Rokojori for ( int i = 0; i < cylinderSides; i++ ) { var angle = ( 360f * i ) / (float) cylinderSides; - _bakers[ index ].viewSettings.yaw = angle; - _bakers[ index ].viewSettings.pitch = 0; + bakerCameras[ index ].viewSettings.yaw = angle; + bakerCameras[ index ].viewSettings.pitch = 0; var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true ); var q = new MeshGeometry(); - q.AddQuad( _bakers[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); + q.AddQuad( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); if ( cylinderSideOffset != 0 ) { - var sideOffset = Vector3.Forward *_bakers[ index ].viewSettings.bakingRotation * cylinderSideOffset * outputScale * -0.5f; + var sideOffset = Vector3.Forward *bakerCameras[ index ].viewSettings.bakingRotation * cylinderSideOffset * outputScale * -0.5f; q.ApplyTranslation( sideOffset, -4 ); } diff --git a/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs b/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs new file mode 100644 index 0000000..8d65144 --- /dev/null +++ b/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs @@ -0,0 +1,70 @@ +using System.Collections; +using System.Collections.Generic; +using Godot; +using System; + +using System.Threading.Tasks; + +namespace Rokojori +{ + [Tool][GlobalClass] + public partial class Flat_Baker:_XX_MultiBakeModeBillboardBase + { + [Export] + public float yawOffset = 0; + + public override int GetNumViews() + { + return 2; + } + + public override void CreateBakers() + { + var fov = multiBaker.GetCameraFOV(); + var distance = multiBaker.GetCameraDistance(); + var outputScale = multiBaker.GetOutputScale(); + + RJLog.Log( "outputScale", outputScale ); + var bakerCameras = multiBaker.bakerCameras; + var mb = multiBaker; + + + bakerCameras.ForEach( + bk => + { + var vs = bk.viewSettings; + vs.fovDistance = Manual_BakingFDSettings.Create( fov, distance ); + vs.rotationMode = BakingViewSettings.RotationMode.Yaw_Pitch; + } + ); + + var mg = new MeshGeometry(); + + var numTextures = GetNumViews(); + var textureAlignment = TextureMerger.ComputeTextureAlignment( numTextures ); + + + var angle = yawOffset; + + for ( int i = 0; i < numTextures; i++ ) + { + var index = i; + + bakerCameras[ index ].viewSettings.yaw = angle + i * 180f; + bakerCameras[ index ].viewSettings.pitch = 0; + + var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true ); + + var q = new MeshGeometry(); + q.AddQuad( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max ); + + mg.Add( q ); + + } + + + mb.X_outputMesh.Mesh = mg.GenerateMesh(); + } + + } +} \ No newline at end of file diff --git a/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs.uid b/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs.uid new file mode 100644 index 0000000..36d00f3 --- /dev/null +++ b/Runtime/Procedural/Baking/MultiBaker/Flat_Baker.cs.uid @@ -0,0 +1 @@ +uid://b4d382v6hcer3 diff --git a/Runtime/Procedural/Baking/MultiBaker/MultiBaker.cs b/Runtime/Procedural/Baking/MultiBaker/MultiBaker.cs index 62cc5be..37a8653 100644 --- a/Runtime/Procedural/Baking/MultiBaker/MultiBaker.cs +++ b/Runtime/Procedural/Baking/MultiBaker/MultiBaker.cs @@ -4,6 +4,7 @@ using Godot; using System; using System.Threading.Tasks; +using System.Linq; namespace Rokojori { @@ -26,21 +27,28 @@ namespace Rokojori Simple_Prebaked } - [ExportGroup("Material")] - [Export] - public MaterialMode materialMode; + // [ExportGroup("Textures")] [Export] - public int dilationRadius = 64; - [ExportGroup("Material/Full Seperated")] - [Export] - public bool mmfs_Normals = true; - [Export] - public bool mmfs_Depth = true; - [Export] - public bool mmfs_ORM = true; + public _XX_MultiTextureBaker textureBaker; + // [Export] + // public MaterialMode materialMode; + + // [Export] + // public int dilationRadius = 64; + // [ExportGroup("Material/Full Seperated")] + // [Export] + // public bool mmfs_Normals = true; + // [Export] + // public bool mmfs_Depth = true; + // [Export] + // public bool mmfs_ORM = true; + + [Export] + public BakingViewSettings viewSettings; + [ExportGroup( "Object")] [Export] @@ -53,11 +61,8 @@ namespace Rokojori public Vector3 targetPivot; - - [ExportGroup( "Camera")] - [Export] - public BakingViewSettings viewSettings; + public float cameraZoom { @@ -78,27 +83,6 @@ namespace Rokojori } } - /* - [Export] - public Baker.CameraDistanceDetectionType distanceDetectionType = Baker.CameraDistanceDetectionType.Automatic_Distance_Detection; - - [Export] - public float customDistance = 50; - - [Export] - public float cameraZoom = 1; - - [Export] - public Baker.CameraFOVMode fovMode = Baker.CameraFOVMode.Compute_Fov_With_Distance; - [Export] - public float originalFOV = 75; - [Export] - public float fovPlacingDistance = 200; - [Export] - public float customFOV = 75; - */ - - [ExportGroup( "Output")] @@ -178,7 +162,7 @@ namespace Rokojori Nodes.RemoveAndDeleteChildren( this ); - _bakers = null; + _bakerCameras = null; X_bakingViewport = this.CreateChild( "Multi Baker Viewport" ); @@ -197,7 +181,7 @@ namespace Rokojori X_textureMerger = this.CreateChild( "Texture Merger" ); X_textureMerger.multiBaker = this; - X_textureMerger.dilationRadius = dilationRadius; + // X_textureMerger.dilationRadius = dilationRadius; X_textureMerger.Initialize(); X_textureDilate = this.CreateChild( "Texture Dilate" ); @@ -223,6 +207,70 @@ namespace Rokojori } + public async Task GrabDilatedTexture( bool srgb, bool alpha, bool mipmaps ) + { + X_textureDilate.viewport = X_textureMerger.X_textureMergerViewport; + var maxRadius = X_textureMerger.GetMaxTextureDimension() / 2; + X_textureDilate.SetDilationRadius( maxRadius ); + var texture = await X_textureDilate.Grab( srgb, alpha, mipmaps ); + + return texture; + } + + bool _targetIsInInitialState = false; + + public void SetTargetDirty() + { + _targetIsInInitialState = false; + } + + public void ResetOriginalTargetState() + { + if ( _targetIsInInitialState ) + { + return; + } + + // _bakerCameras.ForEach( b => b.viewport.en) + + Nodes.RemoveAndDeleteChildren( X_bakingTargetContainer ); + target.DeepCopyTo( X_bakingTargetContainer ); + + _targetIsInInitialState = true; + + return; + } + + + bool _compositorsClean = false; + + public void SetCompositorsDirty() + { + _compositorsClean = false; + } + + + public void ResetCompositorStates() + { + X_worldEnvironment.Compositor = null; + _compositorsClean = true; + } + + public void AddCompositorEffect( CompositorEffect compositorEffect ) + { + if ( X_worldEnvironment.Compositor == null ) + { + X_worldEnvironment.Compositor = new Compositor(); + } + + var compositorEffects = X_worldEnvironment.Compositor.CompositorEffects; + compositorEffects.Add( compositorEffect ); + + X_worldEnvironment.Compositor.CompositorEffects = compositorEffects; + + _compositorsClean = false; + } + public async Task Bake() { @@ -238,109 +286,118 @@ namespace Rokojori { bakeMode.multiBaker = this; + _targetIsInInitialState = false; + this.LogInfo( "Started baking" ); - Nodes.RemoveAndDeleteChildren( X_bakingTargetContainer ); - target.DeepCopyTo( X_bakingTargetContainer ); + ResetOriginalTargetState(); - if ( _bakers == null || _bakers.Count != GetNumViews() ) + if ( _bakerCameras == null || _bakerCameras.Count != GetNumViews() ) { - CreateViews(); + CreateBakerCameras(); await this.RequestNextFrame(); } - SetupViews(); + SetupBakerCameras(); - this.LogInfo( "Views set up" ); + this.LogInfo( "Bake Cameras set up" ); await this.RequestNextFrame(); - - X_setBakingMaterials.SetTarget( X_bakingTargetContainer ); - - var bakingMaterialModes = new List(); - - var preview_QuickMaterial = MaterialMode.Simple_Prebaked == materialMode; - - bakeMode.CreateMaterial( preview_QuickMaterial ); + this.LogInfo( "Render passes" ); + var passes = textureBaker.GetPasses( this ); - if ( preview_QuickMaterial ) - { - bakingMaterialModes.Add( BakingMaterialMode.Preview ); - } - else - { - bakingMaterialModes.Add( BakingMaterialMode.Albedo ); + // X_setBakingMaterials.SetTarget( X_bakingTargetContainer ); - if ( mmfs_Normals ) - { - bakingMaterialModes.Add( BakingMaterialMode.Normals ); - } + // var bakingMaterialModes = new List(); - if ( mmfs_Depth ) - { - bakingMaterialModes.Add( BakingMaterialMode.Depth ); - } + // var preview_QuickMaterial = MaterialMode.Simple_Prebaked == materialMode; - if ( mmfs_ORM ) - { - bakingMaterialModes.Add( BakingMaterialMode.ORM ); - } - } + // bakeMode.CreateMaterial( preview_QuickMaterial ); + + bakeMode.CreateMaterial( passes ); + + // if ( preview_QuickMaterial ) + // { + // bakingMaterialModes.Add( BakingMaterialMode.Preview ); + // } + // else + // { + // bakingMaterialModes.Add( BakingMaterialMode.Albedo ); + + // if ( mmfs_Normals ) + // { + // bakingMaterialModes.Add( BakingMaterialMode.Normals ); + // } + + // if ( mmfs_Depth ) + // { + // bakingMaterialModes.Add( BakingMaterialMode.Depth ); + // } + + // if ( mmfs_ORM ) + // { + // bakingMaterialModes.Add( BakingMaterialMode.ORM ); + // } + // } this.LogInfo( "Prepared baking modes" ); X_textureMerger.textureSize = outputTextureSize; X_textureMerger.Initialize(); X_textureMerger.CreateLayout(); - this.LogInfo( "Prepared texture merger" ); + + // this.LogInfo( "Prepared texture merger" ); // var fovDistance = viewSettings.fovDistance.ComputeFOVDistance( - var objectDistance = GetCameraDistance(); + // var objectDistance = GetCameraDistance(); - this.LogInfo( "Set Camera Distance", objectDistance ); - for ( int i = 0; i < bakingMaterialModes.Count; i++ ) - { - this.LogInfo( "Baking mode:", bakingMaterialModes[ i ] ); - X_setBakingMaterials.mode = bakingMaterialModes[ i ]; - X_setBakingMaterials.ApplyBakingMaterials( objectDistance, _targetBoundingSphere.radius ); + // this.LogInfo( "Set Camera Distance", objectDistance ); - this.LogInfo( "Materials changed:", bakingMaterialModes[ i ] ); - - _bakers.ForEach( b => b.Bake() ); + for ( int i = 0; i < passes.Count; i++ ) + { + ResetOriginalTargetState(); + + _bakerCameras.ForEach( b => b.ApplyCameraSettings() ); + await passes[ i ].Bake(); await this.RequestNextFrame(); - // Texture2D texture = X_textureMerger.X_textureMergerViewport.GetTexture(); + } - // this.LogInfo( "Texture created:", bakingMaterialModes[ i ] ); + bakeMode.AssignMaterial( passes ); - // await this.RequestNextFrame(); + // for ( int i = 0; i < bakingMaterialModes.Count; i++ ) + // { + // this.LogInfo( "Baking mode:", bakingMaterialModes[ i ] ); + // X_setBakingMaterials.mode = bakingMaterialModes[ i ]; + // X_setBakingMaterials.ApplyBakingMaterials( objectDistance, _targetBoundingSphere.radius ); - X_textureDilate.viewport = X_textureMerger.X_textureMergerViewport; - Texture2D texture = await X_textureDilate.Grab(); + // this.LogInfo( "Materials changed:", bakingMaterialModes[ i ] ); + + // _bakers.ForEach( b => b.ApplyCameraSettings() ); + + // await this.RequestNextFrame(); + + // X_textureDilate.viewport = X_textureMerger.X_textureMergerViewport; + // Texture2D texture = await X_textureDilate.Grab(); - this.LogInfo( "Assigning Texture", bakingMaterialModes[ i ] ); - bakeMode.AssignMaterial( bakingMaterialModes[ i ], texture ); + // this.LogInfo( "Assigning Texture", bakingMaterialModes[ i ] ); + // bakeMode.AssignMaterial( bakingMaterialModes[ i ], texture ); - this.LogInfo( "Baking done:", bakingMaterialModes[ i ] ); + // this.LogInfo( "Baking done:", bakingMaterialModes[ i ] ); - await this.RequestNextFrame(); + // await this.RequestNextFrame(); - } + // } - await this.RequestNextFrame(); + // await this.RequestNextFrame(); X_outputMesh.GlobalPosition = target.GlobalPosition - targetPivot; X_outputMesh.Scale = Vector3.One * cameraZoom; - if ( cleanUpAfterBaking ) - { - this.LogInfo( "Cleaning Up" ); - CleanUp(); - } - + this.LogInfo( "All Baking done" ); } @@ -350,6 +407,13 @@ namespace Rokojori this.LogError( e ); } + if ( cleanUpAfterBaking ) + { + this.LogInfo( "Cleaning Up" ); + CleanUp(); + } + + X_baking = false; return; @@ -360,26 +424,26 @@ namespace Rokojori return Nodes.AllIn( X_views, null, false ); } - public void CacheTexture( BakingMaterialMode mode, Texture2D texture ) - { - if ( BakingMaterialMode.Albedo == mode ) - { - X_bakedTextureAlbedo = texture; - } - else if ( BakingMaterialMode.Normals == mode ) - { - X_bakedTextureNormal = texture; - } - else if ( BakingMaterialMode.ORM == mode ) - { - X_bakedTextureORM = texture; - } - else if ( BakingMaterialMode.Depth == mode ) - { - X_bakedTextureDepth = texture; - } + // public void CacheTexture( BakingMaterialMode mode, Texture2D texture ) + // { + // if ( BakingMaterialMode.Albedo == mode ) + // { + // X_bakedTextureAlbedo = texture; + // } + // else if ( BakingMaterialMode.Normals == mode ) + // { + // X_bakedTextureNormal = texture; + // } + // else if ( BakingMaterialMode.ORM == mode ) + // { + // X_bakedTextureORM = texture; + // } + // else if ( BakingMaterialMode.Depth == mode ) + // { + // X_bakedTextureDepth = texture; + // } - } + // } public void CleanUp() { @@ -398,6 +462,8 @@ namespace Rokojori X_textureMerger = null; + X_textureDilate = null; + X_setBakingMaterials = null; X_texturePreview = null; @@ -424,21 +490,24 @@ namespace Rokojori return bakeMode.GetNumViews(); } - List _bakers; + List _bakerCameras; - public List bakers => _bakers; + public List bakerCameras => _bakerCameras; - public void CreateViews() + public void CreateBakerCameras() { Nodes.RemoveAndDeleteChildren( X_views ); var numViews = GetNumViews(); - _bakers = new List(); + _bakerCameras = new List(); - var minViewsPerAxis = TextureMerger.ComputeTextureAlignment( numViews ).Y; + var alginment = TextureMerger.ComputeTextureAlignment( numViews ); + var minViewsPerAxis = Mathf.Max( alginment.X, alginment.Y ); + this.LogInfo( "Size per Baker:", "nv", numViews, "al", alginment, "mvpa", minViewsPerAxis,"s", (Vector2I) ( outputTextureSize / minViewsPerAxis ) ); + for ( int i = 0; i < numViews; i++ ) { var userIndex = ( i + 1 ); @@ -452,15 +521,17 @@ namespace Rokojori baker.camera = bakingCamera; baker.target = X_bakingTargetContainer; baker.viewport = bakingView; + baker.viewport.Msaa3D = Viewport.Msaa.Msaa8X; + - _bakers.Add( baker ); + _bakerCameras.Add( baker ); } } - public void SetupViews() + public void SetupBakerCameras() { var numViews = GetNumViews(); var minViewsPerAxis = TextureMerger.ComputeTextureAlignment( numViews ).Y; @@ -469,7 +540,7 @@ namespace Rokojori for ( int i = 0; i < numViews; i++ ) { - var baker = _bakers[ i ]; + var baker = _bakerCameras[ i ]; var bakingView = baker.viewport as SubViewport; bakingView.Size = (Vector2I) ( outputTextureSize / minViewsPerAxis ); } @@ -532,9 +603,21 @@ namespace Rokojori _targetBoundingBox = X_bakingTargetContainer.GetWorldBounds(); + if ( _targetBoundingBox == null ) + { + return; + } + if ( autoTargetPivot ) { Box3 box = target.GetWorldBounds(); + + if ( box == null ) + { + _targetBoundingSphere = null; + return; + } + targetPivot = new Vector3( 0, -box.center.Y, 0 ); } diff --git a/Runtime/Procedural/Baking/MultiBaker/Octahedral_Baker.cs b/Runtime/Procedural/Baking/MultiBaker/Octahedral_Baker.cs index cd90ca9..1a65cd1 100644 --- a/Runtime/Procedural/Baking/MultiBaker/Octahedral_Baker.cs +++ b/Runtime/Procedural/Baking/MultiBaker/Octahedral_Baker.cs @@ -27,7 +27,7 @@ namespace Rokojori return views; } - public override void CreateMaterial( bool preview ) + public override void CreateMaterial( List<_XX_BakingPass> passes ) { var mb = multiBaker; var material = new ShaderMaterial(); @@ -39,11 +39,10 @@ namespace Rokojori Materials.Set( mb.X_outputMesh, material ); } - public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture ) + public override void AssignMaterial( List<_XX_BakingPass> passes ) { var mb = multiBaker; - mb.CacheTexture( mode, texture ); - + var material = Materials.Get( mb.X_outputMesh ); if ( material == null ) @@ -52,23 +51,18 @@ namespace Rokojori return; } - if ( BakingMaterialMode.Albedo == mode || BakingMaterialMode.Preview == mode ) - { - material.SetShaderParameter( "imposterTextureAlbedo", texture ); - } - else if ( BakingMaterialMode.Normals == mode ) - { - material.SetShaderParameter( "imposterTextureNormal", texture ); - } - else if ( BakingMaterialMode.ORM == mode ) - { - material.SetShaderParameter( "imposterTextureOrm", texture ); - } - else if ( BakingMaterialMode.Depth == mode ) - { - material.SetShaderParameter( "imposterTextureDepth", texture ); - } + + material.SetShaderParameter( "imposterTextureAlbedo", + _XX_BakingPass.Get( passes, BakingTargetType.Albedo, BakingTargetType.Lit ) ); + + material.SetShaderParameter( "imposterTextureNormal", + _XX_BakingPass.Get( passes, BakingTargetType.Normals ) ); + material.SetShaderParameter( "imposterTextureOrm", + _XX_BakingPass.Get( passes, BakingTargetType.ORM ) ); + + material.SetShaderParameter( "imposterTextureDepth", + _XX_BakingPass.Get( passes, BakingTargetType.Depth ) ); } @@ -78,7 +72,7 @@ namespace Rokojori var distance = multiBaker.GetCameraDistance(); var outputScale = multiBaker.GetOutputScale(); - var _bakers = multiBaker.bakers; + var _bakers = multiBaker.bakerCameras; var mb = multiBaker; diff --git a/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeMode.cs b/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeMode.cs index 33b63ea..1ee3710 100644 --- a/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeMode.cs +++ b/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeMode.cs @@ -22,12 +22,12 @@ namespace Rokojori } - public virtual void AssignMaterial( BakingMaterialMode mode, Texture2D texture ) + public virtual void AssignMaterial( List<_XX_BakingPass> passes ) { - + } - public virtual void CreateMaterial( bool preview ) + public virtual void CreateMaterial( List<_XX_BakingPass> passes ) { } diff --git a/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeModeBillboardBase.cs b/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeModeBillboardBase.cs index b0a9786..a5beb40 100644 --- a/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeModeBillboardBase.cs +++ b/Runtime/Procedural/Baking/MultiBaker/_XX_MultiBakeModeBillboardBase.cs @@ -10,44 +10,50 @@ namespace Rokojori [Tool][GlobalClass] public partial class _XX_MultiBakeModeBillboardBase:_XX_MultiBakeMode { - public override void CreateMaterial( bool preview ) + public override void CreateMaterial( List<_XX_BakingPass> passes ) { + var preview = passes.Find( p => p.ContainsBakingOutput( BakingTargetType.Albedo ) ) == null; + var mb = multiBaker; var material = new StandardMaterial3D(); material.ShadingMode = preview ? BaseMaterial3D.ShadingModeEnum.Unshaded : BaseMaterial3D.ShadingModeEnum.PerPixel; material.Transparency = BaseMaterial3D.TransparencyEnum.AlphaScissor; - material.AlphaScissorThreshold = 0.5f; + material.AlphaScissorThreshold = 0.01f; material.AlphaAntialiasingMode = BaseMaterial3D.AlphaAntiAliasing.AlphaToCoverageAndToOne; - material.AlphaAntialiasingEdge = 0.3f; + material.AlphaAntialiasingEdge = 0.95f; material.NormalEnabled = ! preview; Materials.Set( mb.X_outputMesh, material ); } - public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture ) + public override void AssignMaterial( List<_XX_BakingPass> passes ) { var mb = multiBaker; - mb.CacheTexture( mode, texture ); - var material = Materials.Get( mb.X_outputMesh ); - if ( BakingMaterialMode.Albedo == mode || BakingMaterialMode.Preview == mode ) - { - RJLog.Log( "Assign albedo" ); - material.AlbedoTexture = texture; - } - else if ( BakingMaterialMode.Normals == mode ) - { - RJLog.Log( "Assign normal" ); - material.NormalTexture = texture; - } - else if ( BakingMaterialMode.ORM == mode ) - { - material.OrmTexture = texture; - } + material.AlbedoTexture = _XX_BakingPass.Get( passes, BakingTargetType.Albedo, BakingTargetType.Lit ); + material.NormalTexture = _XX_BakingPass.Get( passes, BakingTargetType.Normals ); + + + material.AOTexture = _XX_BakingPass.Get( passes, BakingTargetType.ORM ); + material.RoughnessTexture = _XX_BakingPass.Get( passes, BakingTargetType.ORM ); + material.MetallicTexture = _XX_BakingPass.Get( passes, BakingTargetType.ORM ); + material.AOEnabled = true; + + material.AOLightAffect = 1; + + material.AOTextureChannel = BaseMaterial3D.TextureChannel.Red; + material.RoughnessTextureChannel = BaseMaterial3D.TextureChannel.Green; + material.MetallicTextureChannel = BaseMaterial3D.TextureChannel.Blue; + + material.MetallicSpecular = 0; + + // material.Anisotropy = 1; + // material.AnisotropyEnabled = true; + material.TextureFilter = BaseMaterial3D.TextureFilterEnum.LinearWithMipmapsAnisotropic; } } diff --git a/Runtime/Procedural/Baking/MultiBaker/_XX_Spherical_Baker.cs b/Runtime/Procedural/Baking/MultiBaker/_XX_Spherical_Baker.cs index e2eccd3..2ddb1b3 100644 --- a/Runtime/Procedural/Baking/MultiBaker/_XX_Spherical_Baker.cs +++ b/Runtime/Procedural/Baking/MultiBaker/_XX_Spherical_Baker.cs @@ -29,12 +29,12 @@ namespace Rokojori return views; } - public override void CreateMaterial( bool preview ) + public override void CreateMaterial( List<_XX_BakingPass> passes ) { } - public override void AssignMaterial( BakingMaterialMode mode, Texture2D texture ) + public override void AssignMaterial( List<_XX_BakingPass> passes ) { } diff --git a/Runtime/Procedural/Baking/SetBakingMaterials.cs b/Runtime/Procedural/Baking/SetBakingMaterials.cs index 4b32186..7afc3ff 100644 --- a/Runtime/Procedural/Baking/SetBakingMaterials.cs +++ b/Runtime/Procedural/Baking/SetBakingMaterials.cs @@ -1,7 +1,6 @@ using System.Collections; using System.Collections.Generic; using Godot; -using System; @@ -9,7 +8,7 @@ namespace Rokojori { [Tool] [GlobalClass] - public partial class SetBakingMaterials:Node + public partial class SetBakingMaterials:Action { [Export] public Node targetContainer; @@ -17,8 +16,20 @@ namespace Rokojori [Export] public BakingMaterialMode mode; + [Export] + public float distance; + + [Export] + public float radius; + MapList _originalMaterials; + protected override void _OnTrigger() + { + SetTarget( targetContainer ); + ApplyBakingMaterials( distance, radius ); + } + public void SetTarget( Node targetContainer ) { _originalMaterials = new MapList(); diff --git a/Runtime/Procedural/Baking/TextureDilate.cs b/Runtime/Procedural/Baking/TextureDilate.cs index ff2a0cb..735d03c 100644 --- a/Runtime/Procedural/Baking/TextureDilate.cs +++ b/Runtime/Procedural/Baking/TextureDilate.cs @@ -22,15 +22,28 @@ namespace Rokojori [Export( PropertyHint.Range, "0,15" ) ] public int steps = 0; + [Export] + public bool useSRGB = true; + [ExportToolButton( "Grab Texture")] public Callable GrabButton => Callable.From( () => { - Grab(); + Grab( useSRGB, true ); } ); - public async Task Grab() + public void SetDilationRadius( int pixelSize ) + { + steps = ( Mathf.RoundToInt( MathX.Exponent( 2, pixelSize ) ) - 1 ); + } + + public void SetDilationRadius( Vector2 size ) + { + SetDilationRadius( Mathf.RoundToInt( Mathf.Max( size.X, size.Y ) ) ); + } + + public async Task Grab( bool srgb, bool alpha, bool mipmaps = false ) { var updateMode = viewport.RenderTargetUpdateMode; @@ -50,7 +63,7 @@ namespace Rokojori this.LogInfo( "Creating context" ); var ctx = RDContext.Local(); ctx.computeSize = viewPortSize; - ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); + // ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose ); this.LogInfo( "Creating textures" ); @@ -90,13 +103,13 @@ namespace Rokojori var gammaConversion = 0; - if ( RenderingDevice.DataFormat.R16G16B16A16Sfloat == viewPortFormat ) + if ( RenderingDevice.DataFormat.R16G16B16A16Sfloat == viewPortFormat && srgb ) { gammaConversion = -1; } var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ), gammaConversion ); - var texture = buffer.CreateImageTexture(); + var texture = buffer.CreateImageTexture( alpha, mipmaps ); @@ -121,7 +134,7 @@ namespace Rokojori ctx.Verbose( "Init Texture:", initTexture.GetTexture() ); var jfaInititialize = new CEG_JFAInitialize( graph ); - jfaInititialize.constants.Set( 0.5f ); + jfaInititialize.constants.Set( 0.95f ); var copy = new CEG_Copy( graph ); var jfaIterate = new CEG_JFAIterate( graph ); @@ -132,7 +145,7 @@ namespace Rokojori ( Mathf.RoundToInt( MathX.Exponent( 2, it.maxDimension ) ) - 1 ) : steps; - RJLog.Log( "Steps >>", numSteps, Mathf.Pow( 2, numSteps ) ); + // RJLog.Log( "Steps >>", numSteps, Mathf.Pow( 2, numSteps ) ); repeat.repeats = numSteps; repeat.imageProcessor = jfaIterate; @@ -143,7 +156,6 @@ namespace Rokojori var stepIndex = numSteps - ( index + 1 ); var jump = Mathf.RoundToInt( Mathf.Pow( 2, stepIndex ) ); - this.LogInfo( "Jump:", jump ); jfaIterate.constants.Set( jump ); diff --git a/Runtime/Procedural/Baking/TextureMerger.cs b/Runtime/Procedural/Baking/TextureMerger.cs index 8262b4c..196968c 100644 --- a/Runtime/Procedural/Baking/TextureMerger.cs +++ b/Runtime/Procedural/Baking/TextureMerger.cs @@ -25,7 +25,7 @@ namespace Rokojori public bool createLayout; [Export] - public int dilationRadius = 64; + public int dilationRadius = 3; [ExportGroup("Source")] @@ -211,6 +211,23 @@ namespace Rokojori return new Vector2( x, y ); } + public Vector2 GetGridTextureSize() + { + var alignment = ComputeTextureAlignment( _textures.Count ); + + return new Vector2( textureSize.X / alignment.X, textureSize.Y / alignment.Y ); + } + + public int GetMaxTextureDimension() + { + var size = GetGridTextureSize(); + + return Mathf.RoundToInt( Mathf.Max( size.X, size.Y ) ); + } + + int dilationAlphaTreshold = 30; + int dilationAssignedMinimum = 0; + void CreateGridLayout() { var alignment = ComputeTextureAlignment( _textures.Count ); @@ -232,8 +249,8 @@ namespace Rokojori dilatedMaterial.textureAlbedo.Set( _textures[ i ] ); dilatedMaterial.resolution.Set( _textures[ i ].GetSize() ); dilatedMaterial.maxRadius.Set( dilationRadius ); - dilatedMaterial.alphaTreshold.Set( 1 ); - dilatedMaterial.assignedColorAlphaMinimum.Set( 254 ); + dilatedMaterial.alphaTreshold.Set( dilationAlphaTreshold ); + dilatedMaterial.assignedColorAlphaMinimum.Set( dilationAssignedMinimum ); dilatedMaterial.genericAlphaOffset.Set( 0 ); dilatedMaterial.amount.Set( 1 ); @@ -264,9 +281,9 @@ namespace Rokojori dilatedMaterial.textureAlbedo.Set( _textures[ i ] ); dilatedMaterial.resolution.Set( _textures[ i ].GetSize() ); dilatedMaterial.maxRadius.Set( dilationRadius ); - dilatedMaterial.alphaTreshold.Set( 10 ); - dilatedMaterial.assignedColorAlphaMinimum.Set( 10 ); - dilatedMaterial.genericAlphaOffset.Set( 50 ); + dilatedMaterial.alphaTreshold.Set( dilationAlphaTreshold ); + dilatedMaterial.assignedColorAlphaMinimum.Set( dilationAssignedMinimum ); + dilatedMaterial.genericAlphaOffset.Set( 0 ); dilatedMaterial.amount.Set( 1 ); diff --git a/Runtime/Procedural/Baking/ViewSettings/BakingViewSettings.cs b/Runtime/Procedural/Baking/ViewSettings/BakingViewSettings.cs index 29afeb3..f410858 100644 --- a/Runtime/Procedural/Baking/ViewSettings/BakingViewSettings.cs +++ b/Runtime/Procedural/Baking/ViewSettings/BakingViewSettings.cs @@ -44,16 +44,6 @@ namespace Rokojori */ - [ExportGroup( "Debug Readonly" )] - - [Export] - public float _XX_ComputedFOV = 75; - - [Export] - public float _XX_ComputedDistance = 1; - - [Export] - public float _XX_ComputedOutputScale = 1; /* @@ -94,7 +84,7 @@ namespace Rokojori public float pitch = 0; [Export] - public Quaternion rotationQuaternion; + public Quaternion rotationQuaternion = Quaternion.Identity; public Quaternion bakingRotation => RotationMode.Yaw_Pitch == rotationMode ? @@ -102,7 +92,17 @@ namespace Rokojori rotationQuaternion; + + [ExportGroup( "Debug Readonly" )] + [Export] + public float _XX_ComputedFOV = 75; + + [Export] + public float _XX_ComputedDistance = 1; + + [Export] + public float _XX_ComputedOutputScale = 1; public void ApplySettings( Camera3D camera, Node3D target, Vector3 pivot ) @@ -144,7 +144,9 @@ namespace Rokojori var offset = ( Vector3.Back * _XX_ComputedDistance ) * cameraRotation ; camera.GlobalPosition = target.GlobalPosition + offset - pivot; - camera.SetGlobalQuaternion( cameraRotation.Inverse() ); + + var inverse = cameraRotation.Normalized().Inverse(); + camera.SetGlobalQuaternion( inverse ); _XX_ComputedOutputScale = Cameras.ComputeCameraFittingScale( camera.Fov, _XX_ComputedDistance ); diff --git a/Runtime/Procedural/Mesh/MeshGeometry.cs b/Runtime/Procedural/Mesh/MeshGeometry.cs index 04c2e5f..3981374 100644 --- a/Runtime/Procedural/Mesh/MeshGeometry.cs +++ b/Runtime/Procedural/Mesh/MeshGeometry.cs @@ -904,7 +904,7 @@ namespace Rokojori - public ArrayMesh GenerateMesh( Mesh.PrimitiveType type = Mesh.PrimitiveType.Triangles, ArrayMesh arrayMesh = null ) + public ArrayMesh GenerateMesh( Mesh.PrimitiveType type = Mesh.PrimitiveType.Triangles, ArrayMesh arrayMesh = null, bool generateTangents = true ) { if ( arrayMesh == null ) { @@ -946,6 +946,11 @@ namespace Rokojori arrayMesh.AddSurfaceFromArrays( Mesh.PrimitiveType.Triangles, surfaceArray ); + if ( generateTangents ) + { + arrayMesh.RegenNormalMaps(); + } + return arrayMesh; } diff --git a/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerBuffer.cs b/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerBuffer.cs index a8b588c..2cdd8fc 100644 --- a/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerBuffer.cs +++ b/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerBuffer.cs @@ -37,19 +37,23 @@ namespace Rokojori } } - public static TextureCombinerBuffer From( Texture2D texture, int srgbConversion = 0) + public static TextureCombinerBuffer From( Texture2D texture, int srgbConversion = 0 ) { var buffer = Create( texture.GetWidth(), texture.GetHeight() ); - buffer.CopyFrom( texture.GetImage(), 0, 0, 0, 0, texture.GetWidth(), texture.GetHeight(), srgbConversion ); + buffer.CopyFrom( texture.GetImage(), 0, 0, 0, 0, texture.GetWidth(), texture.GetHeight(), srgbConversion); return buffer; } - public ImageTexture CreateImageTexture() + public ImageTexture CreateImageTexture( bool alpha = true, bool generateMipmaps = false ) { - var image = Image.CreateEmpty( width, height, true, Image.Format.Rgba8 ); - CopyTo( 0, 0, 0, 0, width, height, image ); - image.GenerateMipmaps(); + var image = Image.CreateEmpty( width, height, generateMipmaps, alpha ? Image.Format.Rgba8 : Image.Format.Rgb8); + CopyTo( 0, 0, 0, 0, width, height, image, alpha ); + + if ( generateMipmaps ) + { + image.GenerateMipmaps(); + } return ImageTexture.CreateFromImage( image ); } @@ -120,15 +124,30 @@ namespace Rokojori } } - public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, Image image ) + public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, Image image, bool alpha = true ) { - for ( int i = 0; i < w; i++ ) + if ( ! alpha ) { - for ( int j = 0; j < h; j++ ) + for ( int i = 0; i < w; i++ ) { - var ownPixel = GetAt( ownX + i, ownY + j ); - image.SetPixel( targetX + i, targetY + j, ownPixel ); + for ( int j = 0; j < h; j++ ) + { + var ownPixel = GetAt( ownX + i, ownY + j ); + ownPixel.A = 1; + image.SetPixel( targetX + i, targetY + j, ownPixel ); + } + } + } + else + { + for ( int i = 0; i < w; i++ ) + { + for ( int j = 0; j < h; j++ ) + { + var ownPixel = GetAt( ownX + i, ownY + j ); + image.SetPixel( targetX + i, targetY + j, ownPixel ); + } } } } diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs new file mode 100644 index 0000000..64c3979 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs @@ -0,0 +1,81 @@ + +using Godot; +using Godot.Collections; +using System.Collections.Generic; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class DepthAOEffect:SingleShaderCompositorEffect + { + public static readonly string shaderPath = Path( "DepthAO/DepthAOShader.glsl" ); + + RDSampler sampler; + + [Export( PropertyHint.Range, "0,1") ] + public float greyAmount; + + [Export( PropertyHint.Range, "0,1") ] + public float depthAmount; + + [Export( PropertyHint.Range, "0,5") ] + public float effectStrength = 1; + + [Export( PropertyHint.Range, "2,8") ] + public float depthEdgeTreshold = 2f; + + [Export( PropertyHint.Range, "1,10") ] + public float depthEdgeIntensity = 1f; + + [Export( PropertyHint.Range, "0,8") ] + public float radius = 2f; + + [Export( PropertyHint.Range, "0.001,1") ] + public float jump = 1f; + + [Export( PropertyHint.Range, "0,1") ] + public float debugView = 0f; + + protected override void OnConfigure() + { + EffectCallbackType = EffectCallbackTypeEnum.PostTransparent; + _shaderPath = shaderPath; + _groupSize = 8; + } + + protected override void OnInitialize() + { + base.OnInitialize(); + + sampler = context.Sampler( RenderingDevice.SamplerFilter.Nearest, RenderingDevice.SamplerRepeatMode.ClampToEdge ); + } + + + + protected override void SetConstants() + { + constants.Set( + (Vector2)context.internalSize, + new Vector2( greyAmount, depthAmount ), + effectStrength, + depthEdgeTreshold / 100f, + depthEdgeIntensity * 20f, + radius, + jump, + debugView + ); + } + + protected override void RenderView() + { + context.AssignScreenColorTexture(); + context.AssignScreenDepthTexture( sampler ); + + context.pushConstants = constants; + + context.ProcessComputeProgram(); + + } + } +} \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs.uid b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs.uid new file mode 100644 index 0000000..1aa7d25 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOEffect.cs.uid @@ -0,0 +1 @@ +uid://b2sqklu6pcdcr diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl new file mode 100644 index 0000000..ba2ef9c --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl @@ -0,0 +1,146 @@ +#[compute] +#version 450 + +layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; + +layout( rgba16f, set = 0, binding = 0 ) +uniform image2D color_image; + +layout( set = 1, binding = 0 ) +uniform sampler2D depth_sampler; + + +layout( push_constant, std430 ) +uniform Params +{ + vec2 rasterSize; + vec2 amounts; + float effectStrength; + float edgeThreshold; + float edgeIntensity; + float contrastThreshold; + float contrastIntensity; + float debugView; + +} params; + +float sampleDepth( ivec2 coord ) +{ + coord = clamp( coord, ivec2( 0 ), ivec2( params.rasterSize ) - ivec2( 1 ) ); + + vec2 uv = ( vec2( coord ) + 0.5 ) / params.rasterSize; + return texture( depth_sampler, uv ).r; +} + +float getEdgeStrength( ivec2 uvOffset ) +{ + float centerDepth = sampleDepth( uvOffset ); + + float top = sampleDepth( uvOffset + ivec2( 0, -1 ) ); + float left = sampleDepth( uvOffset + ivec2( -1, 0 ) ); + + + float gx = left - centerDepth; + float gy = top - centerDepth; + + gx = 1.0 - clamp( abs( 10 * abs( gx ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); + gy = 1.0 - clamp( abs( 10 * abs( gy ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); + + return length( vec2( gx, gy ) ); +} + +void main( ) +{ + ivec2 uv = ivec2( gl_GlobalInvocationID.xy ); + ivec2 size = ivec2( params.rasterSize ); + + if ( uv.x >= size.x || uv.y >= size.y ) + { + return; + } + + // float centerDepth = sampleDepth( uv ); + + // float top_left = sampleDepth( uv + ivec2( -1, -1 ) ); + // float top = sampleDepth( uv + ivec2( 0, -1 ) ); + // float top_right = sampleDepth( uv + ivec2( 1, -1 ) ); + // float left = sampleDepth( uv + ivec2( -1, 0 ) ); + // float right = sampleDepth( uv + ivec2( 1, 0 ) ); + // float bottom_left = sampleDepth( uv + ivec2( -1, 1 ) ); + // float bottom = sampleDepth( uv + ivec2( 0, 1 ) ); + // float bottom_right = sampleDepth( uv + ivec2( 1, 1 ) ); + + + // // ( l - c ) + ( c - r ); + // // + // float gx = left - centerDepth; + // float gy = top - centerDepth; + + // gx = 1.0 - clamp( abs( 10 * abs( gx ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); + // gy = 1.0 - clamp( abs( 10 * abs( gy ) - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); + + float edgeStrength = 0; + float amount = 0; + + int radius = int( params.contrastThreshold ); + + for ( int x = -radius; x <= radius; x ++ ) + { + for ( int y = -radius; y <= radius; y ++ ) + { + ivec2 xy = ivec2( x, y ); + float es = getEdgeStrength( uv + xy ); + float a = 1.0 / ( 1.0 + length( xy ) ); + + edgeStrength += es; + amount += pow( a, params.contrastIntensity ); + } + } + + edgeStrength /= amount; + + /* + + edgeStrength = min( abs( edgeStrength - params.edgeThreshold ) * params.edgeIntensity, 1.0 ); + + + + // float edgeStrength = abs( left - right ); + + // edgeStrength = clamp( ( edgeStrength - params.edgeThreshold ) * params.edgeIntensity, 0.0, 1.0 ); + float edge = edgeStrength; + + + vec4 color = imageLoad( color_image, uv ); + + vec4 color_left = imageLoad( color_image, uv + ivec2( -1, 0 ) ); + vec4 color_left2 = imageLoad( color_image, uv + ivec2( -2, 0 ) ); + vec4 color_right = imageLoad( color_image, uv + ivec2( 1, 0 ) ); + vec4 color_right2 = imageLoad( color_image, uv + ivec2( 2, 0 ) ); + + float c = ( length( color_left - color_right ) - params.contrastThreshold ) * params.contrastIntensity; + + float d = min( 1.0, c ); + + edge = max( d, edge ); + + vec4 smoothedColor = color_left + color_left2 + + 2.0 * color + + color_right + color_right2; + + smoothedColor /= 6.0; + + smoothedColor =vec4( 0.0, 0.0, 0.0, 1.0 ); + + float gray = color.r * 0.2125 + color.g * 0.7154 + color.b * 0.0721; + vec3 debugViewColor = vec3( params.amounts.x * gray, params.amounts.y * centerDepth, edge ); + + color.rgb = mix( color.rgb, smoothedColor.rgb, edge * params.effectStrength ); + color.rgb = mix( color.rgb, debugViewColor, params.debugView ); + */ + + vec4 color = imageLoad( color_image, uv ); + color = mix( color, vec4( 0.0, 0.0, 0.0, 1.0 ), edgeStrength * params.effectStrength ); + + imageStore( color_image, uv, color ); +} \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl.import b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl.import new file mode 100644 index 0000000..ca33892 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl.import @@ -0,0 +1,14 @@ +[remap] + +importer="glsl" +type="RDShaderFile" +uid="uid://bshg7rg0k6pre" +path="res://.godot/imported/DepthAOShader.glsl-68a7bb82d9ad472873dfcaa383972842.res" + +[deps] + +source_file="res://addons/rokojori_action_library/Runtime/Rendering/Compositor/CompositorEffects/DepthAO/DepthAOShader.glsl" +dest_files=["res://.godot/imported/DepthAOShader.glsl-68a7bb82d9ad472873dfcaa383972842.res"] + +[params] + diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewEffect.cs index ca3c4ca..10e21f9 100644 --- a/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewEffect.cs +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewEffect.cs @@ -14,13 +14,13 @@ namespace Rokojori RDSampler sampler; [Export( PropertyHint.Range, "0,1") ] - public float greyAmount; - - [Export( PropertyHint.Range, "0,1") ] - public float depthAmount; + public float depthAmount = 1; [Export( PropertyHint.Range, "0.001,3") ] - public float depthPower; + public float depthPower = 1; + + [Export( PropertyHint.Range, "0,1") ] + public float grayAmount = 0f; protected override void OnConfigure() { @@ -39,9 +39,9 @@ namespace Rokojori protected override void SetConstants() { constants.Set( - (Vector2)context.internalSize, - new Vector2( greyAmount, depthAmount ), - depthPower + depthAmount, + depthPower, + grayAmount ); } diff --git a/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewShader.glsl b/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewShader.glsl index 2189f93..c9ac46a 100644 --- a/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewShader.glsl +++ b/Runtime/Rendering/Compositor/CompositorEffects/DepthView/DepthViewShader.glsl @@ -4,45 +4,49 @@ layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; layout( rgba16f, set = 0, binding = 0) -uniform image2D color_image; +uniform image2D colorImage; layout( set = 1, binding = 0) -uniform sampler2D depth_sampler; - +uniform sampler2D depthSampler; layout(push_constant, std430) -uniform Params +uniform Parameters { - vec2 raster_size; - vec2 amounts; - float power; + float depthAmount; + float depthPower; + float grayAmount; + -} params; +} parameters; -float sample_depth( ivec2 coord ) +float sampleDepth( ivec2 coord, ivec2 size ) { - coord = clamp( coord, ivec2( 0 ), ivec2( params.raster_size ) - ivec2( 1 ) ); + coord = clamp( coord, ivec2( 0 ), size - ivec2( 1 ) ); - vec2 uv = ( vec2( coord ) + 0.5 ) / params.raster_size; - return texture( depth_sampler, uv ).r; + vec2 uv = ( vec2( coord ) + 0.5 ) / size; + return texture( depthSampler, uv ).r; } void main() { ivec2 uv = ivec2( gl_GlobalInvocationID.xy ); - ivec2 size = ivec2( params.raster_size ); + ivec2 size = imageSize( colorImage ); if ( uv.x >= size.x || uv.y >= size.y ) { return; } - vec4 color = imageLoad( color_image, uv ); - float depth = sample_depth( uv ); + vec4 color = imageLoad( colorImage, uv ); + float depth = sampleDepth( uv, size ); - float gray = color.r * 0.2125 + color.g * 0.7154 + color.b * 0.0721; + float gray = color.r * 0.2 + color.g * 0.7 + color.b * 0.1; - color.rgb = vec3( params.amounts.x * gray, pow( params.amounts.y * depth, params.power ), 0.0 ); + float depthValue = pow( parameters.depthAmount * depth, parameters.depthPower ); - imageStore( color_image, uv, color ); + depthValue = mix( depthValue, depthValue * gray, parameters.grayAmount ); + + color.rgb = vec3( depthValue, depthValue, depthValue ); + + imageStore( colorImage, uv, color ); } \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs new file mode 100644 index 0000000..3948736 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs @@ -0,0 +1,54 @@ + +using Godot; +using Godot.Collections; +using System.Collections.Generic; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class NormalViewEffect:SingleShaderCompositorEffect + { + public static readonly string shaderPath = Path( "DepthView/NormalViewShader.glsl" ); + + RDSampler sampler; + + [Export( PropertyHint.Range, "0,1") ] + public float normalsAmount = 1; + + [Export( PropertyHint.Range, "0,1") ] + public float grayAmount = 0f; + + protected override void OnConfigure() + { + EffectCallbackType = EffectCallbackTypeEnum.PostTransparent; + _shaderPath = shaderPath; + _groupSize = 8; + } + + protected override void OnInitialize() + { + base.OnInitialize(); + + sampler = context.Sampler( RenderingDevice.SamplerFilter.Nearest, RenderingDevice.SamplerRepeatMode.ClampToEdge ); + } + + protected override void SetConstants() + { + constants.Set( + normalsAmount, + grayAmount + ); + } + + protected override void RenderView() + { + context.AssignScreenColorTexture(); + + context.pushConstants = constants; + + context.ProcessComputeProgram(); + + } + } +} \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs.uid b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs.uid new file mode 100644 index 0000000..4c6100e --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewEffect.cs.uid @@ -0,0 +1 @@ +uid://b04udly3ubuf2 diff --git a/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl new file mode 100644 index 0000000..ee2117b --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl @@ -0,0 +1,49 @@ +#[compute] +#version 450 + +layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; + +layout( rgba16f, set = 0, binding = 0) +uniform image2D colorImage; + +layout( set = 1, binding = 0) +uniform sampler2D normalSampler; + +layout( push_constant, std430 ) +uniform Parameters +{ + float normalsAmount; + float grayAmount; + +} parameters; + +vec3 sampleNormal( ivec2 coord, ivec2 size ) +{ + coord = clamp( coord, ivec2( 0 ), size - ivec2( 1 ) ); + + vec2 uv = ( vec2( coord ) + 0.5 ) / size; + return texture( normalSampler, uv ).xyz; +} + +void main() +{ + ivec2 uv = ivec2( gl_GlobalInvocationID.xy ); + ivec2 size = imageSize( colorImage ); + + if ( uv.x >= size.x || uv.y >= size.y ) + { + return; + } + + vec4 color = imageLoad( colorImage, uv ); + vec3 normal = sampleNormal( uv, size ); + + float gray = color.r * 0.2 + color.g * 0.7 + color.b * 0.1; + + + normal = mix( normal, normal * gray, parameters.grayAmount ); + + color.rgb = normal; + + imageStore( colorImage, uv, color ); +} \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl.import b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl.import new file mode 100644 index 0000000..f2d286e --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl.import @@ -0,0 +1,14 @@ +[remap] + +importer="glsl" +type="RDShaderFile" +uid="uid://bcdpc2kr1ico" +path="res://.godot/imported/NormalViewShader.glsl-8808b7c889cc126ae77b26b3c812033a.res" + +[deps] + +source_file="res://addons/rokojori_action_library/Runtime/Rendering/Compositor/CompositorEffects/NormalView/NormalViewShader.glsl" +dest_files=["res://.godot/imported/NormalViewShader.glsl-8808b7c889cc126ae77b26b3c812033a.res"] + +[params] + diff --git a/Runtime/Rendering/Context/RDContext.cs b/Runtime/Rendering/Context/RDContext.cs index 973bbd4..a762d88 100644 --- a/Runtime/Rendering/Context/RDContext.cs +++ b/Runtime/Rendering/Context/RDContext.cs @@ -69,6 +69,12 @@ namespace Rokojori return RDTexture.Depth( this ); } + public RDTexture GetScreenNormalRoughnessTexture() + { + return RDTexture.NormalRoughness( this ); + } + + public void SetProgram( RDProgram p ) { SetShaderAndPipeline( p.shader, p.pipeline ); @@ -107,6 +113,11 @@ namespace Rokojori AssignTexture( GetScreenDepthTexture(), sampler, setIndex ); } + public void AssignScreenNormalRoughnessTexture( RDSampler sampler = null, int setIndex = -1 ) + { + AssignTexture( GetScreenNormalRoughnessTexture(), sampler, setIndex ); + } + RDTexture _missingTexture = null; Vector2I _missingTextureSize = new Vector2I( 64, 64 ); diff --git a/Runtime/Rendering/Objects/RDTexture.cs b/Runtime/Rendering/Objects/RDTexture.cs index e150bb3..9c291c1 100644 --- a/Runtime/Rendering/Objects/RDTexture.cs +++ b/Runtime/Rendering/Objects/RDTexture.cs @@ -14,18 +14,26 @@ namespace Rokojori public static RDTexture Color( RDContext context ) { - var rid = context.sceneBuffers.GetColorLayer( (uint) context.view ); - + // var rid = context.sceneBuffers.GetColorLayer( (uint) context.view ); + var rid = context.sceneBuffers.GetTextureSlice( "render_buffers", "color", (uint) context.view, 0, 1, 1 ); return new RDTexture( context, rid ); } public static RDTexture Depth( RDContext context ) { - var rid = context.sceneBuffers.GetDepthLayer( (uint) context.view ); - + // var rid = context.sceneBuffers.GetDepthLayer( (uint) context.view ); + var rid = context.sceneBuffers.GetTextureSlice( "render_buffers", "depth", (uint) context.view, 0, 1, 1 ); return new RDTexture( context, rid ); } + public static RDTexture NormalRoughness( RDContext context ) + { + // var rid = context.sceneBuffers.GetDepthLayer( (uint) context.view ); + var rid = context.sceneBuffers.GetTextureSlice( "forward_clustered", "normal_roughness", (uint) context.view, 0, 1, 1 ); + return new RDTexture( context, rid ); + } + + public void SetData( byte[] data, int layer = 0 ) { var error = context.renderingDevice.TextureUpdate( rid, (uint) layer, data ); diff --git a/Runtime/Shading/Library/Colors.gdshaderinc b/Runtime/Shading/Library/Colors.gdshaderinc index b5c60be..ef6612a 100644 --- a/Runtime/Shading/Library/Colors.gdshaderinc +++ b/Runtime/Shading/Library/Colors.gdshaderinc @@ -186,4 +186,14 @@ vec4 mixThreeColors( vec4 a, vec4 b, vec4 c, float t ) float wc = mapClamped( t, 0.5, 1, 0.0, 1.0 ); return a * wa + b * wb + c * wc; +} + +vec3 gamma( vec3 color, float gamma ) +{ + color.r = pow( color.r, gamma ); + color.g = pow( color.g, gamma ); + color.b = pow( color.b, gamma ); + + return color; + } \ No newline at end of file diff --git a/Runtime/Shading/Library/Math.gdshaderinc b/Runtime/Shading/Library/Math.gdshaderinc index 513a351..f44c009 100644 --- a/Runtime/Shading/Library/Math.gdshaderinc +++ b/Runtime/Shading/Library/Math.gdshaderinc @@ -53,4 +53,21 @@ float triangle( float value ) vec2 onCircle( float angle ) { return vec2( cos( angle ), sin( angle ) ); +} + +float normalizeAngle( float degrees ) +{ + while ( degrees < 0.0 ) + { + degrees += 360.0; + } + + return degrees; +} + +float angleDelta( float degreesA, float degreesB ) +{ + float angleDelta = degreesB - degreesA; + angleDelta = mod( angleDelta + 180.0, 360.0 ) - 180.0; + return angleDelta; } \ No newline at end of file diff --git a/Runtime/Shading/Library/Transform.gdshaderinc b/Runtime/Shading/Library/Transform.gdshaderinc index 074ed5e..0d5f1f0 100644 --- a/Runtime/Shading/Library/Transform.gdshaderinc +++ b/Runtime/Shading/Library/Transform.gdshaderinc @@ -15,6 +15,11 @@ vec3 applyMatrixWithoutTranslation( vec3 v, mat4 m ) return ( mw * vec4( v, 1.0 ) ).xyz; } +vec3 applyMatrix( vec3 v, mat3 m ) +{ + return ( m * v ).xyz; +} + // L W V // L // W @@ -25,12 +30,12 @@ vec3 applyMatrixWithoutTranslation( vec3 v, mat4 m ) // WD // VD -vec3 localToWorld( vec3 _VERTEX, mat4 _MODEL_MATRIX ) +vec3 localToWorld( vec3 local, mat4 _MODEL_MATRIX ) { - return ( _MODEL_MATRIX * vec4( _VERTEX, 1.0 ) ).xyz; + return ( _MODEL_MATRIX * vec4( local, 1.0 ) ).xyz; } -vec3 localToWorldDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX ) +vec3 localToWorldDirection( vec3 local, mat4 _MODEL_MATRIX ) { mat4 mw = _MODEL_MATRIX; mw[ 3 ][ 0 ] = 0.0; @@ -38,20 +43,30 @@ vec3 localToWorldDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX ) mw[ 3 ][ 2 ] = 0.0; mw[ 3 ][ 3 ] = 1.0; - return ( mw * vec4( _VERTEX, 1.0 ) ).xyz; + return ( mw * vec4( local, 1.0 ) ).xyz; } -vec3 localToView( vec3 _VERTEX, mat4 _MODELVIEW_MATRIX ) +vec3 localToView( vec3 local, mat4 _MODELVIEW_MATRIX ) { - return ( _MODELVIEW_MATRIX * vec4( _VERTEX, 1.0 ) ).xyz; + return ( _MODELVIEW_MATRIX * vec4( local, 1.0 ) ).xyz; } -vec3 worldToLocal( vec3 _VERTEX, mat4 _MODEL_MATRIX ) +vec3 localToViewDirection( vec3 local, mat4 _MODELVIEW_MATRIX ) { - return ( inverse( _MODEL_MATRIX ) * vec4( _VERTEX, 1.0 ) ).xyz; + return applyMatrixWithoutTranslation( local, _MODELVIEW_MATRIX ); } -vec3 worldToLocalDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX ) +vec3 localToViewDirection( vec3 local, mat3 _MODELVIEW_NORMAL_MATRIX ) +{ + return applyMatrix( local, _MODELVIEW_NORMAL_MATRIX ); +} + +vec3 worldToLocal( vec3 world, mat4 _MODEL_MATRIX ) +{ + return ( inverse( _MODEL_MATRIX ) * vec4( world, 1.0 ) ).xyz; +} + +vec3 worldToLocalDirection( vec3 world, mat4 _MODEL_MATRIX ) { mat4 mw = inverse( _MODEL_MATRIX ); mw[ 3 ][ 0 ] = 0.0; @@ -59,7 +74,7 @@ vec3 worldToLocalDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX ) mw[ 3 ][ 2 ] = 0.0; mw[ 3 ][ 3 ] = 1.0; - return ( mw * vec4( _VERTEX, 1.0 ) ).xyz; + return ( mw * vec4( world, 1.0 ) ).xyz; } @@ -68,7 +83,7 @@ vec3 worldToView( vec3 world, mat4 _VIEW_MATRIX ) return ( _VIEW_MATRIX * vec4( world, 1.0 ) ).xyz; } -vec3 worldToViewDirection( vec3 direction, mat4 _VIEW_MATRIX ) +vec3 worldToViewDirection( vec3 worldDirection, mat4 _VIEW_MATRIX ) { mat4 mw = _VIEW_MATRIX; mw[ 3 ][ 0 ] = 0.0; @@ -76,7 +91,7 @@ vec3 worldToViewDirection( vec3 direction, mat4 _VIEW_MATRIX ) mw[ 3 ][ 2 ] = 0.0; mw[ 3 ][ 3 ] = 1.0; - return ( mw * vec4( direction, 1.0 ) ).xyz; + return ( mw * vec4( worldDirection, 1.0 ) ).xyz; } vec3 viewToWorld( vec3 view, mat4 _INV_VIEW_MATRIX ) @@ -84,7 +99,7 @@ vec3 viewToWorld( vec3 view, mat4 _INV_VIEW_MATRIX ) return applyMatrix( view, _INV_VIEW_MATRIX ); } -vec3 viewToWorldDirection( vec3 view, mat4 _INV_VIEW_MATRIX ) +vec3 viewToWorldDirection( vec3 viewDirection, mat4 _INV_VIEW_MATRIX ) { mat4 mw = _INV_VIEW_MATRIX; mw[ 3 ][ 0 ] = 0.0; @@ -93,7 +108,7 @@ vec3 viewToWorldDirection( vec3 view, mat4 _INV_VIEW_MATRIX ) mw[ 3 ][ 3 ] = 1.0; - return applyMatrix( view, mw ); + return applyMatrix( viewDirection, mw ); } vec3 viewToLocal( vec3 view, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX ) diff --git a/Runtime/Shading/Materials/Materials.cs b/Runtime/Shading/Materials/Materials.cs index 8db78f9..27ee5aa 100644 --- a/Runtime/Shading/Materials/Materials.cs +++ b/Runtime/Shading/Materials/Materials.cs @@ -43,6 +43,13 @@ namespace Rokojori { return material; } + + var mesh = mi.Mesh; + + if ( mesh != null && mesh.SurfaceGetMaterial( 0 ) != null ) + { + return (M) mesh.SurfaceGetMaterial( 0 ); + } } else if ( node is CsgPrimitive3D ) { @@ -87,6 +94,8 @@ namespace Rokojori { if ( node is MeshInstance3D mi) { + var mesh = mi.Mesh; + mi.SetSurfaceOverrideMaterial( index, material ); if ( index == 0 && mi.MaterialOverride != null ) diff --git a/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader b/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader new file mode 100644 index 0000000..512fe1f --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader @@ -0,0 +1,47 @@ + +shader_type spatial; +render_mode blend_mix, depth_draw_opaque, cull_back, unshaded; + +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc" + +uniform float gammaA = 1.0; +uniform sampler2D channelTextureA : hint_default_white, filter_linear_mipmap, repeat_enable; + +uniform float gammaB = 1.0; +uniform sampler2D channelTextureB : hint_default_white, filter_linear_mipmap, repeat_enable; + +uniform float gammaC = 1.0; +uniform sampler2D channelTextureC : hint_default_black, filter_linear_mipmap, repeat_enable; + +uniform vec3 uv1_scale = vec3( 1, 1, 1 ); +uniform vec3 uv1_offset = vec3( 0, 0, 0 ); + + +void vertex() +{ + UV = UV * uv1_scale.xy + uv1_offset.xy; +} + + +vec4 getColor( vec2 uv, sampler2D channelTexture, int index, float gammaPower ) +{ + vec4 color = texture( channelTexture, uv ); + + vec4 outputColor = index == 0 ? vec4( color.r, 0, 0, 1 ) : + index == 1 ? vec4( 0, color.g, 0, 1 ) : + vec4( 0, 0, color.b, 1 ); + + outputColor.rgb = gamma( outputColor.rgb, gammaPower ); + return outputColor; +} + +void fragment() +{ + + vec4 colorA = getColor( UV, channelTextureA, 0, gammaA ); + vec4 colorB = getColor( UV, channelTextureB, 1, gammaB ); + vec4 colorC = getColor( UV, channelTextureC, 2, gammaC ); + + ALBEDO = colorA.rgb + colorB.rgb + colorC.rgb; + +} diff --git a/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader.uid b/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader.uid new file mode 100644 index 0000000..1d100b1 --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/ChannelCopy.gdshader.uid @@ -0,0 +1 @@ +uid://drcoijnirdo13 diff --git a/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader b/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader new file mode 100644 index 0000000..355f5c4 --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader @@ -0,0 +1,17 @@ +shader_type spatial; +render_mode blend_mix, unshaded, alpha_to_coverage; + +uniform sampler2D screenMap: hint_screen_texture, repeat_disable, filter_nearest; +uniform sampler2D normalMap: hint_normal_roughness_texture, repeat_disable, filter_nearest; + + +void vertex() +{ + POSITION = vec4( VERTEX.xy, 0.1, 1.0 ); +} + +void fragment() +{ + ALBEDO = textureLod( normalMap, UV, 0 ).rgb; + ALPHA = textureLod( screenMap, UV, 0 ).w; +} \ No newline at end of file diff --git a/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader.uid b/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader.uid new file mode 100644 index 0000000..f7080ec --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/NormalMapView.gdshader.uid @@ -0,0 +1 @@ +uid://d2xw77vdetaln diff --git a/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader b/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader new file mode 100644 index 0000000..a724415 --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader @@ -0,0 +1,48 @@ +shader_type spatial; +render_mode blend_mix,depth_draw_opaque,cull_disabled, unshaded; +uniform vec4 albedo_color : source_color; +uniform sampler2D albedo_texture : source_color; +uniform sampler2D normal_texture : source_color; + +uniform bool use_normalmap = false; +uniform bool use_alpha_texture = false; + +uniform float alpha_scissor_threshold : hint_range(0,1); +uniform float normal_scale : hint_range(-5,5) = 1.0; + +uniform vec3 uv1_scale; +uniform vec3 uv1_offset; + + +void vertex() +{ + UV = UV * uv1_scale.xy + uv1_offset.xy; +} + +void fragment() +{ + vec2 base_uv = UV; + vec4 albedo = texture( albedo_texture, base_uv ) * albedo_color; + vec4 normal_tex = texture( normal_texture, base_uv ); + + // 0.5 + -1.0 == -1.0 + 0.5 + //ALBEDO = vec3(1.0 - NORMAL.y, 1.0 - NORMAL.x, - NORMAL.z)* 0.5; + + if ( use_normalmap ) + { + vec3 normalmap; + normalmap.xy = normal_tex.xy * 2.0 - 1.0; + normalmap.z = sqrt(max(0.0, 1.0 - dot(normalmap.xy, normalmap.xy))); + NORMAL = normalize(mix(NORMAL, TANGENT * normalmap.x + BINORMAL * normalmap.y + NORMAL * normalmap.z, normal_scale)); + } + + + ALBEDO = vec3( -NORMAL.x, NORMAL.y, -NORMAL.z) * 0.5 + 0.5; + + if ( use_alpha_texture ) + { + ALPHA = albedo.a; + ALPHA_SCISSOR_THRESHOLD = alpha_scissor_threshold; + } + +} diff --git a/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader.uid b/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader.uid new file mode 100644 index 0000000..55683b1 --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/TangentNormals.gdshader.uid @@ -0,0 +1 @@ +uid://xcerdccafolw diff --git a/Runtime/Shading/Shaders/Baking/UVBaker.gdshader b/Runtime/Shading/Shaders/Baking/UVBaker.gdshader new file mode 100644 index 0000000..14105be --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/UVBaker.gdshader @@ -0,0 +1,20 @@ + +shader_type spatial; +render_mode blend_mix, depth_draw_opaque, cull_back, unshaded; + + +uniform vec3 uv1_scale = vec3( 1, 1, 0 ); +uniform vec3 uv1_offset = vec3( 0, 0, 0 ); + +void vertex() +{ + UV = UV * uv1_scale.xy + uv1_offset.xy; +} + + +void fragment() +{ + + ALBEDO = vec3( UV.x, UV.y, 0.0 ); + +} diff --git a/Runtime/Shading/Shaders/Baking/UVBaker.gdshader.uid b/Runtime/Shading/Shaders/Baking/UVBaker.gdshader.uid new file mode 100644 index 0000000..d8c5d8b --- /dev/null +++ b/Runtime/Shading/Shaders/Baking/UVBaker.gdshader.uid @@ -0,0 +1 @@ +uid://c7drksm444hh8 diff --git a/Runtime/Shading/Shaders/PostProcessing/ChromaticDIstortion.material b/Runtime/Shading/Shaders/PostProcessing/ChromaticDIstortion.material index fcd1a68..db70ea3 100644 Binary files a/Runtime/Shading/Shaders/PostProcessing/ChromaticDIstortion.material and b/Runtime/Shading/Shaders/PostProcessing/ChromaticDIstortion.material differ