STK-BI: Previewing STK Materials in Blender

STK-BI: Previewing STK Materials in Blender

Postby Anon » 25 Mar 2015, 08:30

Shoutout to Affray Studios!

TL;DR: I've made a material for Blender's GLSL viewport shading mode that can simulate the STK render engine pretty closely. This should help with the materials workflow for STK.

Introduction

A few months ago, samuncle submitted an issue on the bug tracker that mentioned how much time it takes to tweak and test gloss maps for the STK engine. The main problem seems to be how the game has to be reloaded for every change that occurs in a gloss map, since there's no external tools for previewing them. In a comment, I suggested that a recreation of the STK rendering components using either the Blender Game Engine or Blender Internal's material nodes system could expedite the process, but nobody (myself included) seemed to be too interested in the idea at the time.

Over the past week, I've been working on a project in the Blender Game Engine. One limitation that I encountered early on was the inability to easily control the hardness of specular reflections with Blender Internal's node system. I addressed this issue at first by making a nodegroup that mixed the diffuse and specular components of a very rough material with variable exponents to control roughness and hardness. I called this nodegroup "shaderUber", but there was nothing "uber" about it. It was very inelegant, physically inaccurate, freaked out when the light was not the exact strength it expected, and could only render a single specular highlight at a time. So, two days ago, I sat down and created a proper nodegroup with actual shading models to replace it.

I've now taken that nodegroup, and adapted it to use STK-format gloss maps. What this means is that it's now possible to use it to preview materials for STK inside the Blender window itself. To show what I mean, here's the same model with the same textures rendered in the STK Antarctica Engine and displayed in Blender's 3D viewport:

1_5_reference.jpg
Rendered in Supertuxkart


1_5.jpg
Displayed in Blender

As you can see, it's not exactly the same. This is because STK actually computes reflections based off of the skybox, while my reflections are just glorified sphere mapping... however, the specular and diffuse components are pretty spot on, and while the reflection itself is off by a fair amount, the reflectivity, which is more important in determining the feel of the material, should be pretty close.

Here's another comparison, this time showing not only the specularity and hardness components of the glossmap but also the light emission (blue channel):

glowstk.jpg
Rendered in Supertuxkart

glowbi.jpg
Displayed in Blender

(The differences in colour are caused by STK and Blender interploating differently across the 8-pixel-tall image)

And here's a picture of the nodegroup being tested on Suzanne's Kart:

1_6_suzanne.png
Displayed in Blender

You can download the file containing the material here.

Basic Usage

1. Download the file above.
2. Open the object you want to assign materials to in Blender.
3. Set your render engine to either "Blender Internal" or "Blender Game'.
4. Append the one material from the above file into your current file. This will bring in three lamps as well.
5. Assign the new material to your object.
6. Open a material nodes editor and select your object.
7. In the material nodes editor, assign your diffuse, normal, and gloss maps to the "Diffuse Map", "Gloss Map", and "Normal Map" nodes in the "Setup" frame. These are texture nodes, so you'll have to make a new texture in Blender Internal for each image before you can assign it to a node.

Everything should be working at the most basic level after you've done the above. If you don't have a gloss or normal texture, you can just leave the texture selection in the corresponding node empty. If you don't have a diffuse texture, you can disconnect the first texture node and manually set a colour in the "Diffuse Map (Colour)" input of the "STK Preview" node.

You can also edit the colours and orientations of the new "STK Preview Sun", "STK Preview Sky", and "STK Preview Ground" lamps to be closer to the track your material is meant for. If you want shadows, you can set the render engine to "Blender Game" and enable and configure them in the settings for the "STK Preview Sun" lamp.

You might also notice a "Custom Lamp" node below all the texture nodes in the material nodes editor. You can set an additional lamp here by selecting one from the dropdown. Spot, Sun, and Point lamps should just work without any tricks. Hemi lamps can be simulated with the "Hemi" setting on the "STK Preview" node, which is best used alongside a low "SpecFac". Again, shadows can be enabled per-lamp in lamp settings and configured in the "Blender Game" render engine.

Advanced Usage

Additional Lamps

You can add additional lamps by editing the "shaderGeneral" nodegroup, which is nested inside the "STK Preview" group. To do this, simply duplicate one of the "shaderGeneralLight" nodegroups and connect its "View Vector", "Normal", and "Roughness" inputs to the same nodes as all the other ones. Then, connect the "Lamp"/"Light" settings to a "Lamp Data" node set to the lamp you want to enable. Take the "Diffuse" output, and use a "MixRGB" node set to "Add" to add it to all the other diffuse outputs. Do the same with the specular, but use another "MixRGB" to multiply it with the same node as all the rest first.

