Ejemplo n.º 1
0
        public void UpdateMaterialAndBounds()
        {
            Debug.Assert(m_Master);

            if (ApplyMaterial() == false)
            {
                return;
            }

            MaterialChangeStart();
            {
                if (m_CustomMaterial == null)
                {
                    if (m_MaterialModifierCallback != null)
                    {
                        m_MaterialModifierCallback(this);
                    }
                }

                float slopeRad = (m_Master.coneAngle * Mathf.Deg2Rad) / 2; // use coneAngle (instead of spotAngle) which is more correct with the geometry
                SetMaterialProp(ShaderProperties.ConeSlopeCosSin, new Vector2(Mathf.Cos(slopeRad), Mathf.Sin(slopeRad)));

                // kMinRadius and kMinApexOffset prevents artifacts when fresnel computation is done in the vertex shader
                const float kMinRadius = 0.0001f;
                var         coneRadius = new Vector2(Mathf.Max(m_Master.coneRadiusStart, kMinRadius), Mathf.Max(m_Master.coneRadiusEnd, kMinRadius));
                SetMaterialProp(ShaderProperties.ConeRadius, coneRadius);

                const float kMinApexOffset = 0.0001f;
                float       nonNullApex    = Mathf.Sign(m_Master.coneApexOffsetZ) * Mathf.Max(Mathf.Abs(m_Master.coneApexOffsetZ), kMinApexOffset);
                SetMaterialProp(ShaderProperties.ConeApexOffsetZ, nonNullApex);

                if (m_Master.usedColorMode == ColorMode.Flat)
                {
                    SetMaterialProp(ShaderProperties.ColorFlat, m_Master.color);
                }
                else
                {
                    var precision = Utils.GetFloatPackingPrecision();
                    m_ColorGradientMatrix = m_Master.colorGradient.SampleInMatrix((int)precision);
                    // pass the gradient matrix in OnWillRenderObject()
                }

                float intensityInside, intensityOutside;
                m_Master.GetInsideAndOutsideIntensity(out intensityInside, out intensityOutside);
                SetMaterialProp(ShaderProperties.AlphaInside, intensityInside);
                SetMaterialProp(ShaderProperties.AlphaOutside, intensityOutside);
                SetMaterialProp(ShaderProperties.AttenuationLerpLinearQuad, m_Master.attenuationLerpLinearQuad);
                SetMaterialProp(ShaderProperties.DistanceFallOff, new Vector3(m_Master.fallOffStart, m_Master.fallOffEnd, m_Master.maxGeometryDistance));
                SetMaterialProp(ShaderProperties.DistanceCamClipping, m_Master.cameraClippingDistance);
                SetMaterialProp(ShaderProperties.FresnelPow, Mathf.Max(0.001f, m_Master.fresnelPow)); // no pow 0, otherwise will generate inf fresnel and issues on iOS
                SetMaterialProp(ShaderProperties.GlareBehind, m_Master.glareBehind);
                SetMaterialProp(ShaderProperties.GlareFrontal, m_Master.glareFrontal);
                SetMaterialProp(ShaderProperties.DrawCap, m_Master.geomCap ? 1 : 0);
                SetMaterialProp(ShaderProperties.TiltVector, m_Master.tiltFactor);
                SetMaterialProp(ShaderProperties.AdditionalClippingPlaneWS, m_Master.additionalClippingPlane);

                if (isDepthBlendEnabled)
                {
                    SetMaterialProp(ShaderProperties.DepthBlendDistance, m_Master.depthBlendDistance);
                }

                if (isNoiseEnabled)
                {
                    Noise3D.LoadIfNeeded();

                    var noiseVelocity = m_Master.noiseVelocityUseGlobal ? Config.Instance.globalNoiseVelocity : m_Master.noiseVelocityLocal;
                    var noiseScale    = m_Master.noiseScaleUseGlobal ? Config.Instance.globalNoiseScale : m_Master.noiseScaleLocal;

                    SetMaterialProp(ShaderProperties.NoiseVelocityAndScale, new Vector4(
                                        noiseVelocity.x,
                                        noiseVelocity.y,
                                        noiseVelocity.z,
                                        noiseScale));

                    SetMaterialProp(ShaderProperties.NoiseParam, new Vector2(
                                        m_Master.noiseIntensity,
                                        m_Master.noiseMode == NoiseMode.WorldSpace ? 0f : 1f));
                }

                var localScale = ComputeLocalMatrix(); // compute matrix before sending it to the shader

                if (m_Master.hasMeshSkewing)
                {
                    var localForwardDirectionNormalized = m_Master.skewingLocalForwardDirectionNormalized;
                    SetMaterialProp(ShaderProperties.LocalForwardDirection, localForwardDirectionNormalized);

                    if (coneMesh != null) // coneMesh can be null few frames with Dynamic Occlusion & GPU Instancing
                    {
                        var localForwardDirectionN = localForwardDirectionNormalized;
                        localForwardDirectionN   /= localForwardDirectionN.z;
                        localForwardDirectionN   *= m_Master.fallOffEnd;
                        localForwardDirectionN.x /= localScale.x;
                        localForwardDirectionN.y /= localScale.y;

                        var bounds = MeshGenerator.ComputeBounds(1f, 1f, 1f);
                        var min    = bounds.min;
                        var max    = bounds.max;

                        if (localForwardDirectionN.x > 0.0f)
                        {
                            max.x += localForwardDirectionN.x;
                        }
                        else
                        {
                            min.x += localForwardDirectionN.x;
                        }

                        if (localForwardDirectionN.y > 0.0f)
                        {
                            max.y += localForwardDirectionN.y;
                        }
                        else
                        {
                            min.y += localForwardDirectionN.y;
                        }

                        bounds.min      = min;
                        bounds.max      = max;
                        coneMesh.bounds = bounds;
                    }
                }

#if VLB_SRP_SUPPORT
                // This update is to make QA test 'ReflectionObliqueProjection' pass
                UpdateMatricesPropertiesForGPUInstancingSRP();
#endif
            }
            MaterialChangeStop();

#if DEBUG_SHOW_MESH_NORMALS
            for (int vertexInd = 0; vertexInd < coneMesh.vertexCount; vertexInd++)
            {
                var vertex = coneMesh.vertices[vertexInd];

                // apply modification done inside VS
                vertex.x *= Mathf.Lerp(coneRadius.x, coneRadius.y, vertex.z);
                vertex.y *= Mathf.Lerp(coneRadius.x, coneRadius.y, vertex.z);
                vertex.z *= m_Master.fallOffEnd;

                var cosSinFlat = new Vector2(vertex.x, vertex.y).normalized;
                var normal     = new Vector3(cosSinFlat.x * Mathf.Cos(slopeRad), cosSinFlat.y * Mathf.Cos(slopeRad), -Mathf.Sin(slopeRad)).normalized;

                vertex = transform.TransformPoint(vertex);
                normal = transform.TransformDirection(normal);
                Debug.DrawRay(vertex, normal * 0.25f);
            }
#endif
        }