Beispiel #1
0
        public static Vector4 GetShadowBias(/*ref VisibleLight shadowLight,*/
            ref LightData_Shadow lightShadowData, int shadowLightIndex, ref ShadowData shadowData,
            out Matrix4x4 lightProjectionMatrix, out Matrix4x4 lightViewMatrix, float shadowResolution)
        {
            lightProjectionMatrix = lightShadowData.projMatrix;
            lightViewMatrix       = lightShadowData.viewMatrix;
            if (shadowLightIndex < 0 || shadowLightIndex >= shadowData.bias.Count)
            {
                Debug.LogWarning(string.Format("{0} is not a valid light index.", shadowLightIndex));
                return(Vector4.zero);
            }
            // TODO ?
            float frustumSize = 2.0f / lightProjectionMatrix.m00;
            //if (shadowLight.lightType == LightType.Directional)
            //{
            //    // Frustum size is guaranteed to be a cube as we wrap shadow frustum around a sphere
            //    frustumSize = 2.0f / lightProjectionMatrix.m00;
            //}
            //else if (shadowLight.lightType == LightType.Spot)
            //{
            //    // For perspective projections, shadow texel size varies with depth
            //    // It will only work well if done in receiver side in the pixel shader. Currently LWRP
            //    // do bias on caster side in vertex shader. When we add shader quality tiers we can properly
            //    // handle this. For now, as a poor approximation we do a constant bias and compute the size of
            //    // the frustum as if it was orthogonal considering the size at mid point between near and far planes.
            //    // Depending on how big the light range is, it will be good enough with some tweaks in bias
            //    frustumSize = Mathf.Tan(shadowLight.spotAngle * 0.5f * Mathf.Deg2Rad) * shadowLight.range;
            //}
            //else
            //{
            //    Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline");
            //    frustumSize = 0.0f;
            //}

            // depth and normal bias scale is in shadowmap texel size in world space
            float texelSize  = frustumSize / shadowResolution;
            float depthBias  = -shadowData.bias[shadowLightIndex].x * texelSize;
            float normalBias = -shadowData.bias[shadowLightIndex].y * texelSize;

            if (shadowData.supportsSoftShadows)
            {
                // TODO: depth and normal bias assume sample is no more than 1 texel away from shadowmap
                // This is not true with PCF. Ideally we need to do either
                // cone base bias (based on distance to center sample)
                // or receiver place bias based on derivatives.
                // For now we scale it by the PCF kernel size (5x5)
                const float kernelRadius = 2.5f;
                depthBias  *= kernelRadius;
                normalBias *= kernelRadius;
            }

            return(new Vector4(depthBias, normalBias, 0.0f, 0.0f));
        }
Beispiel #2
0
        public static bool ExtractProjectorLightMatrix(ref ProjectorLight projectorLight, ref LightData_Shadow shadowData,
                                                       out Matrix4x4 shadowMatrix)
        {
            ShadowSplitData splitData = new ShadowSplitData();

            splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
            splitData.cullingPlaneCount = 0;
            //for (int i = 0; i < 6; ++i)
            //{
            //    var splane = shadowData.planes[i];
            //    Plane plane = new Plane(splane.normal, splane.distance);
            //    splitData.SetCullingPlane(i, plane);
            //}
            shadowMatrix = GetShadowTransform(shadowData.projMatrix, shadowData.viewMatrix);
            return(true);
        }
