Render Features Update

This commit is contained in:
Josef 2025-09-21 09:35:17 +02:00
parent 48eb111c45
commit ca056f0678
51 changed files with 879 additions and 40 deletions

197
Icons/RenderingManager.svg Normal file
View File

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="16"
viewBox="0 0 16 16"
width="16"
version="1.1"
id="svg4"
sodipodi:docname="RenderingManager.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs8"><linearGradient
inkscape:collect="never"
id="linearGradient7321"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop7317" /><stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop7319" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient2490"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2480" /><stop
style="stop-color:#f0ece9;stop-opacity:0.15384616;"
offset="0.16326228"
id="stop2482" /><stop
style="stop-color:#9f9492;stop-opacity:0;"
offset="0.34845719"
id="stop2484" /><stop
style="stop-color:#322834;stop-opacity:0.66666675;"
offset="0.75751561"
id="stop2486" /><stop
style="stop-color:#020203;stop-opacity:1;"
offset="1"
id="stop2488" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient1031"><stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop1027" /><stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop1029" /></linearGradient><linearGradient
inkscape:collect="never"
id="linearGradient33765"><stop
style="stop-color:#e4dcbf;stop-opacity:1;"
offset="0"
id="stop33761" /><stop
style="stop-color:#e1d7d0;stop-opacity:1;"
offset="0.19335938"
id="stop2420" /><stop
style="stop-color:#f3543e;stop-opacity:1;"
offset="0.41559249"
id="stop16949" /><stop
style="stop-color:#46254e;stop-opacity:1;"
offset="0.80959076"
id="stop16951" /><stop
style="stop-color:#2f3755;stop-opacity:1;"
offset="1"
id="stop33763" /></linearGradient><linearGradient
id="linearGradient3074"><stop
style="stop-color:#e26708;stop-opacity:1;"
offset="0"
id="stop3070" /><stop
style="stop-color:#bb3c00;stop-opacity:1;"
offset="1"
id="stop3072" /></linearGradient><radialGradient
xlink:href="#linearGradient45008"
id="radialGradient3076"
cx="30.688875"
cy="30.069115"
fx="30.688875"
fy="30.069115"
r="14.05412"
gradientUnits="userSpaceOnUse" /><linearGradient
xlink:href="#linearGradient45008"
id="linearGradient45010"
x1="-31.87768"
y1="22.065159"
x2="-31.87768"
y2="48.78738"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(101.16951,-6.5921995)" /><linearGradient
id="linearGradient45008"><stop
style="stop-color:#e14500;stop-opacity:1;"
offset="0"
id="stop45004" /><stop
style="stop-color:#e17900;stop-opacity:1;"
offset="0.59811592"
id="stop45012" /><stop
style="stop-color:#e19c00;stop-opacity:1;"
offset="1"
id="stop45006" /></linearGradient><linearGradient
xlink:href="#linearGradient45008"
id="linearGradient46715"
x1="31.917692"
y1="47.524929"
x2="31.917692"
y2="22.632998"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.7923447e-6)" /><radialGradient
inkscape:collect="never"
xlink:href="#linearGradient33765"
id="radialGradient33767"
cx="28.252495"
cy="28.914215"
fx="28.252495"
fy="28.914215"
r="14.43763"
gradientTransform="matrix(2.0592515,0,0,2.0182304,-29.633594,-30.690448)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="never"
xlink:href="#linearGradient1031"
id="linearGradient1033"
x1="2.5040113"
y1="4.3790028"
x2="9.6209886"
y2="4.3790028"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="never"
xlink:href="#linearGradient2490"
id="radialGradient2424"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.0705199,0,0,2.0292743,-29.931333,-31.016489)"
cx="27.740032"
cy="29.716822"
fx="27.740032"
fy="29.716822"
r="14.43763" /><linearGradient
inkscape:collect="never"
xlink:href="#linearGradient7321"
id="linearGradient7323"
x1="1.9025939"
y1="4.2053886"
x2="10.222406"
y2="4.2053886"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="namedview6"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
showgrid="false"
inkscape:zoom="22.627417"
inkscape:cx="1.4584077"
inkscape:cy="13.34664"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g33736" /><g
id="g2210"
transform="matrix(0.54328517,0,0,0.54328517,-9.4489315,-11.300948)"><g
id="g33736"><rect
style="fill:url(#radialGradient33767);fill-opacity:1;stroke:none;stroke-width:1.91428;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect18059"
width="28.875259"
height="28.300053"
x="17.679815"
y="21.376339"
ry="4.4076433" /><rect
style="display:inline;opacity:0.56871;fill:#ed008e;fill-opacity:1;stroke:none;stroke-width:1.91428;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="rect5113"
width="28.875259"
height="28.300053"
x="17.679815"
y="21.347578"
ry="4.4076433" /><path
sodipodi:type="star"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99832;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
id="path2626"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="6.0625"
sodipodi:cy="5.40625"
sodipodi:r1="4.1089888"
sodipodi:r2="2.0544944"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 9.6209886,7.4607444 -7.1169773,0 L 6.0625,1.2972612 Z"
transform="matrix(-1.1053675,1.9145529,-1.9145529,-1.1053675,48.521034,31.594784)"
inkscape:transform-center-y="-1.2822129"
inkscape:transform-center-x="0.083880782" /><g
id="g2642"
transform="matrix(1.0851915,0,0,1.0851915,25.209605,-13.00707)" /></g></g></svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://yy73os4iqhw"
path="res://.godot/imported/RenderingManager.svg-f5be4225af141f3c0e92c0529a74c481.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/rokojori_action_library/Icons/RenderingManager.svg"
dest_files=["res://.godot/imported/RenderingManager.svg-f5be4225af141f3c0e92c0529a74c481.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View File

@ -570,6 +570,12 @@ namespace Rokojori
return a.Lerp( b, lerp );
}
// public static Vector4 Lerp( Vector4 a, Vector4 b, float lerp )
// {
// return a.Lerp( b, lerp );
// }
public static Vector3 LerpGlobalPosition( Node3D a, Node3D b, float lerp )
{
return a.GlobalPosition.Lerp( b.GlobalPosition, lerp );

View File

@ -77,6 +77,9 @@ namespace Rokojori
[Export]
public float maxHeight = 100;
[Export]
public float snapDistance = 50;
[Export]
public Texture2D normalMap;

View File

@ -41,12 +41,15 @@ uniform float occupancyHideScale = 0.1;
uniform sampler2D occupancyVariance;
uniform vec2 occupancyUVScale = vec2( 1.0, 1.0 );
uniform vec2 occupancyUVOffset = vec2( 1.0, 1.0 );
uniform bool discardFullyHidden = true;
uniform float hideStart = 40;
uniform float hideMax = 60;
uniform float hideOffset = -0.6;
uniform float discardTreshold = 0.01;
uniform float discardOffset = 1000000;
uniform sampler2D coverageMap;
uniform sampler2D colorMap;
uniform vec2 mapSize = vec2(1024,1024);
@ -108,9 +111,15 @@ void process()
occ = min( occ, 1.0 - sampledCoverage );
sca *= mix( 1.0, occupancyHideScale , occ * occupancyAmount );
position3D.y += occ * occupancyAmount * occupancyHideOffset;
float combinedOcc = occ * occupancyAmount; ;
position3D.y += combinedOcc * occupancyHideOffset;
position3D.y += mix( minHeight, maxHeight, sampledHeight );
if ( combinedOcc >= ( 1.0 - clamp01( discardTreshold ) ) )
{
position3D.y += discardOffset;
}
TRANSFORM = TRS( position3D, rot, vec3( sca.x , sca.y, sca.z ) );
}

