void SetFocus(int idx) { if (!isValid) { return; } if (idx < 0 || idx >= shadowFoci.Length) { Debug.LogError("Invalid active focus: " + m_activeFocus); return; } m_activeFocus = idx; FocusSetup focus = shadowFoci[m_activeFocus]; UpdateAutoFocus(focus); m_shadowCamera.orthographicSize = focus.radius; m_shadowCamera.nearClipPlane = useSceneCapture ? -focus.sceneCaptureDistance : 0f; m_shadowCamera.farClipPlane = focus.radius * 2f; m_shadowCamera.projectionMatrix = GL.GetGPUProjectionMatrix(Matrix4x4.Ortho(-focus.radius, focus.radius, -focus.radius, focus.radius, 0f, focus.radius * 2f), false); bool isD3D9 = SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Direct3D9; bool isD3D = isD3D9 || SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Direct3D11; float to = isD3D9 ? 0.5f / (float)(int)shadowMapSize : 0f; float zs = isD3D ? 1f : 0.5f, zo = isD3D ? 0f : 0.5f; float db = -focus.depthBias; m_shadowSpaceMatrix.SetRow(0, new Vector4(0.5f, 0.0f, 0.0f, 0.5f + to)); m_shadowSpaceMatrix.SetRow(1, new Vector4(0.0f, 0.5f, 0.0f, 0.5f + to)); m_shadowSpaceMatrix.SetRow(2, new Vector4(0.0f, 0.0f, zs, zo + db)); m_shadowSpaceMatrix.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); }
void ApplyShaderParams(Material m) { if (!isValid) { return; } m.SetTexture("u_CharacterShadowTextureFakePoint", ms_shadowTextureFakePoint); // We want the same 'softness' regardless of texture resolution. float texelsInMap = (float)(int)shadowMapSize; float relativeTexelSize = texelsInMap / 2048f; m.SetVector("u_CharacterShadowFilterWidth", new Vector2(1f / (float)(int)shadowMapSize, 1f / (float)(int)shadowMapSize) * fallbackFilterWidth * relativeTexelSize); float characterShadowBlockerWidth = relativeTexelSize * blockerSearchDistance / texelsInMap; m.SetVector("u_CharacterShadowBlockerWidth", Vector4.one * characterShadowBlockerWidth); // This needs to run each frame if we start using multiple foci. FocusSetup focus = shadowFoci[m_activeFocus]; float characterShadowBlockerDistanceScale = blockerDistanceScale * focus.radius * 0.5f / 10f; // 10 samples in shader m.SetFloat("u_CharacterShadowBlockerDistanceScale", characterShadowBlockerDistanceScale); Vector2 CharacterShadowLightWidth = new Vector2(lightNearSize, lightFarSize) * relativeTexelSize / texelsInMap; m.SetVector("u_CharacterShadowLightWidth", CharacterShadowLightWidth); }
/// <summary> /// 是否可见 /// </summary> /// <param name="cam"></param> /// <returns></returns> bool CheckVisibility(Camera cam) { if (!isValid) { return(false); } FocusSetup focus = shadowFoci[m_activeFocus]; UpdateAutoFocus(focus); var targetPos = focus.target.position + focus.target.right * focus.offset.x + focus.target.up * focus.offset.y + focus.target.forward * focus.offset.z; var bounds = new Bounds(targetPos, Vector3.one * focus.radius * 2f); return((targetPos - cam.transform.position).sqrMagnitude < (cullingDistance * cullingDistance) && GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(cam), bounds)); }
public void Bake(Transform target, Renderer BodyRender) { if (!BodyRender) { return; } shadowFoci = new FocusSetup[1]; FocusSetup instanceSetUp = new FocusSetup(); Vector3 oldPos = BodyRender.transform.localPosition; Quaternion oldRot = BodyRender.transform.localRotation; Vector3 oldScale = BodyRender.transform.localScale; BodyRender.transform.localPosition = Vector3.zero; BodyRender.transform.localRotation = Quaternion.identity; BodyRender.transform.localScale = Vector3.one; SphereCollider collider = BodyRender.gameObject.AddComponent <SphereCollider>(); shadowFoci[0] = instanceSetUp; instanceSetUp.autoFocus = false; instanceSetUp.autoFocusRadiusBias = 0.0f; instanceSetUp.target = target; instanceSetUp.radius = collider.radius; instanceSetUp.offset = collider.center; instanceSetUp.depthBias = 0.001f; instanceSetUp.sceneCaptureDistance = 0f; this.BodyRender = null; this.BodyRender = BodyRender; GameObject.DestroyImmediate(collider); BodyRender.transform.localRotation = oldRot; BodyRender.transform.localPosition = oldPos; BodyRender.transform.localScale = oldScale; if (!Initialize.isOnGameRuning) { Debug.Log("CharacterShadow-Bake成功"); } }
void UpdateAutoFocus(FocusSetup focus) { if (!isValid) { return; } if (!focus.autoFocus) { return; } var targetPos = focus.target.position + focus.target.right * focus.offset.x + focus.target.up * focus.offset.y + focus.target.forward * focus.offset.z; Bounds bounds = new Bounds(targetPos, Vector3.one * 0.1f); bounds.Encapsulate(BodyRender.bounds); focus.offset = bounds.center - focus.target.position; focus.radius = focus.autoFocusRadiusBias + bounds.extents.magnitude; }
/// <summary> /// 更新焦点 /// </summary> void UpdateFocus() { if (!isValid) { return; } FocusSetup focus = shadowFoci[m_activeFocus]; Vector3 targetPos = focus.target.position + focus.target.right * focus.offset.x + focus.target.up * focus.offset.y + focus.target.forward * focus.offset.z; Vector3 lightDir = m_lightSource.transform.forward; Quaternion lightOri = m_lightSource.transform.rotation; m_shadowCamera.transform.position = targetPos - lightDir * focus.radius; m_shadowCamera.transform.rotation = lightOri; Matrix4x4 shadowViewMat = m_shadowCamera.worldToCameraMatrix; Matrix4x4 shadowProjMat = GL.GetGPUProjectionMatrix(m_shadowCamera.projectionMatrix, false); m_shadowMatrix = m_shadowSpaceMatrix * shadowProjMat * shadowViewMat; }
void UpdateAutoFocus(FocusSetup focus) { if (!focus.autoFocus) { return; } var targetPos = focus.target.position + focus.target.right * focus.offset.x + focus.target.up * focus.offset.y + focus.target.forward * focus.offset.z; var self = GetComponent <Renderer>(); var bounds = new Bounds(targetPos, Vector3.one * 0.1f); foreach (var r in GetComponentsInChildren <Renderer>()) { if (r != self) { bounds.Encapsulate(r.bounds); } } focus.offset = bounds.center - focus.target.position; focus.radius = focus.autoFocusRadiusBias + bounds.extents.magnitude; }
void UpdateAutoFocus(FocusSetup focus) { if(!focus.autoFocus) return; var targetPos = focus.target.position + focus.target.right * focus.offset.x + focus.target.up * focus.offset.y + focus.target.forward * focus.offset.z; var self = GetComponent<Renderer>(); var bounds = new Bounds(targetPos, Vector3.one * 0.1f); foreach(var r in GetComponentsInChildren<Renderer>()) if(r != self) bounds.Encapsulate(r.bounds); focus.offset = bounds.center - focus.target.position; focus.radius = focus.autoFocusRadiusBias + bounds.extents.magnitude; }