private void RemoveCaster(LightProjectorShadowCaster caster) { for (var i = 0; i < m_shadowCasterCount; ++i) { if (m_shadowCasters[i] == caster) { m_shadowCasters[i] = m_shadowCasters[--m_shadowCasterCount]; m_shadowCasters[m_shadowCasterCount] = null; break; } } }
private bool IsInProjectionVolume(LightProjectorShadowCaster caster) { var shadowTransform = caster.transform; var shadowPos = shadowTransform.position; Vector3 x; Vector3 y; Vector3 lightDir; if (m_projectorInterface.isOrthographic) { lightDir = m_projectorInterface.direction; } else { lightDir = (shadowPos - m_projectorInterface.position).normalized; } caster.GetShadowPlaneAxes(lightDir, out x, out y); var maxExtension = caster.extension.magnitude; for (var plane = 0; plane < m_clipPlanes.clipPlaneCount; ++plane) { var p = m_clipPlanes.clipPlanes[plane]; var d = p.GetDistanceToPoint(shadowPos); if (d < 0) { if (d < -maxExtension) { return(false); } var ext = Mathf.Abs(caster.extension.x * Vector3.Dot(x, p.normal)) + Mathf.Abs(caster.extension.y * Vector3.Dot(y, p.normal)); if (d < -ext) { return(false); } } else if (m_clipPlanes.twoSideClipping && m_clipPlanes.maxDistance[plane] < d) { if (m_clipPlanes.maxDistance[plane] + maxExtension < d) { return(false); } var ext = Mathf.Abs(caster.extension.x * Vector3.Dot(x, p.normal)) + Mathf.Abs(caster.extension.y * Vector3.Dot(y, p.normal)); if (m_clipPlanes.maxDistance[plane] + ext < d) { return(false); } } } return(true); }
private void AddCaster(LightProjectorShadowCaster caster) { if (m_shadowCasterCount < m_maxShadowNum) { for (var i = 0; i < m_shadowCasterCount; ++i) { if (m_shadowCasters[i] == caster) { return; } } m_shadowCasters[m_shadowCasterCount++] = caster; } }
public void UpdateShadows() { m_projectorInterface.GetClipPlanes(ref m_clipPlanes, null); for (var i = 0; i < m_shadowCasterCount; ++i) { m_prevShadowCasters[i] = m_shadowCasters[i]; } for (var i = 0; i < m_shadowCasterCount; ++i) { var caster = m_shadowCasters[i]; if ((m_shadowCasterMask.value & (1 << caster.gameObject.layer)) == 0) { RemoveCaster(m_shadowCasters[i]); --i; } if (!IsInProjectionVolume(caster)) { RemoveCaster(caster); --i; } } var casters = LightProjectorShadowCaster.GetAllCasters(); for (var i = 0; i < casters.Count && m_shadowCasterCount < m_maxShadowNum; ++i) { var caster = casters[i]; if ((m_shadowCasterMask.value & (1 << caster.gameObject.layer)) == 0) { continue; } var alreadyExist = false; for (var j = 0; j < m_prevShadowCasterCount; ++j) { if (caster == m_prevShadowCasters[j]) { alreadyExist = true; break; } } if ((!alreadyExist) && IsInProjectionVolume(caster)) { AddCaster(caster); } } Vector3 lightPos; if (m_projectorInterface.isOrthographic) { lightPos = m_projectorInterface.direction; } else { lightPos = m_projectorInterface.position; } for (var i = 0; i < m_shadowCasterCount; ++i) { Matrix4x4 mat; if (m_projectorInterface.isOrthographic) { mat = m_shadowCasters[i].GetOrthoProjectionMatrix(lightPos); } else { mat = m_shadowCasters[i].GetProjectionMatrix(lightPos); } m_material.SetMatrix(s_shadowProjectionMatrixPropertyIDs[i], mat); m_material.SetTexture(s_shadowTexturePropertyIDs[i], m_shadowCasters[i].shadowTexture); } if (m_prevShadowCasterCount != m_shadowCasterCount) { m_material.DisableKeyword(s_shadowNumKeyword[m_prevShadowCasterCount]); m_material.EnableKeyword(s_shadowNumKeyword[m_shadowCasterCount]); m_prevShadowCasterCount = m_shadowCasterCount; } }