public static unsafe void EncodeSimpleTransient(RendererBGFXInstance *sys, bgfx.Encoder *encoder, bgfx.TransientIndexBuffer *tib, bgfx.TransientVertexBuffer *tvb, int nvertices, int nindices, ushort viewId, ref float4x4 tx, ref SimpleMaterialBGFX mat, byte flipCulling, uint depth)
 {
     EncodeSimpleTransientBuffers(sys, encoder, tib, tvb, nvertices, nindices);
     EncodeSimple(sys, encoder, viewId, ref tx, ref mat, flipCulling, depth);
 }
        // For uniforms and shaders setup. Does not handle vertex/index buffers
        private static unsafe void EncodeSimple(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, ref float4x4 tx, ref SimpleMaterialBGFX mat, byte flipCulling, uint depth)
        {
            bgfx.set_state(mat.state, 0);

            fixed(float4x4 *p = &tx)
            bgfx.encoder_set_transform(encoder, p, 1);

            // material uniforms setup
            fixed(float4 *p = &mat.constAlbedo_Opacity)
            bgfx.encoder_set_uniform(encoder, sys->m_simpleShader.m_uniformColor0, p, 1);

            fixed(float4 *p = &mat.mainTextureScaleTranslate)
            bgfx.encoder_set_uniform(encoder, sys->m_simpleShader.m_uniformTexMad, p, 1);

            fixed(float4 *p = &mat.billboarded)
            bgfx.encoder_set_uniform(encoder, sys->m_simpleShader.m_uniformBillboarded, p, 1);

            bgfx.encoder_set_texture(encoder, 0, sys->m_simpleShader.m_samplerTexColor0, mat.texAlbedoOpacity, UInt32.MaxValue);
            bgfx.encoder_submit(encoder, viewId, sys->m_simpleShader.m_prog, depth, (byte)bgfx.DiscardFlags.All);
        }
 public static unsafe void SubmitSimpleTransientDirect(RendererBGFXInstance *sys, bgfx.TransientIndexBuffer *tib, bgfx.TransientVertexBuffer *tvb, int nvertices, int nindices, ushort viewId, ref float4x4 tx, ref SimpleMaterialBGFX mat, byte flipCulling, uint depth)
 {
     bgfx.Encoder *encoder = bgfx.encoder_begin(false);
     EncodeSimpleTransient(sys, encoder, tib, tvb, nvertices, nindices, viewId, ref tx, ref mat, flipCulling, depth);
     bgfx.encoder_end(encoder);
 }
 // ---------------- simple, unlit, with mesh ----------------------------------------------------------------------------------------------------------------------
 public static unsafe void SubmitSimpleMeshDirect(RendererBGFXInstance *sys, ushort viewId, ref MeshBGFX mesh, ref float4x4 tx, ref SimpleMaterialBGFX mat, int startIndex, int indexCount, byte flipCulling, uint depth)
 {
     bgfx.Encoder *encoder = bgfx.encoder_begin(false);
     EncodeSimpleMesh(sys, encoder, viewId, ref mesh, ref tx, ref mat, startIndex, indexCount, flipCulling, depth);
     bgfx.encoder_end(encoder);
 }
 public static unsafe void EncodeSimpleMesh(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, ref MeshBGFX mesh, ref float4x4 tx, ref SimpleMaterialBGFX mat, int startIndex, int indexCount, byte flipCulling, uint depth)
 {
     mesh.SetForSubmit(encoder, startIndex, indexCount);
     EncodeSimple(sys, encoder, viewId, ref tx, ref mat, flipCulling, depth);
 }
        // 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);
        }
Ejemplo n.º 7
0
        public unsafe bool UpdateSimpleMaterialBGFX(RendererBGFXInstance *sys, ref SimpleMaterial mat, ref SimpleMaterialBGFX matBGFX, bool srgbColors)
        {
            // if constants changed, need to update packed value
            matBGFX.constAlbedo_Opacity = srgbColors ?
                                          new float4(Color.LinearToSRGB(mat.constAlbedo), mat.constOpacity) :
                                          new float4(mat.constAlbedo, mat.constOpacity);
            // if texture entity OR load state changed need to update texture handles
            // content of texture change should transparently update texture referenced by handle
            bool stillLoading = false;

            if (InitTexture(ref matBGFX.texAlbedoOpacity, mat.texAlbedoOpacity, sys->m_whiteTexture))
            {
                stillLoading = true;
            }

            // if twoSided or hasalpha changed, need to update state
            matBGFX.state = (ulong)(bgfx.StateFlags.WriteRgb | bgfx.StateFlags.WriteA | bgfx.StateFlags.DepthTestLess);
            if (!mat.twoSided && !mat.billboarded)
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.CullCw;
            }
            if (mat.transparent)
            {
                matBGFX.state |= RendererBGFXStatic.MakeBGFXBlend(bgfx.StateFlags.BlendOne, bgfx.StateFlags.BlendInvSrcAlpha);
            }
            else
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.WriteZ;
            }
            matBGFX.mainTextureScaleTranslate = new float4(mat.scale, mat.offset);

            matBGFX.billboarded = new float4(mat.billboarded ? 1 : 0, 0, 0, 0);
            return(!stillLoading);
        }
