private void DrawInstanced([NotNull] CommandBuffer cmd, ArraySegment <int> visible, int shaderPass) { if (visible.Count < 1) { return; } EnsureArrayCapacity(ref _matrices, visible.Count); EnsureArrayCapacity(ref _saturation, visible.Count); EnsureArrayCapacity(ref _edgeFadeout, visible.Count); EnsureArrayCapacity(ref _edgeSharpness, visible.Count); if (Batch.Permutation.LayerMode == LayerMode.None) { _yLayerInputStart = null; _yLayerInputExtent = null; _yLayerOutputStart = null; _yLayerOutputEnd = null; } else { EnsureArrayCapacity(ref _yLayerInputStart, visible.Count); EnsureArrayCapacity(ref _yLayerInputExtent, visible.Count); EnsureArrayCapacity(ref _yLayerOutputStart, visible.Count); EnsureArrayCapacity(ref _yLayerOutputEnd, visible.Count); } if (Batch.Permutation.LayerMode != LayerMode.Triplanar) { _xLayerInputStart = null; _xLayerInputExtent = null; _xLayerOutputStart = null; _xLayerOutputEnd = null; _zLayerInputStart = null; _zLayerInputExtent = null; _zLayerOutputStart = null; _zLayerOutputEnd = null; } else { EnsureArrayCapacity(ref _xLayerInputStart, visible.Count); EnsureArrayCapacity(ref _xLayerInputExtent, visible.Count); EnsureArrayCapacity(ref _xLayerOutputStart, visible.Count); EnsureArrayCapacity(ref _xLayerOutputEnd, visible.Count); EnsureArrayCapacity(ref _zLayerInputStart, visible.Count); EnsureArrayCapacity(ref _zLayerInputExtent, visible.Count); EnsureArrayCapacity(ref _zLayerOutputStart, visible.Count); EnsureArrayCapacity(ref _zLayerOutputEnd, visible.Count); } // Copy decal data into arrays var arx = LayerArrays.Create(_xLayerInputStart, _xLayerInputExtent, _xLayerOutputStart, _xLayerOutputEnd); var ary = LayerArrays.Create(_yLayerInputStart, _yLayerInputExtent, _yLayerOutputStart, _yLayerOutputEnd); var arz = LayerArrays.Create(_zLayerInputStart, _zLayerInputExtent, _zLayerOutputStart, _zLayerOutputEnd); for (var i = 0; i < visible.Count; i++) { // ReSharper disable once PossibleNullReferenceException var decal = Batch.Decals[visible.Array[visible.Offset + i]]; decal.Properties.LoadInto( i, _saturation, _edgeFadeout, _edgeSharpness, arx, ary, arz ); _matrices[i] = decal.Decal.WorldTransform; } // Set arrays into instancing property block _instancingPropertyBlock.Clear(); InstanceProperties.LoadInto( _instancingPropertyBlock, _saturation, _edgeFadeout, _edgeSharpness, arx, ary, arz ); var mat = Batch.GetMaterial(true); cmd.DrawMeshInstanced(_box, 0, mat, shaderPass, _matrices, visible.Count, _instancingPropertyBlock); }
public void UpdateProperties(bool batchPropertiesChanged) { var settings = Decal.Settings; // Move decal to appropriate batch if needed if (batchPropertiesChanged) { // Find shader permutation var permuatation = new MaterialPermutation(settings.Mode, settings.LayerMode, settings.LayerProjection, settings.Shape, settings.EnableJitter); // Choose the smallest jitter value of the three textures (or zero if they are all null) var jitter = Min( settings.LayerMode == LayerMode.Triplanar ? Jitter(settings.SampleJitter, settings.XLayer.LayerMask) : null, settings.LayerMode != LayerMode.None ? Jitter(settings.SampleJitter, settings.YLayer.LayerMask) : null, settings.LayerMode == LayerMode.Triplanar ? Jitter(settings.SampleJitter, settings.ZLayer.LayerMask) : null ); // Collect material properties var materialProperties = new MaterialProperties( settings.XLayer.LayerMask, settings.XLayer.LayerMaskScaleOffset, settings.YLayer.LayerMask, settings.YLayer.LayerMaskScaleOffset, settings.ZLayer.LayerMask, settings.ZLayer.LayerMaskScaleOffset, _system.SharedState.BlueNoiseRGBA, new Vector2(29, 31), jitter ); // Update batch if (_batch != null) { _batch.Remove(this); } _batch = _system.SharedState.FindBatch(permuatation, materialProperties); _batch.Add(this); } // Update instance properties struct _properties.Saturation = settings.Saturation; _properties.Fadeout = settings.EdgeFadeoff; _properties.EdgeSharpness = settings.FaceSharpness; if (settings.LayerMode != LayerMode.None) { settings.YLayer.EvaluateRanges(out _properties.YLayer); } if (settings.LayerMode == LayerMode.Triplanar) { settings.XLayer.EvaluateRanges(out _properties.XLayer); settings.ZLayer.EvaluateRanges(out _properties.ZLayer); } // Update material properties block if running non-instanced if (!RenderSettings.Instance.EnableInstancing) { if (PropertyBlock == null) { PropertyBlock = new MaterialPropertyBlock(); } PropertyBlock.Clear(); _properties.LoadInto(PropertyBlock, settings.LayerMode); } }