Skip to main content

New job once again!

Once again i left a company behind and joined another one. This time it's a major difference though, as i completely left the entertainment industry for now. I'm not leaving game dev, I'm still as fascinated by that topic as ever and i will pursue my passion in private, but from a professional point of view I'm out of games. At least preliminary.

And would you believe, from all fields of business, it's medicine. I'm not a doctor or a nurse in the slightest, instead I'm focusing on artificial dataset generation for AI training. What sounds like a boatload of vapor is merely a fancy description for creating a glorified character creator in Unity. It's pretty much another system as you have in games like Skyrim, just with a focus on artificial intelligence. It's quite a challenging task and I haven't been put in so much control of a project ever, but so far I can only say I love it. Being payed to code and do art in Unity is quite a dream come true for me.

So yea, we'll see what the future holds. I'm still a huge scatter brain about my own projects, but I have more time on my hands to work on them. The fact that I post here is already an attribute to that, as I was able to revamp my homepage project a little. The future looks bright for once!



Halftone Rendering in 3DSMAX

Some weeks ago there was a reddit thread about using a pseudo-halftone-shader in 3DSMAX. The solution there was a little more complex than what i thought it should be, so i played around and quickly ended up with something similar:


This look can be archived quite easily, you don't even need textures or special renderers for it, the standard scanline renderer from 3dsmax is good enough.


Map #1 Fallof

We start with a falloff map, which gives us a black and white version of the light on the material.

Make sure to set it on Shadow/Light

Halftone Dots

Then we need a base for our halftone dots. This is a simple gradient ramp map with some funky settings.

As dots are round, we will use the Gradient Type "Radial".

The dots will not adjust to the objects, but will be projected straight from the camera. As such set the coordinates to "Environ" and the mapping to "Screen". Then adjust the tiling to fit the apsect ratio of your final image resolution and the size of the dots. For 1080p, which is an aspect ratio of 16:9, i went the easy way and set the tiling to 160x90.


Map #2 Gradient Ramp for threshold

The next map is a gradient ramp, which combines those two maps and transform the resulting grayscale map to a straight black and white. We are using the values from the falloff map, hence set the gradient type to "mapped" and the source map to the falloff.

Next rightclick the middle gradient point and edit the properties. Here you can feed a map only to this one point and that's where we put the halftone dots map in.


Finally the map needs to be hard-cut to black and white. Open the output tab and enable the color map. Add two points to the map and arrange them something like this:


Now we have the basic halftone dot shader. All we need is some color.

Map #12 Gradient Ramp for Color

This is the easiest and most creative. Create another color ramp and set it to mapped. Add the previous gradient as a source and now select two nice colors for your halftone, kinda like this:


Halftone material

Finally the material to apply onto the object is a basic standard shader. Feed the color map into the diffuse and set Self-Illumation to 100%, as we don't want any "real light" to hit our material.


This concludes this tutorial.

You can exchange the halftone dots for whatever you want, as long as it has some gray tones in it. Also you don't have to duplicate the whole shader tree if you need another shader with a different color. Just feed in the gradient ramp for threshold into a new gradient ramp.

Have fun!

A little substance helper

Substance is an amazing tool, i think this can be considered a fact by now. At least i had a lot of fun tinkering around with substance designer since version 4 and so far it only improved in the right ways. Even the sour acquisition from adobe doesn't really stop my enthusiasm.

A little annoyance though is the boilerplate nodes you usually create before even you can start to experiment. Setup color nodes for metalness and roughness as well as the normal node plus creating a height output, etc... Nothing horrifying, but yea, it's annoying.


Hence i created a little node that takes care of most of this i call "Quick Height to Textures". It takes a color and a height map and outputs all the rest. Additional parameters for metalness, roughness and ambient occlusion add more variety. Again, nothing amazing, but it shortens the setup time to the juicy experimentation phase.




Not that that would be a surprise. But even with things that should be standard Maya finds ways to fuck things up. If you export an object as FBX from Maya, it exports the material with it. If you export the same object as  an OBJ-file, the .MTL-file (which has the material definitions) uses the shading group names as references! And of course, those have no direct relevance to the material name... Why, Maya, why?

"Bad UI"-Quicky #1

Because it's better to enable the "ignore" of a setting than have the setting itself actually enable something...


What's wrong with "Show in Outliner" and "Use Outliner Color"...? This happens when people don't think before implementing stuff.

Another funky maya quirk!

I'm trying to write a function that selects all top level objects that have a child object. In maya that's tricky. First we need to filter out top level objects

{obj for obj in ls(transforms=True) if obj.firstParent2()==None}

