That's a very cool intro to a variety of shader techniques, especially post-processing effects.
What's even more wild, is that modern engines include all of this stuff out of the box, you just have to tick a few check boxes to enable them in your game. :) For example, check out these postprocessing filters built into Unity and Unreal - a ton of person-hours went into these:
I agree with you, however in almost all commercial games that I worked on, we do write our own shaders. For simple shaders, artists use directly a graphical tool included in unity for shaders authoring without writing any code, for complex ones we write our own code.
Oh sure, and especially for custom materials with specific lighting or masking properties, or for tweaking instanced meshes, etc. The standard materials only get you so far.
But post fx like bloom or vignette? I'm okay using a stock shader for that, it's not worth spending the time on building one from scratch. :)
do you write them completely from scratch or do you write custom nodes for whatever node-based shader editor you use? I am a novice when it comes to shaders but I wonder about the performance difference between hand written shaders vs generated from a node-based editor.
Nowadays it's more valuable to create custom nodes to enrich the node-based editor library. Sometimes we write shaders from scratch if we need to implement some original lighting, materials, etc
Especially if it's a 'smaller' game with mechanics that are unique. I just wonder if there are any good resources for the basics that a game engine needs.
The advantage of writing your own "game engine" is that it would only have the exact set of features you need for your game, and it would make the things you need to achieve as fast and as easy as possible.
This means traditional advice for "the basics of a good game engine" doesn't really apply, because if you're just making a bog standard game engine you're wasting your time and making a crappier version of Unity or Unreal.
THREE.js[0] is high enough level that it solves some basic problems (hierarchies of objects, basic materials, basic lighting, rendering pipeline) and low enough level that you still have high granularity control (you can roll your own shaders, lighting, render order, etc).
I don't know if anything like THREE exists for OpenGL, though.
The upshot of THREE is its super easy to develop with (alls you need is a browser). The downside is that it slows down very quickly for even simple things.
I've been looking for something like THREE.js for C++ for years now, to the point where I actually started developing my own. But due to my inexperience with large codebases I have a hard time doing something like it that looks good and works well.
(I am a security analyst, not an engineer, but I'm transitioning to engineering roles now, so this might change in future, who knows :) )
For a general reference I would look at Jason Gregory "Game Engine Architecture".
For a deep dive into all game engine topics I would recommend the Handmade Hero dev streams: https://handmadehero.org
(Note that Handmade is not a useful model for an actual game production, it's more like a platform for investigating cutting-edge engine topics, so you can pick and choose parts to get what you need. It's been going for years and remains mostly a tech demo.)
In languages that don't allow trailing commas, I prefer this comma-first style. It makes it easy to avoid missing or extra commas, which shortens my feedback loop a bit. But I usually don't use it, because a lot of people react the way you do, and I want you to be able to read and enjoy my code despite your irrational and bizarrely extreme prejudice.
I had never really thought about commas that way, but I can totally get why someone would want to use this style now. Thank you for taking the time to explain it!
I've noticed this formatting in sql scripts before too - the biggest benefit I see is making source control diffs only show one line changed rather than two when adding/removing lines.
Some languages/DSL's allow for a comma at the end of the list too, thereby getting the same result but without the slightly strange comma at the start of the line. Adding additional lines is simple then and doesn't cause the line above to be pulled in to any git action
What’s bonkers specifically? Is the the leading commas, alignment, one identifier per line, capitalization, long names, same line braces, something else?
Personally, I like what this looks like. Leading commas are nice in situations where the first argument is fixed, but the remaining arguments move a lot while I’m tweaking & refactoring. I also like leading operators in long multi line math expressions, it’s easier to see at a glance how everything is combined when the operators are in front. I also like seeing arguments aligned, it’s easier to spot mistakes, easier to move things around, easier to use column selection, etc.
I rarely actually use the formatting I like because at work my team uses clang format so we’re standardized. Despite whatever formatting opinions I like, I love not arguing about formatting and having the formatter dictate and handle it for everyone.
If you do a lot of adhoc sql with an editer that supports multiline editing, it allows for pasting in big lists of text and quickly formatting it, trailing commas and ragged edge right data suck to edit in bulk.
This is really nice! The same techniques can be used in WebGL 2.0 which is at ES 3.1 on canary versions of WebKit. I had a hell of a time using the experimental compute shader API to implement a cellular automata framework [1]
The big issue with using WebGL at the current moment, to do large scale sims, is that fragment shaders dont have an entire workload barrier capability - so you cant do interdependent work.
Compute shaders have full workload execution and memory barriers.
Just something to be aware of if you are trying to jerry rig fragment shaders to do more advanced things like HDR via min/max over all colors..there is no way to these kind of aggregates without calling the shader twice, unfortunately.
(I didn't know it was on the horizon until I saw your link). I wonder if getting to ES 3.2 is on the horizon as well? That would bring geometry and tessellation shader support.
> Using geometry shading will generally lead to worse performance, high memory bandwidth, and increased system power consumption. Assert if geometry shaders are used
Geometry shaders are not what you want. They should not have been included in GL ES, and I will fight their inclusion into WebGL 2.1.
Tessellation shaders are better, but still kinda ultimately useless.
Yes, I agree the performance is an issue in most use cases, but wouldn't you agree there is value in there being parity between WebGL and OpenGL ES? It's valuable for those of us who work with Emscripten to cross-compile apps for the web.
Those are two drastically different artstyles. Neither of them really are engine shader stuff, just someone drawing good textures in Photoshop.
Paper Mario is all hand-authored baked vertex colors and very simple textures. Artists spent a lot of time in Maya hand-tweaking each vertex individually, e.g. see my viewer here https://noclip.website/#ttyd/jin_00
Borderlands has some basic engine technology with outlines -- running a basic Sobel on the depth buffer to find depth discontinuities and drawing lines there, but most interior lines are on the texture itself. Lighting is also modified with a ramp -- the "raw" incoming radiance from lighting is thrown into an artist-authored lookup table and tweaked before being thrown to the shader. Normal maps are seldom used.
A very simple implementation of cell shading is to run the result of traditional lighting through a lookup table in the form of a 1D texture. Having runs and steps of solid color posterizes the smooth lighting input so that it resembles painted cell artwork.
A very simple implementation of outlining is to draw the object a second time solid black, with the vertex positions extruded out in the direction of the vertex normals, and with backface culling flipped so that you see only internal faces. Those black, internal faces peeking out around the edge of the regular mesh form the outlines.
What's even more wild, is that modern engines include all of this stuff out of the box, you just have to tick a few check boxes to enable them in your game. :) For example, check out these postprocessing filters built into Unity and Unreal - a ton of person-hours went into these:
https://docs.unity3d.com/Manual/PostProcessingOverview.html
https://docs.unrealengine.com/en-us/Engine/Rendering/PostPro...