Blizzard Projects
Check For Intersections
Created a more efficient way to check for intersections within meshes in Maya. This included intersections between different meshes, intersections within the same mesh's faces, and intersections in the UVs.
Embree was used as a fast BVH solution for finding intersections. It also required some updates of our TBB package in order to use a later version of Embree with the collision functionality. The process included transferring the polygon information from Maya to Embree, checking for intersections for each edge with the rest of the scene using Embree, and gathering those resulting intersecting faces and displaying them in Maya. Used openMP for parallelization and speeding up the process. Other improvements include adding a method for just quickly finding whether two meshes intersect each other. Check for bounding box intersection between meshes before going into Embree calculations. Have each mesh be a different Embree scene (to avoid repetition checks for the same mesh).
Embree could not handle 2D intersections well so a different solution was needed for UV intersections. Approaches tested were: using Embree but instead of using the default triangles uses user-defined shapes (edges) so I could specify the bounding box and intersection methods; using Box2D to create an AABB tree and find intersections between 2D shapes; using Embree but changing the edges of the UVs to be perpendicular to the faces; using the collision functionality in Embree (instead of the intersection one). These methods either failed to correctly find the UV intersections or did not provided sufficient speed up to finding those intersections.
The approach that was used for checking for UV intersections was to use OpenGL to rasterize the UVs and check for any overlaps using a 2 pass method. This allowed us to run this check in the GPU but required some additional tweaking. To avoid the edges giving false overlaps with itself, and additional pass was added were just the edges are drawn into a texture, and that texture is used to discard overlaps that occur at the edges. For UVs that are extremely detailed and small, which might not be drawn in the rasterization, I divided the UVs into different sections, making sure the groups would fill out the entire scene, so that each pass will have more detail and draw those small UV faces too. I used NVIDIA Nsight to profile the results and find areas that slowed down the process to improve them. For example, the ssbo in the glsl shader and the framebuffers with attached textures.
In addition, for this OpenGL process, we integrated all the mesh IDs in a texture as bits, so for every pixel in the texture I have the IDs of the meshes that tried to draw that pixel. There is a limit of 128 IDs I can store per texture (4 color values of 32 bits each) so if there are more than 128 meshes, I create the additinoal needed texture and combine the results from all textures. I encoded the mesh IDs by blending the colors being draw using bitwise operations. Then I decode the pixels individually in the CPU. This ended up being a bit slow to get the results, so instead I changed it to be done in a fragment shader (so it's done in the GPU instead). I changed the rasterization process to be done per-UDIM also for more accuracy.
Decided to use the Embree collision method for UV self-intersections. Required TBB updates. Tested how this would affect our different packages for TBB, Embree, and OpenVDB.
Integrated this new approach for finding intersections into our tool for finding intersections of an animation.
Used:
-
C++
-
Maya's C++ API
-
Embree
-
TBB
-
OpenGL
-
OpenMP
-
NVIDIA Nsight
Simplex Transfer Tool and Automated Splitting
In Simplex, transfer the different poses between two characters with different topology by creating a blendShape node for the new character and connecting the different expressions to it. Included a user-friendly UI.
In addition, I automated the GUI portion of splitting so that artists don't need to manually turn on check boxes, one by one, for all of the dozen of shapes required o split.
Used:
-
Python
-
Maya's Python API
-
Qt
Ptex Tools
We have some tools so that we can convert our UV data to ptex and vice-versa. In addition to some tools to be able to paint our ptex texture and visualize them. This tools were done before I started at Blizzard but I have been one of the main people maintaining and improving these tools in recent years.
One of the main projects improving our current process was allowing to work per-UDIM when mapping our ptex textures to UV. This helps provide the option of reduced time if the artists only wants some specific UDIMs in addition to allowing for more detail from the subdivision process since we can do the UDIMs separately. We use OpenSubdiv to subdivide the UVs to obtain more detail and then map the texture in OpenGL to be able to get the colors for the UVs. There is a limit to the amount of data we can pass to OpenGL so going per-UDIM allows for more detail in OpenGL since we are creating a texture per-UDIM. I also investigated the different options in OpenSubdiv to find the best results, such as Sparse Patch Tables and the face-varying interpolation options.
For testing purposes, I also included a simple command to be able to create a checkered ptex texture from and alembic mesh. This way we can easily visualize the results from the mapping of the ptex texture to UVs and the checkered design allows us to see the flow of the texture.
Used:
-
Ptex
-
C++
-
OpenMP
-
OpenGL
-
OpenSubdiv
Rigging Tools
Added some more components/templates to our proprietary rigging tool in Maya.
-
Added a tool to be able to layer multiple skinclusters.
-
Created a library to be able to use this functionality anywhere we need.
-
Includes a blendshape node to maintain the shape of the corrective mesh.
-
Tracking surface can be a different shape than the final mesh.
-
Works for nurbs surfaces too.
-
-
Created a wing template
-
Included the layout for the finger IK controls with FK controls at the start and end of fingers, the membrane controls and joints, and the overall functionality for wings including turbulence.
-
-
Volume preservation template
-
Provides a curve where we can specify the joints and controls for an are we want to preserve the volume for.
-
An example usage is for the chest area, so that when we pull the arm back the chest is able to maintain its volume.
-
Used:
-
Python
-
Maya
Transfer Weights Tool for Maya
Created a tool for Maya to be able to transfer skincluster weights between different meshes. It has a user-friendly UI that allows the user to select multiple meshes or components as the source and a group of meshes and components as the destination. Then it has different options to select the transfer method from barycentric or from closest vertex, transfer in local or world space, and transfer from the deformed topology or from the rest topology. It can copy the influences from the source components, and can also be used to copy the weights from one side to the mirror of it (like from the left arm to the right arm). Used Embree's BVH to be able to efficiently find the closest vertices from the source to the destination to be able to copy the weights from those.
The tool also includes the option to export weights into a JSON file and import them back from the JSON file.
Used:
-
C++
-
Python
-
Maya
-
Qt
-
JSON
-
Embree
Animation Transfer Tool using Maya's Human IK
Became the owner of the tool we use for transferring animations between humanoid characters in Maya. This involved a lot of support for new shows that had different requirements in addition to multiple improvements to make the tool more useful and efficient for the artists.
This tool gets a source animation, either from an FBX from motion capture or from an animated rig in the scene. Then we also have a database of skeleton and rig definitions we can match to the skeleton and rig to use for Maya's Human IK. The user can then specify a target asset and the tool will automatically load that asset, use Maya's Human IK to transfer the animation from the source to the target, and then bake that new animation in the target rig to be able to save it in a new Maya scene.
There is also the ability to attach a prop to specific prop joints of the characters, mainly in the hands, to be able to attach weapons and things like that.
This tool is greatly used along our motion capture process, in addition to also being used to be able to re-use animation from older shows in our newer ones.
Used:
-
Python
-
Maya
-
Qt
Tool for Generating Paint Meshes
The goal for this tool was to create an easier and more efficient way to create meshes for our surfacers to work on. Surfacing requires meshes that have a lot of detail to paint the UVs but at the same time there are some limitations to the level of detail we can provide them since Mari has some limitations. This requires some iteration to be able to get the proper mesh for surfacing and before this tool, it was the modeling department that needed to do this.
The tools, takes in an Alembic mesh, the user can also specify any shapes or UDIMs they want to work on specifically. Then the mesh is subdivided using Opensubdiv to perform the Catmull-Clark subdivision. After that, we displace the mesh along the normal based on it's ptex map, which has the sculpted detail. After that we do some polygon reduction to reduce the number of vertices of the mesh while keeping the detail to be more easy to handle. Currently we have two methods for the poly-reduction: using OpenMesh and using Houdini's polyReduce. OpenMesh provides a nice solution for decimating the mesh and it is open source so I was able to modify it to make sure the decimation handles the UVs. Houdini's polyReduce is a very effective node they have, which also handles UVs, but it requires to load a Houdini license which might not be ideal. The result is then exported as another Alembic mesh for the artist to use.
Used:
-
C++
-
Python
-
Alembic
-
OpenSubdiv
-
OpenMesh
-
Ptex
Other things I have worked on:
-
Alembic
-
AbcView
-
Simplex
-
Hackathon projects
Example of one of the recent cinematics we have released: