public MaterialBatch(Shader shader, MaterialPermutation permutation, MaterialProperties properties) { Properties = properties; Permutation = permutation; _decals = new List <DecalRenderInstance>(); BoundingSpheres = new BoundingSphere[16]; Decals = new ReadOnlyCollection <DecalRenderInstance>(_decals); var material = new Material(shader) { hideFlags = HideFlags.DontSave }; if (permutation.LayerMode == LayerMode.Single) { material.EnableKeyword("LAYERS_SINGLE"); } else if (permutation.LayerMode == LayerMode.Triplanar) { material.EnableKeyword("LAYERS_TRIPLANAR"); } if (permutation.LayerProjectionMode == ProjectionMode.Local) { material.EnableKeyword("LAYER_PROJECTION_LOCAL"); } else { material.EnableKeyword("LAYER_PROJECTION_WORLD"); } if (permutation.EnableJitter) { material.EnableKeyword("JITTER_LAYERS"); } if (permutation.Shape == DecalShape.Sphere) { material.EnableKeyword("SHAPE_CIRCLE"); } else if (permutation.Shape == DecalShape.Cube) { material.EnableKeyword("SHAPE_SQUARE"); } else if (permutation.Shape == DecalShape.Mesh) { material.EnableKeyword("SHAPE_MESH"); } else { throw new InvalidOperationException("Unknown decal shape `" + permutation.Shape + "`"); } properties.LoadInto(material); _material = material; }
public MaterialBatch FindBatch(MaterialPermutation permutation, MaterialProperties properties) { var id = new MaterialBatchId(permutation, properties); MaterialBatch batch; if (!_batches.TryGetValue(id, out batch)) { batch = new MaterialBatch(permutation.SelectShader(_wetMaskShader, _dryMaskShader), permutation, properties); _batches[id] = batch; _batchesList.Add(batch); unchecked { BatchEpoch++; } } return(batch); }
public MaterialBatchId(MaterialPermutation permutation, MaterialProperties properties) { _permutation = permutation; _properties = properties; }
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); } }