View File

@ -10,7 +10,6 @@ render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_sc
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap_anisotropic, repeat_enable;
uniform ivec2 albedo_texture_size;
uniform float point_size : hint_range(0.1, 128.0, 0.1);
uniform float roughness : hint_range(0.0, 1.0);
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
@ -29,8 +28,6 @@ varying vec3 uv1_power_normal;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
uniform vec2 mapSize = vec2(1024,1024);
uniform vec2 mapCenter = vec2(0,0);
@ -98,7 +95,7 @@ void fragment()
vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
float roughness_tex = dot(triplanar_texture(texture_roughness, uv1_power_normal, uv1_triplanar_pos), roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
ROUGHNESS = clamp(roughness_tex * roughness,0,1);
vec3 worldNormal = computeNormalFromHeightMap( heightMap, heightUV, normalTexelSize, normalHeightSize );
NORMAL = worldToViewDirection( worldNormal, VIEW_MATRIX );

View File

@ -40,7 +40,7 @@ namespace Rokojori
return;
}
_pipeline = RDPipeline.Create( context, _shader );
_pipeline = RDPipeline.CreateRender( context, _shader );
if ( _shader == null )
{

View File

@ -90,7 +90,7 @@ namespace Rokojori
public void SetProgramFromPath( string path )
{
Verbose( "Creating program:", path );
var program = RDProgram.FromPath( this, path );
var program = RDProgram.ComputeFromPath( this, path );
SetProgram( program );
}

View File

@ -0,0 +1,31 @@
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RenderingManager.svg") ]
public partial class DefaultRenderAssets:Resource
{
[Export]
public string prefix = "RJ_";
[ExportGroup("Noise")]
[Export]
public Sampler2DProperty noise;
[Export]
public Sampler2DProperty perlin;
[Export]
public Sampler2DProperty voronoi;
}
}