Normal Maps

By default, the normal map format should be the "Normal" output of a texture node. If it's not possible to use this output however, an alternative is to remap the RGB values of the normal map image colour to the (-1,1) range. Or it is when colour management feels like playing along...

Alternate Reflection Textures

The material comes with a reflection texture that I found in the public domain. If you want to use your own skydome or other texture for reflections, you can set a different set of images by editing the textures named "STK Preview Background", or replacing the images of the same name. Do note that you will need to specify three textures of varying degrees of blurriness.

Greater Accuracy

I've managed to get the material's behaviour pretty close to the STK engine IMAO, but it's still not perfect. If you want, you could try to improve the look by editing the "STK Preview" nodegroup, or if you're really feeling masochistic, "shaderGeneral". There could be many ways to approach this... probably the best would be to find out as many equivalent sets of Roughness/Metallic and GlossmapR/G values as possible, then create a function that translates from one to the other. It'd probably be best to ctrl-X' the Math nodes left of and MixRGB nodes right of the "shaderGeneralLight"'s in "shaderGeneral" before doing this though, since those are really just an ugly hack to make the specularity look right.

Technical Details

Below is a tree that displays the hierarchy of nodegroups and frames in this material, loosely describing what each nodegroup does and the operations that take place within it.

  • STK Preview (Material Nodes Root)
    • Preview material. Emulates STK Antarctica Engine
    • Setup (Frame)
      • Contains most user-defined inputs to the material. Has texture nodes for Diffuse Colour, Gloss, and Normal Map. Also contains option to select a custom lamp.
      • Can be severed from "STK Preview" in order to enable manual inputs on the latter.
    • STK Preview (Nodegroup)
      • Location for choosing SpecFac, Energy, and Hemi settings for custom lamp.
      • Contains Lamp Data nodes for all fixed lights. Inputs outputs into shaderGeneral.
      • Should in theory have L1-L3 energy levels set so that identical Lamp Colour values in STK and Blender will produce identical lighting effects.
      • Takes STK-format inputs and outputs a simulation of the STK Antarctica engine.
      • Translates STK-format gloss input into Roughness and Metallic values for "shaderGeneral".
      • Adds base diffuse texture to output of "shaderGeneral" using gloss-glow as a factor.
      • shaderGeneral (Nodegroup)
        • The meat and potatoes of the material. Derived from another project and responsible for all the lighting calculations of the material.
        • Takes Diffuse Colour, Normal Map, Roughness, and Metallic values as input, in addition to data for four lamps.
        • Uses output of "shaderNormalmap" for all calculations.
        • Includes one "shaderGeneralLight" for each lamp. Outputs are added together to get diffuse and specular lighting of material. In the case of specular, an (inelegant) multiplication operation is performed first to recreate the ultra-bright specular reflections in the Antarctica engine.
        • Scales, mirrors, and tiles reflection texture coordinates outputted by "shaderReflection" in order to simulate an increased field of view in the reflection. Necessary due to reflection textures not being true sphere maps.
        • Mixes reflection textures of varying blurriness using Roughness input to create reflection component.
        • Mixes reflection component with Color input using Metallic input weighted with "shaderSchlick" as factor to create diffuse colour. Uses Multiplication mix mode instead in parent project due to metals tinting their specular highlights in the real world. Vector Math Subtraction and Addition nodes in center can probably be removed; they don't seem to actually do anything (a-b+b).
        • Multiplies diffuse colour with diffuse lighting to create final diffuse component. Does the same with specular in parent project with Metallic value as factor, again due to metals tinting their reflections in the real world.
        • Averages diffuse component with specular component to create final material shading (sans glowmap).
        • shaderNormalmap (Nodegroup)
          • Takes View Vector, Surface Normal, and Normal map as input. Outputs Surface Normal with Normal Map applied.
          • Broken in current upload.
          • NOT IMPLEMENTED IN CURRENT UPLOAD Turns normal map vector input into angle and rotates by surface tangent to transform it from UV-space to the camera-space that all other calculations are done in.
          • NOT IMPLEMENTED IN CURRENT UPLOAD Material (Node)
            • Special material with a normal map that outputs the surface tangent as a vector in camera-space through its Normal output.
          • Adds normal map to Surface Normal to create final normal. Effect of normal map is weighted with the dot product of the surface normal and view vector to eliminate back-wards facing normals.
        • shaderReflection (Nodegroup)
          • Takes surface normal as input. Outputs texture coordinates for sphere mapping-like effects with a rectangular texture.
          • Uses average of View Vector and (0,0,-1) for calculations, for greater "accuracy" with objects near edge of field of view.
        • shaderSchlick (Nodegroup)
          • Implementation of Schlick's approximation for fresnel effects.
          • Takes View Vector, Geometry Normal, and Light Vector as input. Outputs fresnel factor.
        • shaderGeneralLight (Nodegroup) (X4)
          • Takes one set of camera, geometry, material, and lamp data as input. Outputs diffuse and specular components for that lamp.
          • Averages surface normal used for diffuse component with light vector based off of Hemi input. Used to simulate Hemi lamps by shading faces as if they were pointing towards the light source.
          • Converts outputs of shaderCooktorrance and shaderLambert into usable formats. Clips values below 0, incorporates lamp falloff, strength, colour, shadow, data to output final diffuse and specular components for input lamp. Specularity is multiplied by user-specified SpecFac.
          • shaderLambert (Nodegroup)
            • Your basic Lambertian diffuse reflectance model. Nothing too special.
          • shaderCooktorrance (Nodegroup)
            • Implementation of the Cook-Torrance specular reflectance model.
            • Only place where Roughness input of shaderGeneral has any effect on lighting.
            • shaderBeckman (Nodegroup)
              • Implementation of the Beckmann physically based microfacet distribution model
            • shaderSchlick (Nodegroup)
            • Geometric Attenuation (Frame)
              • Geometric attenuation term for Cook-Torrance shader. Simulates self-shadowing due to microfacets. TBH I didn't really bother to check out how these shading models work, but I assume that this refers to the tendency of light to bounce between microfacets and lose energy that way. Or actually, it might bethe shadows cast on microfacets by neighbouring bumps?

