diff --git a/src/mol-gl/renderable.ts b/src/mol-gl/renderable.ts index 1139a14dd9c53796c1903eee76c51c55c2d94d53..afceb5794264e520b290679d0f4427d4e7911fa7 100644 --- a/src/mol-gl/renderable.ts +++ b/src/mol-gl/renderable.ts @@ -22,6 +22,7 @@ export type RenderableState = { export interface Renderable<T extends RenderableValues> { readonly id: number + readonly materialId: number readonly values: T readonly state: RenderableState @@ -34,6 +35,7 @@ export interface Renderable<T extends RenderableValues> { export function createRenderable<T extends Values<RenderableSchema>>(renderItem: RenderItem, values: T, state: RenderableState): Renderable<T> { return { id: getNextRenderableId(), + materialId: renderItem.materialId, values, state, diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts index 6e2685cc33c53ddb08e9d6c00f8f7c27ce92519a..749836fe396ff5d1b56cdf87179c9e316300cda4 100644 --- a/src/mol-gl/scene.ts +++ b/src/mol-gl/scene.ts @@ -38,15 +38,19 @@ function calculateBoundingSphere(renderables: Renderable<RenderableValues & Base function renderableSort(a: Renderable<RenderableValues & BaseValues>, b: Renderable<RenderableValues & BaseValues>) { const drawProgramIdA = a.getProgram('draw').id const drawProgramIdB = b.getProgram('draw').id + const materialIdA = a.materialId + const materialIdB = b.materialId const zA = a.values.boundingSphere.ref.value.center[2] - const zB = a.values.boundingSphere.ref.value.center[2] + const zB = b.values.boundingSphere.ref.value.center[2] if (drawProgramIdA !== drawProgramIdB) { - return drawProgramIdA - drawProgramIdB; // sort by program id to minimize gl state changes + return drawProgramIdA - drawProgramIdB // sort by program id to minimize gl state changes + } else if (materialIdA !== materialIdB) { + return materialIdA - materialIdB // sort by material id to minimize gl state changes } else if (zA !== zB) { return a.state.opaque - ? zA - zB // when opaque draw closer elements first to minimize overdraw - : zB - zA // when transparent draw elements last to maximize partial visibility + ? zA - zB // when opaque, draw closer elements first to minimize overdraw + : zB - zA // when transparent, draw elements last to maximize partial visibility } else { return a.id - b.id; } diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index 5c64e5879f3e119bb658dacb6418cff19e4a5d4f..3939c89a10c1f6d48f108d7b5cd575d059ca27a0 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -35,6 +35,7 @@ export function getDrawMode(ctx: WebGLContext, drawMode: DrawMode) { export interface RenderItem { readonly id: number + readonly materialId: number getProgram: (variant: RenderVariant) => Program render: (variant: RenderVariant) => void @@ -133,6 +134,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo return { id, + materialId, getProgram: (variant: RenderVariant) => programs[variant].value, render: (variant: RenderVariant) => {