Example #1
0
    void Start()
    {
        float inten = 2f;

        if (GetComponent <SpriteRenderer>() != null)
        {
            Material material = GetComponent <SpriteRenderer>().material;
            material.SetColor("Color_F71EC87A", new Color(color.r * inten, color.g * inten, color.b * inten));
        }
        if (GetComponent <UnityEngine.Rendering.Universal.Light2D>() != null)
        {
            UnityEngine.Rendering.Universal.Light2D light = GetComponent <UnityEngine.Rendering.Universal.Light2D>();
            light.color = color;
        }
    }
Example #2
0
        public static void ErrorIfDuplicateGlobalLight(Light2D light)
        {
            if (light.lightType != Light2D.LightType.Global)
            {
                return;
            }

            foreach (var sortingLayer in light.affectedSortingLayers)
            {
                // should this really trigger at runtime?
                if (ContainsDuplicateGlobalLight(sortingLayer, light.blendStyleIndex))
                {
                    Debug.LogError("More than one global light on layer " + SortingLayer.IDToName(sortingLayer) + " for light blend style index " + light.blendStyleIndex);
                }
            }
        }
Example #3
0
        private static Material CreateLightMaterial(Renderer2DData rendererData, Light2D light, bool isVolume)
        {
            var      isPoint = light.isPointLight;
            Material material;

            if (isVolume)
            {
                material = CoreUtils.CreateEngineMaterial(isPoint ? rendererData.pointLightVolumeShader : rendererData.shapeLightVolumeShader);
            }
            else
            {
                material = CoreUtils.CreateEngineMaterial(isPoint ? rendererData.pointLightShader : rendererData.shapeLightShader);

                if (light.overlapOperation == Light2D.OverlapOperation.Additive)
                {
                    SetBlendModes(material, BlendMode.One, BlendMode.One);
                    material.EnableKeyword(k_UseAdditiveBlendingKeyword);
                }
                else
                {
                    SetBlendModes(material, BlendMode.SrcAlpha, BlendMode.OneMinusSrcAlpha);
                }
            }

            if (light.lightType == Light2D.LightType.Sprite)
            {
                material.EnableKeyword(k_SpriteLightKeyword);
            }

            if (isPoint && light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
            {
                material.EnableKeyword(k_UsePointLightCookiesKeyword);
            }

            if (isPoint && light.normalMapQuality == Light2D.NormalMapQuality.Fast)
            {
                material.EnableKeyword(k_LightQualityFastKeyword);
            }

            if (light.normalMapQuality != Light2D.NormalMapQuality.Disabled)
            {
                material.EnableKeyword(k_UseNormalMap);
            }

            return(material);
        }
Example #4
0
        internal bool IsLit(Light2D light)
        {
            // Oddly adding and subtracting vectors is expensive here because of the new structures created...
            Vector3 deltaPos;

            deltaPos.x = m_ProjectedBoundingSphere.position.x + m_CachedPosition.x;
            deltaPos.y = m_ProjectedBoundingSphere.position.y + m_CachedPosition.y;
            deltaPos.z = m_ProjectedBoundingSphere.position.z + m_CachedPosition.z;

            deltaPos.x = light.m_CachedPosition.x - deltaPos.x;
            deltaPos.y = light.m_CachedPosition.y - deltaPos.y;
            deltaPos.z = light.m_CachedPosition.z - deltaPos.z;

            float distanceSq = Vector3.SqrMagnitude(deltaPos);

            float radiiLength = light.boundingSphere.radius + m_ProjectedBoundingSphere.radius;

            return(distanceSq <= (radiiLength * radiiLength));
        }
Example #5
0
        public static Bounds GenerateSpriteMesh(Light2D light, Sprite sprite)
        {
            var mesh = light.lightMesh;

            if (sprite == null)
            {
                mesh.Clear();
                return(new Bounds(Vector3.zero, Vector3.zero));
            }

            // this needs to be called before getting UV at the line below.
            // Venky fixed it, enroute to trunk
            var uvs = sprite.uv;

            var srcVertices = sprite.GetVertexAttribute <Vector3>(VertexAttribute.Position);
            var srcUVs      = sprite.GetVertexAttribute <Vector2>(VertexAttribute.TexCoord0);
            var srcIndices  = sprite.GetIndices();

            var center   = 0.5f * (sprite.bounds.min + sprite.bounds.max);
            var vertices = new NativeArray <LightMeshVertex>(srcIndices.Length, Allocator.Temp);
            var color    = new Color(0, 0, 0, 1);

            for (var i = 0; i < srcVertices.Length; i++)
            {
                vertices[i] = new LightMeshVertex
                {
                    position = new Vector3(srcVertices[i].x, srcVertices[i].y, 0) - center,
                    color    = color,
                    uv       = srcUVs[i]
                };
            }
            mesh.SetVertexBufferParams(vertices.Length, LightMeshVertex.VertexLayout);
            mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length);
            mesh.SetIndices(srcIndices, MeshTopology.Triangles, 0, true);

            light.vertices = new LightMeshVertex[vertices.Length];
            NativeArray <LightMeshVertex> .Copy(vertices, light.vertices, vertices.Length);

            light.indices = new ushort[srcIndices.Length];
            NativeArray <ushort> .Copy(srcIndices, light.indices, srcIndices.Length);

            return(mesh.GetSubMesh(0).bounds);
        }
        public static void RenderShadows(IRenderPass2D pass, RenderingData renderingData, CommandBuffer cmdBuffer, int layerToRender, Light2D light, float shadowIntensity, RenderTargetIdentifier renderTexture, int colorBit)
        {
            using (new ProfilingScope(cmdBuffer, m_ProfilingSamplerShadows))
            {
                bool hasShadow          = false;
                var  shadowCasterGroups = ShadowCasterGroup2DManager.shadowCasterGroups;
                if (shadowCasterGroups != null && shadowCasterGroups.Count > 0)
                {
                    // Before doing anything check to see if any of the shadow casters are visible to this light
                    for (var group = 0; group < shadowCasterGroups.Count; group++)
                    {
                        var shadowCasterGroup = shadowCasterGroups[group];
                        var shadowCasters     = shadowCasterGroup.GetShadowCasters();

                        if (shadowCasters != null)
                        {
                            // Draw the projected shadows for the shadow caster group. Writing into the group stencil buffer bit
                            for (var i = 0; i < shadowCasters.Count; i++)
                            {
                                var shadowCaster = shadowCasters[i];
                                if (shadowCaster.IsLit(light))
                                {
                                    hasShadow = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (hasShadow)
                    {
                        cmdBuffer.SetRenderTarget(renderTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare);

                        if (colorBit == 0)
                        {
                            cmdBuffer.ClearRenderTarget(true, true, Color.clear);  // clear stencil
                        }
                        using (new ProfilingScope(cmdBuffer, m_ProfilingSamplerShadowColorsLookup[colorBit]))
                        {
                            var shadowRadius = light.boundingSphere.radius;

                            cmdBuffer.SetGlobalVector(k_LightPosID, light.transform.position);
                            cmdBuffer.SetGlobalFloat(k_ShadowRadiusID, shadowRadius);


                            cmdBuffer.SetGlobalColor(k_ShadowColorMaskID, k_ColorLookup[colorBit]);
                            var projectedShadowsMaterial = pass.rendererData.GetProjectedShadowMaterial(colorBit);
                            var selfShadowMaterial       = pass.rendererData.GetSpriteSelfShadowMaterial(colorBit);
                            var unshadowMaterial         = pass.rendererData.GetSpriteUnshadowMaterial(colorBit);
                            var setGlobalStencilMaterial = pass.rendererData.GetStencilOnlyShadowMaterial(colorBit);

                            for (var group = 0; group < shadowCasterGroups.Count; group++)
                            {
                                var shadowCasterGroup = shadowCasterGroups[group];
                                var shadowCasters     = shadowCasterGroup.GetShadowCasters();

                                if (shadowCasters != null)
                                {
                                    // Draw the projected shadows for the shadow caster group. Writing into the group stencil buffer bit
                                    for (var i = 0; i < shadowCasters.Count; i++)
                                    {
                                        var shadowCaster = shadowCasters[i];

                                        if (shadowCaster.IsLit(light))
                                        {
                                            if (shadowCaster != null && projectedShadowsMaterial != null && shadowCaster.IsShadowedLayer(layerToRender))
                                            {
                                                if (shadowCaster.castsShadows)
                                                {
                                                    SetShadowProjectionGlobals(cmdBuffer, shadowCaster);
                                                    cmdBuffer.DrawMesh(shadowCaster.mesh, shadowCaster.transform.localToWorldMatrix, projectedShadowsMaterial, 0, 0);
                                                }
                                            }
                                        }
                                    }

                                    // Draw the sprites, either as self shadowing or unshadowing
                                    for (var i = 0; i < shadowCasters.Count; i++)
                                    {
                                        var shadowCaster = shadowCasters[i];

                                        if (shadowCaster.IsLit(light))
                                        {
                                            if (shadowCaster != null && shadowCaster.IsShadowedLayer(layerToRender))
                                            {
                                                if (shadowCaster.useRendererSilhouette)
                                                {
                                                    // Draw using the sprite renderer
                                                    var renderer = (Renderer)null;
                                                    shadowCaster.TryGetComponent <Renderer>(out renderer);

                                                    if (renderer != null)
                                                    {
                                                        var material = shadowCaster.selfShadows ? selfShadowMaterial : unshadowMaterial;
                                                        if (material != null)
                                                        {
                                                            cmdBuffer.DrawRenderer(renderer, material);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    var meshMat  = shadowCaster.transform.localToWorldMatrix;
                                                    var material = shadowCaster.selfShadows ? selfShadowMaterial : unshadowMaterial;

                                                    // Draw using the shadow mesh
                                                    if (material != null)
                                                    {
                                                        cmdBuffer.DrawMesh(shadowCaster.mesh, meshMat, material);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    // Draw the projected shadows for the shadow caster group. Writing clearing the group stencil bit, and setting the global bit
                                    for (var i = 0; i < shadowCasters.Count; i++)
                                    {
                                        var shadowCaster = shadowCasters[i];

                                        if (shadowCaster.IsLit(light))
                                        {
                                            if (shadowCaster != null && projectedShadowsMaterial != null && shadowCaster.IsShadowedLayer(layerToRender))
                                            {
                                                if (shadowCaster.castsShadows)
                                                {
                                                    SetShadowProjectionGlobals(cmdBuffer, shadowCaster);
                                                    cmdBuffer.DrawMesh(shadowCaster.mesh, shadowCaster.transform.localToWorldMatrix, projectedShadowsMaterial, 0, 1);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public static void PrerenderShadows(IRenderPass2D pass, RenderingData renderingData, CommandBuffer cmdBuffer, int layerToRender, Light2D light, int shadowIndex, float shadowIntensity)
        {
            var colorChannel = shadowIndex % 4;
            var textureIndex = shadowIndex / 4;

            if (colorChannel == 0)
            {
                ShadowRendering.CreateShadowRenderTexture(pass, renderingData, cmdBuffer, textureIndex);
            }

            // Render the shadows for this light
            RenderShadows(pass, renderingData, cmdBuffer, layerToRender, light, shadowIntensity, m_RenderTargets[textureIndex].Identifier(), colorChannel);
        }
Example #8
0
        public static Bounds GenerateParametricMesh(Light2D light, float radius, float falloffDistance, float angle, int sides)
        {
            var angleOffset = Mathf.PI / 2.0f + Mathf.Deg2Rad * angle;

            if (sides < 3)
            {
                radius = 0.70710678118654752440084436210485f * radius;
                sides  = 4;
            }

            if (sides == 4)
            {
                angleOffset = Mathf.PI / 4.0f + Mathf.Deg2Rad * angle;
            }

            var vertexCount = 1 + 2 * sides;
            var indexCount  = 3 * 3 * sides;
            var vertices    = new NativeArray <LightMeshVertex>(vertexCount, Allocator.Temp);
            var triangles   = new NativeArray <ushort>(indexCount, Allocator.Temp);
            var centerIndex = (ushort)(2 * sides);
            var mesh        = light.lightMesh;

            // Only Alpha value in Color channel is ever used. May remove it or keep it for batching params in the future.
            var color = new Color(0, 0, 0, 1);

            vertices[centerIndex] = new LightMeshVertex
            {
                position = float3.zero,
                color    = color
            };

            var radiansPerSide = 2 * Mathf.PI / sides;
            var min            = new float3(float.MaxValue, float.MaxValue, 0);
            var max            = new float3(float.MinValue, float.MinValue, 0);

            for (var i = 0; i < sides; i++)
            {
                var endAngle   = (i + 1) * radiansPerSide;
                var extrudeDir = new float3(math.cos(endAngle + angleOffset), math.sin(endAngle + angleOffset), 0);
                var endPoint   = radius * extrudeDir;

                var vertexIndex = (2 * i + 2) % (2 * sides);
                vertices[vertexIndex] = new LightMeshVertex
                {
                    position = endPoint,
                    color    = new Color(extrudeDir.x, extrudeDir.y, 0, 0)
                };
                vertices[vertexIndex + 1] = new LightMeshVertex
                {
                    position = endPoint,
                    color    = color
                };

                // Triangle 1 (Tip)
                var triangleIndex = 9 * i;
                triangles[triangleIndex]     = (ushort)(vertexIndex + 1);
                triangles[triangleIndex + 1] = (ushort)(2 * i + 1);
                triangles[triangleIndex + 2] = centerIndex;

                // Triangle 2 (Upper Top Left)
                triangles[triangleIndex + 3] = (ushort)(vertexIndex);
                triangles[triangleIndex + 4] = (ushort)(2 * i);
                triangles[triangleIndex + 5] = (ushort)(2 * i + 1);

                // Triangle 2 (Bottom Top Left)
                triangles[triangleIndex + 6] = (ushort)(vertexIndex + 1);
                triangles[triangleIndex + 7] = (ushort)(vertexIndex);
                triangles[triangleIndex + 8] = (ushort)(2 * i + 1);

                min = math.min(min, endPoint + extrudeDir * falloffDistance);
                max = math.max(max, endPoint + extrudeDir * falloffDistance);
            }

            mesh.SetVertexBufferParams(vertexCount, LightMeshVertex.VertexLayout);
            mesh.SetVertexBufferData(vertices, 0, 0, vertexCount);
            mesh.SetIndices(triangles, MeshTopology.Triangles, 0, false);

            light.vertices = new LightMeshVertex[vertexCount];
            NativeArray <LightMeshVertex> .Copy(vertices, light.vertices, vertexCount);

            light.indices = new ushort[indexCount];
            NativeArray <ushort> .Copy(triangles, light.indices, indexCount);

            return(new Bounds
            {
                min = min,
                max = max
            });
        }
Example #9
0
 // Called during OnEnable
 public static void DeregisterLight(Light2D light)
 {
     Debug.Assert(lights.Contains(light));
     lights.Remove(light);
 }
Example #10
0
        public static Bounds GenerateShapeMesh(Light2D light, Vector3[] shapePath, float falloffDistance)
        {
            var         ix            = 0;
            var         vcount        = 0;
            var         icount        = 0;
            const float kClipperScale = 10000.0f;
            var         mesh          = light.lightMesh;

            // todo Revisit this while we do Batching.
            var meshInteriorColor = new Color(0.0f, 0, 0, 1.0f);
            var meshExteriorColor = new Color(0.0f, 0, 0, 0.0f);
            var vertices          = new NativeArray <LightMeshVertex>(shapePath.Length * 256, Allocator.Temp);
            var indices           = new NativeArray <ushort>(shapePath.Length * 256, Allocator.Temp);

            // Create shape geometry
            var inputPointCount = shapePath.Length;
            var inner           = new ContourVertex[inputPointCount + 1];

            for (var i = 0; i < inputPointCount; ++i)
            {
                inner[ix++] = new ContourVertex()
                {
                    Position = new Vec3()
                    {
                        X = shapePath[i].x, Y = shapePath[i].y, Z = 0
                    }
                }
            }
            ;
            inner[ix++] = inner[0];

            var tess = new Tess();

            tess.AddContour(inner, ContourOrientation.CounterClockwise);
            Tessellate(tess, ElementType.Polygons, indices, vertices, meshInteriorColor, ref vcount, ref icount);

            // Create falloff geometry
            List <IntPoint> path = new List <IntPoint>();

            for (var i = 0; i < inputPointCount; ++i)
            {
                var newPoint = new Vector2(inner[i].Position.X, inner[i].Position.Y) * kClipperScale;
                var addPoint = new IntPoint((System.Int64)(newPoint.x), (System.Int64)(newPoint.y));
                addPoint.N = i; addPoint.D = -1;
                path.Add(addPoint);
            }
            var lastPointIndex = inputPointCount - 1;

            // Generate Bevels.
            List <List <IntPoint> > solution   = new List <List <IntPoint> >();
            ClipperOffset           clipOffset = new ClipperOffset(24.0f);

            clipOffset.AddPath(path, JoinType.jtRound, EndType.etClosedPolygon);
            clipOffset.Execute(ref solution, kClipperScale * falloffDistance, path.Count);

            if (solution.Count > 0)
            {
                // Fix path for Pivots.
                var outPath = solution[0];
                var minPath = (long)inputPointCount;
                for (int i = 0; i < outPath.Count; ++i)
                {
                    minPath = (outPath[i].N != -1) ? Math.Min(minPath, outPath[i].N) : minPath;
                }
                var containsStart = minPath == 0;
                outPath = FixPivots(outPath, path);

                // Tessellate.
                var bIndices = new NativeArray <ushort>(icount + (outPath.Count * 6) + 6, Allocator.Temp);
                for (int i = 0; i < icount; ++i)
                {
                    bIndices[i] = indices[i];
                }
                var bVertices = new NativeArray <LightMeshVertex>(vcount + outPath.Count + inputPointCount, Allocator.Temp);
                for (int i = 0; i < vcount; ++i)
                {
                    bVertices[i] = vertices[i];
                }

                var innerIndices = new ushort[inputPointCount];

                // Inner Vertices. (These may or may not be part of the created path. Beware!!)
                for (int i = 0; i < inputPointCount; ++i)
                {
                    bVertices[vcount++] = new LightMeshVertex()
                    {
                        position = new float3(inner[i].Position.X, inner[i].Position.Y, 0),
                        color    = meshInteriorColor
                    };
                    innerIndices[i] = (ushort)(vcount - 1);
                }

                var saveIndex = (ushort)vcount;
                var pathStart = saveIndex;
                var prevIndex = outPath[0].N == -1 ? 0 : outPath[0].N;

                for (int i = 0; i < outPath.Count; ++i)
                {
                    var curr      = outPath[i];
                    var currPoint = new float2(curr.X / kClipperScale, curr.Y / kClipperScale);
                    var currIndex = curr.N == -1 ? 0 : curr.N;

                    bVertices[vcount++] = new LightMeshVertex()
                    {
                        position = new float3(currPoint.x, currPoint.y, 0),
                        color    = meshExteriorColor
                    };

                    if (prevIndex != currIndex)
                    {
                        bIndices[icount++] = innerIndices[prevIndex];
                        bIndices[icount++] = innerIndices[currIndex];
                        bIndices[icount++] = (ushort)(vcount - 1);
                    }

                    bIndices[icount++] = innerIndices[prevIndex];
                    bIndices[icount++] = saveIndex;
                    bIndices[icount++] = saveIndex = (ushort)(vcount - 1);
                    prevIndex          = currIndex;
                }

                // Close the Loop.
                {
                    bIndices[icount++] = pathStart;
                    bIndices[icount++] = innerIndices[minPath];
                    bIndices[icount++] = containsStart ? innerIndices[lastPointIndex] : saveIndex;

                    bIndices[icount++] = containsStart ? pathStart : saveIndex;
                    bIndices[icount++] = containsStart ? saveIndex : innerIndices[minPath];
                    bIndices[icount++] = containsStart ? innerIndices[lastPointIndex] : innerIndices[minPath - 1];
                }

                TransferToMesh(bVertices, vcount, bIndices, icount, light);
            }
            else
            {
                TransferToMesh(vertices, vcount, indices, icount, light);
            }

            return(mesh.GetSubMesh(0).bounds);
        }
Example #11
0
        public static bool PrerenderShadows(IRenderPass2D pass, RenderingData renderingData, CommandBuffer cmdBuffer, int layerToRender, Light2D light, int shadowIndex, float shadowIntensity)
        {
            var colorChannel = shadowIndex % 4;
            var textureIndex = shadowIndex / 4;

            if (colorChannel == 0)
            {
                ShadowRendering.CreateShadowRenderTexture(pass, renderingData, cmdBuffer, textureIndex);
            }

            bool hadShadowsToRender = RenderShadows(pass, renderingData, cmdBuffer, layerToRender, light, shadowIntensity, m_RenderTargets[textureIndex].nameID, colorChannel);

            m_LightInputTextures[textureIndex] = m_RenderTargets[textureIndex].nameID;

            return(hadShadowsToRender);
        }
Example #12
0
 // Called during OnEnable
 public static void RegisterLight(Light2D light)
 {
     Debug.Assert(!lights.Contains(light));
     lights.Add(light);
     ErrorIfDuplicateGlobalLight(light);
 }
Example #13
0
        private static void SetPointLightShaderGlobals(IRenderPass2D pass, CommandBuffer cmd, Light2D light)
        {
            // This is used for the lookup texture
            GetScaledLightInvMatrix(light, out var lightInverseMatrix);

            var innerRadius     = GetNormalizedInnerRadius(light);
            var innerAngle      = GetNormalizedAngle(light.pointLightInnerAngle);
            var outerAngle      = GetNormalizedAngle(light.pointLightOuterAngle);
            var innerRadiusMult = 1 / (1 - innerRadius);

            cmd.SetGlobalVector(k_LightPositionID, light.transform.position);
            cmd.SetGlobalMatrix(k_LightInvMatrixID, lightInverseMatrix);
            cmd.SetGlobalFloat(k_InnerRadiusMultID, innerRadiusMult);
            cmd.SetGlobalFloat(k_OuterAngleID, outerAngle);
            cmd.SetGlobalFloat(k_InnerAngleMultID, 1 / (outerAngle - innerAngle));
            cmd.SetGlobalTexture(k_LightLookupID, Light2DLookupTexture.GetLightLookupTexture());
            cmd.SetGlobalTexture(k_FalloffLookupID, pass.rendererData.fallOffLookup);
            cmd.SetGlobalFloat(k_FalloffIntensityID, light.falloffIntensity);
            cmd.SetGlobalFloat(k_IsFullSpotlightID, innerAngle == 1 ? 1.0f : 0.0f);

            cmd.SetGlobalFloat(k_LightZDistanceID, light.normalMapDistance);

            if (light.lightCookieSprite != null && light.lightCookieSprite.texture != null)
            {
                cmd.SetGlobalTexture(k_PointLightCookieTexID, light.lightCookieSprite.texture);
            }
        }
Example #14
0
        private static void SetGeneralLightShaderGlobals(IRenderPass2D pass, CommandBuffer cmd, Light2D light)
        {
            float intensity = light.intensity * light.color.a;
            Color color     = intensity * light.color;

            color.a = 1.0f;

            float volumeIntensity = light.volumeIntensity;

            cmd.SetGlobalFloat(k_FalloffIntensityID, light.falloffIntensity);
            cmd.SetGlobalFloat(k_FalloffDistanceID, light.shapeLightFalloffSize);
            cmd.SetGlobalColor(k_LightColorID, color);
            cmd.SetGlobalFloat(k_VolumeOpacityID, volumeIntensity);
        }
Example #15
0
 private static float GetNormalizedInnerRadius(Light2D light)
 {
     return(light.pointLightInnerRadius / light.pointLightOuterRadius);
 }
Example #16
0
        private static bool CanCastVolumetricShadows(Light2D light, int endLayerValue)
        {
            var topMostLayerValue = light.GetTopMostLitLayer();

            return(light.volumetricShadowsEnabled && light.shadowVolumeIntensity > 0 && topMostLayerValue == endLayerValue);
        }
Example #17
0
 private static bool CanCastShadows(Light2D light, int layerToRender)
 {
     return(light.shadowsEnabled && light.shadowIntensity > 0 && light.IsLitLayer(layerToRender));
 }