Future Possibilities

Automation Addon

Right now, the artist using this material has to create a new material and assign textures for every image. A Blender add-on could probably be written which automates this process, assigning materials for faces depending on their face textures and the STK image properties.

More Accurate Node-Based Shaders

The material I've presented here wasn't made to be used for previewing Supertuxkart materials. I made it without even thinking of the game, and really created this version as an afterthought. As a result, it likely uses completely different shading models and (does use) a bunch of ugly tricks to make it look right. However, Blender's node system seems to provide all the information needed for most shaders. Consequently, it might be possible to use it to recreate the actual Supertuxkart shaders. I am not going to be the one to do that, however :twisted:

Viewport GLSL

There's a Blender development project that promises to implement better viewport rendering (beginning with 2.74 actually, which should be coming out any day now). One of the features is going to be using GLSL scripts in the viewport. TBH I have very little idea what that is or what it means, but it sounds like it might make it easier recreate the STK shaders...?

Physically Based Rendering

According to the STK Wiki, the Antarctica engine will soon (or "eventually". I don't want to put any pressure on the devs :p ) sport physically based rendering. It sounds as if it should be pretty similar to the current version of my shader in the original project I took it from, so it might be possible to just use that in the future. The only differences seem to be the usage of CGX as opposed to Beckmann for microfacet distribution (they're basically identical up to roughness 0.75, after which Beckmann is slightly brighter), the usage of some fancy Disney-made heuristic for Diffuse reflection light as opposed to my custom Lambert * Weighted Schlick formula for diffuse, and of course, actual reflections (which I have no intentions of implementing in my project).

Conclusion

To end, I'd like to leave you with this gif of Xue dancing (rendered with this material, of course):

Image

Known Issues

  • Behaviour with specularity values below 0.125 is untested.

  • Power nodes with dynamic inputs and exponents of 0.5 cause entire shader to render as orange on Windows
    • Tested on Win8.1 with nVidia geForce 610m
    • Easily fixed by changing exponents to 0.51 (or some other similar value)
  • Normal maps are sometimes inverted
    • Easily fixed by changing "Vector Math" node in "shaderNormalmap" from "Subtract" to "Add"
    • Actually caused by normals being relative to face/UV space and not camera space. Might not be trivial to fix.
    • Fixed in latest version of parent project (note to self: import fixed "shaderNormalmap" into this file as part of next version (ttm/engine/ version > 1_74.blend))
  • Orthographic view breaks reflections
    • Not a big enough issue to spend time on IMAO, let me know if it actually impacts the shader's usefulness
  • Latest versions of "shaderGeneral" and "shaderGeneralLight" have been refactored and modified for vastly improved physical accuracy (in original project)
    • Not a bad thing, but means that they're now less compatible with this STK variant. So it will be harder to merge improvements from them into this material.
    • Might be worth it to rebuild this shader from the ground up as well, using the already-completed phong, lambert, beckmann, cooktorr, etc nodegroups

