Skip to content

Commit 8d05ea9

Browse files
committed
optimize transparent pass draw
1 parent ddb15b0 commit 8d05ea9

File tree

3 files changed

+54
-55
lines changed

3 files changed

+54
-55
lines changed

scripts/dynamic_box.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
obj3 = viewer.scene.add(mesh)
1616
obj3.transformation = Translation.from_vector([-5, 0, 0])
1717

18+
obj1.opacity = 0.7
1819

1920
@viewer.on(interval=100)
2021
def deform_mesh(frame):

src/compas_viewer/renderer/renderer.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -559,32 +559,18 @@ def paint(self, is_instance: bool = False):
559559

560560
self.shader_model.uniform4x4("viewworld", viewworld)
561561
self.shader_model.uniform1i("is_instance", is_instance)
562-
563-
# First pass: Draw grid and opaque objects with depth writing enabled
564-
GL.glDepthMask(GL.GL_TRUE)
565562

563+
566564
if self.viewer.config.renderer.show_grid:
567565
self.grid.draw(self.shader_model)
568566

569567
# Draw opaque objects
570568
self.buffer_manager.draw(
571569
self.shader_model,
572-
wireframe=(self.rendermode == "wireframe"),
573-
is_lighted=(self.rendermode == "lighted"),
574-
transparent=False # Only draw opaque objects in this pass
570+
self.rendermode,
571+
is_instance=is_instance,
575572
)
576573

577-
# Second pass: Draw transparent objects with depth writing disabled
578-
if not is_instance: # Skip transparent objects in instance rendering
579-
GL.glDepthMask(GL.GL_FALSE) # Disable depth writing for transparent objects
580-
self.buffer_manager.draw(
581-
self.shader_model,
582-
wireframe=(self.rendermode == "wireframe"),
583-
is_lighted=(self.rendermode == "lighted"),
584-
transparent=True # Only draw transparent objects in this pass
585-
)
586-
GL.glDepthMask(GL.GL_TRUE) # Re-enable depth writing
587-
588574
self.shader_model.release()
589575

590576
# Draw text tag sprites

src/compas_viewer/scene/buffermanager.py

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -155,20 +155,23 @@ def create_buffers(self) -> None:
155155
else:
156156
self.buffer_ids[buffer_type]["elements"] = make_index_buffer(self.elements[buffer_type])
157157

158-
def draw(self, shader: Shader, wireframe: bool = False, is_lighted: bool = True, transparent: bool = False) -> None:
158+
def draw(self, shader: Shader, rendermode: str, is_instance: bool = False) -> None:
159159
"""Draw all objects using the combined buffers.
160160
161161
Parameters
162162
----------
163163
shader : Shader
164164
The shader to use for rendering.
165-
wireframe : bool, optional
166-
Whether to render in wireframe mode.
167-
is_lighted : bool, optional
168-
Whether to apply lighting.
169-
transparent : bool, optional
170-
If True, only draw transparent objects. If False, only draw opaque objects.
165+
rendermode : str
166+
The rendering mode to use, either "wireframe", "lighted", or "ghosted".
167+
is_instance : bool
168+
Whether the rendering is for an instance.
171169
"""
170+
171+
is_wireframe = rendermode == "wireframe"
172+
is_lighted = rendermode == "lighted"
173+
is_ghosted = rendermode == "ghosted"
174+
172175
for obj in self.objects:
173176
self.update_object_settings(obj)
174177

