Esempio n. 1
0
        internal RenderStateBlock GetDefaultRenderStateBlock(bool stencilTest, StencilTestOptions stencilTestOptions)
        {
            RenderStateBlock renderStateBlock = new RenderStateBlock();

            if (stencilTest && m_stencilTestState != StencilTestState.None)
            {
                int stencilMask = StencilMaskAllocator.GetCurrentBit();
                renderStateBlock.mask             = RenderStateMask.Stencil;
                renderStateBlock.stencilReference = stencilMask;
                if (m_stencilTestState == StencilTestState.BothSide)
                {
                    if ((stencilTestOptions & StencilTestOptions.PreventOverwriting) == 0)
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, 0, CompareFunction.Equal, StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
                    }
                    else
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, (byte)stencilMask, CompareFunction.Equal, StencilOp.Zero, StencilOp.Keep, StencilOp.Keep);
                    }
                }
                else
                {
                    if ((stencilTestOptions & StencilTestOptions.PreventOverwriting) == 0)
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, 0, CompareFunction.NotEqual, StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
                    }
                    else
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, (byte)stencilMask, CompareFunction.NotEqual, StencilOp.Replace, StencilOp.Keep, StencilOp.Keep);
                    }
                }
            }
            return(renderStateBlock);
        }
Esempio n. 2
0
        protected void GetDefaultDrawSettings(ref RenderingData renderingData, Material material, out DrawingSettings drawingSettings, out FilteringSettings filteringSettings, out RenderStateBlock renderStateBlock)
        {
            base.GetDefaultDrawSettings(renderingData.cameraData.camera, material, out drawingSettings, out filteringSettings);
            drawingSettings.enableDynamicBatching = renderingData.supportsDynamicBatching;
            drawingSettings.perObjectData         = perObjectData;

            renderStateBlock = new RenderStateBlock();
            if (useStencilTest && m_stencilTestState != StencilTestState.None)
            {
                int stencilMask = StencilMaskAllocator.GetCurrentBit();
                renderStateBlock.mask             = RenderStateMask.Stencil;
                renderStateBlock.stencilReference = stencilMask;
                if (m_stencilTestState == StencilTestState.BothSide)
                {
                    if ((m_stencilTestOptions & StencilTestOptions.PreventOverwriting) == 0)
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, 0, CompareFunction.Equal, StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
                    }
                    else
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, (byte)stencilMask, CompareFunction.Equal, StencilOp.Zero, StencilOp.Keep, StencilOp.Keep);
                    }
                }
                else
                {
                    if ((m_stencilTestOptions & StencilTestOptions.PreventOverwriting) == 0)
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, 0, CompareFunction.NotEqual, StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
                    }
                    else
                    {
                        renderStateBlock.stencilState = new StencilState(true, (byte)stencilMask, (byte)stencilMask, CompareFunction.NotEqual, StencilOp.Replace, StencilOp.Keep, StencilOp.Keep);
                    }
                }
            }
        }
Esempio n. 3
0
        internal void WriteFrustumStencil(ScriptableRenderContext context, Camera camera, Material nonSharedStencilMaterial)
        {
            int stencilMask = StencilMaskAllocator.GetCurrentBit();

            if (stencilMask == 0)
            {
                m_stencilTestState = StencilTestState.None;
                Debug.LogError("Couldn't use stencil test. No stencil bits available. Please change Stencil Mask value in Projector Renderer Feature.");
                return;
            }

            // check if the frustum intersect with camera near plane.
            Vector3 cameraLocalPos = transform.InverseTransformPoint(camera.transform.position);
            Vector3 nearClipRect   = camera.nearClipPlane * 2.0f * Mathf.Tan(Mathf.Deg2Rad * camera.fieldOfView) * new Vector3(camera.aspect, 1.0f, 0.0f);

            nearClipRect.z = camera.nearClipPlane;
            Matrix4x4 localToCamera = camera.worldToCameraMatrix * transform.localToWorldMatrix;
            bool      clipped       = true;

            for (int i = 0; i < 6; ++i)
            {
                int     face         = i >> 1;
                int     n            = i & 1;
                int     axis1        = (face + 1 + n) % 3;
                int     axis2        = (face + 2 - n) % 3;
                int     vtx1         = n * (1 << face);
                int     vtx2         = vtx1 + (1 << axis1);
                int     vtx3         = vtx1 + (1 << axis2);
                Plane   frustumPlane = new Plane(GetProjectorFrustumVertex(vtx1), GetProjectorFrustumVertex(vtx2), GetProjectorFrustumVertex(vtx3));
                Vector3 offset       = Vector3.Scale(nearClipRect, localToCamera.MultiplyVector(frustumPlane.normal));
                if (Mathf.Abs(offset.x) + Mathf.Abs(offset.y) + Mathf.Max(0, offset.z) < frustumPlane.GetDistanceToPoint(cameraLocalPos))
                {
                    clipped = false;
                    break;
                }
            }
            CommandBuffer commandBuffer = CommandBufferPool.Get();

            if (StencilMaskAllocator.loopFlag)
            {
                StencilMaskAllocator.ClearLoopFlag();
                ClearFullscreenStencil(commandBuffer);
            }
            nonSharedStencilMaterial.SetFloat(s_shaderPropIdStencilRef, stencilMask);
            nonSharedStencilMaterial.SetFloat(s_shaderPropIdStencilMask, stencilMask);
            Mesh frustumMesh = GetFrustumMesh();

            if (clipped)
            {
                m_stencilTestState = StencilTestState.BackfaceOnly;
                commandBuffer.DrawMesh(frustumMesh, transform.localToWorldMatrix, nonSharedStencilMaterial, 0, 2);
            }
            else
            {
                m_stencilTestState = StencilTestState.BothSide;
                commandBuffer.DrawMesh(frustumMesh, transform.localToWorldMatrix, nonSharedStencilMaterial, 0, 0);
                commandBuffer.DrawMesh(frustumMesh, transform.localToWorldMatrix, nonSharedStencilMaterial, 0, 1);
            }
            context.ExecuteCommandBuffer(commandBuffer);
            CommandBufferPool.Release(commandBuffer);
        }