示例#1
0
        public void SetupBounds(Decal decal)
        {
            if (decal == null)
            {
                return;
            }

            decal.SetupBounds();
        }
示例#2
0
        public void AddOrUpdateDecal(Decal d)
        {
            RemoveDecal(d);

            if (d.DecalMaterial == null)
            {
                return;
            }

            if (m_Decals.Count == 0)
            {
                m_Decals.Add(d);
            }
            else
            {
                for (int i = 0; i <= m_Decals.Count; i++)
                {
                    if (i == m_Decals.Count)
                    {
                        m_Decals.Add(d);
                        break;
                    }

                    if (m_Decals[i].SortingOrder > d.SortingOrder)
                    {
                        m_Decals.Insert(i, d);
                        break;
                    }
                }
            }

            /*for (int i = 0; i < m_Decals.Count; i++)
             * {
             *  Debug.LogWarning(m_Decals[i].name + " " + m_Decals[i].SortingOrder);
             * }*/
        }
示例#3
0
 private void OnEnable()
 {
     decal = target as Decal;
 }
示例#4
0
 public void RemoveDecal(Decal d)
 {
     m_Decals.Remove(d);
 }
示例#5
0
        public void Render(Camera camera)
        {
            var cam = camera;

            if (!cam)
            {
                return;
            }

            // before lighting buffer
            CommandBuffer bufferBeforeLighting = null;

            if (m_Cameras.ContainsKey(cam))
            {
                bufferBeforeLighting = m_Cameras[cam];
                if (LockRebuild)
                {
                    return;
                }
                bufferBeforeLighting.Clear();
            }
            else
            {
                bufferBeforeLighting      = new CommandBuffer();
                bufferBeforeLighting.name = "Deferred decals";
                m_Cameras[cam]            = bufferBeforeLighting;

                // set this command buffer to be executed just before deferred lighting pass
                // in the camera
                var buffers = cam.GetCommandBuffers(CameraEvent.BeforeReflections);

                for (int i = 0; i < buffers.Length; i++)
                {
                    if (buffers[i].name.Equals("Deferred decals"))
                    {
                        cam.RemoveCommandBuffer(CameraEvent.BeforeReflections, buffers[i]);
                    }
                }

                cam.AddCommandBuffer(CameraEvent.BeforeReflections, bufferBeforeLighting);
            }

            if (UseExclusionMask)
            {
                if (!m_ExclusionMasks.TryGetValue(cam, out exclusionMaskRenderTarget))
                {
                    exclusionMaskRenderTarget            = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 16, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
                    exclusionMaskRenderTarget.filterMode = FilterMode.Point;
                    exclusionMaskRenderTarget.Create();
                    exclusionMaskRenderTarget.name = "Exclusion Mask for camera " + cam.name;
                    m_ExclusionMasks.Add(cam, exclusionMaskRenderTarget);
                }
                if (exclusionMaskRenderTarget != null && (cam.pixelWidth != exclusionMaskRenderTarget.width || cam.pixelHeight != exclusionMaskRenderTarget.height))
                {
                    m_ExclusionMasks.Remove(cam);
                    DestroyImmediate(exclusionMaskRenderTarget, true);

                    exclusionMaskRenderTarget            = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 16, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
                    exclusionMaskRenderTarget.filterMode = FilterMode.Point;
                    exclusionMaskRenderTarget.Create();
                    exclusionMaskRenderTarget.name = "Exclusion Mask for camera " + cam.name;
                    m_ExclusionMasks.Add(cam, exclusionMaskRenderTarget);
                }

                exclusionCamera.CopyFrom(cam);
                exclusionCamera.depth = cam.depth - 0.01f;
                exclusionCamera.transform.position = cam.transform.position;
                exclusionCamera.transform.rotation = cam.transform.rotation;
                exclusionCamera.cullingMask        = ExclusionMask;
                exclusionCamera.targetTexture      = exclusionMaskRenderTarget;
                exclusionCamera.renderingPath      = RenderingPath.Forward;
                exclusionCamera.clearFlags         = CameraClearFlags.Color;
                exclusionCamera.backgroundColor    = Color.clear;
                exclusionCamera.RenderWithShader(depthShader, "RenderType");

                bufferBeforeLighting.EnableShaderKeyword("EXCLUSIONMASK");

                bufferBeforeLighting.SetGlobalTexture("_ExclusionMask", exclusionMaskRenderTarget);
            }
            else
            {
                bufferBeforeLighting.DisableShaderKeyword("EXCLUSIONMASK");
            }

            bool          isSceneViewCamera = cam.cameraType == CameraType.SceneView;
            CommandBuffer selectionBuffer   = null;

            if (m_CamerasSceneview.ContainsKey(cam))
            {
                selectionBuffer = m_CamerasSceneview[cam];
                selectionBuffer.Clear();
            }
            else
            {
                if (isSceneViewCamera)
                {
                    selectionBuffer         = new CommandBuffer();
                    selectionBuffer.name    = "Deferred decals selection";
                    m_CamerasSceneview[cam] = selectionBuffer;

                    // set this command buffer to be executed just before deferred lighting pass
                    // in the camera
                    var buffers = cam.GetCommandBuffers(CameraEvent.AfterLighting);

                    for (int i = 0; i < buffers.Length; i++)
                    {
                        if (buffers[i].name.Equals("Deferred decals selection"))
                        {
                            cam.RemoveCommandBuffer(CameraEvent.AfterLighting, buffers[i]);
                        }
                    }

                    cam.AddCommandBuffer(CameraEvent.AfterLighting, selectionBuffer);
                }
            }

            // frustum culling
            cameraPlanes = GeometryUtility.CalculateFrustumPlanes(camera);
            currentDecalsVisibility.Clear();
            var system = DeferredDecalsManager.instance;

            // cache visibility for each decal
            if (FrustumCulling)
            {
                foreach (var decal in system.m_Decals)
                {
                    if (decal == null)
                    {
                        continue;
                    }

                    SetupBounds(decal);
                    bool isDecalVisible = IsBoundsVisible(cameraPlanes, decal.Bounds);
                    currentDecalsVisibility.Add(decal, isDecalVisible);
                }
            }
            else
            {
                foreach (var decal in system.m_Decals)
                {
                    if (decal == null)
                    {
                        continue;
                    }

                    currentDecalsVisibility.Add(decal, true);
                }
            }

            BuiltinRenderTextureType emissionTexture = cam.allowHDR ? BuiltinRenderTextureType.CameraTarget : BuiltinRenderTextureType.GBuffer3;

            // copy g-buffer normals into a temporary RT
            var normalsID = Shader.PropertyToID("_NormalsCopy");

            bufferBeforeLighting.GetTemporaryRT(normalsID, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
            bufferBeforeLighting.Blit(BuiltinRenderTextureType.GBuffer2, normalsID);

            // copy g-buffer specrough into a temporary RT
            var specularID = Shader.PropertyToID("_SpecularTarget");

            bufferBeforeLighting.GetTemporaryRT(specularID, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
            bufferBeforeLighting.Blit(BuiltinRenderTextureType.GBuffer1, specularID);

            // copy g-buffer specrough into a temporary RT
            var smoothnessID = Shader.PropertyToID("_SmoothnessTarget");

            bufferBeforeLighting.GetTemporaryRT(smoothnessID, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
            bufferBeforeLighting.Blit(BuiltinRenderTextureType.GBuffer1, smoothnessID, specularSmoothnessBlitterMaterial, 0);

            // copy g-buffer camera target into a temporary RT
            var emissionID = Shader.PropertyToID("_CameraTargetCopy");

            bufferBeforeLighting.GetTemporaryRT(emissionID, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
            bufferBeforeLighting.Blit(emissionTexture, emissionID);

            instancedBlock.Clear();

            var sortedDecalsBySortingOrder = system.m_Decals;

            decalsGrouped.Clear();

            DecalsGroup groupKey;
            Vector3     camPos = cam.transform.position;
            float       currentDistanceToCamera;
            float       fadeFactor;

            foreach (var decal in sortedDecalsBySortingOrder)
            {
                if (!currentDecalsVisibility[decal])
                {
                    continue;
                }
                if (DistanceCulling)
                {
                    currentDistanceToCamera = Vector3.Distance(camPos, decal.transform.position);

                    if (currentDistanceToCamera >= StartFadeDistance + FadeLength)
                    {
                        continue;
                    }

                    fadeFactor         = Mathf.InverseLerp(StartFadeDistance, StartFadeDistance + FadeLength, currentDistanceToCamera);
                    decal.DistanceFade = 1 - fadeFactor;
                }
                else
                {
                    decal.DistanceFade = 1f;
                }

                groupKey.Material     = decal.DecalMaterial;
                groupKey.SortingOrder = decal.SortingOrder;
                groupKey.Instancing   = decal.DecalMaterial.enableInstancing;
                List <Decal> decalsByMaterials;
                if (!decalsGrouped.TryGetValue(groupKey, out decalsByMaterials))
                {
                    decalsByMaterials = new List <Decal>();
                    decalsGrouped.Add(groupKey, decalsByMaterials);
                }
                decalsByMaterials.Add(decal);
            }

            RenderTargetIdentifier[] mrtDifNormSpecRough = { BuiltinRenderTextureType.GBuffer0, BuiltinRenderTextureType.GBuffer2, emissionTexture };
            bufferBeforeLighting.SetRenderTarget(mrtDifNormSpecRough, BuiltinRenderTextureType.CameraTarget);
            Color   tint;
            Vector4 uv;
            Vector4 uvOne = new Vector4(1, 1, 0, 0);

            foreach (var decalGroup in decalsGrouped)
            {
                var decalsList = decalGroup.Value;
                if (decalGroup.Key.Instancing)
                {
                    bufferBeforeLighting.SetGlobalColor("_NotInstancedColor", Color.white);
                    bufferBeforeLighting.SetGlobalVector("_NotInstancedUV", uvOne);
                    int batchCount = 1 + Mathf.FloorToInt(decalsList.Count / 1024);
                    for (int i = 0; i < batchCount; i++)
                    {
                        int drawCount = Mathf.Min(1023, decalsList.Count);
                        for (int j = 0; j < drawCount; j++)
                        {
                            tintArray[j]    = decalsList[j].InstancedColor;
                            tintArray[j].w *= decalsList[j].Fade * decalsList[j].DistanceFade;
                            uvArray[j]      = decalsList[j].UV;
                            matrices[j]     = decalsList[j].transform.localToWorldMatrix;
                        }
                        if (drawCount > 0)
                        {
                            instancedBlock.SetVectorArray("_Tint", tintArray);
                            instancedBlock.SetVectorArray("_UV", uvArray);
                            bufferBeforeLighting.DrawMeshInstanced(CubeMesh, 0, decalGroup.Key.Material, 0, matrices, drawCount, instancedBlock);
                        }
                    }
                }
                else
                {
                    foreach (var decal in decalsList)
                    {
                        tint    = decal.InstancedColor;
                        tint.a *= decal.Fade * decal.DistanceFade;
                        bufferBeforeLighting.SetGlobalColor("_NotInstancedColor", tint);
                        uv = decal.UV;
                        bufferBeforeLighting.SetGlobalVector("_NotInstancedUV", uv);
                        bufferBeforeLighting.DrawMesh(CubeMesh, decal.transform.localToWorldMatrix, decal.DecalMaterial, 0, 0);
                    }
                }
            }

            mrtDifNormSpecRough = new RenderTargetIdentifier[] { specularID, smoothnessID };
            bufferBeforeLighting.SetRenderTarget(mrtDifNormSpecRough, BuiltinRenderTextureType.CameraTarget);

            foreach (var decalGroup in decalsGrouped)
            {
                var decalsList = decalGroup.Value;
                if (decalGroup.Key.Instancing)
                {
                    bufferBeforeLighting.SetGlobalColor("_NotInstancedColor", Color.white);
                    bufferBeforeLighting.SetGlobalVector("_NotInstancedUV", uvOne);
                    int batchCount = 1 + Mathf.FloorToInt(decalsList.Count / 1024);
                    for (int i = 0; i < batchCount; i++)
                    {
                        int drawCount = Mathf.Min(1023, decalsList.Count);
                        for (int j = 0; j < drawCount; j++)
                        {
                            tintArray[j]    = decalsList[j].InstancedColor;
                            tintArray[j].w *= decalsList[j].Fade;
                            uvArray[j]      = decalsList[j].UV;
                            matrices[j]     = decalsList[j].transform.localToWorldMatrix;
                        }
                        if (drawCount > 0)
                        {
                            instancedBlock.SetVectorArray("_Tint", tintArray);
                            instancedBlock.SetVectorArray("_UV", uvArray);
                            bufferBeforeLighting.DrawMeshInstanced(CubeMesh, 0, decalGroup.Key.Material, 2, matrices, drawCount, instancedBlock);
                        }
                    }
                }
                else
                {
                    foreach (var decal in decalsList)
                    {
                        tint    = decal.InstancedColor;
                        tint.a *= decal.Fade;
                        bufferBeforeLighting.SetGlobalColor("_NotInstancedColor", tint);
                        uv = decal.UV;
                        bufferBeforeLighting.SetGlobalVector("_NotInstancedUV", uv);
                        bufferBeforeLighting.DrawMesh(CubeMesh, decal.transform.localToWorldMatrix, decal.DecalMaterial, 0, 2);
                    }
                }
            }

            bufferBeforeLighting.SetGlobalTexture("_Alpha", smoothnessID);
            bufferBeforeLighting.Blit(specularID, BuiltinRenderTextureType.GBuffer1, specularSmoothnessBlitterMaterial, 1);

            if (TerrainDecals == TerrainDecalsType.MultiTerrain)
            {
                foreach (var d in system.m_Decals)
                {
                    d.DecalMaterial.EnableKeyword("MULTI_TERRAIN_DECAL");
                }
            }
            else
            {
                foreach (var d in system.m_Decals)
                {
                    d.DecalMaterial.DisableKeyword("MULTI_TERRAIN_DECAL");
                }
            }
            if (Terrain.activeTerrains == null || Terrain.activeTerrains.Length == 0)
            {
                foreach (var d in system.m_Decals)
                {
                    d.DecalMaterial.EnableKeyword("NO_TERRAIN");
                }
            }
            else
            {
                foreach (var d in system.m_Decals)
                {
                    d.DecalMaterial.DisableKeyword("NO_TERRAIN");
                }
            }

            if (TerrainDecals != TerrainDecalsType.None)
            {
                if (TerrainDecals == TerrainDecalsType.OneTerrain)
                {
                    Terrain terrain = Terrain.activeTerrain;
                    terrain.drawHeightmap = true;
                    Shader.SetGlobalMatrix("_World2Terrain", terrain.transform.worldToLocalMatrix);
                    Shader.SetGlobalTexture("_TerrainHeightMap", terrain.terrainData.heightmapTexture);
                    Shader.SetGlobalVector("_TerrainSize", terrain.terrainData.size);
                }
                else if (TerrainDecals == TerrainDecalsType.MultiTerrain)
                {
                    Terrain[] terrains = Terrain.activeTerrains;

                    if (copyHeightmapsBuffer == null)
                    {
                        CopyHeightmaps();
                    }

                    terrainsDataBuffer.SetData(terrainsData);

                    SetupToShaders();
                }
            }

#if UNITY_EDITOR
            if (isSceneViewCamera)
            {
                float deltaTime = (float)(UnityEditor.EditorApplication.timeSinceStartup - lastRenderTime);
                lastRenderTime = UnityEditor.EditorApplication.timeSinceStartup;
                decalsToRemove.Clear();

                foreach (var decalTime in lastSelectedDecals)
                {
                    decalTime.Value.Value += deltaTime;
                    if (decalTime.Value.Value >= selectionDuration)
                    {
                        decalsToRemove.Add(decalTime.Key);
                    }
                }

                foreach (var decal in decalsToRemove)
                {
                    lastSelectedDecals.Remove(decal);
                }

                var selectedObjects = UnityEditor.Selection.objects;

                if (selectedObjects != null)
                {
                    selectionBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.CameraTarget);
                    foreach (var o in selectedObjects)
                    {
                        GameObject go = o as GameObject;

                        if (go != null)
                        {
                            Decal decal = go.GetComponent <Decal>();
                            if (decal != null)
                            {
                                FloatValue time;
                                if (lastSelectedDecals.TryGetValue(decal, out time))
                                {
                                    tint    = decal.InstancedColor;
                                    tint.a *= decal.Fade;
                                    selectionBuffer.SetGlobalColor("_NotInstancedColor", tint);
                                    uv = decal.UV;
                                    selectionBuffer.SetGlobalVector("_NotInstancedUV", uv);

                                    selectionBuffer.SetGlobalFloat("SelectionTime", selectionFadeCurve.Evaluate(time.Value / selectionDuration));
                                    selectionBuffer.DrawMesh(CubeMesh, decal.transform.localToWorldMatrix, decal.DecalMaterial, 0, 1); // selection pass - 1
                                }
                            }
                        }
                    }
                }
            }
#endif
            // release temporary RT
            bufferBeforeLighting.ReleaseTemporaryRT(normalsID);
            bufferBeforeLighting.ReleaseTemporaryRT(specularID);

            if (selectionBuffer != null)
            {
                selectionBuffer.ReleaseTemporaryRT(normalsID);
            }
        }