コード例 #1
0
        internal void Draw()
        {
            EntityShadow mode = game.Players.ShadowMode;
            Vector3 Position = entity.Position;
            float posX = Position.X, posZ = Position.Z;
            int posY = Math.Min( (int)Position.Y, game.World.Height - 1 );
            int index = 0, vb = 0;

            VertexP3fT2fC4b[] verts = null;
            int posCount = 0, dataCount = 0;
            Vector3I* coords = stackalloc Vector3I[4];
            ShadowData* data = stackalloc ShadowData[4];
            for( int i = 0; i < 4; i++ ) {
                coords[i] = new Vector3I( int.MinValue );
                data[i] = new ShadowData();
            }

            if( mode == EntityShadow.SnapToBlock ) {
                vb = game.Graphics.texVb; verts = game.Graphics.texVerts;
                if( !GetBlocks( coords, ref posCount, posX, posZ, posY, data, ref dataCount ) ) return;

                float x1 = Utils.Floor( posX ), z1 = Utils.Floor( posZ );
                DraqSquareShadow( verts, ref index, data[0].Y, 220, x1, z1 );
            } else {
                vb = game.ModelCache.vb; verts = game.ModelCache.vertices;

                float x = posX - 7/16f, z = posZ - 7/16f;
                if( GetBlocks( coords, ref posCount, x, z, posY, data, ref dataCount ) && data[0].A > 0 )
                    DrawCircle( verts, ref index, data, dataCount, x, z );

                x = Math.Max( posX - 7/16f, Utils.Floor( posX + 7/16f ) );
                if( GetBlocks( coords, ref posCount, x, z, posY, data, ref dataCount ) && data[0].A > 0 )
                    DrawCircle( verts, ref index, data, dataCount, x, z );

                z = Math.Max( posZ - 7/16f, Utils.Floor( posZ + 7/16f ) );
                if( GetBlocks( coords, ref posCount, x, z, posY, data, ref dataCount ) && data[0].A > 0 )
                    DrawCircle( verts, ref index, data, dataCount, x, z );

                x = posX - 7/16f;
                if( GetBlocks( coords, ref posCount, x, z, posY, data, ref dataCount ) && data[0].A > 0 )
                    DrawCircle( verts, ref index, data, dataCount, x, z );
            }

            if( index == 0 ) return;
            CheckShadowTexture( game.Graphics );

            if( !boundShadowTex ) {
                game.Graphics.BindTexture( shadowTex );
                boundShadowTex = true;
            }
            game.Graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, verts, index, index * 6 / 4 );
        }
コード例 #2
0
        static void CalcAlpha( float playerY, ref ShadowData data )
        {
            float y = data.Y;
            if( (playerY - y) <= 6 ) {
                data.A = (byte)(160 - 160 * (playerY - y) / 6);
                data.Y += 1/64f; return;
            }

            data.A = 0;
            if( (playerY - y) <= 16 ) data.Y += 1/64f;
            else if( (playerY - y) <= 32 ) data.Y += 1/16f;
            else if( (playerY - y) <= 96 ) data.Y += 1/8f;
            else data.Y += 1/4f;
        }
コード例 #3
0
        void DrawCoords( VertexP3fT2fC4b[] verts, ref int index, ShadowData data, 
            float x1, float z1, float x2, float z2)
        {
            Vector3 centre = entity.Position;
            BlockInfo info = game.BlockInfo;

            if( lequal( x2, x1 ) || lequal( z2, z1 ) ) return;
            float u1 = (x1 - centre.X) * 16/14f + 0.5f;
            float v1 = (z1 - centre.Z) * 16/14f + 0.5f;
            float u2 = (x2 - centre.X) * 16/14f + 0.5f;
            float v2 = (z2 - centre.Z) * 16/14f + 0.5f;
            if( u2 <= 0 || v2 <= 0 || u1 >= 1 || v1 >= 1 ) return;

            x1 = Math.Max( x1, centre.X - 7/16f ); u1 = Math.Max( u1, 0 );
            z1 = Math.Max( z1, centre.Z - 7/16f ); v1 = Math.Max( v1, 0 );
            x2 = Math.Min( x2, centre.X + 7/16f ); u2 = Math.Min( u2, 1 );
            z2 = Math.Min( z2, centre.Z + 7/16f ); v2 = Math.Min( v2, 1 );

            FastColour col = FastColour.White; col.A = data.A;
            verts[index++] = new VertexP3fT2fC4b( x1, data.Y, z1, u1, v1, col );
            verts[index++] = new VertexP3fT2fC4b( x2, data.Y, z1, u2, v1, col );
            verts[index++] = new VertexP3fT2fC4b( x2, data.Y, z2, u2, v2, col );
            verts[index++] = new VertexP3fT2fC4b( x1, data.Y, z2, u1, v2, col );
        }
コード例 #4
0
        bool GetBlocks( Vector3I* coords, ref int posCount, float x, float z,
            int posY, ShadowData* data, ref int index)
        {
            int blockX = Utils.Floor( x ), blockZ = Utils.Floor( z );
            Vector3I p = new Vector3I( blockX, 0, blockZ );
            BlockInfo info = game.BlockInfo;
            Vector3 Position = entity.Position;
            index = 0;

            // Check we have not processed this particular block already.
            if( Position.Y < 0 ) return false;
            for( int i = 0; i < 4; i++ ) {
                if( coords[i] == p ) return false;
                data[i] = new ShadowData();
            }
            coords[posCount] = p; posCount++;

            while( posY >= 0 && index < 4 ) {
                byte block = GetShadowBlock( blockX, posY, blockZ );
                posY--;
                if( info.IsAir[block] || info.IsSprite[block] || info.IsLiquid[block] ) continue;
                float blockY = posY + 1 + info.MaxBB[block].Y;
                if( blockY >= Position.Y + 0.01f ) continue;

                data[index].Block = block; data[index].Y = blockY;
                CalcAlpha( Position.Y, ref data[index] );
                index++;
                // Check if the casted shadow will continue on further down.
                if( info.MinBB[block].X == 0 && info.MaxBB[block].X == 1 &&
                   info.MinBB[block].Z == 0 && info.MaxBB[block].Z == 1 ) return true;
            }

            if( index < 4 ) {
                data[index].Block = (byte)game.World.Env.EdgeBlock; data[index].Y = 0;
                CalcAlpha( Position.Y, ref data[index] );
                index++;
            }
            return true;
        }
コード例 #5
0
        void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            NativeArray <VisibleLight> visibleLights = lightData.visibleLights;

            bool          additionalLightHasSoftShadows = false;
            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);

            using (new ProfilingScope(cmd, m_ProfilingSampler))
            {
                bool anyShadowSliceRenderer = false;
                int  shadowSlicesCount      = m_AdditionalShadowCastingLightIndices.Count;
                for (int i = 0; i < shadowSlicesCount; ++i)
                {
                    // we do the shadow strength check here again here because when using
                    // the uniform array path we might have zero strength shadow lights.
                    // In that case we need the shadow data buffer but we can skip
                    // rendering them to shadowmap.
                    if (!m_UseStructuredBuffer && Mathf.Approximately(m_AdditionalLightsShadowParams[i].x, 0.0f))
                    {
                        continue;
                    }

                    // Index of the VisibleLight
                    int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                    ShadowSliceData shadowSliceData = m_AdditionalLightSlices[i];

                    var     settings   = new ShadowDrawingSettings(cullResults, shadowLightIndex);
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex,
                                                                   ref shadowData, shadowSliceData.projectionMatrix, shadowSliceData.resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref shadowSliceData, ref settings, shadowBias, shadowLight, i);
                    additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft;
                    anyShadowSliceRenderer         = true;
                }

                // We share soft shadow settings for main light and additional lights to save keywords.
                // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows
                // to enable the keyword.
                // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster.
                bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows &&
                                               lightData.mainLightIndex != -1 &&
                                               visibleLights[lightData.mainLightIndex].light.shadows ==
                                               LightShadows.Soft;

                bool softShadows = shadowData.supportsSoftShadows &&
                                   (mainLightHasSoftShadows || additionalLightHasSoftShadows);

                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, anyShadowSliceRenderer);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                if (anyShadowSliceRenderer)
                {
                    SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData, softShadows);
                }
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
コード例 #6
0
        void DrawCircle( VertexP3fT2fC4b[] verts, ref int index, 
            ShadowData* data, int dataCount, float x, float z)
        {
            x = Utils.Floor( x ); z = Utils.Floor( z );
            BlockInfo info = game.BlockInfo;
            Vector3 min = info.MinBB[data[0].Block], max = info.MaxBB[data[0].Block];

            DrawCoords( verts, ref index, data[0], x + min.X, z + min.Z, x + max.X, z + max.Z );
            for( int i = 1; i < dataCount; i++ ) {
                Vector3 nMin = info.MinBB[data[i].Block], nMax = info.MaxBB[data[i].Block];
                DrawCoords( verts, ref index, data[i], x + min.X, z + nMin.Z, x + max.X, z + min.Z );
                DrawCoords( verts, ref index, data[i], x + min.X, z + max.Z, x + max.X, z + nMax.Z );

                DrawCoords( verts, ref index, data[i], x + nMin.X, z + nMin.Z, x + min.X, z + nMax.Z );
                DrawCoords( verts, ref index, data[i], x + max.X, z + nMin.Z, x + nMax.X, z + nMax.Z );
                min = nMin; max = nMax;
            }
        }
コード例 #7
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
            // Currently there's an issue which results in mismatched markers.
            CommandBuffer cmd = CommandBufferPool.Get();

            using (new ProfilingScope(cmd, m_ProfilingSampler))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                SetupMainLightShadowReceiverConstants(cmd, shadowLight, shadowData.supportsSoftShadows);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
コード例 #8
0
        internal void Draw()
        {
            EntityShadow mode = game.Entities.ShadowMode;
            Vector3      Position = entity.Position;
            float        posX = Position.X, posZ = Position.Z;
            int          posY = Math.Min((int)Position.Y, game.World.Height - 1);
            int          index = 0, vb = 0;

            radius = 7f * Math.Min(entity.ModelScale, 1) * entity.Model.ShadowScale;

            VertexP3fT2fC4b[] verts = null;
            int         posCount = 0, dataCount = 0;
            Vector3I *  coords = stackalloc Vector3I[4];
            ShadowData *data   = stackalloc ShadowData[4];

            for (int i = 0; i < 4; i++)
            {
                coords[i] = new Vector3I(int.MinValue);
                data[i]   = new ShadowData();
            }

            if (mode == EntityShadow.SnapToBlock)
            {
                vb = game.Graphics.texVb; verts = game.Graphics.texVerts;
                if (!GetBlocks(coords, ref posCount, posX, posZ, posY, data, ref dataCount))
                {
                    return;
                }

                float x1 = Utils.Floor(posX), z1 = Utils.Floor(posZ);
                DraqSquareShadow(verts, ref index, data[0].Y, 220, x1, z1);
            }
            else
            {
                vb = game.ModelCache.vb; verts = game.ModelCache.vertices;

                float x = posX - radius / 16f, z = posZ - radius / 16f;
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                x = Math.Max(posX - radius / 16f, Utils.Floor(posX + radius / 16f));
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                z = Math.Max(posZ - radius / 16f, Utils.Floor(posZ + radius / 16f));
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                x = posX - radius / 16f;
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }
            }

            if (index == 0)
            {
                return;
            }
            CheckShadowTexture(game.Graphics);

            if (!boundShadowTex)
            {
                game.Graphics.BindTexture(shadowTex);
                boundShadowTex = true;
            }
            game.Graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, vb, verts, index);
        }
