馃寪 Translate:
A Brief Introduction to Multithreaded Programming and Unity's C# Job System
I recently finished all of Games104 on Bilibili. One lesson discussed multithreading and the Job System, so I decided to record some of the key points and introduce Unity’s C# Job System for parallel processing. Multithreaded programming means distributing program tasks across multiple threads so hardware can be used more efficiently and the program can be accelerated. Why do we need the Job System? C# itself provides APIs such as Thread.Start and TaskFactory.StartNew. How does the Job System’s multithreading differ from calling those APIs directly? Before discussing the differences, we need to understand the advantages and disadvantages of writing multithreaded programs.
Using DrawMeshInstancedIndirect in Shader Graph
When rendering more than ten thousand objects, it is common to use an API called Instanced Indirect. In Unity, this means calling Graphics.DrawMeshInstancedIndirect. Whether the shader is written in CG or SRP HLSL, this API can efficiently render a large number of objects. Rewriting a custom shader every time I want to use instanced indirect rendering is rather time-consuming. This is especially true for a pipeline such as HDRP, where the lighting calculations are more complicated and the cost of writing a custom shader is high. That led me to Shader Graph: shaders generated by Shader Graph can switch between SRPs with less pain, and modifying an effect is cheaper. A quick search reveals that Shader Graph does not support DrawMeshInstancedIndirect, but fortunately it can be made to support it. The implementation is hidden in Particle System GPU Instancing.
A Simple Verlet Integration Implementation in Unity
Verlet integration is an integration method for Newton’s second law of motion. It is commonly used for cloth simulation and for effects such as ropes and ragdolls. I first came across Verlet integration while researching ragdolls and happened to find Advanced Character Physics, a paper by a former Hitman developer. It explains how they had to make dead NPCs produce convincing ragdoll effects (the player had to be able to interact with and drag them, for example) while keeping the ragdoll calculation lightweight. Treating every body part as a Rigidbody was presumably impractical (it was the year 2000), so Verlet integration was the method they used to calculate ragdoll motion.
A Custom Lighting Shader in Unity URP
The toon-rendering shader I made on a whim has been published for a while, so I am writing these notes to help organize my thoughts. Most Chinese-language resources about custom lighting shaders in Unity stop at the Built-in Render Pipeline. There are fewer resources for the Universal Render Pipeline in the SRP family, but because SRP is open source, tracing the source code makes it fairly easy to understand the entire rendering process of a lit shader.
Implementing a Toon-Rendering Shader in Unity
Toon rendering, also called NPR or toon shading, may be the rendering style most commonly used by Unity developers besides Unity’s built-in Standard shader. I wrote a toon-rendering shader a few months ago; below, I divide its key features into the following areas. Ramp-based diffuse lighting Stylized specular highlights Rim lighting Outline effects Specular highlights on hair Halftone overlay Hatching overlay Custom shadow color A custom material editor Other details Ramp-based diffuse lighting Among the many common lighting models, the Lambert and Half-Lambert models are the most commonly used for diffuse lighting. The result of dot(normal, lightDirection)鈥攚hich I will call NdotL鈥攃an give an object’s surface a basic diffuse-lighting response.