Last edited by Anon on March 30th, 2015, 6:36 pm, edited 7 times in total.
Last edited by Anon on 26 Mar 2018, 10:32, edited 8 times in total.
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby XGhost » 25 Mar 2015, 15:10

WOW!!! These are absolute fantastic news!!! :o :)
This is very useful for artist. Thank you very much for this awesome work, it looks beautiful!! I will test it by myself asap.
I am very thrilled by your knowledge of blender.
User avatar
XGhost
 
Posts: 147
Joined: 02 Jan 2014, 15:49
Location: Zurich (Switzerland)

Re: STK-BI: Previewing STK Materials in Blender

Postby samuncle » 25 Mar 2015, 15:22

\o/ I'm speechless :).

I need to test that as soon as possible :)

I will write a more detailed answer a bit later.
Image
User avatar
samuncle
STK Moderator
 
Posts: 752
Joined: 16 Mar 2010, 21:28

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 26 Mar 2015, 00:18

@XGhost, samuncle:

Thanks for the nice words!

I'd like to request as much feedback (or maybe even greater contribution :think:) as possible on the accuracy of this shader. Since the reflection mapping, shading models, etc are already completed, the biggest thing needed to improve its quality is just more testing and iterative refinement. So far, I've only tried it with the two examples shown in the first post, plus some models and textures from the media repository. I guess the inconvenience of reloading STK for every gloss map change is holding back this material as well ^^.

There's a lot of different scenarios that I haven't tried with this setup and I honestly don't feel testing all of them myself... too many possible combinations of lamp colour, material colour, normal mapping, and specularity. So what I'm asking is that if anyone finds that this system behaves inaccurately with some inputs, then they report it so that it can be fixed (rather than just putting the thing down).

Of course, I'd also appreciate it (and help them) if someone felt like taking it onto themselves to tweak and perfect this material ;) (it's licensed under CC-BY-SA 4.0).
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby GunChleoc » 26 Mar 2015, 23:03

I'm not a Blender artist, but I expect it will save artists lots and lots of time. Well done! :)
User avatar
GunChleoc
 
Posts: 502
Joined: 20 Sep 2012, 22:45

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 26 Mar 2015, 23:43

@Gunchleoc: Thank you :)
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 26 Mar 2015, 23:47

I've just tested the project that this shader is derived from on Windows for the first time, and found that it doesn't work (it renders as pure orange). There's a super-easy workaround, but I'd like to confirm that it's broken before uploading a new file. Can someone on Windows please tell me if it works?

If anyone runs into this problem now, it can be fixed easily by changing all "Power" "Math" nodes with exponents of 0.5 to 0.51 (or any other number that's not 0.5).
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby XGhost » 27 Mar 2015, 21:07

I have tested your project and it works very well! I can't reproduce your issue with the orange shader on Windows (Windows 7 / Blender 2.73a) and neither on my Mac (OS X 10.8.x / Blender 2.73a). So for me it looks fine ;) .
The simulation is pretty close to the graphics engine that STK uses, congratulations on that! Maybe the gloss is a little bit (but just a skosh) too glossy :) . I personally will use this in my future stk projects even if it needs a bit of time to setup everything. But overall it is very helpful!

Once again thank you very much for your work! As a little thank-you I attached Tux, rendered in Blender :kiss: .
Cheers
Attachments
tux_preview.png
User avatar
XGhost
 
Posts: 147
Joined: 02 Jan 2014, 15:49
Location: Zurich (Switzerland)

Re: STK-BI: Previewing STK Materials in Blender

Postby GeekPenguinBR » 27 Mar 2015, 23:12

Well, I'm not a Blender user (actually, I know nothing including the basic modelling) :( , but it's clear for me that you done a very good job. Congratulations! I hope this may be used in many tracks of STK in the future.

The karts are very good too. Congratulations Anon (Xue) and XGhost (Tux).
User avatar
GeekPenguinBR
 
