public void DestroyDecalEntity(DecalEntity decalEntity)
        {
            if (!m_DecalEntityIndexer.IsValid(decalEntity))
            {
                return;
            }

            var decalItem = m_DecalEntityIndexer.GetItem(decalEntity);

            m_DecalEntityIndexer.DestroyDecalEntity(decalEntity);

            int chunkIndex = decalItem.chunkIndex;
            int arrayIndex = decalItem.arrayIndex;

            DecalEntityChunk   entityChunk   = entityChunks[chunkIndex];
            DecalCachedChunk   cachedChunk   = cachedChunks[chunkIndex];
            DecalCulledChunk   culledChunk   = culledChunks[chunkIndex];
            DecalDrawCallChunk drawCallChunk = drawCallChunks[chunkIndex];

            int lastArrayIndex = entityChunk.count - 1;

            if (arrayIndex != lastArrayIndex)
            {
                m_DecalEntityIndexer.UpdateIndex(entityChunk.decalEntities[lastArrayIndex], arrayIndex);
            }

            entityChunk.RemoveAtSwapBack(arrayIndex);
            cachedChunk.RemoveAtSwapBack(arrayIndex);
            culledChunk.RemoveAtSwapBack(arrayIndex);
            drawCallChunk.RemoveAtSwapBack(arrayIndex);
        }
Example #2
0
        private void Execute(DecalEntityChunk entityChunk, DecalCachedChunk cachedChunk, int count)
        {
            if (count == 0)
            {
                return;
            }

            cachedChunk.currentJobHandle.Complete();

            // Make sure draw order is up to date
            var material = entityChunk.material;

            if (material.HasProperty("_DrawOrder"))
            {
                cachedChunk.drawOrder = material.GetInt("_DrawOrder");
            }

            // Shader can change any time in editor, so we have to update passes each time
#if !UNITY_EDITOR
            if (!cachedChunk.isCreated)
#endif
            {
                int passIndexDBuffer = material.FindPass(DecalShaderPassNames.DBufferProjector);
                cachedChunk.passIndexDBuffer = passIndexDBuffer;

                int passIndexEmissive = material.FindPass(DecalShaderPassNames.DecalProjectorForwardEmissive);
                cachedChunk.passIndexEmissive = passIndexEmissive;

                int passIndexScreenSpace = material.FindPass(DecalShaderPassNames.DecalScreenSpaceProjector);
                cachedChunk.passIndexScreenSpace = passIndexScreenSpace;

                int passIndexGBuffer = material.FindPass(DecalShaderPassNames.DecalGBufferProjector);
                cachedChunk.passIndexGBuffer = passIndexGBuffer;

                cachedChunk.isCreated = true;
            }

            using (new ProfilingScope(null, m_SamplerJob))
            {
                UpdateTransformsJob updateTransformJob = new UpdateTransformsJob()
                {
                    positions       = cachedChunk.positions,
                    rotations       = cachedChunk.rotation,
                    scales          = cachedChunk.scales,
                    dirty           = cachedChunk.dirty,
                    scaleModes      = cachedChunk.scaleModes,
                    sizeOffsets     = cachedChunk.sizeOffsets,
                    decalToWorlds   = cachedChunk.decalToWorlds,
                    normalToWorlds  = cachedChunk.normalToWorlds,
                    boundingSpheres = cachedChunk.boundingSpheres,
                    minDistance     = 0.0001f,
                };

                var handle = updateTransformJob.Schedule(entityChunk.transformAccessArray);
                cachedChunk.currentJobHandle = handle;
            }
        }
        public DecalEntity CreateDecalEntity(DecalProjector decalProjector)
        {
            var material = decalProjector.material;

            if (material == null)
            {
                material = errorMaterial;
            }

            using (new ProfilingScope(null, m_AddDecalSampler))
            {
                int chunkIndex  = CreateChunkIndex(material);
                int entityIndex = entityChunks[chunkIndex].count;

                DecalEntity entity = m_DecalEntityIndexer.CreateDecalEntity(entityIndex, chunkIndex);

                DecalEntityChunk   entityChunk   = entityChunks[chunkIndex];
                DecalCachedChunk   cachedChunk   = cachedChunks[chunkIndex];
                DecalCulledChunk   culledChunk   = culledChunks[chunkIndex];
                DecalDrawCallChunk drawCallChunk = drawCallChunks[chunkIndex];

                // Make sure we have space to add new entity
                if (entityChunks[chunkIndex].capacity == entityChunks[chunkIndex].count)
                {
                    using (new ProfilingScope(null, m_ResizeChunks))
                    {
                        int newCapacity = entityChunks[chunkIndex].capacity + entityChunks[chunkIndex].capacity;
                        newCapacity = math.max(8, newCapacity);

                        entityChunk.SetCapacity(newCapacity);
                        cachedChunk.SetCapacity(newCapacity);
                        culledChunk.SetCapacity(newCapacity);
                        drawCallChunk.SetCapacity(newCapacity);
                    }
                }

                entityChunk.Push();
                cachedChunk.Push();
                culledChunk.Push();
                drawCallChunk.Push();

                entityChunk.decalProjectors[entityIndex] = decalProjector;
                entityChunk.decalEntities[entityIndex]   = entity;
                entityChunk.transformAccessArray.Add(decalProjector.transform);

                UpdateDecalEntityData(entity, decalProjector);

                return(entity);
            }
        }
