A good way to capture GIFs

When I look back at all of the documentation I wrote for artists, and a lot of the conversations I’ve had with art leads and directors – one of the most critical ways to communicate changes, or instructions was to provide animated gifs. I’m not a huge fan of video tutorials – they typically are too long for the amount of content they cover and are typically very barebones and hard to use as reference. On the flipside, a long wall of text with dozens of images can also be hard to digest.

A happy middle ground I’ve found has been short text blurbs with animated GIFs. GIFs loop, they can be fairly long and add a lot to the wow factor. They are also much easier to embed onto online wikis like Confluence – infact they are just as easy as images, simply drag and drop or copy/paste into the text.

And thanks to GIFCam – they are just as easy to make (and it’s free!) : http://blog.bahraniapps.com/gifcam/

Just like FRAPs, GifCam is great when capturing openGL and DirectX applications, and was the best way to document and demonstrate material and tool workflows.

 

Python and images

During mid-development of Batman and Walking Dead Season 3,  an artist requested the ability to strip out alpha from textures without having to necessarily open it up in Photoshop. As it turned out, she noticed that Substance Painter had been exporting images with an alpha channel, regardless of whether or not it was using it. While this has been fixed in more recent releases of Painter, I ended up using part of the script to basically get a better understanding of how assets were being generated by the art department. Keeping track of it helped get ‘easy wins’ when it came down to optimizations, as having an alpha channel in a texture that wasn’t being used just took up more memory.

There are a number of image manipulation / operation modules available for Python – but I found PIL ( https://pypi.python.org/pypi/PIL ) to be fairly straight forward to use when analyzing targas – the texture format of choice at Telltale. Below is a snippet of how easy it is to find textures with an alpha channel and strip them out. At Telltale I ended up passing the file-list to a QListWidget and connected a QPushButton to a function to re-save.

for tga in fileList[:]:
			
			print ("Processing {0}").format(tga)
		 	TGA = Image.open(tga)
		 	if TGA.mode == 'RGBA':
		 		print ("Found Alpha channel")
		 		try:
		 			TGA = TGA.convert('RGB')
		 			TGA.save (tga)
		 			print ("Successfully saved without alpha")
		 		except IOError as e:
		 			print ("Couldn't save - please make sure the file is checked out")
		 		finally: 
		 			pass

Looking at this old code I noticed I unnecessarily use fileList[:]  instead of just fileList . I’m not sure why I used to do this, but it’s definitely not something I do anymore.

A full list of image modes can be found on the PIL docs here: http://effbot.org/imagingbook/concepts.htm#mode , but as a tech artist in games you’ll probably run into L, RGB and RGBA the most.

First posts are always the hardest

Many moons ago, I did some contract work for the now non-existent Maxis team over in Emeryville, California (not to be confused with the Maxis team in Redwood Shores that works on the Sims).

We had an issue with a lot of copy and pasted assets in Maya – as it happens that Maya absolutely loves to append ‘pasted__’ into the namespace of transforms, mesh shapes and almost every node that ends up being pasted into the Maya scene. While Maya has the ability to search and replace names on transforms and mesh shapes in the Maya scene, it did not and still does not have the ability to clean up the hypershade nodes – which can lead to fairly unreadable hypershade, as at some point you’ll have scenes with material names similar to ‘pasted__pasted__pasted__blinn3’.

One of the artists made a script that removed ‘pasted__’ from the material names, but unfortunately only removed the first instance. While I never ended up looking at the script at the time, I imagine he simply wrote something to check the first x characters and remove if it matched. This lead artists into having to run a few times to clean up the hypershade.

When I eventually worked at Telltale, I noticed the art team had similar issues, except it was much worse as the production times for each episode of the game were very short, and a lot of copy and pasting was used – either through the standard Ctrl+C/Ctrl+V or through a custom import script.

I ended up writing the below script to catch all instances of a defined set of characters via regex – as I did not want artists to have to click on buttons multiple times.

# Author : Farhan Noor 7/13/2015
# Hypershade Cleanup
import pymel.core as pm
import re


def renameHypershadeNodes(hypRemove, hypReplace):
    
    hypSelection = pm.ls(type='shadingEngine', mat=True)
    print hypSelection
    for shadeNode in hypSelection:
        if re.search(hypRemove, str(shadeNode.name())):
            print (("Renaming %s to %s") % (
                shadeNode.name(), shadeNode.name().replace(hypRemove, hypReplace)))
            shadeNode.rename(shadeNode.name().replace(hypRemove, hypReplace))

renameHypershadeNodes("pasted__", "")

Note that we did not care about the file texture nodes – only the materials themselves as the names were baked into the mesh export, so this doesn’t really look at any other nodes. You can easily adjust the file texture nodes by adjusting to look for type=’ftn’.