Exemplo n.º 1
0
        public void Add(Decal decal, GameObject limitTo)
        {
            switch (decal.RenderMode)
            {
            case Decal.DecalRenderMode.Deferred:
                AddDeferred(decal);
                break;

            case Decal.DecalRenderMode.Unlit:
                AddUnlit(decal);
                break;

            default:
                break;
            }
        }
Exemplo n.º 2
0
        protected void AddUnlit(Decal decal)
        {
            if (!_unlitDecals.ContainsKey(decal.RenderOrder))
            {
                _unlitDecals.Add(decal.RenderOrder, new Dictionary <Material, HashSet <Decal> >());
            }
            var dict = _unlitDecals[decal.RenderOrder];

            if (!dict.ContainsKey(decal.Material))
            {
                dict.Add(decal.Material, new HashSet <Decal>()
                {
                    decal
                });
            }
            else
            {
                dict[decal.Material].Add(decal);
            }
        }
Exemplo n.º 3
0
        private void DrawUnlitDecals(Camera cam)
        {
            if (_unlitDecals.Count == 0)
            {
                return;
            }

            // Render third pass: unlit decals
            _bufferUnlit.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);

            // Traverse over decal render order values
            var allRenderOrderEnum = _unlitDecals.GetEnumerator();

            while (allRenderOrderEnum.MoveNext())
            {
                var allDecalEnum = allRenderOrderEnum.Current.Value.GetEnumerator();
                while (allDecalEnum.MoveNext())
                {
                    Material        material = allDecalEnum.Current.Key;
                    HashSet <Decal> decals   = allDecalEnum.Current.Value;
                    int             n        = 0;

                    var decalListEnum = decals.GetEnumerator();
                    while (decalListEnum.MoveNext())
                    {
                        Decal decal = decalListEnum.Current;
                        if (decal != null)
                        {
#if UNITY_5_5_OR_NEWER
                            if (UseInstancing)
                            {
                                _matrices[n]      = decal.transform.localToWorldMatrix;
                                _fadeValues[n]    = decal.Fade;
                                _limitToValues[n] = decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN;
                                ++n;

                                if (n == 1023)
                                {
                                    _instancedBlock.Clear();
                                    _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                                    _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                                    _bufferUnlit.DrawMeshInstanced(_cubeMesh, 0, material, 0, _matrices, n, _instancedBlock);
                                    n = 0;
                                }
                            }
                            else
#endif
                            {
                                _instancedBlock.Clear();
                                _instancedBlock.SetFloat("_MaskMultiplier", decal.Fade);
                                _instancedBlock.SetFloat("_LimitTo", decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN);
                                _bufferUnlit.DrawMesh(_cubeMesh, decal.transform.localToWorldMatrix, material, 0, 0, _instancedBlock);
                            }
                        }
                    }

#if UNITY_5_5_OR_NEWER
                    if (UseInstancing && n > 0)
                    {
                        _instancedBlock.Clear();
                        _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                        _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                        _bufferUnlit.DrawMeshInstanced(_cubeMesh, 0, material, 0, _matrices, n, _instancedBlock);
                    }
#endif
                }
            }
        }
Exemplo n.º 4
0
        private void DrawDeferredDecals_NormSpecSmooth(Camera cam)
        {
            if (_deferredDecals.Count == 0)
            {
                return;
            }

            var copy1id = Shader.PropertyToID("_CameraGBufferTexture1Copy");

            _bufferDeferred.GetTemporaryRT(copy1id, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);

            var copy2id = Shader.PropertyToID("_CameraGBufferTexture2Copy");

            _bufferDeferred.GetTemporaryRT(copy2id, -1, -1, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);

            // Traverse over decal render order values
            var allRenderOrderEnum = _deferredDecals.GetEnumerator();

            while (allRenderOrderEnum.MoveNext())
            {
                // Render second pass: specular / smoothness and normals
                var allDecalEnum = allRenderOrderEnum.Current.Value.GetEnumerator();
                while (allDecalEnum.MoveNext())
                {
                    Material        material = allDecalEnum.Current.Key;
                    HashSet <Decal> decals   = allDecalEnum.Current.Value;
                    int             n        = 0;

                    var decalListEnum = decals.GetEnumerator();
                    while (decalListEnum.MoveNext())
                    {
                        Decal decal = decalListEnum.Current;
                        if (decal != null && decal.DrawNormalAndGloss)
                        {
                            if (decal.HighQualityBlending)
                            {
                                // Create of copy of GBuffer1 (specular / smoothness) and GBuffer 2 (normal)
                                _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer1, copy1id);
                                _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer2, copy2id);

                                _bufferDeferred.SetRenderTarget(_normalRenderTarget, BuiltinRenderTextureType.CameraTarget);

                                _instancedBlock.Clear();
                                _instancedBlock.SetFloat("_MaskMultiplier", decal.Fade);
                                _instancedBlock.SetFloat("_LimitTo", decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN);
                                _bufferDeferred.DrawMesh(_cubeMesh, decal.transform.localToWorldMatrix, material, 0, 1, _instancedBlock);
                            }
                            else
                            {
#if UNITY_5_5_OR_NEWER
                                if (UseInstancing)
                                {
                                    // Instanced drawing
                                    _matrices[n]      = decal.transform.localToWorldMatrix;
                                    _fadeValues[n]    = decal.Fade;
                                    _limitToValues[n] = decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN;
                                    ++n;

                                    if (n == 1023)
                                    {
                                        // Create of copy of GBuffer1 (specular / smoothness) and GBuffer 2 (normal)
                                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer1, copy1id);
                                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer2, copy2id);

                                        _bufferDeferred.SetRenderTarget(_normalRenderTarget, BuiltinRenderTextureType.CameraTarget);
                                        _instancedBlock.Clear();
                                        _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                                        _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                                        _bufferDeferred.DrawMeshInstanced(_cubeMesh, 0, material, 1, _matrices, n, _instancedBlock);
                                        n = 0;
                                    }
                                }
                                else
#endif
                                {
                                    if (n == 0)
                                    {
                                        // Create of copy of GBuffer1 (specular / smoothness) and GBuffer 2 (normal)
                                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer1, copy1id);
                                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer2, copy2id);
                                    }

                                    _bufferDeferred.SetRenderTarget(_normalRenderTarget, BuiltinRenderTextureType.CameraTarget);
                                    _instancedBlock.Clear();
                                    _instancedBlock.SetFloat("_MaskMultiplier", decal.Fade);
                                    _instancedBlock.SetFloat("_LimitTo", decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN);
                                    _bufferDeferred.DrawMesh(_cubeMesh, decal.transform.localToWorldMatrix, material, 0, 1, _instancedBlock);
                                    ++n;
                                }
                            }
                        }
                    }

#if UNITY_5_5_OR_NEWER
                    if (UseInstancing && n > 0)
                    {
                        // Create of copy of GBuffer1 (specular / smoothness) and GBuffer 2 (normal)
                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer1, copy1id);
                        _bufferDeferred.Blit(BuiltinRenderTextureType.GBuffer2, copy2id);

                        _bufferDeferred.SetRenderTarget(_normalRenderTarget, BuiltinRenderTextureType.CameraTarget);

                        _instancedBlock.Clear();
                        _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                        _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                        _bufferDeferred.DrawMeshInstanced(_cubeMesh, 0, material, 1, _matrices, n, _instancedBlock);
                    }
#endif
                }
            }
        }
Exemplo n.º 5
0
        private void DrawDeferredDecals_Albedo(Camera cam)
        {
            if (_deferredDecals.Count == 0)
            {
                return;
            }

            // Render first pass: albedo
            _bufferDeferred.SetRenderTarget(_albedoRenderTarget, BuiltinRenderTextureType.CameraTarget);

            // Traverse over decal render order values
            var allRenderOrderEnum = _deferredDecals.GetEnumerator();

            while (allRenderOrderEnum.MoveNext())
            {
                var allMaterialEnum = allRenderOrderEnum.Current.Value.GetEnumerator();
                while (allMaterialEnum.MoveNext())
                {
                    Material        material   = allMaterialEnum.Current.Key;
                    HashSet <Decal> decals     = allMaterialEnum.Current.Value;
                    int             decalCount = decals.Count;
                    int             n          = 0;

                    var decalListEnum = decals.GetEnumerator();
                    while (decalListEnum.MoveNext())
                    {
                        Decal decal = decalListEnum.Current;
                        if (decal != null && decal.DrawAlbedo)
                        {
#if UNITY_5_5_OR_NEWER
                            if (UseInstancing && !decal.UseLightProbes)
                            {
                                _matrices[n]      = decal.transform.localToWorldMatrix;
                                _fadeValues[n]    = decal.Fade;
                                _limitToValues[n] = decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN;
                                ++n;

                                if (n == 1023)
                                {
                                    _instancedBlock.Clear();
                                    _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                                    _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                                    SetLightProbeOnBlock(RenderSettings.ambientProbe, _instancedBlock);
                                    _bufferDeferred.DrawMeshInstanced(_cubeMesh, 0, material, 0, _matrices, n, _instancedBlock);
                                    n = 0;
                                }
                            }
                            else
#endif
                            {
                                // Fall back to non-instanced rendering
                                _directBlock.Clear();
                                _directBlock.SetFloat("_MaskMultiplier", decal.Fade);
                                _directBlock.SetFloat("_LimitTo", decal.LimitTo ? decal.LimitTo.GetInstanceID() : float.NaN);

                                // Interpolate a light probe for this probe, if requested
                                if (decal.UseLightProbes)
                                {
                                    SphericalHarmonicsL2 probe;
                                    // TODO: GC allocs due to GetComponent?
                                    LightProbes.GetInterpolatedProbe(decal.transform.position, decal.GetComponent <MeshRenderer>(), out probe);
                                    SetLightProbeOnBlock(probe, _directBlock);
                                }

                                _bufferDeferred.DrawMesh(_cubeMesh, decal.transform.localToWorldMatrix, material, 0, 0, _directBlock);
                            }
                        }
                    }

#if UNITY_5_5_OR_NEWER
                    if (UseInstancing && n > 0)
                    {
                        _instancedBlock.Clear();
                        _instancedBlock.SetFloatArray("_MaskMultiplier", _fadeValues);
                        _instancedBlock.SetFloatArray("_LimitTo", _limitToValues);
                        SetLightProbeOnBlock(RenderSettings.ambientProbe, _instancedBlock);
                        _bufferDeferred.DrawMeshInstanced(_cubeMesh, 0, material, 0, _matrices, n, _instancedBlock);
                    }
#endif
                }
            }
        }