Example #4
0
        private void Draw(CommandBuffer cmd, DecalEntityChunk decalEntityChunk, DecalCachedChunk decalCachedChunk, DecalDrawCallChunk decalDrawCallChunk, int passIndex)
        {
            var mesh     = m_EntityManager.decalProjectorMesh;
            var material = GetMaterial(decalEntityChunk);

            decalCachedChunk.propertyBlock.SetVector("unity_LightData", new Vector4(1, 1, 1, 0)); // GetMainLight requires z component to be set

            int subCallCount = decalDrawCallChunk.subCallCount;

            for (int i = 0; i < subCallCount; ++i)
            {
                var subCall = decalDrawCallChunk.subCalls[i];

                for (int j = subCall.start; j < subCall.end; ++j)
                {
                    decalCachedChunk.propertyBlock.SetMatrix("_NormalToWorld", decalDrawCallChunk.normalToDecals[j]);
                    cmd.DrawMesh(mesh, decalDrawCallChunk.decalToWorlds[j], material, 0, passIndex, decalCachedChunk.propertyBlock);
                }
            }
        }
Example #5
0
        private void Execute(CommandBuffer cmd, DecalEntityChunk decalEntityChunk, DecalCachedChunk decalCachedChunk, DecalDrawCallChunk decalDrawCallChunk, int count)
        {
            decalCachedChunk.currentJobHandle.Complete();
            decalDrawCallChunk.currentJobHandle.Complete();

            Material material  = GetMaterial(decalEntityChunk);
            int      passIndex = GetPassIndex(decalCachedChunk);

            if (count == 0 || passIndex == -1 || material == null)
            {
                return;
            }

            if (SystemInfo.supportsInstancing && material.enableInstancing)
            {
                DrawInstanced(cmd, decalEntityChunk, decalCachedChunk, decalDrawCallChunk, passIndex);
            }
            else
            {
                Draw(cmd, decalEntityChunk, decalCachedChunk, decalDrawCallChunk, passIndex);
            }
        }
Example #6
0
        private void DrawInstanced(CommandBuffer cmd, DecalEntityChunk decalEntityChunk, DecalCachedChunk decalCachedChunk, DecalDrawCallChunk decalDrawCallChunk, int passIndex)
        {
            var mesh     = m_EntityManager.decalProjectorMesh;
            var material = GetMaterial(decalEntityChunk);

            decalCachedChunk.propertyBlock.SetVector("unity_LightData", new Vector4(1, 1, 1, 0)); // GetMainLight requires z component to be set

            int subCallCount = decalDrawCallChunk.subCallCount;

            for (int i = 0; i < subCallCount; ++i)
            {
                var subCall = decalDrawCallChunk.subCalls[i];

                var decalToWorldSlice = decalDrawCallChunk.decalToWorlds.Reinterpret <Matrix4x4>();
                NativeArray <Matrix4x4> .Copy(decalToWorldSlice, subCall.start, m_WorldToDecals, 0, subCall.count);

                var normalToWorldSlice = decalDrawCallChunk.normalToDecals.Reinterpret <Matrix4x4>();
                NativeArray <Matrix4x4> .Copy(normalToWorldSlice, subCall.start, m_NormalToDecals, 0, subCall.count);

                decalCachedChunk.propertyBlock.SetMatrixArray("_NormalToWorld", m_NormalToDecals);
                cmd.DrawMeshInstanced(mesh, 0, material, passIndex, m_WorldToDecals, subCall.end - subCall.start, decalCachedChunk.propertyBlock);
            }
        }
 protected override Material GetMaterial(DecalEntityChunk decalEntityChunk) => m_EntityManager.errorMaterial;
Example #8
0
 protected virtual Material GetMaterial(DecalEntityChunk decalEntityChunk) => decalEntityChunk.material;