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 }