Ejemplo n.º 8
0
        public static unsafe void EncodeSimpleSkinnedmesh(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ushort viewId, ref MeshBGFX mesh, ref float4x4 tx, ref SimpleMaterialBGFX mat,
                                                          int startIndex, int indexCount, byte flipCulling, uint depth, float4x4[] boneMatrices)
        {
            mesh.SetForSubmit(encoder, startIndex, indexCount);
            fixed(float4x4 *p = boneMatrices)
            {
                bgfx.encoder_set_uniform(encoder, sys->m_simpleSkinnedMeshShader.m_uniformBoneMatrices, p, (ushort)boneMatrices.Length);
            }

            EncodeSimple(sys, encoder, ref sys->m_simpleSkinnedMeshShader.m_simpleShader, viewId, ref tx, ref mat, flipCulling, depth);
        }
Ejemplo n.º 9
0
        public bool UpdateSimpleMaterialBGFX(RendererBGFXSystem sys, ref SimpleMaterial mat, ref SimpleMaterialBGFX matBGFX)
        {
            // if constants changed, need to update packed value
            matBGFX.constAlbedo_Opacity = new float4(mat.constAlbedo, mat.constOpacity);
            // if texture entity OR load state changed need to update texture handles
            // content of texture change should transparently update texture referenced by handle
            bool stillLoading = false;

            if (InitTexture(ref matBGFX.texAlbedo, mat.texAlbedo, sys.WhiteTexture))
            {
                stillLoading = true;
            }
            if (InitTexture(ref matBGFX.texOpacity, mat.texOpacity, sys.WhiteTexture))
            {
                stillLoading = true;
            }

            // if twoSided or hasalpha changed, need to update state
            matBGFX.state = (ulong)(bgfx.StateFlags.WriteRgb | bgfx.StateFlags.WriteA | bgfx.StateFlags.DepthTestLess);
            if (!mat.twoSided)
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.CullCw;
            }
            if (mat.transparent)
            {
                matBGFX.state |= RendererBGFXSystem.MakeBGFXBlend(bgfx.StateFlags.BlendOne, bgfx.StateFlags.BlendInvSrcAlpha);
            }
            else
            {
                matBGFX.state |= (ulong)bgfx.StateFlags.WriteZ;
            }
            matBGFX.mainTextureScaleTranslate = new float4(mat.scale, mat.offset);
            return(!stillLoading);
        }
Ejemplo n.º 10
0
 public static unsafe void EncodeSimpleTransient(RendererBGFXSystem sys, bgfx.Encoder *encoder, ushort viewId, SimpleVertex *vertices, int nvertices, ushort *indices, int nindices, ref float4x4 tx, ref SimpleMaterialBGFX mat)
 {
     EncodeSimpleTransient(sys, encoder, viewId, vertices, nvertices, indices, nindices, ref tx, mat.constAlbedo_Opacity, mat.texAlbedo, mat.state);
 }
Ejemplo n.º 11
0
 // ---------------- simple, transient, for ui/text ----------------------------------------------------------------------------------------------------------------------
 public static unsafe void SubmitSimpleTransientDirect(RendererBGFXSystem sys, ushort viewId, SimpleVertex *vertices, int nvertices, ushort *indices, int nindices, ref float4x4 tx, ref SimpleMaterialBGFX mat)
 {
     bgfx.Encoder *encoder = bgfx.encoder_begin(false);
     EncodeSimpleTransient(sys, encoder, viewId, vertices, nvertices, indices, nindices, ref tx, ref mat);
     bgfx.encoder_end(encoder);
 }
Ejemplo n.º 12
0
        public static unsafe void EncodeSimple(RendererBGFXSystem sys, bgfx.Encoder *encoder, ushort viewId, ref SimpleMeshBGFX mesh, ref float4x4 tx, ref SimpleMaterialBGFX mat, int startIndex, int indexCount, byte flipCulling)
        {
            bgfx.set_state(mat.state, 0);

            fixed(float4x4 *p = &tx)
            bgfx.encoder_set_transform(encoder, p, 1);

            bgfx.encoder_set_index_buffer(encoder, mesh.indexBufferHandle, (uint)startIndex, (uint)indexCount);
            bgfx.encoder_set_vertex_buffer(encoder, 0, mesh.vertexBufferHandle, (uint)mesh.vertexFirst, (uint)mesh.vertexCount, mesh.vertexDeclHandle);

            // material uniforms setup
            fixed(float4 *p = &mat.constAlbedo_Opacity)
            bgfx.encoder_set_uniform(encoder, sys.SimpleShader.m_uniformColor0, p, 1);

            fixed(float4 *p = &mat.mainTextureScaleTranslate)
            bgfx.encoder_set_uniform(encoder, sys.SimpleShader.m_uniformTexMad, p, 1);

            bgfx.encoder_set_texture(encoder, 0, sys.SimpleShader.m_samplerTexColor0, mat.texAlbedo, UInt32.MaxValue);
            bgfx.encoder_submit(encoder, viewId, sys.SimpleShader.m_prog, 0, false);
        }