Example #1
0
        protected override void OnUpdate()
        {
            Dependency.Complete();
            var sys = World.GetExistingSystem <RendererBGFXSystem>().InstancePointer();

            if (!sys->m_initialized)
            {
                return;
            }
            // get all MeshRenderer, cull them, and add them to graph nodes that need them
            // any mesh renderer MUST have a shared component data that has a list of passes to render to
            // this list is usually very shared - all opaque meshes will render to all ZOnly and Opaque passes
            // this shared data is not dynamically updated - other systems are responsible to update them if needed
            // simple
            Entities.WithNone <DisableRendering>().WithAll <SimpleMeshRenderer>().WithoutBurst().ForEach((Entity e, ref MeshRenderer mr, ref LocalToWorld tx, in WorldBounds wb, in WorldBoundingSphere wbs) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }

                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    if (Culling.Cull(in wbs, in pass.frustum) == Culling.CullingResult.Outside)
                    {
                        continue;
                    }
                    // double cull as example only
                    if (Culling.IsCulled(in wb, in pass.frustum))
                    {
                        continue;
                    }
                    var mesh   = EntityManager.GetComponentData <MeshBGFX>(mr.mesh);
                    uint depth = 0;
                    switch (pass.passType)
                    {
                    case RenderPassType.ShadowMap:
                        SubmitHelper.SubmitShadowMapMeshDirect(sys, pass.viewId, ref mesh, ref tx.Value, mr.startIndex, mr.indexCount, pass.GetFlipCullingInverse(), default);
                        break;

                    case RenderPassType.Transparent:
                        depth = pass.ComputeSortDepth(tx.Value.c3);
                        goto case RenderPassType.Opaque;

                    case RenderPassType.Opaque:
                        var material = EntityManager.GetComponentData <SimpleMaterialBGFX>(mr.material);
                        SubmitHelper.SubmitSimpleMeshDirect(sys, pass.viewId, ref mesh, ref tx.Value, ref material, mr.startIndex, mr.indexCount, pass.GetFlipCulling(), depth);
                        break;

                    default:
                        Assert.IsTrue(false);
                        break;
                    }
                }
            }).Run();
Example #2
0
        protected override void OnUpdate()
        {
            var sys = World.GetExistingSystem <RendererBGFXSystem>();

            if (!sys.Initialized)
            {
                return;
            }

            Entities.ForEach((Entity e, ref BlitRenderer br) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }

                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                var tex         = EntityManager.GetComponentData <TextureBGFX>(br.texture);
                var im2d        = EntityManager.GetComponentData <Image2D>(br.texture);
                float srcAspect = (float)im2d.imagePixelWidth / (float)im2d.imagePixelHeight;
                float4x4 m      = float4x4.identity;
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    if (br.preserveAspect)
                    {
                        float destAspect = (float)pass.viewport.w / (float)pass.viewport.h;
                        if (destAspect <= srcAspect)   // flip comparison to zoom in instead of black bars
                        {
                            m.c0.x = 1.0f; m.c1.y = destAspect / srcAspect;
                        }
                        else
                        {
                            m.c0.x = srcAspect / destAspect; m.c1.y = 1.0f;
                        }
                    }
                    if (sys.BlitPrimarySRGB)
                    {
                        // need to convert linear to srgb if we are not rendering to a texture in linear workflow
                        bool toPrimaryWithSRGB = EntityManager.HasComponent <RenderNodePrimarySurface>(pass.inNode) && sys.AllowSRGBTextures;
                        if (!toPrimaryWithSRGB)
                        {
                            SubmitHelper.SubmitBlitDirectFast(sys, pass.viewId, ref m, br.color, tex.handle);
                        }
                        else
                        {
                            SubmitHelper.SubmitBlitDirectExtended(sys, pass.viewId, ref m, tex.handle,
                                                                  false, true, 0.0f, new float4(1.0f), new float4(0.0f), false);
                        }
                    }
                    else
                    {
                        SubmitHelper.SubmitBlitDirectFast(sys, pass.viewId, ref m, br.color, tex.handle);
                    }
                }
            });
        }
        private void EncodeBox(RendererBGFXInstance *sys, bgfx.Encoder *encoder, Entity ePass, ref float4x4 tx, float3 cMin, float3 cMax, float width, float4 color)
        {
            var      pass = EntityManager.GetComponentData <RenderPass>(ePass);
            float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
            float2   normWidth          = new float2(width / pass.viewport.w, width / pass.viewport.h);

            for (int j = 0; j < Culling.EdgeTable.Length; j++)
            {
                float3 p0 = Culling.SelectCoordsMinMax(cMin, cMax, Culling.EdgeTable[j] & 7);
                float3 p1 = Culling.SelectCoordsMinMax(cMin, cMax, Culling.EdgeTable[j] >> 3);
                SubmitHelper.EncodeLine(sys, encoder, pass.viewId, p0, p1, color, normWidth,
                                        ref tx, ref pass.viewTransform, ref adjustedProjection);
            }
        }
