private void Update() { WPShadowSetting setting = GetCurrentSetting(); // Main camera maybe changed m_mainCamera = Camera.main; // Culling intersection with main camera activeCullingMask = setting.cullingMask & (m_mainCamera ? m_mainCamera.cullingMask : 0); if (activeCullingMask == 0 || setting.shadowIntensity <= 0.001f) { ClearShadow(); return; } UpdateShadowDepthMap(setting); UpdateShadowMap(setting); }
private void UpdateShadowDepthMap(WPShadowSetting setting) { int size = setting.resolution == 3 ? 2048 : (setting.resolution == 2 ? 1024 : 512); if (size == m_shadowMapSize) { return; } if (m_shadowMap) { RenderTexture.ReleaseTemporary(m_shadowMap); } m_shadowMapSize = size; m_shadowMap = RenderTexture.GetTemporary(size, size, 0, m_rtFormat); m_shadowMap.filterMode = FilterMode.Point; shadowCamera.targetTexture = m_shadowMap; Shader.SetGlobalTexture(ID_WP_ShadowMap, m_shadowMap); }
private void UpdateShadowMap(WPShadowSetting setting) { /* * 0 1 * near * 2 3 */ float nearDistance = m_mainCamera.nearClipPlane; float tanHalfFov = Mathf.Tan(m_mainCamera.fieldOfView * 0.5f * Mathf.Deg2Rad); float nearHalfHeight = tanHalfFov * nearDistance; float nearHalfWidth = nearHalfHeight * m_mainCamera.aspect; float farHalfHeight = tanHalfFov * setting.shadowDistance; float farHalfWidth = farHalfHeight * m_mainCamera.aspect; m_frustumVertexs[0] = new Vector3(-nearHalfWidth, nearHalfHeight, nearDistance); m_frustumVertexs[1] = new Vector3(nearHalfWidth, nearHalfHeight, nearDistance); m_frustumVertexs[2] = new Vector3(-nearHalfWidth, -nearHalfHeight, nearDistance); m_frustumVertexs[3] = new Vector3(nearHalfWidth, -nearHalfHeight, nearDistance); m_frustumVertexs[4] = new Vector3(-farHalfWidth, farHalfHeight, setting.shadowDistance); m_frustumVertexs[5] = new Vector3(farHalfWidth, farHalfHeight, setting.shadowDistance); m_frustumVertexs[6] = new Vector3(-farHalfWidth, -farHalfHeight, setting.shadowDistance); m_frustumVertexs[7] = new Vector3(farHalfWidth, -farHalfHeight, setting.shadowDistance); Matrix4x4 viewToWorld = m_mainCamera.transform.localToWorldMatrix; Matrix4x4 worldToLight = m_transLight.worldToLocalMatrix; Matrix4x4 VL = worldToLight * viewToWorld; for (int i = 0; i < 8; i++) { m_frustumVertexs[i] = VL.MultiplyPoint(m_frustumVertexs[i]); } float xMin = float.MaxValue, xMax = float.MinValue; float yMin = float.MaxValue, yMax = float.MinValue; float zMin = float.MaxValue, zMax = float.MinValue; for (int i = 0; i < 8; i++) { Vector3 v = m_frustumVertexs[i]; xMin = Mathf.Min(xMin, v.x); xMax = Mathf.Max(xMax, v.x); yMin = Mathf.Min(yMin, v.y); yMax = Mathf.Max(yMax, v.y); zMin = Mathf.Min(zMin, v.z); zMax = Mathf.Max(zMax, v.z); } m_transShadowCamera.localPosition = new Vector3((xMin + xMax) * 0.5f, (yMin + yMax) * 0.5f, 0); shadowCamera.orthographicSize = Mathf.Max((xMax - xMin) * 0.5f, (yMax - yMin) * 0.5f); shadowCamera.nearClipPlane = zMin; shadowCamera.farClipPlane = zMax; shadowCamera.cullingMask = activeCullingMask; Matrix4x4 worldToView = shadowCamera.worldToCameraMatrix; Matrix4x4 projection = GL.GetGPUProjectionMatrix(shadowCamera.projectionMatrix, false); Matrix4x4 VPC = m_correction4x4 * projection * worldToView; Shader.SetGlobalMatrix(ID_WP_MatrixV, worldToView); Shader.SetGlobalMatrix(ID_WP_MatrixVPC, VPC); Shader.SetGlobalVector(ID_WP_ControlParams, new Vector4(setting.shadowIntensity, (int)setting.antiAliasing, zMin, 1f / (zMax - zMin))); shadowCamera.RenderWithShader(shadowMapShader, "RenderType"); }