コード例 #1
0
        // public int createdContainerCount;
        // public int releasedContainerCount;

        public void Get(ShadowRenderingRequest request, ref ShadowContainer container)
        {
            if (float.IsNaN(request.dimensions.x) || request.dimensions.x < 1 ||
                float.IsNaN(request.dimensions.y) || request.dimensions.y < 1)
            {
                ReleaseContainer(container);
                return;
            }

#if LETAI_TRUESHADOW_DEBUG
            RenderTexture.ReleaseTemporary(debugTexture);
            if (request.shadow.alwaysRender)
            {
                debugTexture = RenderShadow(request);
            }
#endif

            // Each request need a coresponding shadow texture
            // Texture may be shared by multiple elements
            // Texture are released when no longer used by any element
            // ShadowContainer keep track of texture and their usage


            int requestHash = request.GetHashCode();

            // Case: requester can keep the same texture
            if (container?.requestHash == requestHash)
            {
                return;
            }

            ReleaseContainer(container);

            if (shadowCache.TryGetValue(requestHash, out var existingContainer))
            {
                // Case: requester got texture from someone else
                existingContainer.RefCount++;
                container = existingContainer;
            }
            else
            {
                // Case: requester got new unique texture
                container = shadowCache[requestHash] = new ShadowContainer(RenderShadow(request), request);
                // Debug.Log($"Created new container for request\t{requestHash}\tTotal Created: {++createdContainerCount}\t Alive: {createdContainerCount - releasedContainerCount}");
            }
        }
コード例 #2
0
        RenderTexture RenderShadow(ShadowRenderingRequest request)
        {
            // return GenColoredTexture(request.GetHashCode());

            cmd.Clear();
            cmd.BeginSample("TrueShadow:Capture");

            var padding      = Mathf.CeilToInt(request.shadowSize);
            var imprintViewW = Mathf.CeilToInt(request.dimensions.x);
            var imprintViewH = Mathf.CeilToInt(request.dimensions.y);
            var tw           = imprintViewW + padding * 2;
            var th           = imprintViewH + padding * 2;
            var shadowTex    = RenderTexture.GetTemporary(tw, th, 0, RenderTextureFormat.Default);

            cmd.GetTemporaryRT(IMPRINT_TEX_ID, tw, th, 0, FilterMode.Bilinear, RenderTextureFormat.Default);

            bool needPostProcess = request.shadow.IgnoreCasterColor || request.shadow.Inset;

            if (needPostProcess)
            {
                cmd.GetTemporaryRT(IMPRINT_AFTER_POSTPROCESS_TEX_ID, tw, th, 0, FilterMode.Bilinear,
                                   RenderTextureFormat.Default);
            }

            var texture = request.shadow.Content;

            if (texture)
            {
                materialProps.SetTexture(ShaderId.MAIN_TEX, texture);
            }
            else
            {
                materialProps.SetTexture(ShaderId.MAIN_TEX, Texture2D.whiteTexture);
            }

            cmd.SetRenderTarget(IMPRINT_TEX_ID);
            cmd.ClearRenderTarget(true, true, request.shadow.ClearColor);

            cmd.SetViewport(new Rect(padding, padding, imprintViewW, imprintViewH));
            var bounds = request.rect;

            cmd.SetViewProjectionMatrices(
                Matrix4x4.identity,
                Matrix4x4.Ortho(bounds.min.x, bounds.max.x + bounds.width * (imprintViewW / request.dimensions.x - 1),
                                bounds.min.y, bounds.max.y + bounds.height * (imprintViewH / request.dimensions.y - 1),
                                -1, 1)
                );

            request.shadow.ModifyShadowCastingMesh(request.shadow.SpriteMesh);
            request.shadow.ModifyShadowCastingMaterialProperties(materialProps);
            cmd.DrawMesh(request.shadow.SpriteMesh,
                         Matrix4x4.identity,
                         request.shadow.GetShadowCastingMaterial(),
                         0, 0,
                         materialProps);

            if (needPostProcess)
            {
                ImprintPostProcessMaterial.SetKeyword("BLEACH", request.shadow.IgnoreCasterColor);
                ImprintPostProcessMaterial.SetKeyword("INSET", request.shadow.Inset);

                cmd.Blit(IMPRINT_TEX_ID, IMPRINT_AFTER_POSTPROCESS_TEX_ID, ImprintPostProcessMaterial);
            }

            cmd.EndSample("TrueShadow:Capture");


            cmd.BeginSample("TrueShadow:Cast");
            int source = needPostProcess ? IMPRINT_AFTER_POSTPROCESS_TEX_ID : IMPRINT_TEX_ID;

            if (request.shadowSize < 1e-2)
            {
                cmd.Blit(source, shadowTex);
            }
            else
            {
                blurConfig.Strength = request.shadowSize;
                blurProcessor.Blur(cmd, source, UNIT_RECT, shadowTex);
            }

            cmd.EndSample("TrueShadow:Cast");

            if (request.shadow.Cutout)
            {
                cmd.BeginSample("TrueShadow:Cutout");
                CutoutMaterial.SetVector(ShaderId.OFFSET, new Vector2(request.shadowOffset.x / tw,
                                                                      request.shadowOffset.y / th));
                CutoutMaterial.SetFloat(ShaderId.OVERFLOW_ALPHA, request.shadow.Inset ? 1 : 0);
                cmd.SetViewport(UNIT_RECT);
                cmd.Blit(source, shadowTex, CutoutMaterial);
                cmd.EndSample("TrueShadow:Cutout");
            }

            cmd.ReleaseTemporaryRT(source);

            Graphics.ExecuteCommandBuffer(cmd);

            return(shadowTex);
        }
コード例 #3
0
 public ShadowContainer(RenderTexture texture, ShadowRenderingRequest request)
 {
     Texture     = texture;
     RefCount    = 1;
     requestHash = request.GetHashCode();
 }