예제 #1
0
 void Update()
 {
     if (_isStatic != isStatic)
     {
         if (isStatic == true)              //becoming static
         {
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, meshKey);
         }
         else                 //becoming dynamic
         {
             FS_MeshKey oldMeshKey = meshKey;
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, oldMeshKey);
         }
         _isStatic = isStatic;
     }
     if (!isStatic)
     {
         UnityEngine.Profiling.Profiler.BeginSample("CalculateShadowGeometry");
         CalculateShadowGeometry();
         UnityEngine.Profiling.Profiler.EndSample();
     }
 }
예제 #2
0
 public static FS_ShadowManager Manager()
 {
     if (FS_ShadowManager._manager == null)
     {
         GameObject gameObject = new GameObject("FS_ShadowManager");
         FS_ShadowManager._manager = gameObject.AddComponent <FS_ShadowManager>();
     }
     return(FS_ShadowManager._manager);
 }
	//Singleton, returns this manager.
    public static FS_ShadowManager Manager (){
        if (_manager == null) {
			FS_ShadowManager sm = (FS_ShadowManager) FindObjectOfType(typeof(FS_ShadowManager));
			if (sm == null){
            	GameObject go = new GameObject("FS_ShadowManager");
				_manager = go.AddComponent<FS_ShadowManager>();
			} else {
				_manager = sm;	
			}
        }
        return _manager;
    }
예제 #4
0
 //Singleton, returns this manager.
 public static FS_ShadowManager Manager()
 {
     if (_manager == null)
     {
         FS_ShadowManager sm = FindObjectOfType(typeof(FS_ShadowManager)) as FS_ShadowManager;
         if (sm == null)
         {
             GameObject go = new GameObject("FS_ShadowManager");
             _manager = go.AddComponent <FS_ShadowManager>();
         }
         else
         {
             _manager = sm;
         }
     }
     return(_manager);
 }
예제 #5
0
 public static FS_ShadowManager Manager()
 {
     if (FS_ShadowManager._manager == null)
     {
         FS_ShadowManager fS_ShadowManager = (FS_ShadowManager)UnityEngine.Object.FindObjectOfType(typeof(FS_ShadowManager));
         if (fS_ShadowManager == null)
         {
             GameObject gameObject = new GameObject("FS_ShadowManager");
             FS_ShadowManager._manager = gameObject.AddComponent <FS_ShadowManager>();
         }
         else
         {
             FS_ShadowManager._manager = fS_ShadowManager;
         }
     }
     return(FS_ShadowManager._manager);
 }
예제 #6
0
 void Update()
 {
     if (_isStatic != isStatic)
     {
         if (isStatic == true)              //becoming static
         {
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, meshKey);
         }
         else                 //becoming dynamic
         {
             FS_MeshKey oldMeshKey = meshKey;
             meshKey = new FS_MeshKey(shadowMaterial, isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, oldMeshKey);
         }
         _isStatic = isStatic;
     }
     if (!isStatic)
     {
         CalculateShadowGeometry();
     }
 }
예제 #7
0
 private void Update()
 {
     if (this._isStatic != this.isStatic)
     {
         if (this.isStatic)
         {
             this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
             this.CalculateShadowGeometry();
             FS_ShadowManager.Manager().RecalculateStaticGeometry(null, this.meshKey);
         }
         else
         {
             FS_MeshKey fS_MeshKey = this.meshKey;
             this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
             FS_ShadowManager.Manager().RecalculateStaticGeometry(this, fS_MeshKey);
         }
         this._isStatic = this.isStatic;
     }
     if (!this.isStatic)
     {
         this.CalculateShadowGeometry();
     }
 }
