writeDebugView function
Vector4?
writeDebugView(
- FragmentContext c,
- Float32List v,
- ShaderBindings b,
- Surface s,
- Vector3 lit, {
- bool transformed = false,
- Vector3? geometric,
WriteDebugView from surface.glsl — P6: the material channel
FragInfo.debug_view asks for, in place of lit, or null when no view
is on or the fragment sits left of the split, and the caller writes the
light.
Display values converted to linear, through the surface buffer and the
weighted-blended targets as writeLit writes them, and without the fog,
for the reasons the GLSL gives. geometric is the normal the surface
buffer takes when the stage hands writeLit another than Surface.normal
— the impostor's card.
Implementation
Vector4? writeDebugView(
FragmentContext c,
Float32List v,
ShaderBindings b,
Surface s,
Vector3 lit, {
bool transformed = false,
Vector3? geometric,
}) {
final debug = b.vec4('FragInfo', 'debug_view', Vector4.zero());
// `A5.22`: left of the column the view in z, right of it the one in x.
final view = c.coord.x < debug.y ? debug.z : debug.x;
if (view < 0.5) return null;
Vector3 srgbOf(Vector3 linear) => Vector3(
toSrgb(linear.x.clamp(0.0, 1.0)),
toSrgb(linear.y.clamp(0.0, 1.0)),
toSrgb(linear.z.clamp(0.0, 1.0)),
);
// `A5.21`: the vertex tangent square to the vertex normal, and the draw's
// identity unpacked from w, as `WriteDebugView` has them.
final vertexNormal = Vector3(v[kVNormal], v[kVNormal + 1], v[kVNormal + 2])
..normalize();
final rawTangent = Vector3(v[kVTangent], v[kVTangent + 1], v[kVTangent + 2]);
final tangent = rawTangent - vertexNormal * vertexNormal.dot(rawTangent);
final tangentUsable =
tangent.length2 > 1e-12 && (v[kVTangent + 3].abs() - 1.0).abs() < 0.01;
final identityObject = (debug.w / 8192.0).floorToDouble();
final identityRest = debug.w - identityObject * 8192.0;
final identityMaterial = (identityRest / 2.0).floorToDouble();
final normalMapped = identityRest - identityMaterial * 2.0 > 0.5;
final shown = switch ((view + 0.5).floor()) {
1 => srgbOf(s.albedo),
2 => Vector3(
s.normal.x * 0.5 + 0.5,
s.normal.y * 0.5 + 0.5,
s.normal.z * 0.5 + 0.5,
),
3 => Vector3.all(s.roughness.clamp(0.0, 1.0)),
4 => Vector3.all(s.metallic.clamp(0.0, 1.0)),
5 => Vector3.all(s.occlusion.clamp(0.0, 1.0)),
6 => srgbOf(s.emissive),
7 => () {
final (u: u, v: w, footprint: _) = mapUv(
kMapBaseColor,
v,
b,
c,
transformed: transformed,
);
return Vector3(fract(u), fract(w), 0.0);
}(),
8 =>
nonFinite(lit)
? Vector3(1.0, 0.0, 1.0)
: () {
final e = srgbOf(lit);
return Vector3.all(
(0.2126 * e.x + 0.7152 * e.y + 0.0722 * e.z) * 0.5,
);
}(),
9 =>
tangentUsable
? ((tangent.normalized()..scale(0.5))..add(Vector3.all(0.5)))
: Vector3.zero(),
10 => () {
final (u: u, v: w, footprint: _) = mapUv(
kMapBaseColor,
v,
b,
c,
transformed: transformed,
);
final cellSum = (u * 8.0).floorToDouble() + (w * 8.0).floorToDouble();
final odd = fract(cellSum * 0.5) * 2.0;
final grey = 0.22 + (0.92 - 0.22) * odd;
return Vector3(
grey * (0.55 + 0.45 * fract(u)),
grey * (0.55 + 0.45 * fract(w)),
grey * 0.85,
);
}(),
11 => c.frontFacing ? Vector3(0.2, 0.35, 0.95) : Vector3(0.95, 0.15, 0.15),
12 => srgbOf(Vector3(v[kVColour], v[kVColour + 1], v[kVColour + 2])),
13 || 14 => debugIdentityColour(
(view + 0.5).floor() == 13 ? identityObject : identityMaterial,
)..scale(0.55 + 0.45 * s.nDotV),
15 => () {
final e = srgbOf(s.albedo);
final luma = 0.2126 * e.x + 0.7152 * e.y + 0.0722 * e.z;
final metal = s.metallic > 0.5;
final brightest = math.max(e.x, math.max(e.y, e.z));
return !metal && luma < 30.0 / 255.0
? Vector3(0.1, 0.3, 1.0)
: !metal && brightest > 240.0 / 255.0
? Vector3(1.0, 0.1, 0.1)
: metal && luma < 180.0 / 255.0
? Vector3(1.0, 0.85, 0.1)
: Vector3.all(luma);
}(),
16 =>
s.metallic > 0.05 && s.metallic < 0.95
? Vector3(1.0, 0.5, 0.0)
: Vector3.all(s.metallic > 0.5 ? 1.0 : 0.15),
17 =>
!normalMapped
? Vector3.all(0.5)
: tangentUsable
? Vector3(0.2, 0.8, 0.3)
: Vector3(1.0, 0.1, 0.1),
_ => Vector3.zero(),
};
writeSurface(c, v, b, geometric ?? s.normal, s.roughness);
final weight = premultiplies(b) ? s.alpha : 1.0;
return writeWeightedBlended(
c,
v,
b,
Vector4(
toLinear(shown.x) * weight,
toLinear(shown.y) * weight,
toLinear(shown.z) * weight,
s.alpha,
),
);
}