Skip to content

Avoid rendering in both the opaque and transparent pass? #810

@hmaarrfk

Description

@hmaarrfk

If render_mask=0 then often objects will render in both the opaque and transparent pass

See for example the text shader

else:
render_mask |= RenderMask.opaque
if material.aa:
render_mask |= RenderMask.transparent

In some benchmarks of mine: I've found that this can actually cause you to pay twice for the rendering the object

for render_pipeline_container in render_pipeline_containers:
render_pipeline_container.draw(
render_pass, environment, pass_index, render_mask
)

So its quite difficult to actually show the effect, but what i tried to do is to generate about 1000 pieces of text on the screen
on the left window, i specified render_mask=2 and on the right render_mask=0.

with render_mask=2 (transparent) I can reach about 27 fps, with render_mask=0 i can't get past about 22.

the code
import os
import random
from wgpu.gui.auto import WgpuCanvas, run
import pygfx as gfx
import argparse

parser = argparse.ArgumentParser(description="Render Mark with Too Much Text")
parser.add_argument(
    "--render-mask", type=int, default=1, help="Render mask parameter"
)
args = parser.parse_args()
render_mask = args.render_mask

scene = gfx.Scene()

scene.add(gfx.Background.from_color("#fff", "#000"))

material = gfx.TextMaterial(color="#B4F8C8", outline_color="#000", outline_thickness=0.15)
assert material.aa
for i in range(1000):
    text = gfx.Text(
        gfx.TextGeometry(
            text=f"{i}",
            font_size=40,
            screen_space=True,
        ),
        material=material,
        render_mask=render_mask,
    )
    text.local.position = (
        # Random number between -400 and 400
        random.randint(-400, 300),
        random.randint(-300, 200),
        0)

    scene.add(text)

canvas = WgpuCanvas(title=f"Render Mask {render_mask}")
renderer = gfx.WgpuRenderer(canvas)

camera = gfx.OrthographicCamera(800, 600)
controller = gfx.PanZoomController(camera, register_events=renderer)

if __name__ == "__main__":
    canvas.request_draw(lambda: renderer.render(scene, camera))
    run()

I used mangohud to display the fps

I guess mangohud also shows that with render_mask=0 the utilization is higher than with render_mask=2.

https://www.youtube.com/watch?v=jmr412zZM0Y
hmaarrfk#6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions