TA Log

Created: March 21, 2022 12:23 PM

HLSL

float is 32 bits. It is for world space position, texture coordinates, trigonometry or power/exponentiation.

half is 15 bits. It is for short vectors, directions, object space positions, high dynamic range colors.

real is half in default if the platform supports it. It can be either half or float in a function

fixed is not supported in HLSL. Old CG syntax.

Data type does not matter on PC GPUs, because they always use the high precision. Mobile GPUs might have issues on precision.

Global Illumination

The slow computation of real-time indirect light is usually not suitable for video games. But Unity uses Baked GI: it calculates the static objects’ indirect light ahead of time to save the computation time.

Light Probes are the positions where Unity measure in the baking. Non-static objects can use the value from the closest probes to approximate the indirect light.

Trick

Modifying the skybox along with the directional light might create a time-of-day effect. (Procedural skybox.)

Bézier Curves

or splines.

Interpolation

Lerp: Linear interpolation calculates the blended result between two points.

Quadratic Bezier Curve: Calculate 2 lerp between 3 points, and calculate the 3rd lerp between 2 results.

beizer

Cubit Bezier Curve: repeat the same process between 4 points. This is also “De Casteljau’s Algorithm”

beizer

A = lerp(P0, P1, t)
B = lerp(P1, P2, t)
C = lerp(P2, P3, t)
D = lerp(A, B, t)
E = lerp(B, C, t)
P = lerp(E, E, t)

// Expanding the lerp to mathmatical equations, we will finally have:
// Bernstein Polynomial Form
P(t) = P0 ( -t^3 +3t^2 -3t +1) +
			 P1 ( 3t^3 -6t^2 +3t) +
			 P2 ( -3t^3 + 3t^2) +
			 P3 ( t^3)

$$ P(t) = P_0(-t^3 + 3t^2 - 3t + 1) + \ P_1(3t^3 - 6t^2 + 3t)+ \ P_2( -3t^3 + 3t^2) + \ P_3(t^3) $$

Bernstein Polynomial form trades weights between 4 vectors, so the sum of the weights is one.

Derivatives

The 1st derivative P’ is the velocity of the vector given t value in the curve. It’s the rate of change. The 2nd derivative P’’ is the rate of the change of velocity, the acceleration. The 3rd derivative P’’’ is Jerk (Jolt). It’s a 2D constant.

The 1st derivate is also tangent of the curve. Normalizing it will give us the tangent vector, and normal vector by rotation of 90 degrees.

Curvature

$$ k = \frac{det(P', P'')}{ \lVert P' \rVert ^{3} } $$

Curvature is “how bent the curve is at a point.” Curvature is 0, then the curve is flat. The unit is rad/m. or reciprocal of radiance. Or the reciprocal of the radius of a circle with the same curvature.

$$ r = k^{-1} $$

We can calculate the osculating circle by r.

At the inflection point, the sign of curvature will change. It passes through zero and can not define an osculating circle.

Bounding Box

Soft Particles

Calculate the alpha values for fading particles based on the depth to the background pixel. Examples are fire on the ground and smoke in the higher place.

softparticles

// near and far
// usually near should be smaller than far, the default should be 0 and 1. 
// they are both offsets on depth
// if the near and far are too big, the particle might appear behind the background pixel.

// first we calculate the rawDepth
float4 positionNDC = positionCS * 0.5f;
positionNDC.xy = float2(positionNDC.x, positionNDC.y * _ProjectionParams.x) + positionNDC.w;
positionNDC.zw = input.positionCS.zw;
float rawDepth = SampleSceneDepth(positionNDC.xy / positionNDC.w);

// then we calculate scene depth and this fragment's depth
float sceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float thisDepth = LinearEyeDepth(params.positionWS.xyz, GetWorldToViewMatrix());

// and finally we calculate fade
fade = saturate(far * (sceneDepth - near) - thisDepth);