Foliage Update
This commit is contained in:
parent
fe2460239f
commit
94c90e03e7
|
@ -21,6 +21,16 @@ namespace Rokojori
|
|||
return GetAnyChild<T>( node );
|
||||
}
|
||||
|
||||
public static T GetSelfOrChildOf<T>( this Node node ) where T:Node
|
||||
{
|
||||
if ( node is T t )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return GetAnyChild<T>( node );
|
||||
}
|
||||
|
||||
public static T GetChild<T>( this Node node ) where T:Node
|
||||
{
|
||||
return GetDirectChild<T>( node );
|
||||
|
|
|
@ -44,6 +44,20 @@ namespace Rokojori
|
|||
return b;
|
||||
}
|
||||
|
||||
public static Box3 WithSize( Vector3 size )
|
||||
{
|
||||
size = size.Abs();
|
||||
var max = size * 0.5f;
|
||||
var min = -max;
|
||||
|
||||
return Box3.Create( min, max );
|
||||
}
|
||||
|
||||
public static Box3 WithSize( float size )
|
||||
{
|
||||
return WithSize( Vector3.One * size );
|
||||
}
|
||||
|
||||
public static Box3 Create<T>( List<T> data, System.Func<T,Vector3> getPosition )
|
||||
{
|
||||
var min = new Vector3( float.MaxValue, float.MaxValue, float.MaxValue );
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 MiB |
|
@ -0,0 +1,35 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c30nul6romace"
|
||||
path.s3tc="res://.godot/imported/Foliage Renderer Default Noise.png-18f32fa6cf85749d36ab7c25bf9094e5.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Assets/Foliage/Foliage Renderer Default Noise.png"
|
||||
dest_files=["res://.godot/imported/Foliage Renderer Default Noise.png-18f32fa6cf85749d36ab7c25bf9094e5.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
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=0
|
|
@ -0,0 +1,14 @@
|
|||
[gd_resource type="Resource" script_class="TextureCombiner" load_steps=2 format=3 uid="uid://bmesbkwqek8ck"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://2srq0trsfhq1" path="res://addons/rokojori_action_library/Runtime/Procedural/Textures/TextureCombiner/TextureCombiner.cs" id="1_10cp2"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_10cp2")
|
||||
createMipmaps = true
|
||||
create = false
|
||||
autoCreate = false
|
||||
width = 1024
|
||||
height = 1024
|
||||
_creatingTexture = false
|
||||
_blockSize = 512
|
||||
metadata/_custom_type_script = "uid://2srq0trsfhq1"
|
|
@ -0,0 +1,105 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
/** <summary for="class FoliageData">
|
||||
|
||||
<title>
|
||||
Resource to define foliage data
|
||||
</title>
|
||||
|
||||
<description>
|
||||
|
||||
</description>
|
||||
|
||||
</summary>
|
||||
*/
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ]
|
||||
public partial class FoliageData:Resource
|
||||
{
|
||||
|
||||
[Export]
|
||||
public float cellSize;
|
||||
|
||||
[Export]
|
||||
public float visibilityRange;
|
||||
|
||||
[Export]
|
||||
public float visibilityFadeRelative = 0.1f;
|
||||
|
||||
[Export]
|
||||
public float visibilityFadeAbsolute = 0f;
|
||||
|
||||
[Export]
|
||||
public float visibilityFadeHidingOffset = -0.7f;
|
||||
|
||||
/** <summary for="field renderPriority">Render priority, only for transparent objects</summary>*/
|
||||
[Export]
|
||||
public int renderPriority;
|
||||
|
||||
|
||||
|
||||
[Export]
|
||||
public string layerName;
|
||||
|
||||
[Export]
|
||||
public Vector3 positionVarianceMaxOffset = Vector3.Zero;
|
||||
[Export]
|
||||
public float positionVarianceScale = 1f;
|
||||
[Export]
|
||||
public Vector2 positionVarianceOffset = Vector2.Zero;
|
||||
|
||||
[Export]
|
||||
public Vector3 rotationMin = Vector3.Zero;
|
||||
[Export]
|
||||
public Vector3 rotationMax = new Vector3( 0, 1, 0 );
|
||||
|
||||
[Export]
|
||||
public float rotationVarianceScale = 1f;
|
||||
[Export]
|
||||
public Vector2 rotationVarianceOffset = Vector2.Zero;
|
||||
|
||||
|
||||
[Export]
|
||||
public Vector3 scaleVarianceMinScale = Vector3.One;
|
||||
[Export]
|
||||
public Vector3 scaleVarianceMaxScale = Vector3.One;
|
||||
[Export]
|
||||
public float scaleVarianceScale = 1f;
|
||||
[Export]
|
||||
public Vector2 scaleVarianceOffset = Vector2.Zero;
|
||||
|
||||
|
||||
[Export(PropertyHint.Range,"0,1")]
|
||||
public float occupancyVarianceAmount = 1f;
|
||||
[Export(PropertyHint.Range,"0,50")]
|
||||
public float occupancyVariancePower = 0f;
|
||||
|
||||
[Export(PropertyHint.Range,"0,1")]
|
||||
public float occupancyTreshold = 0f;
|
||||
|
||||
[Export]
|
||||
public float occupancyHideOffset = -3f;
|
||||
[Export]
|
||||
public float occupancyHideScale = 0.1f;
|
||||
|
||||
[Export]
|
||||
public float occupancyVarianceScale = 1f;
|
||||
[Export]
|
||||
public Vector2 occupancyVarianceOffset = Vector2.Zero;
|
||||
|
||||
public virtual void Initialize( FoliageRenderLayer renderLayer )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://bcl28l8d5lxye
|
|
@ -0,0 +1,106 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
/** <summary for="class FoliageRenderLayer">
|
||||
|
||||
<title>
|
||||
Is used by the FoliageRenderer to book keep and render a layer defined by the FoliageData.
|
||||
|
||||
</title>
|
||||
|
||||
<description>
|
||||
|
||||
|
||||
</description>
|
||||
|
||||
</summary>
|
||||
*/
|
||||
|
||||
public class FoliageRenderLayer
|
||||
{
|
||||
public FoliageRenderer renderer;
|
||||
public FoliageData data;
|
||||
public GpuParticles3D gpuParticles3D;
|
||||
public GPUFoliageShaderMaterial gpuFoliageShaderMaterial;
|
||||
float _lastCellSize = -1;
|
||||
float _lastMaxVisibility = -1;
|
||||
|
||||
public static FoliageRenderLayer Create( FoliageRenderer renderer, FoliageData data )
|
||||
{
|
||||
var rl = new FoliageRenderLayer();
|
||||
rl.renderer = renderer;
|
||||
rl.data = data;
|
||||
|
||||
|
||||
return rl;
|
||||
}
|
||||
|
||||
public void Update( double delta )
|
||||
{
|
||||
if ( gpuFoliageShaderMaterial != null )
|
||||
{
|
||||
gpuFoliageShaderMaterial.cameraPosition.Set( renderer.GetAssignedCamera().GlobalPosition );
|
||||
|
||||
var sizeInt = Mathf.CeilToInt( data.visibilityRange / data.cellSize ) * 2;
|
||||
|
||||
if ( _lastCellSize != data.cellSize || _lastMaxVisibility != data.visibilityRange )
|
||||
{
|
||||
_lastCellSize = data.cellSize;
|
||||
_lastMaxVisibility = data.visibilityRange;
|
||||
|
||||
gpuFoliageShaderMaterial.cellSize.Set( data.cellSize );
|
||||
|
||||
|
||||
|
||||
|
||||
gpuParticles3D.Amount = sizeInt * sizeInt;
|
||||
gpuFoliageShaderMaterial.width.Set( sizeInt );
|
||||
gpuFoliageShaderMaterial.height.Set( sizeInt );
|
||||
|
||||
}
|
||||
|
||||
var hideStart = data.visibilityRange - ( data.visibilityRange * data.visibilityFadeRelative + data.visibilityFadeAbsolute );
|
||||
gpuFoliageShaderMaterial.hideMax.Set( data.visibilityRange );
|
||||
gpuFoliageShaderMaterial.hideStart.Set( hideStart );
|
||||
gpuFoliageShaderMaterial.hideOffset.Set( data.visibilityFadeHidingOffset );
|
||||
|
||||
gpuFoliageShaderMaterial.positionVariance.Set( renderer.noise );
|
||||
gpuFoliageShaderMaterial.rotationVariance.Set( renderer.noise );
|
||||
gpuFoliageShaderMaterial.scaleVariance.Set( renderer.noise );
|
||||
gpuFoliageShaderMaterial.occupancyVariance.Set( renderer.noise );
|
||||
|
||||
gpuFoliageShaderMaterial.maxPositionOffset.Set( data.positionVarianceMaxOffset );
|
||||
gpuFoliageShaderMaterial.positionUvScale.Set( Vector2.One * data.positionVarianceScale );
|
||||
gpuFoliageShaderMaterial.positionUvOffset.Set( Vector2.One * data.positionVarianceOffset );
|
||||
|
||||
gpuFoliageShaderMaterial.minRotation.Set( data.rotationMin );
|
||||
gpuFoliageShaderMaterial.maxRotation.Set( data.rotationMax );
|
||||
gpuFoliageShaderMaterial.rotationUvScale.Set( Vector2.One * data.rotationVarianceScale );
|
||||
gpuFoliageShaderMaterial.rotationUvOffset.Set( Vector2.One * data.rotationVarianceOffset );
|
||||
|
||||
gpuFoliageShaderMaterial.minScale.Set( data.scaleVarianceMinScale );
|
||||
gpuFoliageShaderMaterial.maxScale.Set( data.scaleVarianceMaxScale );
|
||||
gpuFoliageShaderMaterial.scaleUvScale.Set( Vector2.One * data.scaleVarianceScale );
|
||||
gpuFoliageShaderMaterial.scaleUvOffset.Set( Vector2.One * data.scaleVarianceOffset );
|
||||
|
||||
gpuFoliageShaderMaterial.occupancyAmount.Set( data.occupancyVarianceAmount );
|
||||
gpuFoliageShaderMaterial.occupancyPower.Set( data.occupancyVariancePower );
|
||||
gpuFoliageShaderMaterial.occupancyTreshold.Set( data.occupancyTreshold );
|
||||
|
||||
gpuFoliageShaderMaterial.occupancyHideOffset.Set( data.occupancyHideOffset );
|
||||
gpuFoliageShaderMaterial.occupancyHideScale.Set( data.occupancyHideScale );
|
||||
|
||||
gpuFoliageShaderMaterial.occupancyUvScale.Set( Vector2.One * data.occupancyVarianceScale );
|
||||
gpuFoliageShaderMaterial.occupancyUvOffset.Set( Vector2.One * data.occupancyVarianceOffset );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://6ie7ggcqvjtj
|
|
@ -0,0 +1,97 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
/** <summary for="class FoliageRenderer">
|
||||
|
||||
<title>
|
||||
A node to render foliage.
|
||||
</title>
|
||||
|
||||
<description>
|
||||
The GrassPatch has various settings to create a different styles of grass.
|
||||
It allows to change the shapes of the blades, their number and distribution, their triangle count,
|
||||
rotation and scale, LOD levels and much more.
|
||||
|
||||
|
||||
</description>
|
||||
|
||||
</summary>
|
||||
*/
|
||||
|
||||
[Tool]
|
||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Scatterer.svg") ]
|
||||
public partial class FoliageRenderer:Node
|
||||
{
|
||||
[Export]
|
||||
public FoliageData[] foliage;
|
||||
|
||||
List<FoliageRenderLayer> renderLayers = [];
|
||||
|
||||
[Export]
|
||||
public bool processLayers = true;
|
||||
|
||||
[Export]
|
||||
public bool updateLayers = true;
|
||||
|
||||
[Export]
|
||||
public Camera3D camera;
|
||||
|
||||
|
||||
Camera3D _assignedCamera;
|
||||
|
||||
[Export]
|
||||
public Texture2D noise;
|
||||
|
||||
public Camera3D GetAssignedCamera()
|
||||
{
|
||||
return _assignedCamera;
|
||||
}
|
||||
|
||||
public override void _Process( double delta )
|
||||
{
|
||||
_assignedCamera = null;
|
||||
|
||||
if ( ! processLayers )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( updateLayers || foliage.Length != renderLayers.Count )
|
||||
{
|
||||
updateLayers = false;
|
||||
this.DestroyChildren();
|
||||
renderLayers = foliage.Map<FoliageData,FoliageRenderLayer>( f => FoliageRenderLayer.Create( this, f ) ).ToList();
|
||||
renderLayers.ForEach( r => r.data.Initialize( r ) );
|
||||
}
|
||||
|
||||
|
||||
if ( Engine.IsEditorHint() )
|
||||
{
|
||||
_assignedCamera = EditorInterface.Singleton.GetEditorViewport3D().GetCamera3D();
|
||||
}
|
||||
else
|
||||
{
|
||||
_assignedCamera = camera;
|
||||
}
|
||||
|
||||
if ( _assignedCamera == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// this.LogInfo( "Processing", renderLayers.Count );
|
||||
|
||||
renderLayers.ForEach( r => r.Update( delta ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://b1sjdhnriaeg6
|
|
@ -0,0 +1,75 @@
|
|||
shader_type spatial;
|
||||
render_mode blend_mix, depth_draw_never, cull_back, diffuse_burley, specular_schlick_ggx;
|
||||
|
||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc"
|
||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
|
||||
|
||||
uniform vec4 albedo : source_color;
|
||||
uniform sampler2D albedoTexture: source_color, filter_linear_mipmap, repeat_enable;
|
||||
uniform float albedoUV;
|
||||
uniform float albedoFadeDistance;
|
||||
|
||||
uniform sampler2D opacity : filter_linear_mipmap, repeat_enable;
|
||||
uniform float opacityVarianceScale = 1.0;
|
||||
uniform float opacityScale = 1.0;
|
||||
uniform float opacityTreshold = 0.5;
|
||||
|
||||
uniform float opacityVarianceScale2 = 1.0;
|
||||
uniform float opacityScale2 = 1.0;
|
||||
uniform float opacityTreshold2 = 0.5;
|
||||
uniform float opacity2Amount: hint_range( 0.0, 1.0 ) = 0.5;
|
||||
|
||||
uniform float roughness : hint_range( 0.0, 1.0 );
|
||||
uniform float specular : hint_range( 0.0, 1.0 );
|
||||
uniform float metallic : hint_range( 0.0, 1.0 );
|
||||
|
||||
uniform sampler2D texture_normal : hint_roughness_normal, filter_linear_mipmap, repeat_enable;
|
||||
uniform float normal_scale : hint_range(0, 2);
|
||||
uniform float normal_uv = 1.0;
|
||||
|
||||
uniform vec2 mapSize;
|
||||
uniform vec2 mapCenter;
|
||||
|
||||
uniform float fadeOutMax;
|
||||
uniform float fadeOutStart;
|
||||
|
||||
varying vec2 positionUV;
|
||||
|
||||
void vertex()
|
||||
{
|
||||
VERTEX += CAMERA_POSITION_WORLD * vec3( 1.0, 0.0, 1.0);
|
||||
|
||||
positionUV = UV;
|
||||
|
||||
UV = worldUVfromLocalXZ( VERTEX, mapCenter, mapSize, MODEL_MATRIX );
|
||||
}
|
||||
|
||||
void fragment()
|
||||
{
|
||||
vec2 uv = UV;
|
||||
|
||||
float d = length( positionUV - vec2( 0.5, 0.5 ) );
|
||||
float fading = 1.0 - clamp01( d / 0.5 );
|
||||
float albedoFading = 1.0 - clamp01( d / albedoFadeDistance );
|
||||
vec4 sampledAlbedo = texture( albedoTexture, uv * albedoUV );
|
||||
ALBEDO = albedo.rgb * mix( vec3( 1, 1, 1 ), sampledAlbedo.rgb, albedoFading );
|
||||
|
||||
METALLIC = metallic;
|
||||
SPECULAR = specular;
|
||||
ROUGHNESS = roughness;
|
||||
|
||||
float sampledOpacity = texture( opacity, uv * opacityVarianceScale ).r;
|
||||
sampledOpacity = ( sampledOpacity - opacityTreshold ) * opacityScale + opacityTreshold;
|
||||
sampledOpacity = clamp01( sampledOpacity );
|
||||
|
||||
float sampledOpacity2 = texture( opacity, uv * opacityVarianceScale2 ).r;
|
||||
sampledOpacity2 = ( sampledOpacity2 - opacityTreshold2 ) * opacityScale2 + opacityTreshold2;
|
||||
sampledOpacity2 = mix( 1, clamp01( sampledOpacity2 ), opacity2Amount );
|
||||
|
||||
|
||||
|
||||
NORMAL_MAP = texture( texture_normal, uv * normal_uv ).rgb;
|
||||
NORMAL_MAP_DEPTH = normal_scale;
|
||||
|
||||
ALPHA *= albedo.a * sampledOpacity * sampledOpacity2 * mix( 1, sampledAlbedo.a, albedoFading ) * fading;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://dffj0xp766wka
|
|
@ -0,0 +1,97 @@
|
|||
shader_type particles;
|
||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc"
|
||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
|
||||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Textures.gdshaderinc"
|
||||
|
||||
uniform vec3 cameraPosition;
|
||||
uniform float yaw;
|
||||
uniform float cellSize = 1.0;
|
||||
uniform int width = 10;
|
||||
uniform int height = 10;
|
||||
|
||||
uniform sampler2D positionVariance;
|
||||
uniform vec3 maxPositionOffset = vec3(0,0,0);
|
||||
uniform vec2 positionUVScale = vec2( 1.0, 1.0 );
|
||||
uniform vec2 positionUVOffset = vec2( 1.0, 1.0 );
|
||||
uniform float heightOffset = 0;
|
||||
|
||||
uniform sampler2D rotationVariance;
|
||||
uniform vec3 minRotation = vec3( 0, 0, 0 );
|
||||
uniform vec3 maxRotation = vec3( 0, 1, 0 );
|
||||
uniform vec2 rotationUVScale = vec2( 1.0, 1.0 );
|
||||
uniform vec2 rotationUVOffset = vec2( 1.0, 1.0 );
|
||||
|
||||
uniform sampler2D scaleVariance;
|
||||
uniform vec3 minScale = vec3( 1, 1, 1 );
|
||||
uniform vec3 maxScale = vec3( 1, 1, 1 );
|
||||
uniform vec2 scaleUVScale = vec2( 1.0, 1.0 );
|
||||
uniform vec2 scaleUVOffset = vec2( 1.0, 1.0 );
|
||||
|
||||
uniform float occupancyAmount = 0;
|
||||
uniform float occupancyPower = 0;
|
||||
uniform float occupancyTreshold = 0.5;
|
||||
uniform float occupancyHideOffset = -3;
|
||||
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 float hideStart = 40;
|
||||
uniform float hideMax = 60;
|
||||
uniform float hideOffset = -0.6;
|
||||
|
||||
uniform vec2 mapSize = vec2(1024,1024);
|
||||
uniform vec2 mapCenter = vec2(0,0);
|
||||
|
||||
vec2 indexToPosition( int index )
|
||||
{
|
||||
int x = index % width;
|
||||
int y = index / height;
|
||||
|
||||
return vec2( float(x), float(y) );
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
vec2 position = indexToPosition( int(INDEX) );
|
||||
float rotation = round( 4.0 * yaw / 360.0 ) * PI / 2.0;
|
||||
|
||||
vec3 snappedCameraPosition = vec3(
|
||||
floor( cameraPosition.x / cellSize ) * cellSize,
|
||||
0,
|
||||
floor( cameraPosition.z / cellSize ) * cellSize
|
||||
);
|
||||
|
||||
vec2 origin = vec2( float(width)/2.0, float(height)/2.0 );
|
||||
position -= origin;
|
||||
|
||||
position = rotate_v2( position, rotation ) * cellSize;
|
||||
|
||||
|
||||
vec3 position3D = vec3( position.x, heightOffset, position.y ) + snappedCameraPosition;
|
||||
|
||||
float d = length( position3D - cameraPosition );
|
||||
float yOffset = mapClamped( d, hideStart, hideMax, 0, hideOffset );
|
||||
position3D.y += yOffset;
|
||||
|
||||
|
||||
vec2 mapOffset = mapCenter - mapSize/2.0;
|
||||
vec2 uv = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize;
|
||||
|
||||
vec3 offset = (textureLod( positionVariance, tilingOffset( uv, positionUVScale, positionUVOffset ), 0 ).rgb - vec3(0.5,0.5,0.5) ) * maxPositionOffset;
|
||||
position3D += offset;
|
||||
vec3 rotSampled = textureLod( rotationVariance, tilingOffset( uv, rotationUVScale, rotationUVOffset ), 0 ).rgb;
|
||||
vec3 rot = ( rotSampled * ( maxRotation - minRotation ) + minRotation ) * PI * 2.0;
|
||||
// rot.y = round( 4.0 * rot.y / PI * 2.0 ) / 4.0 * PI * 2.0;
|
||||
vec3 sca = textureLod( scaleVariance, tilingOffset( uv, scaleUVScale, scaleUVOffset ), 0 ).rgb;
|
||||
sca = sca * ( maxScale - minScale ) + minScale;
|
||||
|
||||
vec2 uv2 = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize;
|
||||
|
||||
float occ = textureLod( occupancyVariance, tilingOffset( uv2, occupancyUVScale, occupancyUVOffset ), 0 ).r;
|
||||
occ = clamp( ( occ - occupancyTreshold ) * occupancyPower + occupancyTreshold, 0.0, 1.0 );
|
||||
sca *= mix( 1.0, occupancyHideScale , ( 1.0 - occ ) * occupancyAmount );
|
||||
position3D.y += ( 1.0 - occ ) * occupancyAmount * occupancyHideOffset;
|
||||
TRANSFORM = TRS( position3D, rot, vec3( sca.x , sca.y, sca.z ) );
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://brk5g221ccd2x
|
|
@ -0,0 +1,129 @@
|
|||
using Godot;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
// Generated by ShaderClassGenerator
|
||||
|
||||
public class GPUFoliageShaderShader
|
||||
{
|
||||
public static readonly CachedResource<Shader> shader = new CachedResource<Shader>(
|
||||
"res://addons/rokojori_action_library/Runtime/Rendering/Assets/Foliage/GPUFoliageShader.gdshader"
|
||||
);
|
||||
|
||||
public static readonly Vector3PropertyName cameraPosition = Vector3PropertyName.Create( "cameraPosition" );
|
||||
public static readonly FloatPropertyName yaw = FloatPropertyName.Create( "yaw" );
|
||||
public static readonly FloatPropertyName cellSize = FloatPropertyName.Create( "cellSize" );
|
||||
public static readonly IntPropertyName width = IntPropertyName.Create( "width" );
|
||||
public static readonly IntPropertyName height = IntPropertyName.Create( "height" );
|
||||
public static readonly Texture2DPropertyName positionVariance = Texture2DPropertyName.Create( "positionVariance" );
|
||||
public static readonly Vector3PropertyName maxPositionOffset = Vector3PropertyName.Create( "maxPositionOffset" );
|
||||
public static readonly Vector2PropertyName positionUvScale = Vector2PropertyName.Create( "positionUVScale" );
|
||||
public static readonly Vector2PropertyName positionUvOffset = Vector2PropertyName.Create( "positionUVOffset" );
|
||||
public static readonly FloatPropertyName heightOffset = FloatPropertyName.Create( "heightOffset" );
|
||||
public static readonly Texture2DPropertyName rotationVariance = Texture2DPropertyName.Create( "rotationVariance" );
|
||||
public static readonly Vector3PropertyName minRotation = Vector3PropertyName.Create( "minRotation" );
|
||||
public static readonly Vector3PropertyName maxRotation = Vector3PropertyName.Create( "maxRotation" );
|
||||
public static readonly Vector2PropertyName rotationUvScale = Vector2PropertyName.Create( "rotationUVScale" );
|
||||
public static readonly Vector2PropertyName rotationUvOffset = Vector2PropertyName.Create( "rotationUVOffset" );
|
||||
public static readonly Texture2DPropertyName scaleVariance = Texture2DPropertyName.Create( "scaleVariance" );
|
||||
public static readonly Vector3PropertyName minScale = Vector3PropertyName.Create( "minScale" );
|
||||
public static readonly Vector3PropertyName maxScale = Vector3PropertyName.Create( "maxScale" );
|
||||
public static readonly Vector2PropertyName scaleUvScale = Vector2PropertyName.Create( "scaleUVScale" );
|
||||
public static readonly Vector2PropertyName scaleUvOffset = Vector2PropertyName.Create( "scaleUVOffset" );
|
||||
public static readonly FloatPropertyName occupancyAmount = FloatPropertyName.Create( "occupancyAmount" );
|
||||
public static readonly FloatPropertyName occupancyPower = FloatPropertyName.Create( "occupancyPower" );
|
||||
public static readonly FloatPropertyName occupancyTreshold = FloatPropertyName.Create( "occupancyTreshold" );
|
||||
public static readonly FloatPropertyName occupancyHideOffset = FloatPropertyName.Create( "occupancyHideOffset" );
|
||||
public static readonly FloatPropertyName occupancyHideScale = FloatPropertyName.Create( "occupancyHideScale" );
|
||||
public static readonly Texture2DPropertyName occupancyVariance = Texture2DPropertyName.Create( "occupancyVariance" );
|
||||
public static readonly Vector2PropertyName occupancyUvScale = Vector2PropertyName.Create( "occupancyUVScale" );
|
||||
public static readonly Vector2PropertyName occupancyUvOffset = Vector2PropertyName.Create( "occupancyUVOffset" );
|
||||
public static readonly FloatPropertyName hideStart = FloatPropertyName.Create( "hideStart" );
|
||||
public static readonly FloatPropertyName hideMax = FloatPropertyName.Create( "hideMax" );
|
||||
public static readonly FloatPropertyName hideOffset = FloatPropertyName.Create( "hideOffset" );
|
||||
public static readonly Vector2PropertyName mapSize = Vector2PropertyName.Create( "mapSize" );
|
||||
public static readonly Vector2PropertyName mapCenter = Vector2PropertyName.Create( "mapCenter" );
|
||||
|
||||
}
|
||||
|
||||
[Tool]
|
||||
public partial class GPUFoliageShaderMaterial:CustomMaterial
|
||||
{
|
||||
|
||||
|
||||
public readonly CustomMaterialProperty<Vector3> cameraPosition;
|
||||
public readonly CustomMaterialProperty<float> yaw;
|
||||
public readonly CustomMaterialProperty<float> cellSize;
|
||||
public readonly CustomMaterialProperty<int> width;
|
||||
public readonly CustomMaterialProperty<int> height;
|
||||
public readonly CustomMaterialProperty<Texture2D> positionVariance;
|
||||
public readonly CustomMaterialProperty<Vector3> maxPositionOffset;
|
||||
public readonly CustomMaterialProperty<Vector2> positionUvScale;
|
||||
public readonly CustomMaterialProperty<Vector2> positionUvOffset;
|
||||
public readonly CustomMaterialProperty<float> heightOffset;
|
||||
public readonly CustomMaterialProperty<Texture2D> rotationVariance;
|
||||
public readonly CustomMaterialProperty<Vector3> minRotation;
|
||||
public readonly CustomMaterialProperty<Vector3> maxRotation;
|
||||
public readonly CustomMaterialProperty<Vector2> rotationUvScale;
|
||||
public readonly CustomMaterialProperty<Vector2> rotationUvOffset;
|
||||
public readonly CustomMaterialProperty<Texture2D> scaleVariance;
|
||||
public readonly CustomMaterialProperty<Vector3> minScale;
|
||||
public readonly CustomMaterialProperty<Vector3> maxScale;
|
||||
public readonly CustomMaterialProperty<Vector2> scaleUvScale;
|
||||
public readonly CustomMaterialProperty<Vector2> scaleUvOffset;
|
||||
public readonly CustomMaterialProperty<float> occupancyAmount;
|
||||
public readonly CustomMaterialProperty<float> occupancyPower;
|
||||
public readonly CustomMaterialProperty<float> occupancyTreshold;
|
||||
public readonly CustomMaterialProperty<float> occupancyHideOffset;
|
||||
public readonly CustomMaterialProperty<float> occupancyHideScale;
|
||||
public readonly CustomMaterialProperty<Texture2D> occupancyVariance;
|
||||
public readonly CustomMaterialProperty<Vector2> occupancyUvScale;
|
||||
public readonly CustomMaterialProperty<Vector2> occupancyUvOffset;
|
||||
public readonly CustomMaterialProperty<float> hideStart;
|
||||
public readonly CustomMaterialProperty<float> hideMax;
|
||||
public readonly CustomMaterialProperty<float> hideOffset;
|
||||
public readonly CustomMaterialProperty<Vector2> mapSize;
|
||||
public readonly CustomMaterialProperty<Vector2> mapCenter;
|
||||
|
||||
public GPUFoliageShaderMaterial()
|
||||
{
|
||||
Shader = GPUFoliageShaderShader.shader.Get();
|
||||
|
||||
cameraPosition = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.cameraPosition );
|
||||
yaw = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.yaw );
|
||||
cellSize = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.cellSize );
|
||||
width = new CustomMaterialProperty<int>( this, GPUFoliageShaderShader.width );
|
||||
height = new CustomMaterialProperty<int>( this, GPUFoliageShaderShader.height );
|
||||
positionVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.positionVariance );
|
||||
maxPositionOffset = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.maxPositionOffset );
|
||||
positionUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvScale );
|
||||
positionUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.positionUvOffset );
|
||||
heightOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.heightOffset );
|
||||
rotationVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.rotationVariance );
|
||||
minRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.minRotation );
|
||||
maxRotation = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.maxRotation );
|
||||
rotationUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.rotationUvScale );
|
||||
rotationUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.rotationUvOffset );
|
||||
scaleVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.scaleVariance );
|
||||
minScale = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.minScale );
|
||||
maxScale = new CustomMaterialProperty<Vector3>( this, GPUFoliageShaderShader.maxScale );
|
||||
scaleUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.scaleUvScale );
|
||||
scaleUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.scaleUvOffset );
|
||||
occupancyAmount = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.occupancyAmount );
|
||||
occupancyPower = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.occupancyPower );
|
||||
occupancyTreshold = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.occupancyTreshold );
|
||||
occupancyHideOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.occupancyHideOffset );
|
||||
occupancyHideScale = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.occupancyHideScale );
|
||||
occupancyVariance = new CustomMaterialProperty<Texture2D>( this, GPUFoliageShaderShader.occupancyVariance );
|
||||
occupancyUvScale = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.occupancyUvScale );
|
||||
occupancyUvOffset = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.occupancyUvOffset );
|
||||
hideStart = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideStart );
|
||||
hideMax = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideMax );
|
||||
hideOffset = new CustomMaterialProperty<float>( this, GPUFoliageShaderShader.hideOffset );
|
||||
mapSize = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapSize );
|
||||
mapCenter = new CustomMaterialProperty<Vector2>( this, GPUFoliageShaderShader.mapCenter );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://c4hg6rvrmjm6j
|
|
@ -0,0 +1,69 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
/** <summary for="class PackedSceneFoliageData">
|
||||
|
||||
<title>
|
||||
A node to render foliage.
|
||||
</title>
|
||||
|
||||
<description>
|
||||
The GrassPatch has various settings to create a different styles of grass.
|
||||
It allows to change the shapes of the blades, their number and distribution, their triangle count,
|
||||
rotation and scale, LOD levels and much more.
|
||||
|
||||
|
||||
</description>
|
||||
|
||||
</summary>
|
||||
*/
|
||||
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class SceneFoliageData:FoliageData
|
||||
{
|
||||
[Export]
|
||||
public SceneReference sceneReference;
|
||||
|
||||
public override void Initialize( FoliageRenderLayer renderLayer )
|
||||
{
|
||||
var particles = renderLayer.renderer.CreateChild<GpuParticles3D>();
|
||||
|
||||
renderLayer.gpuParticles3D = particles;
|
||||
|
||||
var processMaterial = new GPUFoliageShaderMaterial();
|
||||
particles.ProcessMaterial = processMaterial;
|
||||
particles.Lifetime = 0.01f;
|
||||
particles.Explosiveness = 1f;
|
||||
particles.FixedFps = 0;
|
||||
particles.Interpolate = false;
|
||||
particles.FractDelta = false;
|
||||
|
||||
particles.CustomAabb = Box3.WithSize( 10000 );
|
||||
|
||||
processMaterial.positionVariance.Set( renderLayer.renderer.noise );
|
||||
processMaterial.rotationVariance.Set( renderLayer.renderer.noise );
|
||||
processMaterial.scaleVariance.Set( renderLayer.renderer.noise );
|
||||
processMaterial.occupancyVariance.Set( renderLayer.renderer.noise );
|
||||
|
||||
renderLayer.gpuFoliageShaderMaterial = processMaterial;
|
||||
|
||||
var packedScene = sceneReference.LoadScene();
|
||||
var sceneRoot = packedScene.Instantiate();
|
||||
|
||||
this.LogInfo( packedScene, sceneRoot );
|
||||
|
||||
var meshInstance = sceneRoot.GetSelfOrChildOf<MeshInstance3D>();
|
||||
particles.DrawPasses = 1;
|
||||
particles.DrawPass1 = meshInstance.Mesh;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://cm7ayfu511ijr
|
|
@ -0,0 +1,34 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
/** <summary for="class SceneReference">
|
||||
|
||||
<title>
|
||||
A resource to reference scenes safely by path.
|
||||
</title>
|
||||
|
||||
<description>
|
||||
When the path is assigned, it will be updated, when the path moves.
|
||||
</description>
|
||||
|
||||
</summary>
|
||||
*/
|
||||
|
||||
[Tool]
|
||||
[GlobalClass ]
|
||||
public partial class SceneReference:Resource
|
||||
{
|
||||
[Export(PropertyHint.File, "*.tscn,*.gltf,*.glb,*.fbx,*.obj,*.dae")]
|
||||
public string scenePath;
|
||||
|
||||
public PackedScene LoadScene() => scenePath == null || scenePath == "" ? null : GD.Load<PackedScene>( scenePath );
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://d18oon3mkd5s4
|
|
@ -140,3 +140,7 @@ vec3 heightMapNormalSmoothed( sampler2D terrain, vec2 terrainUV, vec2 kernelSize
|
|||
return normalize( n0 + n1 + n2 );
|
||||
}
|
||||
|
||||
vec2 tilingOffset( vec2 uv, vec2 scale, vec2 offset )
|
||||
{
|
||||
return uv * scale + offset;
|
||||
}
|
|
@ -577,6 +577,22 @@ mat4 mixTRS( mat4 a, mat4 b, float t )
|
|||
vec3 o = mix( oA, oB, t );
|
||||
vec3 s = mix( sA, sB, t );
|
||||
vec4 r = quaternionSlerp( rA, rB, t );
|
||||
|
||||
|
||||
return TRS( o, r, s );
|
||||
}
|
||||
|
||||
vec2 worldUVfromWorldXZ( vec3 worldVertex, vec2 centerXZ, vec2 sizeXZ )
|
||||
{
|
||||
vec2 worldUV = vec2( worldVertex.x, worldVertex.z );
|
||||
|
||||
vec2 mapOffset = centerXZ - sizeXZ / 2.0;
|
||||
|
||||
return ( worldUV - mapOffset ) / sizeXZ;
|
||||
}
|
||||
|
||||
vec2 worldUVfromLocalXZ( vec3 localVertex, vec2 centerXZ, vec2 sizeXZ, mat4 _MODEL_MATRIX )
|
||||
{
|
||||
vec3 worldVertex = localToWorld( localVertex, _MODEL_MATRIX );
|
||||
|
||||
return worldUVfromWorldXZ( worldVertex, centerXZ, sizeXZ );
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace Rokojori
|
|||
return Array.IndexOf( values, other );
|
||||
}
|
||||
|
||||
public static U[] Map<T,U>( T[] values, Func<T,U> mapper )
|
||||
public static U[] Map<T,U>( this T[] values, Func<T,U> mapper )
|
||||
{
|
||||
var u = new U[ values.Length ];
|
||||
|
||||
|
|
|
@ -16,6 +16,18 @@ namespace Rokojori.Tools
|
|||
public static void Save( Node3D node, string path, string texturesPath = null, string binPath = null )
|
||||
{
|
||||
|
||||
if ( ! path.EndsWith( ".gltf" ) )
|
||||
{
|
||||
if ( path.EndsWith( ".glb" ) )
|
||||
{
|
||||
path.ReplaceEnd( ".glb", ".gltf" );
|
||||
}
|
||||
else
|
||||
{
|
||||
path += ".gltf";
|
||||
}
|
||||
}
|
||||
|
||||
FilesSync.EnsureParentDirectoryExists( path );
|
||||
|
||||
if ( binPath != null )
|
||||
|
@ -43,7 +55,7 @@ namespace Rokojori.Tools
|
|||
var gltfFilePath = FilePath.Absolute( path ); // Defines file name and gltfPath;
|
||||
var gltfParentFilePath = gltfFilePath.CreateAbsoluteParent();
|
||||
var texturesDirPath = FilePath.Absolute( texturesPath ); // Only directory for textures
|
||||
var binDirPath = FilePath.Absolute( binPath ); // Only directory for bins, name comes from gltf.
|
||||
var binDirPath = binPath == null ? gltfParentFilePath : FilePath.Absolute( binPath ); // Only directory for bins, name comes from gltf.
|
||||
|
||||
var temporaryFilePath = FilePath.Create( ProjectSettings.GlobalizePath( temporaryPath ) + "/" + gltfFilePath.fullFileName );
|
||||
var temporaryDirPath = temporaryFilePath.CreateAbsoluteParent();
|
||||
|
|
Loading…
Reference in New Issue