View File

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

View File

@ -0,0 +1,20 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class RDFrameBuffer: RDObject
{
public RDFrameBuffer( RDContext context, Rid rid ):base( context, rid )
{}
public static RDFrameBuffer Create( RDContext context, List<RDTexture> textures, RDFrameBufferFormat format )
{
var RD = context.renderingDevice;
var rid = RD.FramebufferCreate( textures.Map( t => t.rid ).ToGodotArray(), format.id );
return new RDFrameBuffer( context, rid );
}
}
}

View File

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

View File

@ -0,0 +1,28 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class RDFrameBufferFormat
{
RDContext _context;
long _id;
public long id => _id;
public RDFrameBufferFormat( RDContext context, long id )
{
_context = context;
_id = id;
}
public static RDFrameBufferFormat Create( RDContext context, List<RDAttachmentFormat> formats, int viewCount = 1 )
{
var id = context.renderingDevice.FramebufferFormatCreate( formats.ToGodotArray(), (uint)viewCount );
return new RDFrameBufferFormat( context, id );
}
}
}

View File

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

View File

@ -8,9 +8,21 @@ namespace Rokojori
public RDPipeline( RDContext context, Rid rid ):base( context, rid )
{}
public static RDPipeline Create( RDContext context, RDShader shader )
public static RDPipeline CreateCompute( RDContext context, RDShader shader )
{
return new RDPipeline( context, context.renderingDevice.ComputePipelineCreate( shader.rid ) );
}
public static RDPipeline CreateRender( RDContext context, RDShader shader, RDRenderPipelineSetup setup )
{
var pipelineRid = context.renderingDevice.RenderPipelineCreate(
shader.rid, setup.frameBufferFormat.id, setup.vertexFormat.id,
setup.primitive, setup.rasterizationState,
setup.multisampleState,
setup.stencilState, setup.blendState
);
return new RDPipeline( context, pipelineRid );
}
}
}

View File

@ -30,7 +30,7 @@ namespace Rokojori
protected RDPipeline _pipeline;
public RDPipeline pipeline => _pipeline;
public static RDProgram FromPath( RDContext context, string path )
public static RDProgram ComputeFromPath( RDContext context, string path )
{
var p = new RDProgram( context );
@ -42,7 +42,7 @@ namespace Rokojori
return null;
}
p._pipeline = RDPipeline.Create( context, p._shader );
p._pipeline = RDPipeline.CreateCompute( context, p._shader );
if ( p._pipeline == null || ! p._pipeline.rid.IsValid )
{
@ -53,4 +53,29 @@ namespace Rokojori
return p;
}
}
public static RDProgram RenderFromPath( RDContext context, string path, RDRenderPipelineSetup setup )
{
var p = new RDProgram( context );
p._shader = RDShader.FromPath( context, path );
if ( p._shader == null || ! p._shader.rid.IsValid )
{
context.Error( "Invalid shader", path );
return null;
}
p._pipeline = RDPipeline.CreateRender( context, p._shader, setup );
if ( p._pipeline == null || ! p._pipeline.rid.IsValid )
{
context.Error( "Invalid pipeline", path );
return null;
}
return p;
}
}
}
}

View File