@@ -177,44 +180,53 @@ def draw(self, shader: Shader, wireframe: bool = False, is_lighted: bool = True,
177180
shader.enable_attribute("color")
178181
shader.enable_attribute("object_index")
179182

183+
# Frist Draw all the opaque elements
180184
# Draw faces
181-
if not wireframe:
185+
if not is_wireframe and (not is_ghosted or is_instance):
182186
shader.uniform1i("is_lighted", is_lighted)
183187
shader.uniform1i("element_type", 2)
184-
185188
for face_type in ["_frontfaces_data", "_backfaces_data"]:
186189
if self.buffer_ids[face_type]:
187-
# Skip if we're only drawing specific transparency types
188-
if not transparent:
189-
# Draw all objects
190-
shader.bind_attribute("position", self.buffer_ids[face_type]["positions"])
191-
shader.bind_attribute("color", self.buffer_ids[face_type]["colors"], step=4)
192-
shader.bind_attribute("object_index", self.buffer_ids[face_type]["object_indices"], step=1)
193-
shader.draw_triangles(elements=self.buffer_ids[face_type]["elements"], n=len(self.elements[face_type]))
194-
else:
195-
shader.bind_attribute("position", self.buffer_ids[face_type]["positions"])
196-
shader.bind_attribute("color", self.buffer_ids[face_type]["colors"], step=4)
197-
shader.bind_attribute("object_index", self.buffer_ids[face_type]["object_indices"], step=1)
190+
shader.bind_attribute("position", self.buffer_ids[face_type]["positions"])
191+
shader.bind_attribute("color", self.buffer_ids[face_type]["colors"], step=4)
192+
shader.bind_attribute("object_index", self.buffer_ids[face_type]["object_indices"], step=1)
193+
shader.draw_triangles(elements=self.buffer_ids[face_type]["elements"], n=len(self.elements[face_type]))
194+
if is_instance:
195+
# Also include transparent elements when rendering instance map
198196
shader.draw_triangles(elements=self.buffer_ids[face_type]["elements_transparent"], n=len(self.elements[face_type + "_transparent"]))
199197

200-
# For lines and points, we'll only filter if transparent is specified
201-
if not transparent: # Draw opaque objects or all objects
202-
# Draw lines
203-
shader.uniform1i("is_lighted", False)
204-
shader.uniform1i("element_type", 1)
205-
if self.buffer_ids["_lines_data"]:
206-
shader.bind_attribute("position", self.buffer_ids["_lines_data"]["positions"])
207-
shader.bind_attribute("color", self.buffer_ids["_lines_data"]["colors"], step=4)
208-
shader.bind_attribute("object_index", self.buffer_ids["_lines_data"]["object_indices"], step=1)
209-
shader.draw_lines(elements=self.buffer_ids["_lines_data"]["elements"], n=len(self.elements["_lines_data"]), width=1.0)
210-
211-
# Draw points
212-
shader.uniform1i("element_type", 0)
213-
if self.buffer_ids["_points_data"]:
214-
shader.bind_attribute("position", self.buffer_ids["_points_data"]["positions"])
215-
shader.bind_attribute("color", self.buffer_ids["_points_data"]["colors"], step=4)
216-
shader.bind_attribute("object_index", self.buffer_ids["_points_data"]["object_indices"], step=1)
217-
shader.draw_points(elements=self.buffer_ids["_points_data"]["elements"], n=len(self.elements["_points_data"]), size=10.0)
198+
# Draw lines
199+
shader.uniform1i("is_lighted", False)
200+
shader.uniform1i("element_type", 1)
201+
if self.buffer_ids["_lines_data"]:
202+
shader.bind_attribute("position", self.buffer_ids["_lines_data"]["positions"])
203+
shader.bind_attribute("color", self.buffer_ids["_lines_data"]["colors"], step=4)
204+
shader.bind_attribute("object_index", self.buffer_ids["_lines_data"]["object_indices"], step=1)
205+
shader.draw_lines(elements=self.buffer_ids["_lines_data"]["elements"], n=len(self.elements["_lines_data"]), width=1.0)
206+
207+
# Draw points
208+
shader.uniform1i("element_type", 0)
209+
if self.buffer_ids["_points_data"]:
210+
shader.bind_attribute("position", self.buffer_ids["_points_data"]["positions"])
211+
shader.bind_attribute("color", self.buffer_ids["_points_data"]["colors"], step=4)
212+
shader.bind_attribute("object_index", self.buffer_ids["_points_data"]["object_indices"], step=1)
213+
shader.draw_points(elements=self.buffer_ids["_points_data"]["elements"], n=len(self.elements["_points_data"]), size=10.0)
214+
215+
if not is_instance and not is_wireframe:
216+
# Then Draw all the transparent elements
217+
shader.uniform1i("is_lighted", is_lighted)
218+
shader.uniform1i("element_type", 2)
219+
GL.glDepthMask(GL.GL_FALSE) # Disable depth writing for transparent objects
220+
for face_type in ["_frontfaces_data", "_backfaces_data"]:
221+
if self.buffer_ids[face_type]:
222+
shader.bind_attribute("position", self.buffer_ids[face_type]["positions"])
223+
shader.bind_attribute("color", self.buffer_ids[face_type]["colors"], step=4)
224+
shader.bind_attribute("object_index", self.buffer_ids[face_type]["object_indices"], step=1)
225+
shader.draw_triangles(elements=self.buffer_ids[face_type]["elements_transparent"], n=len(self.elements[face_type + "_transparent"]))
226+
if is_ghosted:
227+
# Draw the opaque elements in transparent pass too in ghosted mode
228+
shader.draw_triangles(elements=self.buffer_ids[face_type]["elements"], n=len(self.elements[face_type]))
229+
GL.glDepthMask(GL.GL_TRUE) # Re-enable depth writing
218230

219231
shader.disable_attribute("object_index")
220232
shader.disable_attribute("position")

0 commit comments

Comments
 (0)