Example #4
0
        protected override void OnUpdate()
        {
            var sys = World.GetExistingSystem <RendererBGFXSystem>().InstancePointer();

            if (!sys->m_initialized)
            {
                return;
            }
            Dependency.Complete();

            Entities.WithNone <DisableRendering>().WithoutBurst().ForEach((Entity e, ref BlitRenderer br) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                if (!EntityManager.HasComponent <TextureBGFX>(br.texture))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                var tex      = EntityManager.GetComponentData <TextureBGFX>(br.texture);
                float4x4 idm = float4x4.identity;
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    if (sys->m_blitPrimarySRGB)
                    {
                        // need to convert linear to srgb if we are not rendering to a texture in linear workflow
                        bool toPrimaryWithSRGB = EntityManager.HasComponent <RenderNodePrimarySurface>(pass.inNode) && sys->m_allowSRGBTextures;
                        if (!toPrimaryWithSRGB)
                        {
                            SubmitHelper.SubmitBlitDirectFast(sys, pass.viewId, ref idm, br.color, tex.handle);
                        }
                        else
                        {
                            SubmitHelper.SubmitBlitDirectExtended(sys, pass.viewId, ref idm, tex.handle,
                                                                  false, true, 0.0f, new float4(1.0f), new float4(0.0f), false);
                        }
                    }
                    else
                    {
                        SubmitHelper.SubmitBlitDirectFast(sys, pass.viewId, ref idm, br.color, tex.handle);
                    }
                }
            }).Run();
        }
        static private void Circle(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, float3 org, float3 du, float3 dv, float r, int n, float4 color, float2 normWidth,
                                   ref float4x4 tx, ref float4x4 txView, ref float4x4 txProj)
        {
            float3 pprev = org + dv * r;

            for (int i = 1; i <= n; i++)
            {
                float  a = ((float)i / (float)n) * math.PI * 2.0f;
                float  u = math.sin(a) * r;
                float  v = math.cos(a) * r;
                float3 p = org + du * u + dv * v;
                SubmitHelper.EncodeLine(sys, encoder, viewId, pprev, p, color, normWidth, ref tx, ref txView, ref txProj);
                pprev = p;
            }
        }
        // gizmos for debuging
        protected override void OnUpdate()
        {
            RendererBGFXInstance *sys = World.GetExistingSystem <RendererBGFXSystem>().InstancePointer();

            if (!sys->m_initialized)
            {
                return;
            }
            Dependency.Complete();

            bgfx.Encoder *encoder = bgfx.encoder_begin(false);

            // tangents & normals
            Entities.WithoutBurst().WithAll <RenderToPasses>().ForEach((Entity e, ref MeshRenderer mr, ref LocalToWorld tx, ref GizmoNormalsAndTangents giz) =>
            {
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    if (EntityManager.HasComponent <LitMeshRenderData>(mr.mesh))
                    {
                        var meshBase = EntityManager.GetComponentData <LitMeshRenderData>(mr.mesh);
                        Assert.IsTrue(giz.length > 0);
                        float2 normWidth = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                        SubmitHelper.EncodeDebugTangents(sys, encoder, pass.viewId, normWidth, giz.length, ref meshBase, ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                    }
                }
            }).Run();

            // object bounding box
            Entities.WithoutBurst().ForEach((Entity e, ref MeshRenderer mr, ref LocalToWorld tx, ref GizmoObjectBoundingBox giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                AABB b = EntityManager.GetComponentData <MeshBounds>(mr.mesh).Bounds;
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    EncodeBox(sys, encoder, ePass, ref tx.Value, b.Min, b.Max, giz.width, giz.color);
                }
            }).Run();

            // world bounds
            Entities.WithoutBurst().ForEach((Entity e, ref WorldBounds b, ref LocalToWorld tx, ref GizmoWorldBoundingBox giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4x4 idm = float4x4.identity;
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    float2 normWidth            = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                    for (int j = 0; j < Culling.EdgeTable.Length; j++)
                    {
                        float3 p0 = b.GetVertex(Culling.EdgeTable[j] & 7);
                        float3 p1 = b.GetVertex(Culling.EdgeTable[j] >> 3);
                        SubmitHelper.EncodeLine(sys, encoder, pass.viewId, p0, p1, giz.color, normWidth,
                                                ref idm, ref pass.viewTransform, ref adjustedProjection);
                    }
                }
            }).Run();

            // transform
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref GizmoTransform giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    float2 normWidth            = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                    Assert.IsTrue(giz.length > 0);
                    SubmitHelper.EncodeLine(sys, encoder, pass.viewId, new float3(0), new float3(giz.length, 0, 0), new float4(1, 0, 0, 1), normWidth, ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                    SubmitHelper.EncodeLine(sys, encoder, pass.viewId, new float3(0), new float3(0, giz.length, 0), new float4(0, 1, 0, 1), normWidth, ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                    SubmitHelper.EncodeLine(sys, encoder, pass.viewId, new float3(0), new float3(0, 0, giz.length), new float4(0, 0, 1, 1), normWidth, ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                }
            }).Run();

            // sphere
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref WorldBoundingSphere bs, ref GizmoBoundingSphere giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4x4 idm = float4x4.identity;
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    float2 normWidth            = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                    Assert.IsTrue(giz.subdiv >= 4);
                    Circle(sys, encoder, pass.viewId, bs.position, new float3(0, 0, 1), new float3(0, 1, 0), bs.radius, giz.subdiv, new float4(1, 0, 0, 1), normWidth, ref idm, ref pass.viewTransform, ref adjustedProjection); // z/y plane
                    Circle(sys, encoder, pass.viewId, bs.position, new float3(1, 0, 0), new float3(0, 0, 1), bs.radius, giz.subdiv, new float4(0, 1, 0, 1), normWidth, ref idm, ref pass.viewTransform, ref adjustedProjection); // x/z plane
                    Circle(sys, encoder, pass.viewId, bs.position, new float3(0, 1, 0), new float3(1, 0, 0), bs.radius, giz.subdiv, new float4(0, 0, 1, 1), normWidth, ref idm, ref pass.viewTransform, ref adjustedProjection); // y/x plane
                }
            }).Run();

            // spot lights
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref Light l, ref SpotLight sl, ref GizmoLight giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4 color = giz.overrideColor ? giz.color : new float4(l.color, 1.0f);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass                = toPasses[i].e;
                    var pass                    = EntityManager.GetComponentData <RenderPass>(ePass);
                    float2 normWidth            = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    // render frustum
                    float t = math.tan(math.radians(sl.fov) * .5f);
                    for (int j = 0; j < Culling.EdgeTable.Length; j++)
                    {
                        float3 pp0 = ProjectionHelper.FrustumVertexPerspective(Culling.EdgeTable[j] & 7, t, t, l.clipZNear, l.clipZFar);
                        float3 pp1 = ProjectionHelper.FrustumVertexPerspective(Culling.EdgeTable[j] >> 3, t, t, l.clipZNear, l.clipZFar);
                        SubmitHelper.EncodeLine(sys, encoder, pass.viewId, pp0, pp1, color, normWidth,
                                                ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                    }
                }
            }).Run();

            // directional lights
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref Light l, ref DirectionalLight dl, ref GizmoLight giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4 color = giz.overrideColor ? giz.color : new float4(l.color, 1.0f);
                float3 cMin  = new float3(-1, -1, l.clipZNear);
                float3 cMax  = new float3(1, 1, l.clipZFar);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    EncodeBox(sys, encoder, ePass, ref tx.Value, cMin, cMax, giz.width, color);
                }
            }).Run();

            // point lights

            // cameras
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref Camera cam, ref GizmoCamera giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass                = toPasses[i].e;
                    var pass                    = EntityManager.GetComponentData <RenderPass>(ePass);
                    float2 normWidth            = new float2(giz.width / pass.viewport.w, giz.width / pass.viewport.h);
                    float4x4 adjustedProjection = sys->GetAdjustedProjection(ref pass);
                    // render box
                    if (cam.mode == ProjectionMode.Orthographic)
                    {
                        float3 cMin = new float3(-cam.fov, -cam.fov, cam.clipZNear);
                        float3 cMax = new float3(cam.fov, cam.fov, cam.clipZFar);
                        EncodeBox(sys, encoder, ePass, ref tx.Value, cMin, cMax, giz.width, giz.color);
                    }
                    else if (cam.mode == ProjectionMode.Perspective)
                    {
                        float h = math.tan(math.radians(cam.fov) * .5f);
                        float w = h * cam.aspect;
                        for (int j = 0; j < Culling.EdgeTable.Length; j++)
                        {
                            float3 pp0 = ProjectionHelper.FrustumVertexPerspective(Culling.EdgeTable[j] & 7, w, h, cam.clipZNear, cam.clipZFar);
                            float3 pp1 = ProjectionHelper.FrustumVertexPerspective(Culling.EdgeTable[j] >> 3, w, h, cam.clipZNear, cam.clipZFar);
                            SubmitHelper.EncodeLine(sys, encoder, pass.viewId, pp0, pp1, giz.color, normWidth,
                                                    ref tx.Value, ref pass.viewTransform, ref adjustedProjection);
                        }
                    }
                }
            }).Run();

            // auto bounds
            Entities.WithoutBurst().ForEach((Entity e, ref LocalToWorld tx, ref AutoMovingDirectionalLight amd, ref GizmoAutoMovingDirectionalLight giz) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4x4 idm = float4x4.identity;
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    EncodeBox(sys, encoder, ePass, ref idm, amd.bounds.Min, amd.bounds.Max, giz.width, giz.colorCasters);
                    EncodeBox(sys, encoder, ePass, ref idm, amd.boundsClipped.Min, amd.boundsClipped.Max, giz.width, giz.colorClippedReceivers);
                }
            }).Run();

            // debug display textures as overlays
            Entities.WithoutBurst().ForEach((Entity e, ref TextureBGFX tex, ref GizmoDebugOverlayTexture giz) => {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }
                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                float4x4 m            = float4x4.identity;
                m.c3.xy               = giz.pos;
                m.c0.x                = giz.size.x;
                m.c1.y                = giz.size.y;
                SimpleMaterialBGFX sm = new SimpleMaterialBGFX
                {
                    texAlbedoOpacity          = tex.handle,
                    constAlbedo_Opacity       = giz.color,
                    mainTextureScaleTranslate = new float4(1, 1, 0, 0),
                    state = (ulong)bgfx.StateFlags.WriteRgb
                };
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    SubmitHelper.EncodeSimpleMesh(sys, encoder, pass.viewId, ref sys->m_quadMesh, ref m, ref sm, 0, 6, pass.GetFlipCulling(), 0);
                }
            }).Run();
            bgfx.encoder_end(encoder);
        }
Example #7
0
            public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var chunkLocalToWorld        = chunk.GetNativeArray(LocalToWorldType);
                var chunkMeshRenderer        = chunk.GetNativeArray(MeshRendererType);
                var chunkMeshReference       = chunk.GetNativeArray(LitMeshType);
                var chunkWorldBoundingSphere = chunk.GetNativeArray(WorldBoundingSphereType);
                var boundingSphere           = chunk.GetChunkComponentData(ChunkWorldBoundingSphereType).Value;
                var bounds = chunk.GetChunkComponentData(ChunkWorldBoundsType).Value;

                Entity lighte   = SharedLightingRef[chunkIndex];
                var    lighting = ComponentLightingBGFX[lighte];
                Entity rtpe     = SharedRenderToPass[chunkIndex];

                Assert.IsTrue(ThreadIndex >= 0 && ThreadIndex < MaxPerThreadData);
                bgfx.Encoder *encoder = PerThreadData[ThreadIndex].encoder;
                if (encoder == null)
                {
                    encoder = bgfx.encoder_begin(true);
                    Assert.IsTrue(encoder != null);
                    PerThreadData[ThreadIndex].encoder = encoder;
                }
                DynamicBuffer <RenderToPassesEntry> toPasses = BufferRenderToPassesEntry[rtpe];

                // we can do this loop either way, passes first or renderers first.
                // TODO: profile what is better!
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity  ePass   = toPasses[i].e;
                    Frustum frustum = default;
                    if (ComponentFrustum.Exists(ePass))
                    {
                        frustum = ComponentFrustum[ePass]; // TODO, just make frustum a member of pass?
                        if (Culling.Cull(ref boundingSphere, ref frustum) == Culling.CullingResult.Outside)
                        {
                            continue; // nothing to do for this pass
                        }
                    }
                    Assert.IsTrue(encoder != null);
                    var pass = ComponentRenderPass[ePass];
                    for (int j = 0; j < chunk.Count; j++)
                    {
                        var wbs          = chunkWorldBoundingSphere[j];
                        var meshRenderer = chunkMeshRenderer[j];
                        var meshRef      = chunkMeshReference[j];
                        var mesh         = ComponentSimpleMeshBGFX[meshRef.mesh];
                        var tx           = chunkLocalToWorld[j].Value;
                        if (Culling.Cull(ref wbs, ref frustum) == Culling.CullingResult.Outside) // TODO: fine cull only if rough culling was !Inside
                        {
                            continue;
                        }
                        switch (pass.passType)   // TODO: we can hoist this out of the loop
                        {
                        case RenderPassType.ZOnly:
                            SubmitHelper.EncodeZOnly(BGFXSystem, encoder, pass.viewId, ref mesh, ref tx, meshRenderer.startIndex, meshRenderer.indexCount, pass.flipCulling);
                            break;

                        case RenderPassType.ShadowMap:
                            float4 bias = new float4(0);
                            SubmitHelper.EncodeShadowMap(BGFXSystem, encoder, pass.viewId, ref mesh, ref tx, meshRenderer.startIndex, meshRenderer.indexCount, (byte)(pass.flipCulling ^ 0x3), bias);
                            break;

                        case RenderPassType.Transparent:
                        case RenderPassType.Opaque:
                            var material = ComponentLitMaterialBGFX[meshRenderer.material];
                            SubmitHelper.EncodeLit(BGFXSystem, encoder, pass.viewId, ref mesh, ref tx, ref material, ref lighting, ref pass.viewTransform, meshRenderer.startIndex, meshRenderer.indexCount, pass.flipCulling, ref PerThreadData[ThreadIndex].viewSpaceLightCache);
                            break;

                        default:
                            Assert.IsTrue(false);
                            break;
                        }
                    }
                }
            }
