using System.Collections; using System.Collections.Generic; using Godot; using System; using System.Threading.Tasks; namespace Rokojori { /** Is used by the FoliageRenderer to book keep and render a layer defined by the FoliageData. */ public class FoliageRenderLayer { public FoliageRenderer renderer; public FoliageData data; public int subLayerIndex = -1; public GpuParticles3D gpuParticles3D; public GPUFoliageShaderMaterial gpuFoliageShaderMaterial; float _lastCellSize = -1; float _lastMaxVisibility = -1; public static FoliageRenderLayer Create( FoliageRenderer renderer, FoliageData data, int subIndex = -1 ) { var rl = new FoliageRenderLayer(); rl.renderer = renderer; rl.data = data; rl.subLayerIndex = subIndex; return rl; } bool _isEnabled = false; public void Update( double delta ) { if ( gpuFoliageShaderMaterial == null ) { return; } if ( data.enabled != _isEnabled) { _isEnabled = data.enabled; gpuParticles3D.SetEnabledState( _isEnabled ); return; } if ( ! _isEnabled ) { return; } gpuFoliageShaderMaterial.cameraPosition.Set( renderer.GetAssignedCamera().GlobalPosition ); if ( ! data.updateSettings ) { return; } UpdateProcessMaterial(); data.materialOverride?.UpdateFoliageOverideMaterial( this ); var material = data.materialOverride != null ? data.materialOverride.GetOverrideMaterial( this ) : gpuParticles3D.DrawPass1.SurfaceGetMaterial( 0 ); data.materialOverride?.translucencySettings?.ApplyTranslucency( material, this ); // if ( data.overwriteAlphaScissorToDepthPrepass && gpuParticles3D.DrawPass1.SurfaceGetMaterial( 0 ) is StandardMaterial3D standardDrawMaterial ) // { // if ( BaseMaterial3D.TransparencyEnum.AlphaScissor == standardDrawMaterial.Transparency ) // { // var overrideMaterial = (StandardMaterial3D) standardDrawMaterial.Duplicate(); // overrideMaterial.Transparency = BaseMaterial3D.TransparencyEnum.AlphaDepthPrePass; // gpuParticles3D.MaterialOverride = overrideMaterial; // overrideMaterial.RenderPriority = data.renderPriority; // } // } // if ( gpuParticles3D.DrawPass1.SurfaceGetMaterial( 0 ) is ShaderMaterial drawMaterial ) // { // drawMaterial.RenderPriority = data.renderPriority; // drawMaterial.SetShaderParameter( "obstacle1", renderer.GetObstacleData( 0 ) ); // drawMaterial.SetShaderParameter( "obstacle2", renderer.GetObstacleData( 1 ) ); // drawMaterial.SetShaderParameter( "obstacle3", renderer.GetObstacleData( 2 ) ); // drawMaterial.SetShaderParameter( "obstacle4", renderer.GetObstacleData( 3 ) ); // // RJLog.Log( drawMaterial, renderer.GetObstacleData( 0 ) ); // } } void UpdateProcessMaterial() { var cellSize = FoliageQualitySettings.GetCellSize( renderer.quality, renderer.qualitySettingsAll, data.qualitySettings, data.GetCellSize( subLayerIndex ) ); var visibilityRange = FoliageQualitySettings.GetVisibilityRange( renderer.quality, renderer.qualitySettingsAll, data.qualitySettings, data.GetVisibilityRange( subLayerIndex ) ); var sizeInt = Mathf.CeilToInt( visibilityRange / cellSize ) * 2; if ( _lastCellSize != cellSize || _lastMaxVisibility != visibilityRange ) { _lastCellSize = cellSize; _lastMaxVisibility = visibilityRange; gpuFoliageShaderMaterial.cellSize.Set( cellSize ); gpuParticles3D.Amount = sizeInt * sizeInt; gpuFoliageShaderMaterial.width.Set( sizeInt ); gpuFoliageShaderMaterial.height.Set( sizeInt ); } var hideStart = visibilityRange - ( visibilityRange * data.GetVisibilityFadeRelative( subLayerIndex ) + data.GetVisibilityFadeAbsolute( subLayerIndex ) ); gpuFoliageShaderMaterial.hideMax.Set( visibilityRange ); gpuFoliageShaderMaterial.hideStart.Set( hideStart ); gpuFoliageShaderMaterial.hideOffset.Set( data.GetVisibilityFadeHidingOffset( subLayerIndex ) ); gpuFoliageShaderMaterial.positionVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.rotationVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.scaleVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.occupancyVariance.Set( renderer.noise ); gpuFoliageShaderMaterial.maxPositionOffset.Set( data.positionVarianceAbsoluteOffset + data.positionVarianceCellSizeRelativeOffset * cellSize ); gpuFoliageShaderMaterial.positionOffset.Set( data.GetPositionOffset( subLayerIndex ) ); 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 ); if ( data.GetSort( subLayerIndex ) ) { gpuParticles3D.DrawOrder = GpuParticles3D.DrawOrderEnum.ViewDepth; } } } }