@ -0,0 +1,57 @@
using Godot;
using System;
using System.Collections.Generic;
namespace Rokojori
{
public class RDRenderPipelineSetup
{
public RDFrameBufferFormat frameBufferFormat;
public RDVertexFormat vertexFormat;
public RDPipelineRasterizationState rasterizationState;
public RDPipelineMultisampleState multisampleState;
public RDPipelineDepthStencilState stencilState;
public RDPipelineColorBlendState blendState;
public RenderingDevice.RenderPrimitive primitive;
public static RDPipelineColorBlendState CreateBlendState()
{
var blend = new RDPipelineColorBlendState();
var blendAttachment = new RDPipelineColorBlendStateAttachment();
blend.Attachments.Add( blendAttachment );
return blend;
}
public static RDPipelineDepthStencilState CreateStencilState(
RenderingDevice.CompareOperator compareOperator, int mask, int reference,
RenderingDevice.StencilOperation failOperation, RenderingDevice.StencilOperation passOperation
)
{
var stencil_state = new RDPipelineDepthStencilState();
stencil_state.FrontOpCompare = compareOperator;
stencil_state.FrontOpCompareMask = (uint) mask;
stencil_state.FrontOpReference = (uint) reference;
stencil_state.FrontOpFail = failOperation;
stencil_state.FrontOpPass = passOperation;
return stencil_state;
}
public static RDRenderPipelineSetup Create( RDFrameBufferFormat fbFormat, RDVertexFormat vxFormat, RDPipelineDepthStencilState stencilState )
{
var setup = new RDRenderPipelineSetup();
setup.rasterizationState = new RDPipelineRasterizationState();
setup.multisampleState = new RDPipelineMultisampleState();
setup.primitive = RenderingDevice.RenderPrimitive.Triangles;
setup.blendState = CreateBlendState();
setup.stencilState = stencilState;
return setup;
}
}
}

View File

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

View File

@ -5,7 +5,7 @@ namespace Rokojori
{
public class RDSampler: RDObject
{
public RDSampler( RDContext effect, Rid rid ):base( effect, rid )
public RDSampler( RDContext context, Rid rid ):base( context, rid )
{}
public static RDSampler Create( RDContext context, RDSamplerState samplerState )

View File

@ -0,0 +1,26 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class RDVertexFormat
{
RDContext _context;
long _id;
public long id => _id;
public RDVertexFormat( RDContext context, long id )
{
_context = context;
_id = id;
}
public static RDVertexFormat Create( RDContext context, List<RDVertexAttribute> vertexAttributes )
{
var id = context.renderingDevice.VertexFormatCreate( vertexAttributes.ToGodotArray() );
return new RDVertexFormat( context, id );
}
}
}

View File

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

View File

@ -46,7 +46,7 @@ namespace Rokojori
return;
}
_pipeline = RDPipeline.Create( graph.context, _shader );
_pipeline = RDPipeline.CreateRender( graph.context, _shader );
if ( _shader == null )
{

View File

@ -8,8 +8,8 @@ using Godot;
namespace Rokojori
{
[Tool]
[GlobalClass]
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RenderingManager.svg") ]
public partial class RenderingManager:Node
{
[Export]

View File

@ -18,5 +18,8 @@ namespace Rokojori
[Export]
public StencilLayer[] stencilLayers;
[Export]
public ShaderProperty[] globalShaderProperties;
}
}

View File

@ -87,6 +87,8 @@ namespace Rokojori
public static List<ShaderCode> IncludeLightLibrary(){ return IncludeFromLibrary( "Light" ); }
public static List<ShaderCode> IncludeUVLibrary(){ return IncludeFromLibrary( "UV" ); }
public static ShaderVariant ToVariant( List<ShaderCode> code )
{
var variant = new ShaderVariant();

View File

@ -0,0 +1,22 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public enum VertexSwizzleType
{
XX,
YY,
ZZ,
XY,
YX,
XZ,
ZX,
YZ,
ZY
}
}

View File

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

View File

@ -0,0 +1,13 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
public enum VertexTransformSpace
{
Local,
World,
View
}
}

View File

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

View File

@ -0,0 +1,46 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class UVChannel:ShaderGenerationModule
{
[Export]
public string uvTarget = "UV";
[Export]
public UVSource uvSource = new MeshUVSource();
[Export]
public UVModifier modifier = new UVScaleOffset();
public List<ShaderCode> GetShaderCode( ShaderGenerationContext context )
{
var sourceCode = uvSource.GetUV( context, uvTarget, 0 );
var modifierCode = modifier.ModifyUV( context, uvTarget );
if ( sourceCode == null && modifierCode == null )
{
return null;
}
var list = new List<ShaderCode>();
if ( sourceCode != null )
{
list.AddRange( sourceCode );
}
if ( modifierCode != null )
{
list.AddRange( modifierCode );
}
return list;
}
}
}