This works okay. But figuring out wether it has children is a tough call in maya, because:

Group objects are transforms without shape nodesShape nodes are the first child of transform nodesHence when you check a node, you cannot simply ask how many childs it has. If you filter for nodes with one or more children, you're basically get all meshes, cameras, lights and so on. If you filter for two or more, you don't get groups with only one child. Anyhow you need a lot of filtering for what should be a really small issue.

Maya scripting crap - The 3rd

I stumbled over some more marvels of maya scripting. This time it's about user interface layout. You see, sometimes you don't know the parent of a certain UI, so you have to ask maya. And how do you do that?

form = cmds.setParent(q=True)

Yes. You're pretending to set the parent, but actually get the parent! All because of that "clever" way of calling command in query mode. You hardly can get less python-codex than this.

Also there is a command called "iconTextScrollList". And it has nothing to do with icons. Nothing. Nada. Niente. How crude must the development of this program been that these kinds of errors/lazinesses happened...?

Installation routine programming in python for a 3d graphic artist workflow or how i made maya my bitch - Part 1

Every 3D artist who works with maya uses scripts. You'd be an idiot if you don't, as the base functionality of maya most often is not sufficient for every 3D modeling, rigging or animating task. But when you're in a bigger team (10 people) with a company-specific workflow, it's highly inefficient (or simply impossible) to work without a dedicated toolchain.

I wasn't sure whether i bit off too much to chew when i went on to set up the base for the toolchain at my company. My python skills and my understanding of maya's architecture sure improved over the last two years, but i felt nowhere near the level of security and control i felt with maxscript. But dang, i'd feel like the old man that i am if i would let myself scare away of that challenge!

The worldly conditions for the toolchain are pretty hefty:

  1. The target is an in-house engine and probably one of the most ill-conceived ones i've seen in my 15-year-life as a game artist. The story goes the management of this former purely 2D-focused company perceived 3D as a short-lived trend and the architecture of the engine reflects that. Add to that 3D-inexperienced coders and artists and you get an idea of the monster that i made myself a mission to tame.

  2. I'm only here for about 2 years now, but the company is far older (>20 years). Hence loads of structures are in place that i won't be able to change, no matter how much (or little) sense they make. The workflow for installing scripts was the old "copy it from the network in your script folder"-approach. Hence every artist has a different version of tools (if at all). Also due to loads of projects running pretty much parallel, every artist has different downloaded scripts that might tamper with the prefs. And ordering of new software is a painful chain of convincing superiors and waiting sometimes months for delivery. It's pretty much the wild west of 3D graphics and i'm only the deputy sheriff at best. At least i might not get shot...?

  3. Some programmers see artists more as a necessary evil, which over here seems to be grown over decades out of standard coder-artist communication differences. Creating tools for them is seen as an annoying distraction from their actual work. The philosophy "an engine is only as good as its tools to create content" is even in times of Unity3D and Unreal hardly widespread. Hence the in-house tools aren't more than a handful of buggy and unintuitive MEL-scripts. At the same time it seems the engine coders are overly protective of those hacky scripts. Conclusively i won't get rid of those scripts in the short run and will have to incorporate them in a safe way, until we manage to generate a more partner-like atmosphere.

  4. "Usability" is unknown or at best a futuristic concept around here. A script doesn't work? Well, obviously the user made a mistake! The general tools approach here boggles my mind to the point that i actually question whether the year is really 2017. As far as i understand it's a result of the company atmosphere, which is often more interested in holding somebody accountable than to actually fix a problem. And as long as "usability" is not a measurable value, it's easy to shift the blame for inefficiency between artists and coders.

  5. On the shaky plus side is the fact that projects here take "only" around 6 months and due to the inefficiency of the tools and the feedback loop, it's easy for me to make loads of iterations and tests in various workload-conditions on the tools.

So far so scary, lets research what we got on the technical side!

  1. MEL is a horrible scripting language. Its style clearly resembles a UNIX shell. I wouldn't want to code a toolchain as batch-files and as such i won't even consider using MEL.

  2. This only leaves python, which thankfully is the quasi-standard nowadays for technical artists. But which implementation to choose? With the quality of python there comes the quantity of options: Maya Python, PyMel, Maya Python API 1.0, 2.0, PySide, ... We don't want to over-engineer the codebase, as i seem to be the most python-adept around here (not a huge bar to jump though) and don't have or want to have the sole control over the toolchain. I really want to encourage collaboration with this one and further a sorta "band of brothers"-approach between the tools guys. Shit might hit the fan and i don't need pointy fingers then.

This background evaluation concludes Part one. Lets see when i get to the next one.