コード例 #9
0
    void RenderDirectionalCascadeShadowmap(ref ScriptableRenderContext context, ref RenderingData renderingData)
    {
        LightData   lightData      = renderingData.lightData;
        ShadowData  shadowData     = renderingData.shadowData;
        CullResults cullResults    = renderingData.cullResults;
        float       shadowFarPlane = renderingData.cameraData.maxShadowDistance;

        int shadowLightIndex = lightData.mainLightIndex;

        if (shadowLightIndex == -1)
        {
            return;
        }

        VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
        Light        light       = shadowLight.light;

        if (light.shadows == LightShadows.None)
        {
            return;
        }

        Bounds bounds;

        if (!cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
        {
            return;
        }

        CommandBuffer cmd = commandBufferPool.Get(k_RenderDirectionalShadowmapTag);

        {
            m_ShadowCasterCascadesCount = shadowData.directionalLightCascadeCount;

            int shadowResolution = (m_ShadowCasterCascadesCount > 1) ?
                                   (int)(shadowData.directionalShadowAltasRes / 2f) : shadowData.directionalShadowAltasRes;
            float shadowNearPlane = light.shadowNearPlane;

            Matrix4x4           view, proj;
            DrawShadowsSettings settings = new DrawShadowsSettings(cullResults, shadowLightIndex);

            m_DirectionalShadowmapTexture = RenderTexture.GetTemporary(shadowData.directionalShadowAltasRes,
                                                                       shadowData.directionalShadowAltasRes, k_ShadowmapBufferBits, m_ShadowmapFormat);
            m_DirectionalShadowmapTexture.filterMode = FilterMode.Bilinear;
            m_DirectionalShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;

            cmd.GetTemporaryRT(destination.id, m_DirectionalShadowmapTexture.descriptor);

            SetRenderTarget(cmd, destination.Identifier(), RenderBufferLoadAction.DontCare,
                            RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

            bool success = false;
            for (int i = 0; i < m_ShadowCasterCascadesCount; i++)
            {
                success = CoreShadowUtils.ExtractDirectionalLightMatrix(ref cullResults, ref shadowData, shadowLightIndex,
                                                                        i, shadowResolution, shadowNearPlane, shadowFarPlane, out m_CascadeSplitDistances[i], out m_CascadeSlices[i], out view, out proj);
                if (success)
                {
                    //Debug.Log("Cascade " + i.ToString() + " " + m_ShadowCasterCascadesCount.ToString() +  " " + view * proj);
                    settings.splitData.cullingSphere = m_CascadeSplitDistances[i];
                    CoreShadowUtils.SetupShadowCasterConstants(cmd, ref shadowLight, proj, shadowResolution);
                    CoreShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[i], ref settings, proj, view);
                }
            }

            if (success)
            {
                SetupDirectionalShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }
        }
        context.ExecuteCommandBuffer(cmd);
        commandBufferPool.Release(cmd);
    }
コード例 #10
0
ファイル: ShadowBase.cs プロジェクト: sjb8100/SRP
 abstract public bool Reserve(FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray <ShadowData> entries, ref VectorArray <ShadowPayload> payloads, VisibleLight[] lights);
コード例 #11
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
            // Currently there's an issue which results in mismatched markers.
            CommandBuffer cmd = CommandBufferPool.Get();

            using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    //settings.splitData = m_CascadeSlices[cascadeIndex].splitData; // NOTE: currently DrawShadows culls more casters if no ShadowSplitData.cullingPlanes are set (version cds 8652678b), so it is currently better to not pass the m_CascadeSlices[cascadeIndex].splitData object returned by CullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives (change introduced in 8bf71cf). Culling is only based on the ShadowSplitData.cullingSphere distances.
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;

                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.CastingPunctualLightShadow, false);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
                CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);

                SetupMainLightShadowReceiverConstants(cmd, shadowLight, shadowData.supportsSoftShadows);
            }

            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }