Class StandardSurface
SurfaceOutputs for the built-in metallic-roughness material,
the same surface the hand-written reference shader computes, expressed as
neutral IR so one code generator can target multiple shading languages. The
expressions reference the engine's provided inputs by name (the framework
declares u_baseColor, u_mr, u_emissiveHasTex,
u_baseColorTex, u_normalTex, v_uv, v_color).
Every optional input has a neutral default bound for it (a 1×1 white texture, a 1×1 flat normal map, a per-vertex colour of opaque white, a normal scale of zero), so this one surface covers every material without variants. One surface means one compiled program, and that is worth more than the few multiplies it costs: the pass's uniforms are program state, so a second program would have to re-issue all of them or silently sample the wrong texture unit.
-
Method Summary
Modifier and TypeMethodDescriptionstatic SurfaceOutputsBase color = sRGB-decoded factor × sRGB-decoded base-color texture × per-vertex colour, with alpha the product of all three.
-
Method Details
-
metallicRoughness
Base color = sRGB-decoded factor × sRGB-decoded base-color texture × per-vertex colour, with alpha the product of all three.Three things about that sentence are load-bearing.
The texture's alpha is honoured. It used to be dropped in favour of the factor's, which makes a soft-edged sprite unreachable: the falloff that turns a quad into a puff of smoke lives in exactly that channel.
The per-vertex colour is neither decoded nor clamped. It is already linear (glTF
COLOR_0semantics), so passing it throughsrgbToLinearwould darken it; and a component above 1 is a legitimate over-range tint, so clamping it would flatten the brightest thing in the frame. A mesh without the attribute reads opaque white and nothing changes.The per-vertex colour also modulates emissive, which is what makes an over-range tint mean anything. Base colour is reflectance: 1.6 there is not "bright", it is unphysical, and with no light it is black. Emissive is added after the BRDF, so it reaches the tonemap as light. This is a deliberate step past glTF, where
COLOR_0touches base colour only. It is also the only way a per-vertex value can drive emission at all, since the emissive factor is per material.
-