New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editor model rendering optimizations and fixes #8694
Conversation
@@ -238,7 +238,6 @@ | |||
|
|||
(input included-proj-paths+full-lines ProjPath+Lines :array) | |||
|
|||
(output build-targets g/Any :cached produce-build-targets) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused output. Fun fact: produce-build-targets
does not even exist in this file. We never check this in the defnode
macro, and this situation will create an output that always produces nil
. I started to add more validation to the defnode
macro, but I stashed it since it was turning out to be a bit of a rabbit hole.
Reported as #8702.
(.normalize n) ; Need to normalize since the matrix may be scaled. | ||
[(.x n) (.y n) (.z n) 0.0]) | ||
normals))) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved here from model.clj
.
(subvec default-element-values old-element-count new-element-count))) | ||
|
||
:else | ||
double-values))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: We used to put a zero in the W coordinate of positions as we copied X Y Z components from the mesh scene. This results in the points not being transformed correctly by the 4x4 transform matrix. For vectors (like normals or tangents), we should use 0.0
, but for points it needs to be 1.0
.
@@ -266,16 +310,18 @@ | |||
:element-count 1} | |||
{:name "normal" | |||
:semantic-type :semantic-type-normal | |||
:coordinate-space :coordinate-space-world |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The presence of the :coordinate-space
key on an attribute ensures we will assoc
in the default-coordinate-space
supplied to the shader-bound-attributes
function below.
(let [shader-bound-attribute? (comp boolean (shader/attribute-infos shader gl) :name) | ||
declared-material-attribute-key? (into #{} (map :name-key) material-attribute-infos) | ||
manufactured-attribute-infos (into [] | ||
(comp (remove declared-material-attribute-key?) | ||
(map attribute-key->default-attribute-info)) | ||
manufactured-stream-keys) | ||
manufactured-attribute-keys) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were some inconsistent naming in this file. I decided to use consistent terms everywhere.
(gl/gl-disable gl GL/GL_CULL_FACE) | ||
(.glBlendFunc gl GL/GL_SRC_ALPHA GL/GL_ONE_MINUS_SRC_ALPHA) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need. Since we're drawing an opaque mesh, we've disabled blending completely above.
material-name (mesh-material-index->material-name material-index)] | ||
{:aabb mesh-aabb | ||
:material-name material-name | ||
:renderable-data mesh-renderable-data})))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do less work in the render-fn
now. We can prepare the renderable-datas
and cache them in the renderable-mesh-set
output before producing the scene.
Potentially we might be able to fully create and cache the populated VertexBuffers
here, but currently we rely on getting the shader-bound-attributes
from the OpenGL context that is only available to us in the render-fn
. I think we may want to introduce a shared "resource" OpenGL context that we use to store vertex buffers and textures so they can be shared between scene views, but that is a larger change that could have potential issues with some hardware.
(recur (+ i 3) (geom/aabb-incorporate aabb p))) | ||
aabb))] | ||
(recur aabb (next meshes))) | ||
aabb)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now use the aabb-min
and aabb-max
values from the importer! 🌈
(mesh->vb! vb world-transform vertex-space vertex-attribute-bytes mesh))) | ||
(defn- update-vb [^GL2 _gl ^VertexBuffer vb data] | ||
(let [{:keys [mesh-renderable-data ^Matrix4d world-transform ^Matrix4d normal-transform vertex-attribute-bytes]} data] | ||
(mesh->vb! vb world-transform normal-transform vertex-attribute-bytes mesh-renderable-data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added normal-transform
, changed final argument to renderable-data
for the mesh.
vbuf (vtx/make-vertex-buffer vertex-description :dynamic (alength ^ints (:indices mesh)))] | ||
(let [{:keys [mesh-renderable-data vertex-description]} data | ||
position-data (:position-data mesh-renderable-data) | ||
vbuf (vtx/make-vertex-buffer vertex-description :dynamic (count position-data))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The :indices
have been used to construct a non-indexed triangle list already in the renderable-mesh-set
output, so at this point we can just count the number of positions.
(let [mesh-renderable (:renderable mesh-scene) | ||
material-name (:material-name mesh-renderable) | ||
material-scene-info (material-name->material-scene-info material-name) | ||
claimed-scene (scene/claim-child-scene old-node-id new-node-id new-node-outline-key mesh-scene)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An issue with the old code was that the Model using a particular model-scene
did not claim ownership of the scene-data produced by its scene
output. This resulted in meshes that had different requirements in terms of materials and transforms sharing the same request-id
for the scene-cache
. There were also issues related to picking and selection, since the renderables could not be uniquely identified to belong to the referencing Model.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did I read it? Yes. Did I get it? Well... :D
Haha, OK... I'll ask Jhonny to have a look as well. 😅 |
(defn coordinate-space-info | ||
"Returns a map of coordinate-space to sets of semantic-type that expect that | ||
coordinate-space. Only :semantic-type-position and :semantic-type-normal | ||
attributes are considered. We use this to determine if we need to include | ||
a :world-transform or :normal-transform in the renderable-datas we supply to | ||
the graphics/put-attributes! function. We can also use this information to | ||
figure out if we should cancel out the world transform from the render | ||
transforms we feed into shaders as uniforms in case the same shader is used to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent info!
TODO: | ||
We should probably just deprecate this behavior, since it will confuse users | ||
that mix local-space and world-space attributes of the same type." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
(if (not scene) | ||
(g/defnk produce-scene [_node-id scene material-name->material-scene-info] | ||
(if scene | ||
(model-scene/augment-scene scene _node-id model-resource-type-label material-name->material-scene-info) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, didn't know this function existed!
(attribute vec2 texcoord0) | ||
(varying vec3 var_normal) | ||
(varying vec2 var_texcoord0) | ||
(defn void main [] | ||
(setq gl_Position (* gl_ModelViewProjectionMatrix position)) | ||
(setq gl_Position (* world_view_proj_matrix position)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, the gl_ModelViewProjectionMatrix is an old GL remnant that we should move away from!
@@ -870,6 +870,7 @@ | |||
(.destroy drawable)) | |||
(when-let [^GLAutoDrawable picking-drawable (g/node-value node-id :picking-drawable)] | |||
(gl/with-drawable-as-current picking-drawable | |||
(scene-cache/drop-context! gl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know we created a secondary context for the picking, why do we need that?
.gltf
,.dae
, etc.). Previously you'd only see the bounding boxes if you opened a.gltf
file in the editor.scene-cache
data associated with the OpenGL context used for scene picking hit tests after closing an editor tab.Fixes #8666.