예제 #8
0
    public void CalculateShadowGeometry()
    {
        Vector3 proj;

        if (shadowMaterial == null)
        {
            return;
        }

        if (useLightSource && lightSource == null)
        {
            useLightSource = false;
            Debug.LogWarning("No light source object given using light direction vector.");
        }
        if (useLightSource)
        {
            Vector3 ls  = transform.position - lightSource.transform.position;
            float   mag = ls.magnitude;
            if (mag != 0f)
            {
                lightDirection = ls / mag;
            }
            else
            {
                return;                 //object is on top of light source
            }
        }
        else if (lightDirection != _lightDirection || lightDirection == Vector3.zero)            //light direction is dirty
        {
            if (lightDirection == Vector3.zero)
            {
                Debug.LogWarning("Light Direction vector cannot be zero. assuming -y.");
                lightDirection = -Vector3.up;
            }
            lightDirection.Normalize();
            _lightDirection = lightDirection;
        }

        if (shadowCaster == null || girth != _girth)
        {
            if (shadowCaster == null)
            {
                shadowCaster = new GameObject("shadowSimple");
                cornerGOs    = new GameObject[4];
                for (int i = 0; i < 4; i++)
                {
                    GameObject c = cornerGOs[i] = new GameObject("c" + i);
                    c.transform.parent = shadowCaster.transform;
                }
                shadowCaster.transform.parent        = transform;
                shadowCaster.transform.localPosition = shadowpostion;

                shadowCaster.transform.localRotation = Quaternion.identity;
                shadowCaster.transform.localScale    = Vector3.one;
            }
            if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f)
            {
                proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection;
            }
            else
            {
                proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
            }
            shadowCaster.transform.rotation = Quaternion.LookRotation(proj, -lightDirection);
            cornerGOs[0].transform.position = shadowCaster.transform.position + girth * (shadowCaster.transform.forward - shadowCaster.transform.right);
            cornerGOs[1].transform.position = shadowCaster.transform.position + girth * (shadowCaster.transform.forward + shadowCaster.transform.right);
            cornerGOs[2].transform.position = shadowCaster.transform.position + girth * (-shadowCaster.transform.forward + shadowCaster.transform.right);
            cornerGOs[3].transform.position = shadowCaster.transform.position + girth * (-shadowCaster.transform.forward - shadowCaster.transform.right);
            _girth = girth;
        }
        Transform t = shadowCaster.transform;

        r.origin    = t.position;
        r.direction = lightDirection;

        if (maxProjectionDistance > 0f && Physics.Raycast(r, out rh, maxProjectionDistance, layerMask))
        {
            if (doVisibilityCulling && !isPerspectiveProjection)
            {
                Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                bounds.center = rh.point;
                bounds.size   = new Vector3(2f * girth, 2f * girth, 2f * girth);
                if (!GeometryUtility.TestPlanesAABB(camPlanes, bounds))
                {
                    return;
                }
            }

            // Rotate Shadowcaster
            //project forward or up vector onto a plane whos normal is lightDirection
            if (Mathf.Abs(Vector3.Dot(transform.forward, lightDirection)) < .9f)
            {
                proj = transform.forward - Vector3.Dot(transform.forward, lightDirection) * lightDirection;
            }
            else
            {
                proj = transform.up - Vector3.Dot(transform.up, lightDirection) * lightDirection;
            }
            shadowCaster.transform.rotation = Quaternion.Lerp(shadowCaster.transform.rotation, Quaternion.LookRotation(proj, -lightDirection), .01f);

            float alpha;
            float dist = rh.distance - shadowHoverHeight;
            alpha = 1.0f - dist / maxProjectionDistance;
            if (alpha < 0f)
            {
                return;
            }
            alpha    = Mathf.Clamp01(alpha);
            _color.a = alpha;

            _normal = rh.normal;
            Vector3 hitPoint = rh.point - shadowHoverHeight * lightDirection;
            shadowPlane.SetNormalAndPosition(_normal, hitPoint);

            isGoodPlaneIntersect = true;

            float rayDist = 0f;
            float mag     = 0f;
            if (useLightSource && isPerspectiveProjection)
            {
                r.origin = lightSource.transform.position;
                Vector3 lightSource2Corner = cornerGOs[0].transform.position - lightSource.transform.position;
                mag                  = lightSource2Corner.magnitude;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[0]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[1].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[1]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[2].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[2]          = r.origin + r.direction * rayDist;

                lightSource2Corner   = cornerGOs[3].transform.position - lightSource.transform.position;
                r.direction          = lightSource2Corner / mag;
                isGoodPlaneIntersect = isGoodPlaneIntersect && shadowPlane.Raycast(r, out rayDist);
                _corners[3]          = r.origin + r.direction * rayDist;
                if (doVisibilityCulling)
                {
                    Plane[] camPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                    bounds.center = rh.point;
                    bounds.size   = Vector3.zero;
                    bounds.Encapsulate(_corners[0]);
                    bounds.Encapsulate(_corners[1]);
                    bounds.Encapsulate(_corners[2]);
                    bounds.Encapsulate(_corners[3]);
                    if (!GeometryUtility.TestPlanesAABB(camPlanes, bounds))
                    {
                        return;
                    }
                }
            }
            else
            {
                //r.origin = cornerGOs[0].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[0] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[1].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[1] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[2].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[2] = r.origin + r.direction * rayDist;

                //r.origin = cornerGOs[3].transform.position;
                //isGoodPlaneIntersect = shadowPlane.Raycast(r, out rayDist);
                //if (isGoodPlaneIntersect == false && rayDist == 0f)
                //    return;
                //else
                //    isGoodPlaneIntersect = true;
                //_corners[3] = r.origin + r.direction * rayDist;

                r.origin    = cornerGOs[0].transform.position;
                _corners[0] = r.origin;
                r.origin    = cornerGOs[1].transform.position;
                _corners[1] = r.origin;
                r.origin    = cornerGOs[2].transform.position;
                _corners[2] = r.origin;
                r.origin    = cornerGOs[3].transform.position;
                _corners[3] = r.origin;
            }

            if (isGoodPlaneIntersect)
            {
                if (meshKey == null || meshKey.mat != shadowMaterial || meshKey.isStatic != isStatic)
                {
                    meshKey = new FS_MeshKey(shadowMaterial, isStatic);
                }
                FS_ShadowManager.Manager().registerGeometry(this, meshKey);
                gizmoColor = Color.white;
            }
            else
            {
                gizmoColor = Color.magenta;
            }
        }
        else
        {
            isGoodPlaneIntersect = false;
            gizmoColor           = Color.red;
        }
    }
예제 #9
0
    private void CalculateShadowGeometry()
    {
        if (this.shadowMaterial == null)
        {
            return;
        }
        if (this.useLightSource && this.lightSource == null)
        {
            this.useLightSource = false;
            Debug.LogWarning("No light source object given using light direction vector.");
        }
        if (this.useLightSource)
        {
            Vector3 a         = base.transform.position - this.lightSource.transform.position;
            float   magnitude = a.magnitude;
            if (magnitude == 0f)
            {
                return;
            }
            this.lightDirection = a / magnitude;
        }
        else if (this.lightDirection != this._lightDirection || this.lightDirection == Vector3.zero)
        {
            if (this.lightDirection == Vector3.zero)
            {
                Debug.LogWarning("Light Direction vector cannot be zero. assuming -y.");
                this.lightDirection = -Vector3.up;
            }
            this.lightDirection.Normalize();
            this._lightDirection = this.lightDirection;
        }
        if (this.shadowCaster == null || this.girth != this._girth)
        {
            if (this.shadowCaster == null)
            {
                this.shadowCaster = new GameObject("shadowSimple");
                this.cornerGOs    = new GameObject[4];
                for (int i = 0; i < 4; i++)
                {
                    GameObject gameObject = this.cornerGOs[i] = new GameObject("c" + i);
                    gameObject.transform.parent = this.shadowCaster.transform;
                }
                this.shadowCaster.transform.parent        = base.transform;
                this.shadowCaster.transform.localPosition = Vector3.zero;
                this.shadowCaster.transform.localRotation = Quaternion.identity;
                this.shadowCaster.transform.localScale    = Vector3.one;
            }
            Vector3 forward;
            if (Mathf.Abs(Vector3.Dot(base.transform.forward, this.lightDirection)) < 0.9f)
            {
                forward = base.transform.forward - Vector3.Dot(base.transform.forward, this.lightDirection) * this.lightDirection;
            }
            else
            {
                forward = base.transform.up - Vector3.Dot(base.transform.up, this.lightDirection) * this.lightDirection;
            }
            this.shadowCaster.transform.rotation = Quaternion.LookRotation(forward, -this.lightDirection);
            this.cornerGOs[0].transform.position = this.shadowCaster.transform.position + this.girth * (this.shadowCaster.transform.forward - this.shadowCaster.transform.right);
            this.cornerGOs[1].transform.position = this.shadowCaster.transform.position + this.girth * (this.shadowCaster.transform.forward + this.shadowCaster.transform.right);
            this.cornerGOs[2].transform.position = this.shadowCaster.transform.position + this.girth * (-this.shadowCaster.transform.forward + this.shadowCaster.transform.right);
            this.cornerGOs[3].transform.position = this.shadowCaster.transform.position + this.girth * (-this.shadowCaster.transform.forward - this.shadowCaster.transform.right);
            this._girth = this.girth;
        }
        Transform transform = this.shadowCaster.transform;

        this.r.origin    = transform.position;
        this.r.direction = this.lightDirection;
        if (this.maxProjectionDistance > 0f && Physics.Raycast(this.r, out this.rh, this.maxProjectionDistance, this.layerMask))
        {
            if (this.doVisibilityCulling && !this.isPerspectiveProjection)
            {
                Plane[] cameraFustrumPlanes = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                this.bounds.center = this.rh.point;
                this.bounds.size   = new Vector3(2f * this.girth, 2f * this.girth, 2f * this.girth);
                if (!GeometryUtility.TestPlanesAABB(cameraFustrumPlanes, this.bounds))
                {
                    return;
                }
            }
            Vector3 forward;
            if (Mathf.Abs(Vector3.Dot(base.transform.forward, this.lightDirection)) < 0.9f)
            {
                forward = base.transform.forward - Vector3.Dot(base.transform.forward, this.lightDirection) * this.lightDirection;
            }
            else
            {
                forward = base.transform.up - Vector3.Dot(base.transform.up, this.lightDirection) * this.lightDirection;
            }
            this.shadowCaster.transform.rotation = Quaternion.Lerp(this.shadowCaster.transform.rotation, Quaternion.LookRotation(forward, -this.lightDirection), 0.01f);
            float num  = this.rh.distance - this.shadowHoverHeight;
            float num2 = 1f - num / this.maxProjectionDistance;
            if (num2 < 0f)
            {
                return;
            }
            num2          = Mathf.Clamp01(num2);
            this._color.a = num2;
            this._normal  = this.rh.normal;
            Vector3 inPoint = this.rh.point - this.shadowHoverHeight * this.lightDirection;
            this.shadowPlane.SetNormalAndPosition(this._normal, inPoint);
            this.isGoodPlaneIntersect = true;
            float num3 = 0f;
            if (this.useLightSource && this.isPerspectiveProjection)
            {
                this.r.origin = this.lightSource.transform.position;
                Vector3 a2         = this.cornerGOs[0].transform.position - this.lightSource.transform.position;
                float   magnitude2 = a2.magnitude;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[0]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[1].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[1]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[2].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[2]          = this.r.origin + this.r.direction * num3;
                a2 = this.cornerGOs[3].transform.position - this.lightSource.transform.position;
                this.r.direction          = a2 / magnitude2;
                this.isGoodPlaneIntersect = (this.isGoodPlaneIntersect && this.shadowPlane.Raycast(this.r, out num3));
                this._corners[3]          = this.r.origin + this.r.direction * num3;
                if (this.doVisibilityCulling)
                {
                    Plane[] cameraFustrumPlanes2 = FS_ShadowManager.Manager().getCameraFustrumPlanes();
                    this.bounds.center = this.rh.point;
                    this.bounds.size   = Vector3.zero;
                    this.bounds.Encapsulate(this._corners[0]);
                    this.bounds.Encapsulate(this._corners[1]);
                    this.bounds.Encapsulate(this._corners[2]);
                    this.bounds.Encapsulate(this._corners[3]);
                    if (!GeometryUtility.TestPlanesAABB(cameraFustrumPlanes2, this.bounds))
                    {
                        return;
                    }
                }
            }
            else
            {
                this.r.origin             = this.cornerGOs[0].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[0]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[1].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[1]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[2].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[2]          = this.r.origin + this.r.direction * num3;
                this.r.origin             = this.cornerGOs[3].transform.position;
                this.isGoodPlaneIntersect = this.shadowPlane.Raycast(this.r, out num3);
                if (!this.isGoodPlaneIntersect && num3 == 0f)
                {
                    return;
                }
                this.isGoodPlaneIntersect = true;
                this._corners[3]          = this.r.origin + this.r.direction * num3;
            }
            if (this.isGoodPlaneIntersect)
            {
                if (this.meshKey == null || this.meshKey.mat != this.shadowMaterial || this.meshKey.isStatic != this.isStatic)
                {
                    this.meshKey = new FS_MeshKey(this.shadowMaterial, this.isStatic);
                }
                FS_ShadowManager.Manager().registerGeometry(this, this.meshKey);
                this.gizmoColor = Color.white;
            }
            else
            {
                this.gizmoColor = Color.magenta;
            }
        }
        else
        {
            this.isGoodPlaneIntersect = false;
            this.gizmoColor           = Color.red;
        }
    }