rj-action-library/Runtime/Rendering/Assets/Foliage/FoliageRenderLayer.cs

176 lines
6.5 KiB
C#

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 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;
}
}
}
}