View File

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

View File

@ -6,8 +6,8 @@ namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class UVModifier:ShaderGenerationModule
public abstract partial class UVModifier:ShaderGenerationModule
{
public abstract List<ShaderCode> ModifyUV( ShaderGenerationContext context, string uvTarget );
}
}

View File

@ -8,38 +8,56 @@ namespace Rokojori
[GlobalClass]
public partial class UVModule:ShaderGenerationModule
{
[Export]
public UVScaleOffset uvScaleOffset = new UVScaleOffset();
// [Export]
// public UVScaleOffset uvScaleOffset = new UVScaleOffset();
// [Export]
// public UVModifier[] modifiers = [];
[Export]
public UVModifier[] modifiers = [];
public UVChannel[] channels = [ ];
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
var list = new List<ShaderVariant>();
var list = new List<ShaderCode>();
var allModifiers = Lists.From( modifiers ).FilterNulls();
if ( uvScaleOffset != null )
{
allModifiers.Insert( 0, uvScaleOffset );
}
allModifiers.ForEach(
( m )=>
channels.ForEach(
( c )=>
{
var variants = m.GetVariants( context );
if ( variants == null )
var code = c.GetShaderCode( context );
if ( code == null )
{
return;
}
list = ShaderVariant.CombineVariants( list, variants );
list.AddRange( code );
}
);
// var list = new List<ShaderVariant>();
return list;
// var allModifiers = Lists.From( modifiers ).FilterNulls();
// if ( uvScaleOffset != null )
// {
// allModifiers.Insert( 0, uvScaleOffset );
// }
// allModifiers.ForEach(
// ( m )=>
// {
// var variants = m.GetVariants( context );
// if ( variants == null )
// {
// return;
// }
// list = ShaderVariant.CombineVariants( list, variants );
// }
// );
return ToVariants( list );
}
}
}

View File

@ -21,7 +21,8 @@ namespace Rokojori
public string target = "UV";
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
public override List<ShaderCode> ModifyUV( ShaderGenerationContext context, string uvTarget )
{
if ( ShaderPhase.Variables == context.phase )
{
@ -36,7 +37,7 @@ namespace Rokojori
);
return ToVariants( AsUniformGroup( "UV", lines.Join( "" ) ) );
return AsUniformGroup( "UV", lines.Join( "" ) );
}
@ -61,7 +62,7 @@ namespace Rokojori
expression += ";";
return ToVariants( ToCode( expression ) );
return ToCode( expression );
}

View File

@ -0,0 +1,48 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class MeshUVSource:UVSource
{
public enum MeshUV
{
UV,
UV2,
CUSTOM0_XY,
CUSTOM0_YW,
CUSTOM1_XY,
CUSTOM1_YW,
CUSTOM2_XY,
CUSTOM2_YW,
CUSTOM3_XY,
CUSTOM3_YW,
COLOR_XY,
COLOR_ZW
}
[Export]
public MeshUV meshUV;
public override List<ShaderCode> GetUV( ShaderGenerationContext context, string target, int offsetIndex )
{
if ( ShaderPhase.Vertex != context.phase )
{
return null;
}
var meshUVstring = meshUV + "";
if ( meshUVstring[ meshUVstring.Length - 3 ] == '_' )
{
var member = "." + meshUVstring.Substring( meshUVstring.Length - 2 );
meshUVstring = meshUVstring.Substring( 0, meshUVstring.Length - 3 ) + member;
}
return ShaderGenerationModule.ToCode( $"{target} = {meshUVstring};" );
}
}
}

View File

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

View File

@ -0,0 +1,13 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public abstract partial class UVSource:Resource
{
public abstract List<ShaderCode> GetUV( ShaderGenerationContext context, string target, int offsetIndex );
}
}

View File

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

View File