Posts: 466
Joined: 22 Mar 2014, 00:41
Location: Rio de Janeiro

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 28 Mar 2015, 00:50

@XGhost: Okay, it's probably not a big issue then. I actually couldn't reproduce it on another computer with the same file today either. I'll still introduce the workaround in the next version though.

And that's a very nice Tux kart. I'm glad that you find my work useful ^^


@GeekPenguinBR: Thank you! Although, I didn't make the Xue kart (and I actually butchered the animations a bit when I made it loop...)
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby GeekPenguinBR » 28 Mar 2015, 01:04

Anon {l Wrote}: I didn't make the Xue kart (and I actually butchered the animations a bit when I made it loop...)


Ok. I mean the animation using the new material/lights.
User avatar
GeekPenguinBR
 
Posts: 466
Joined: 22 Mar 2014, 00:41
Location: Rio de Janeiro

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 31 Mar 2015, 04:24

Bump (I've updated the Future Plans section at the top, added a Known Issues list and finished the Technical Overview)
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby Arthur » 01 Apr 2015, 23:24

Really good work! Can't wait to see what this can make possible. :)
Hey pal, I took an oath for justice! "In happy days or tightest tights..." or something like that.
User avatar
Arthur
 
Posts: 1073
Joined: 06 Dec 2009, 00:49

Re: STK-BI: Previewing STK Materials in Blender

Postby vlj » 04 Apr 2015, 18:56

Anon {l Wrote}:Physically Based Rendering

According to the STK Wiki, the Antarctica engine will soon (or "eventually". I don't want to put any pressure on the devs :p ) sport physically based rendering. It sounds as if it should be pretty similar to the current version of my shader in the original project I took it from, so it might be possible to just use that in the future. The only differences seem to be the usage of CGX as opposed to Beckmann for microfacet distribution (they're basically identical up to roughness 0.75, after which Beckmann is slightly brighter), the usage of some fancy Disney-made heuristic for Diffuse reflection light as opposed to my custom Lambert * Weighted Schlick formula for diffuse, and of course, actual reflections (which I have no intentions of implementing in my project).


STK uses the classic blinn phong brdf model, the response is (H.N)^a where H is the half vector (ie normalized light + view sum vector) and a is computed from glossyness.
Issue is that alpha is basically unbound (in contrary to GGX where gloss coeff is between 0 and 1) and thus it makes IBL reflexion quite bad (which is apparent on your first screenshoot).
But GGX didn't please samuncle so it didnt make it into stk.
vlj
 
Posts: 58
Joined: 27 Dec 2013, 04:22

Re: STK-BI: Previewing STK Materials in Blender

Postby Anon » 04 Apr 2015, 23:24

Hi vlj, thank you for the information!

I actually tried to create a new version of this Blender material that uses Blinn-Phong yesterday, but there were couple of things that I couldn't figure out.

Specifically, how exactly is the exponent in Blinn-Phong computed from the glossmap's red channel? The closest I got was to first normalize the RGB value to the (0-150) range, then add 2. This didn't seem to be recreate the extremely sharp specular highlights that Antarctica renders with high sharpness values, though.

I'd also like to know how the specular and diffuse components are combined. The lack of diffuse shading with a specularity of 1 led me to believe that the two values are simply mixed together using the glossmap's green channel to blend between them. Trying this however, I found that I could not reproduce Antarctica's behaviour with specularity values around 0.1-0.4. It seems that direct specular highlights are basically constant in strength in STK with spec values above 0.15-ish, while the specular IBL reflections are slowly blended in. How exactly does this work?

Thanks in advance!
Anon
 
Posts: 208
Joined: 03 Jul 2014, 16:30

Re: STK-BI: Previewing STK Materials in Blender

Postby vlj » 05 Apr 2015, 19:01

Code is in stk-code/data/shaders/utils/SpecularBRDF.frag

the exponent is exp2(10. * roughness + 1.); with roughness the value (between 0 and 1) from the red component of the texture
(it's the same formula as the one used in Remember Me btw)
You're right, green channel is used as a mix coefficient between pure diffuse and pure specular.

However all these values are stored in a floating point buffer, which is then remapped to [0, 1] with tonemap post process pass in
stk-code/data/shaders/tonemap.frag

I think it's possible to do tonemap directly in the blinn phong shader (afaik blender does not support GL 3 and so float texture are maybe not available).
vlj
 
Posts: 58
Joined: 27 Dec 2013, 04:22

Who is online

Users browsing this forum: No registered users and 1 guest