Beispiel #3
0
        public LightDataInAll GetLightData(Matrix4x4 c2w, int currentShadowIndex)
        {
            LightDataInAll lightDataInAll = new LightDataInAll();

            var ps = iFPipelineProjector.GetProjectorSettings;
            {
                //bound.planes = Projector.GetCullingPlanes(ps.frustumMatrix, c2w);//world to view
                Projector.GetCullingPlanesAndSphere(
                    out lightDataInAll.sFiniteLightBound.planes,
                    out lightDataInAll.sFiniteLightBound.aabb,
                    ps.frustumMatrix, c2w);
            }

            LightData lightData = new LightData();

            lightData.pos = cacheTransform.position;
            //lightData.lightParms = (uint)LightParams;
            lightData.posShadow   = new Vector4();
            lightData.falloffR    = ps.falloffR;
            lightData.projS       = ps.projectMatrixX;
            lightData.projT       = ps.projectMatrixY;
            lightData.projQ       = ps.projectMatrixW;
            lightData.colorPacked = ColorTools.packRGBE(ColorTools.Color2Vec3(FinalColor));
            var unpack = ColorTools.unpackRGBE(2256963201);

            //Debug.Log(unpack.ToString());
            //Debug.Log(FinalColor.ToString());
            lightData.specMultiplier    = specMultiplier;
            lightData.shadowBleedReduce = shadowBleedReduce;

            int sizex = spritesAtlas.width;
            int sizey = spritesAtlas.height;
            {
                SpriteData spriteData = projSpriteData;
                float      x          = spriteData.x;
                float      y          = sizey - spriteData.y - spriteData.height;//GPU得纹理坐标y轴反的,原点左上角
                float      width      = spriteData.width;
                float      height     = spriteData.height;
                float      scalex     = width / sizex;//todo:optimize
                float      scaley     = height / sizey;
                float      offsetx    = x / sizex;
                float      offsety    = y / sizey;
                ColorTools.packR15G15B15A15(
                    out lightData.scaleBias.x,
                    out lightData.scaleBias.y,
                    new Vector4(scalex, scaley, offsetx, offsety));
            }

            {
                SpriteData spriteData = falloffSpriteData;
                float      x          = spriteData.x;
                float      y          = sizey - spriteData.y - spriteData.height;//GPU得纹理坐标y轴反的,原点左上角
                float      width      = spriteData.width;
                float      height     = spriteData.height;
                float      scalex     = width / sizex;//todo:optimize
                float      scaley     = height / sizey;
                float      offsetx    = x / sizex;
                float      offsety    = y / sizey;
                ColorTools.packR15G15B15A15(
                    out lightData.scaleBias.z,
                    out lightData.scaleBias.w,
                    new Vector4(scalex, scaley, offsetx, offsety));
            }

            //public Vector4 boxMin;
            //public Vector4 boxMax;
            //public Vector4 areaPlane;
            {
                Plane   plane    = lightDataInAll.sFiniteLightBound.planes.Near;
                Vector3 normalws = plane.normal.normalized;
                plane.distance      = Vector3.Dot(lightData.pos, normalws);
                plane.normal        = normalws * area_falloff;
                lightData.areaPlane = new Vector4(
                    plane.normal.x,
                    plane.normal.y,
                    plane.normal.z,
                    plane.distance);

                //问题:已知plane,求面上偏移width,height的点
                Vector3   topright    = new Vector3(area_width, area_height, 0);
                Vector3   bottomleft  = new Vector3(-area_width, -area_height, 0);
                Matrix4x4 local2world = cacheTransform.localToWorldMatrix;
                topright   = local2world.MultiplyPoint3x4(topright);
                bottomleft = local2world.MultiplyPoint3x4(bottomleft);
#if UNITY_EDITOR
                posa = bottomleft;
                posc = topright;
                posb = new Vector3(-area_width, area_height, 0);
                posb = local2world.MultiplyPoint3x4(posb);
                posd = new Vector3(area_width, -area_height, 0);
                posd = local2world.MultiplyPoint3x4(posd);
#endif
                Vector3 boxMin = new Vector3(
                    Mathf.Min(bottomleft.x, topright.x),
                    Mathf.Min(bottomleft.y, topright.y),
                    Mathf.Min(bottomleft.z, topright.z)
                    );
                Vector3 boxMax = new Vector3(
                    Mathf.Max(bottomleft.x, topright.x),
                    Mathf.Max(bottomleft.y, topright.y),
                    Mathf.Max(bottomleft.z, topright.z)
                    );

                lightData.boxMin = boxMin;
                lightData.boxMax = boxMax;
            }

#if UNITY_EDITOR
            cacheLightData = lightDataInAll;
#endif

            // shadow
            {
                LightData_Shadow shadowData = new LightData_Shadow();
                if (lightParms_Shadow && currentShadowIndex != -1)
                {
                    needDrawShadow          = true;
                    lightParams_ShadowIndex = currentShadowIndex;
                    shadowData.projMatrix   = iFPipelineProjector.GetProjectorSettings.projMatrix;
                    shadowData.viewMatrix   = iFPipelineProjector.GetProjectorSettings.viewMatrix;
#if UNITY_EDITOR
                    shadowData.planes = cacheLightData.sFiniteLightBound.planes;
#endif
                }
                else
                {
                    needDrawShadow = false;
                }
                lightDataInAll.shadowData = shadowData;
            }

            lightData.lightParms     = (uint)LightParams;
            lightDataInAll.lightData = lightData;

            return(lightDataInAll);
        }