@ -0,0 +1,83 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class VertexUVSource:UVSource
{
[Export]
public VertexTransformSpace space;
[Export]
public VertexSwizzleType dimensions;
[Export]
public string sizeCustomName;
[Export]
public string centerCustomName;
public override List<ShaderCode> GetUV( ShaderGenerationContext context, string target, int offsetIndex )
{
var size = sizeCustomName == null ? "vertexUVSourceSize" : sizeCustomName;
var center = centerCustomName == null ? "vertexUVSourceCenter" : centerCustomName;
var suffix = offsetIndex == 0 ? "" : ( "_" + ( offsetIndex + 1 ) );
size += suffix;
center += suffix;
if ( ShaderPhase.Includes == context.phase )
{
return ShaderGenerationModule.IncludeUVLibrary();
}
else if ( ShaderPhase.Variables == context.phase )
{
var uniforms =
@$"
uniform vec2 {size};
uniform vec2 {center};
";
return ShaderGenerationModule.ToCode( uniforms.Indent( "" ) );
}
if ( ShaderPhase.Vertex != context.phase )
{
return null;
}
var member = ( dimensions + "" ).ToLower();
var vertex = "VERTEX";
if ( VertexTransformSpace.World == space )
{
vertex = "localToWorld( VERTEX, MODEL_MATRIX )";
}
else if ( VertexTransformSpace.View == space )
{
vertex = "localToView( VERTEX, MODELVIEW_MATRIX )";
}
var code =
@$"
{{
vec3 vertex = {vertex};
{target} = mapUV( vertex.{member}, {size}, {center} );
}}
";
return ShaderGenerationModule.ToCode( code.Indent( " ") );
}
}
}

View File

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

View File

@ -0,0 +1,9 @@
// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/UV.gdshaderinc"
vec2 mapUV( vec2 position, vec2 size, vec2 center )
{
vec2 offset = center - size/2.0;
vec2 uv = ( position - offset ) / mapSize;
return uv;
}

View File

@ -0,0 +1 @@
uid://7uu03yaikt2

View File

@ -0,0 +1,35 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Sampler2DProperty : ShaderProperty
{
[Export]
public Sampler2DPropertyName propertyName;
[Export]
public Texture2D value;
public override void Apply( Material material )
{
propertyName.Set( material, value );
}
public void ReadFrom( Material material )
{
value = propertyName.Get( material );
}
public static Sampler2DProperty Create( string name, Texture2D value )
{
var sp = new Sampler2DProperty();
sp.propertyName = Sampler2DPropertyName.Create( name );
sp.value = value;
return sp;
}
}
}

View File

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

View File

@ -6,7 +6,7 @@ namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class ShaderProperty : Resource
public abstract partial class ShaderProperty : Resource
{
public virtual void Apply( Material material )
{

View File

@ -28,7 +28,7 @@ namespace Rokojori
public void ApplyLerped( Material material, Vector3 from, float lerpState )
{
var lerpedValue = Math3D.Lerp( from, value, lerpState );
Vector3 lerpedValue = Math3D.Lerp( from, value, lerpState );
propertyName.Set( material, lerpedValue );
}

View File

@ -0,0 +1,43 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Vector4Property : ShaderProperty
{
[Export]
public Vector4PropertyName propertyName;
public string name => propertyName.propertyName;
[Export]
public Vector4 value;
public override void Apply( Material material )
{
propertyName.Set( material, value );
}
public void ReadFrom( Material material )
{
value = propertyName.Get( material );
}
public void ApplyLerped( Material material, Vector4 from, float lerpState )
{
var lerpedValue = from.Lerp( value, lerpState );
propertyName.Set( material, lerpedValue );
}
public static Vector4Property Create( string name, Vector4 value )
{
var fp = new Vector4Property();
fp.propertyName = Vector4PropertyName.Create( name );
fp.value = value;
return fp;
}
}
}

View File

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

View File

@ -0,0 +1,29 @@
using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class Sampler2DPropertyName : ShaderPropertyName
{
public void Set( Material material, Texture2D value )
{
_Set( material, value );
}
public Texture2D Get( Material material )
{
return _Get<Texture2D>( material, null );
}
public static Sampler2DPropertyName Create( string name )
{
var p = new Sampler2DPropertyName();
p.propertyName = name;
return p;
}
}
}

View File

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

View File

@ -1081,6 +1081,11 @@ namespace Rokojori
return list;
}
public static Godot.Collections.Array<T> ToGodotArray<[MustBeVariant] T>( this List<T> values )
{
return [.. values];
}
public static List<U> Map<[Godot.MustBeVariant]T,U>( Godot.Collections.Array<T> inputList, Func<T,U> mapper, List<U> list = null )
{
if ( list == null )