Example #8
0
        protected override void OnUpdate()
        {
            var sys = World.GetExistingSystem <RendererBGFXSystem>();

            if (!sys.Initialized)
            {
                return;
            }
            // get all MeshRenderer, cull them, and add them to graph nodes that need them
            // any mesh renderer MUST have a shared component data that has a list of passes to render to
            // this list is usually very shared - all opaque meshes will render to all ZOnly and Opaque passes
            // this shared data is not dynamically updated - other systems are responsible to update them if needed
            // simple
            Entities.ForEach((Entity e, ref MeshRenderer mr, ref SimpleMeshReference meshRef, ref LocalToWorld tx, ref WorldBounds wb, ref WorldBoundingSphere wbs) =>
            {
                if (!EntityManager.HasComponent <RenderToPasses>(e))
                {
                    return;
                }

                RenderToPasses toPassesRef = EntityManager.GetSharedComponentData <RenderToPasses>(e);
                DynamicBuffer <RenderToPassesEntry> toPasses = EntityManager.GetBufferRO <RenderToPassesEntry>(toPassesRef.e);
                for (int i = 0; i < toPasses.Length; i++)
                {
                    Entity ePass = toPasses[i].e;
                    var pass     = EntityManager.GetComponentData <RenderPass>(ePass);
                    if (EntityManager.HasComponent <Frustum>(ePass))
                    {
                        var frustum = EntityManager.GetComponentData <Frustum>(ePass);
                        if (Culling.Cull(ref wbs, ref frustum) == Culling.CullingResult.Outside)
                        {
                            continue;
                        }
                        // double cull as example only
                        if (Culling.IsCulled(ref wb, ref frustum))
                        {
                            continue;
                        }
                    }
                    var mesh = EntityManager.GetComponentData <SimpleMeshBGFX>(meshRef.mesh);
                    switch (pass.passType)
                    {
                    case RenderPassType.ZOnly:
                        SubmitHelper.SubmitZOnlyDirect(sys, pass.viewId, ref mesh, ref tx.Value, mr.startIndex, mr.indexCount, pass.flipCulling);
                        break;

                    case RenderPassType.ShadowMap:
                        SubmitHelper.SubmitZOnlyDirect(sys, pass.viewId, ref mesh, ref tx.Value, mr.startIndex, mr.indexCount, (byte)(pass.flipCulling ^ 0x3));
                        break;

                    case RenderPassType.Transparent:
                    case RenderPassType.Opaque:
                        var material = EntityManager.GetComponentData <SimpleMaterialBGFX>(mr.material);
                        SubmitHelper.SubmitSimpleDirect(sys, pass.viewId, ref mesh, ref tx.Value, ref material, mr.startIndex, mr.indexCount, pass.flipCulling);
                        break;

                    default:
                        Assert.IsTrue(false);
                        break;
                    }
                }
            });
        }