Example #1
0
    /// <summary>
    /// 通过顶点列表获取AABB包围盒
    /// </summary>
    /// <param name="vertexList"></param>
    /// <returns></returns>
    public static AABBBounds GetAABBBoundsByVertexList(List <Vector3> vertexList)
    {
        AABBBounds aabbBounds = new AABBBounds();

        for (int i = 0; i < vertexList.Count; ++i)
        {
            aabbBounds.UpdatePoint(vertexList[i]);
        }

        return(aabbBounds);
    }
Example #2
0
    public static AABBBounds GetAABBBoundsOnTargetSpace(Transform targetSpaceTransform, List <Vector3> worldVertexList)
    {
        AABBBounds aabbBounds = new AABBBounds();

        foreach (Vector3 vertex in worldVertexList)
        {
            Vector3 pointOnTargetSpace = targetSpaceTransform.worldToLocalMatrix.MultiplyPoint(vertex);
            aabbBounds.UpdatePoint(pointOnTargetSpace);
        }

        return(aabbBounds);
    }
Example #3
0
    /// <summary>
    /// 设置LightCamera 适应视角
    /// </summary>
    /// <param name="lightTransform"></param>
    /// <param name="lightCamera"></param>
    /// <param name="mainCamera"></param>
    /// <param name="sceneConnerList"></param>
    private void SetLightCameraFitView(Transform lightTransform, Camera lightCamera, Camera mainCamera, List <Vector3> sceneConnerList)
    {
        List <Vector3> mainCameraFrustumConners  = GetCameraPerspectiveFrustumConners(mainCamera);
        AABBBounds     frustumBoundsInLightSpace = new AABBBounds();

        mainCameraFrustumConners.ForEach(connerVertex =>
        {
            Vector3 worldFrustumConner = mainCamera.transform.localToWorldMatrix.MultiplyPoint(connerVertex);

            Vector3 pointInLightSpace = lightTransform.worldToLocalMatrix.MultiplyPoint(worldFrustumConner);

            frustumBoundsInLightSpace.UpdatePoint(pointInLightSpace);
        });


        AABBBounds sceneBounds = GetSceneAABBBoundsInTargetSpace(sceneConnerList, lightTransform);

        //计算Frustum 时,需要注意,如果Camera.farpanel 特别大,计算出的AABB太大, 所以可以采取AABBFrustum 跟 SceneAABB 相交作为最终的投影包围体
        //或者设置farpanel neaarpanel到合理的大小

        //lightCamera.transform.localPosition = new Vector3(frustumBoundsInLightSpace.Center.x, frustumBoundsInLightSpace.Center.y, frustumBoundsInLightSpace.Min.z - 0.05f);
        //lightCamera.orthographicSize = Mathf.Max(frustumBoundsInLightSpace.Extends.x, frustumBoundsInLightSpace.Extends.y);
        //lightCamera.nearClipPlane = 0.05f;
        //lightCamera.farClipPlane = 0.05f + (frustumBoundsInLightSpace.Size.z);

        Vector3 shadowCameraMin = new Vector3(
            Mathf.Max(sceneBounds.Min.x, frustumBoundsInLightSpace.Min.x),
            Mathf.Max(sceneBounds.Min.y, frustumBoundsInLightSpace.Min.y),
            Mathf.Max(sceneBounds.Min.z, frustumBoundsInLightSpace.Min.z));

        Vector3 shadowCameraMax = new Vector3(
            Mathf.Min(sceneBounds.Max.x, frustumBoundsInLightSpace.Max.x),
            Mathf.Min(sceneBounds.Max.y, frustumBoundsInLightSpace.Max.y),
            Mathf.Min(sceneBounds.Max.z, frustumBoundsInLightSpace.Max.z));

        Vector3 center  = (shadowCameraMax + shadowCameraMin) / 2;
        Vector3 extends = (shadowCameraMax - shadowCameraMin) / 2;

        lightCamera.transform.localPosition = new Vector3(center.x, center.y, shadowCameraMin.z - 0.05f);
        lightCamera.orthographicSize        = Mathf.Max(extends.x, extends.y);
        lightCamera.nearClipPlane           = 0.05f;
        lightCamera.farClipPlane            = 0.05f + (extends.z * 2);


        Matrix4x4 lightCameraProjectionUVMatrix = new Matrix4x4();
        Vector3   transpose = new Vector3(0.5f, 0.5f, 0);
        Vector3   scale     = new Vector3(0.5f, 0.5f, 1);

        lightCameraProjectionUVMatrix.SetTRS(transpose, Quaternion.identity, scale);
        lightCameraProjectionUVMatrix = lightCameraProjectionUVMatrix * GL.GetGPUProjectionMatrix(lightCamera.projectionMatrix, false) * lightCamera.worldToCameraMatrix;

        Shader.SetGlobalMatrix("_LightSpaceProjectionUVMatrix", lightCameraProjectionUVMatrix);
    }
Example #4
0
    private AABBBounds GetSceneAABBBoundsInTargetSpace(List <Vector3> worldConnerList, Transform targetSpace)
    {
        AABBBounds boundsInLightSpace = new AABBBounds();

        worldConnerList.ForEach(worldConnerVertex =>
        {
            Vector3 connerPosInLightSpace = targetSpace.worldToLocalMatrix.MultiplyPoint(worldConnerVertex);
            boundsInLightSpace.UpdatePoint(connerPosInLightSpace);
        });

        return(boundsInLightSpace);
    }
Example #5
0
    public static AABBBounds GetAABBBoundsOnWorldSpace(List <Vector3> vertexList, Transform relativeToSpace)
    {
        AABBBounds aabbBounds = new AABBBounds();

        foreach (Vector3 vertex in vertexList)
        {
            Vector3 worldPos = relativeToSpace.localToWorldMatrix.MultiplyPoint(vertex);

            aabbBounds.UpdatePoint(worldPos);
        }

        return(aabbBounds);
    }
    private void UpdateShadowmapCameraParams(BoundsType boundsType)
    {
        if (boundsType == BoundsType.AABB)
        {
            for (int i = 0; i < CascadeStepNum; ++i)
            {
                List <Vector3> frustumVertex             = m_cameraFrustumList[i];
                AABBBounds     frustumBoundsOnLightSpace = GeometryUtility.GetAABBBoundsOnTargetSpace(Mainlight.transform, frustumVertex);

                CascadedShadowMapCameraParams cameraParams = new CascadedShadowMapCameraParams();
                cameraParams.cameraPosition       = new Vector3(frustumBoundsOnLightSpace.Center.x, frustumBoundsOnLightSpace.Center.y, frustumBoundsOnLightSpace.Min.z - 0.05f);
                cameraParams.cameraOrthogonalSize = Mathf.Max(frustumBoundsOnLightSpace.Extends.x, frustumBoundsOnLightSpace.Extends.y) / 2;           //todo:orthogonalSize算法需要以后好好研究一下
                cameraParams.cameraZSize          = frustumBoundsOnLightSpace.Size.z;

                m_shadowMapCameraParams.Add(cameraParams);
            }
        }
    }
Example #7
0
    /// <summary>
    /// 摄像机正适应场景
    /// </summary>
    /// <param name="lightTransform"></param>
    /// <param name="lightCamara"></param>
    /// <param name="sceneConnerList"></param>
    private void SetLightCameraFitScene(Transform lightTransform, Camera lightCamara, List <Vector3> sceneConnerList)
    {
        AABBBounds boundsInLightSpace = GetSceneAABBBoundsInTargetSpace(sceneConnerList, lightTransform);

        //由于lightcamera,位置由x,y确定,z由 camera.near far确定  脑补一下侧视图 还有俯视图
        //x,y的中间就是摄像机位置,z值为near~far 需要保证near~far大于0
        lightCamara.transform.localPosition = new Vector3(boundsInLightSpace.Center.x, boundsInLightSpace.Center.y, boundsInLightSpace.Min.z - 0.05f);
        lightCamara.orthographicSize        = Mathf.Max(boundsInLightSpace.Extends.x, boundsInLightSpace.Extends.y);
        lightCamara.nearClipPlane           = 0.05f;
        lightCamara.farClipPlane            = 0.05f + (boundsInLightSpace.Size.z);

        Matrix4x4 lightCameraProjectionUVMatrix = new Matrix4x4();
        Vector3   transpose = new Vector3(0.5f, 0.5f, 0f);
        Vector3   scale     = new Vector3(0.5f, 0.5f, 1f);

        lightCameraProjectionUVMatrix.SetTRS(transpose, Quaternion.identity, scale);

        //  (P*V) *0.5 +0.5
        lightCameraProjectionUVMatrix = lightCameraProjectionUVMatrix * GL.GetGPUProjectionMatrix(lightCamara.projectionMatrix, false) * lightCamara.worldToCameraMatrix;

        Shader.SetGlobalMatrix("_LightSpaceProjectionUVMatrix", lightCameraProjectionUVMatrix);
    }