Recommended Parameter Values#

How to read these tables#

Every value below is what you type into the material (ksEditor / .ini). There is one column for ksPerPixelReflection, ksPerPixelNM and ksPerPixelMultiMap alike — in the shipped Gamma (non-LCS) build these three take exactly the same code path for specular (GAMMA_BLINNPHONG_EXP / GAMMA_BLINNPHONG_ADJ are identities, so both families reduce to pow(specBase, exp) × NdotL × ksSpecular), and no per-family scaling is needed. See the gotchas page for the derivation. sunSpecular / sunSpecularEXP exist only in ksPerPixelMultiMap (non-NMDetail) and are listed as separate rows.

The values target Gamma (non-LCS) rendering, which is what CSP tells you to author for. Under Linear Colour Space the shader remaps them itself; the remap is documented on the gotchas page and is deliberately designed so that a correctly-authored Gamma material stays correct. Do not pre-compensate for LCS.

Three calibration anchors used throughout:

  • ksAmbient / ksDiffuse = 0.225 is neutral — not an approximation but an exact number: GAMMA_EXPECTED_KS = 0.45 and GAMMA_ALBEDO_BOOST = 2/0.45 = 4.4444 (recreated/include_new/base/_gamma.fx:24,28,37), so at k = 0.225 the inner multiplier of applyGamma is exactly 1.0 and the texture renders precisely the albedo it claims. In Gamma mode the same 0.22–0.27 band is empirically correct for CSP+Pure light levels. The legacy AC value of 0.4 overexposes in both modes.
  • fresnelMaxLevel is the fraction of diffuse energy the surface trades for reflection at grazing angles, and it means the same thing in both modes (the LCS squaring at utils_ps.fx:585 is cancelled exactly by the sqrt() at utils_ps.fx:672). Set it to the material’s real grazing reflectance, capped by cubemap blur quality (see the reflBlur table on the gotchas page).
  • ksSpecular should rise with ksSpecularEXP. AC’s Blinn-Phong is unnormalised — narrowing the lobe does not raise its peak the way a physical BRDF would — so a tight highlight needs a proportionally larger intensity to carry the same energy. A useful sanity rule for dielectrics is ksSpecular ≈ F0 × (EXP + 8) / 21, which the values below track within ~20%. Values much above ~0.3 on dielectrics blow out because extSpecularColor (the sun colour, already scene-scaled) multiplies everything.

1a. Glossy / Smooth Leather#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.18
ksSpecularEXP 60
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 0.28
sunSpecular 0.12
sunSpecularEXP 120

Why: Smooth-finished leather (coated steering wheel rims, luxury seat bolsters, polished hide) is a thin dielectric finish over compressed fibres, so the coating owns the optics: fresnelC is the dielectric F0 of 0.04, and fresnelEXP 5.0 is the Schlick ramp. ksSpecularEXP 60 puts reflBlur at ≈3.5 — soft enough that the cubemap reads as “sheen”, not “mirror”, which is what a wheel rim actually shows. fresnelMaxLevel 0.28 gives a real, visible rim light at grazing without the mid-surface washing to sky colour; the pairing with the full 5.0 exponent is what keeps that safe (see the gotchas page). The tight sunSpecularEXP 120 pinpoint rides on the broader base lobe.

Dyed leather: dye changes the diffuse texture only. Use these parameters for every colour.

1b. Matte Leather#

Parameter Value
ksAmbient 0.24
ksDiffuse 0.24
ksSpecular 0.08
ksSpecularEXP 24
fresnelC 0.025
fresnelEXP 4.0
fresnelMaxLevel 0.12
sunSpecular 0.04
sunSpecularEXP 45

Why: Raw, aged or nubuck leather has an open fibrous microstructure that scatters broadly. ksSpecularEXP 24 gives reflBlur ≈4.9, where the cubemap has degraded to an averaged sky tone — so the reflection must stay quiet, hence fresnelMaxLevel 0.12. fresnelC drops below the smooth-dielectric 0.04 because microfacet shadowing on a rough surface suppresses the coherent head-on return. Diffuse is nudged above neutral to give back the energy a glossier finish would return as specular.

1c. Coated Textured Surface (vinyl, faux leather, varnished/painted wood)#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.17
ksSpecularEXP 55
fresnelC 0.04
fresnelEXP 4.5
fresnelMaxLevel 0.25
sunSpecular 0.11
sunSpecularEXP 100

Why: Anything where a smooth dielectric coat sits over visible texture — PU/vinyl dash covers, armrests, door cards, lacquered wheel rims, varnished boards. The coating (IOR ≈1.5) owns the specular and fresnel behaviour entirely; the substrate only shows through in the diffuse. reflBlur ≈3.7 keeps environment detail vague, which is how these surfaces actually look. For ungrained gloss vinyl or high-build lacquer, use Glossy Plastic (2) instead.

2. Glossy Plastic#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.26
ksSpecularEXP 120
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 0.50
sunSpecular 0.20
sunSpecularEXP 220

Why: ABS and polycarbonate have IOR 1.46–1.58 → F0 ≈ 0.04, which is fresnelC directly, and fresnelEXP 5.0 is the Schlick exponent. ksSpecularEXP 120 gives reflBlur ≈1.7 — recognisable but soft environment reflections, correct for injection-moulded gloss plastic, which is never optically flat. ksSpecular 0.26 follows the energy rule for that exponent while staying under the ~0.3 blow-out threshold. fresnelMaxLevel 0.50 is deliberately short of a true dielectric’s grazing reflectance: at this blur the cubemap is a smeared approximation, and pushing past ~0.55 turns interior plastic into a blue wash wherever the probe sees sky through the glass.

2b. Satin Plastic#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.15
ksSpecularEXP 65
fresnelC 0.035
fresnelEXP 4.5
fresnelMaxLevel 0.28
sunSpecular 0.09
sunSpecularEXP 120

Why: The most common interior finish — centre consoles, door panel mid-sections, column shrouds, glovebox lids, pillar trim. A broad sun reflection and vague environmental highlights, nothing you could read text in. reflBlur ≈3.3. The whole point of this material is that it sits visibly between Glossy Plastic and Rough Plastic, so every parameter is roughly the geometric midpoint of the two.

3. Rough Plastic#

Parameter Value
ksAmbient 0.235
ksDiffuse 0.235
ksSpecular 0.08
ksSpecularEXP 30
fresnelC 0.03
fresnelEXP 4.0
fresnelMaxLevel 0.14
sunSpecular 0.04
sunSpecularEXP 55

Why: Same polymer as glossy plastic, but grained or textured so the specular lobe is spread across a wide cone. ksSpecularEXP 30 → reflBlur ≈4.7, where the cubemap is essentially averaged sky. fresnelMaxLevel 0.14 keeps that flat sky sample from becoming the dominant term on shaded panels. The lowered fresnelEXP 4.0 is physically right too: microfacet averaging flattens the fresnel ramp on rough surfaces relative to the ideal Schlick curve — and on this shader family the lerp(0.8, 1, fresnelMaxLevel) scale broadens it further, in the correct direction.

3c. Smooth Painted Surface (bumpers, signs, body panels, smooth painted metal/plastic)#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.24
ksSpecularEXP 100
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 0.45
sunSpecular 0.18
sunSpecularEXP 190

Why: Any smooth substrate under a paint coat: painted bumpers, mirror caps, road signs, fresh guardrails, painted steel panels. Paint is a smooth dielectric layer; whether metal or plastic sits underneath is optically irrelevant. Effectively Glossy Plastic with a marginally softer highlight (reflBlur ≈2.2), because sprayed paint carries slightly more orange-peel than moulded gloss. For retroreflective sign faces push fresnelMaxLevel toward 0.7. For paint over a rough substrate use Rough Painted Surface (17).

Metallic car paint (CSP smCarPaint): everything that makes the paint read as metallic — coloured specular, flake, ambient specular, clear coat — comes from the Material_CarPaint_Metallic override template, not the base cbuffer, and CSP overrides fresnelC / fresnelMaxLevel from that template too. The base values only matter as a non-CSP fallback, so use this section’s numbers and let the template do the work. Note that smCarPaint puts ksSpecular through GAMMA_BLINNPHONG_ADJ (custom_objects/smCarPaint_ps.fx:121-128), i.e. it behaves like the MultiMap family under LCS, not like ksPerPixelReflection.

4. Smooth Metal#

Parameter Value
ksAmbient 0.14
ksDiffuse 0.09
ksSpecular 0.65
ksSpecularEXP 220
fresnelC 0.62
fresnelEXP 2.2
fresnelMaxLevel 0.98
sunSpecular 0.70
sunSpecularEXP 420

Why: Metals are conductors: incident light is absorbed and re-emitted at the surface rather than scattered through it, so ksDiffuse sits far below neutral and exists only to pick up oxide/anodising colour from the texture. fresnelC 0.62 is the headline number — that is F0, a compromise across chrome (~0.55), steel (~0.56) and aluminium (~0.91) that reads as “polished metal” against AC’s cubemaps — and it makes the surface strongly reflective even head-on, which is the single thing separating metal from paint. The energy-conservation term dims the diffuse by that same fraction, which is exactly the metallic look. The low fresnelEXP 2.2 broadens the already-high reflectance rather than ramping it late. ksSpecularEXP 220 gives reflBlur ≈0.11, near-mirror. Use extColoredReflection > 0 to tint reflections for gold, copper or brass.

5. Rough Metal#

Parameter Value
ksAmbient 0.16
ksDiffuse 0.11
ksSpecular 0.30
ksSpecularEXP 60
fresnelC 0.50
fresnelEXP 2.5
fresnelMaxLevel 0.38
sunSpecular 0.26
sunSpecularEXP 110

Why: Brushed steel, cast iron, weathered aluminium. F0 stays high — it is still metal — so fresnelC holds at 0.50. But ksSpecularEXP 60 puts reflBlur at ≈3.5, where the cubemap is a smear, so fresnelMaxLevel is capped at 0.38: pushing a conductor’s true ~0.95 grazing reflectance through a blurred probe just paints the object sky-blue. Diffuse runs slightly above smooth metal because rough metal usually carries oxide, dirt or patina that genuinely does scatter.

6a. Grass#

Parameter Value
ksAmbient 0.27
ksDiffuse 0.27
ksSpecular 0.03
ksSpecularEXP 10
fresnelC 0.015
fresnelEXP 4.0
fresnelMaxLevel 0.05
sunSpecular 0.015
sunSpecularEXP 16

Why: Plant cuticle wax has IOR ≈1.4, but blade geometry is chaotic enough to destroy any coherent specular, and ksSpecularEXP 10 puts reflBlur at ≈5.5 (essentially maximum blur) anyway. Everything reflective is therefore held near zero. Diffuse runs above neutral because foliage scatters light into its own shadowed side (subsurface and multi-bounce), keeping the green vivid under direct sun. When rain is active, RAINFX_WET / RAINFX_SHINY raise specular and reflection automatically, so there is no reason to pre-load the dry values.

6b. Grass Multilayer#

Parameter Value
ksAmbient 0.27
ksDiffuse 0.27
ksSpecular 0 (unused)
ksSpecularEXP 10
fresnelC 0.015
fresnelEXP 4.0
fresnelMaxLevel 0.06
tarmacSpecularMultiplier 0.35
magicMult 2.0

Why: In ksMultilayer_fresnel_nm the fresnel triple drives specular intensity directly — there is no cubemap — and ksSpecular is genuinely ignored (recreated/ksMultilayer_fresnel_nm_ps.fx:88). tarmacSpecularMultiplier is the primary shininess knob and 0.35 is the lowest of the terrain set, matching a surface with essentially no coherent highlight. magicMult 2.0 restores brightness after the mask-weighted detail layers (which average ~0.5) multiply the diffuse down; note it scales the diffuse alpha as well, and that alpha masks the specular (:71-72, :84), so raising magicMult also raises the highlight.

GrassFX samples this material through a different path. The fxgrass pass compiles terrain shaders with MODE_GRASSFX, which defines SIMPLEST_LIGHTING and reduces the whole material to txDiffuse × combined × magicMult × ksAmbientksDiffuse is never read, and neither is any fresnel or specular parameter. Keep ksAmbient equal to ksDiffuse here or the grass blades will drift in tone away from the ground they stand on, and remember that retuning magicMult moves the grass tint along with the terrain. See the gotchas page.

7a. Gravel#

Parameter Value
ksAmbient 0.25
ksDiffuse 0.25
ksSpecular 0.06
ksSpecularEXP 12
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.08
sunSpecular 0.03
sunSpecularEXP 22

Why: Individual stones are quartz and feldspar with IOR ≈1.5, but they are randomly oriented, so the aggregate is effectively Lambertian. Slightly more specular than grass because mineral surfaces are harder and shinier than waxy plant tissue. reflBlur ≈5.4, so reflections are held near zero — all of gravel’s visual interest is in the diffuse texture and normal map.

7b. Gravel Multilayer#

Parameter Value
ksAmbient 0.25
ksDiffuse 0.25
ksSpecular 0 (unused)
ksSpecularEXP 12
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.10
tarmacSpecularMultiplier 0.50
magicMult 2.0

Why: Larger fragments than sand with more chaotic orientation, so the aggregate specular is less coherent despite the harder material. Sits just below concrete on the shininess scale.

8a. Sand#

Parameter Value
ksAmbient 0.26
ksDiffuse 0.26
ksSpecular 0.08
ksSpecularEXP 16
fresnelC 0.025
fresnelEXP 4.0
fresnelMaxLevel 0.10
sunSpecular 0.04
sunSpecularEXP 28

Why: Finer grains than gravel and individually quite reflective (quartz, IOR 1.54), which produces the characteristic aggregate glitter in direct sun. That is what the slightly raised ksSpecular and fresnelC buy. At the macro scale it is still a diffuse material — the sparkle is a highlight, not a reflection, so fresnelMaxLevel stays low.

8b. Sand Multilayer#

Parameter Value
ksAmbient 0.26
ksDiffuse 0.26
ksSpecular 0 (unused)
ksSpecularEXP 14
fresnelC 0.025
fresnelEXP 4.0
fresnelMaxLevel 0.12
tarmacSpecularMultiplier 0.55
magicMult 2.0

Why: Marginally shinier than gravel or concrete to carry the quartz sparkle, and the raised fresnelC gives a small floor of specular even at moderate viewing angles, which is what makes a sand trap read as sand rather than as flat brown paint.

9a. Raw Wood#

Parameter Value
ksAmbient 0.24
ksDiffuse 0.24
ksSpecular 0.07
ksSpecularEXP 18
fresnelC 0.025
fresnelEXP 4.0
fresnelMaxLevel 0.10
sunSpecular 0.03
sunSpecularEXP 30

Why: Unfinished wood is rough, fibrous and porous — almost entirely diffuse. Cellulose has IOR ≈1.5 so there is a faint surface sheen, but open grain breaks up any coherent specular. Suits pit-lane barriers, trackside fencing, unpainted posts. For painted or varnished wood use Coated Textured Surface (1c).

10a. Rough Concrete#

Parameter Value
ksAmbient 0.24
ksDiffuse 0.24
ksSpecular 0.05
ksSpecularEXP 12
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.08
sunSpecular 0.02
sunSpecularEXP 20

Why: Exposed-aggregate, broom-finished or weathered concrete is about the most diffuse man-made surface there is — macro-roughness from the stones and micro-roughness from the cement paste both scatter everything. Covers pit walls, barriers, run-off areas and general outdoor structures.

10a-ii. Smooth Concrete#

Parameter Value
ksAmbient 0.23
ksDiffuse 0.23
ksSpecular 0.11
ksSpecularEXP 32
fresnelC 0.03
fresnelEXP 4.5
fresnelMaxLevel 0.16
sunSpecular 0.05
sunSpecularEXP 48

Why: Trowel-finished floors, precast panels, polished garage floors. The cement paste forms a continuous smooth skin with almost no exposed aggregate, so there is a real sun highlight and a hint of environmental brightness. reflBlur ≈4.6 still — noticeably glossier than rough concrete, still far from plastic.

10a-iii. Painted Rough Concrete#

Parameter Value
ksAmbient 0.23
ksDiffuse 0.23
ksSpecular 0.12
ksSpecularEXP 26
fresnelC 0.03
fresnelEXP 4.0
fresnelMaxLevel 0.14
sunSpecular 0.06
sunSpecularEXP 42

Why: Paint over rough concrete — painted pit walls, building facades, garage floors that were never ground flat. The paint fills micro-porosity and adds a dielectric sheen, but the aggregate roughness underneath still dominates the highlight shape, so the exponent stays low even though the intensity rises.

10a-iv. Painted Concrete (kerbs, painted floors, painted walls)#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.15
ksSpecularEXP 38
fresnelC 0.035
fresnelEXP 4.5
fresnelMaxLevel 0.20
sunSpecular 0.08
sunSpecularEXP 65

Why: Paint over a reasonably smooth concrete substrate: race kerbs, painted precast panels, painted garage floors. Shinier than painted rough concrete because the substrate does not fight the coating. Kerbs in particular need a visible glint at low sun to read correctly on replays. Heavily scuffed kerbs should drop ksSpecular and fresnelMaxLevel by ~15%. All colour comes from the diffuse texture.

Note: painted tyre lettering is optically the same problem — paint over a rough substrate. Use these values for white-letter tyre markings.

10b. Concrete Multilayer#

Parameter Value
ksAmbient 0.24
ksDiffuse 0.24
ksSpecular 0 (unused)
ksSpecularEXP 10
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.10
tarmacSpecularMultiplier 0.45
magicMult 2.0

Why: The most diffuse of the three road surfaces. tarmacSpecularMultiplier 0.45 makes the fresnel-driven specular nearly vanish, which is correct — concrete run-off should look flat and matte until rain FX activates.

11a. Asphalt — Smooth New Tarmac#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.14
ksSpecularEXP 28
fresnelC 0.035
fresnelEXP 4.0
fresnelMaxLevel 0.22
sunSpecular 0.09
sunSpecularEXP 60

Why: Fresh tarmac still has its bitumen binder at the surface (IOR ≈1.5–1.6) and has not yet been polished open by traffic, so it looks faintly oily. fresnelMaxLevel 0.22 is the highest of the dry road surfaces and is what produces the characteristic low-sun sheen down the straight — a real and important effect; driving it near zero is what makes AC tracks look like grey felt. ksSpecularEXP 28 keeps the highlight broad, which is correct: even new tarmac never shows a defined cubemap image.

11b. Asphalt — Smooth New Tarmac Multilayer#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0 (unused)
ksSpecularEXP 28
fresnelC 0.035
fresnelEXP 4.0
fresnelMaxLevel 0.30
tarmacSpecularMultiplier 1.10
magicMult 2.0

Why: tarmacSpecularMultiplier above 1.0 is what makes the road glint when the sun is near the horizon, and new tarmac is the only terrain material that earns it. The fresnelMaxLevel cap of 0.30 stops that glint from turning into a mirror. Because this shader has no cubemap, a higher cap here is far safer than on ksPerPixelReflection — there is no environment colour to leak in, only sun-coloured highlight.

12a. Asphalt — Grainy Old Tarmac#

Parameter Value
ksAmbient 0.25
ksDiffuse 0.25
ksSpecular 0.07
ksSpecularEXP 14
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.12
sunSpecular 0.035
sunSpecularEXP 26

Why: Worn tarmac has lost its bitumen film; the aggregate is exposed and the surface is granular, so optically it converges on gravel. Diffuse goes slightly above new tarmac because exposed stone is lighter than fresh bitumen. Rain FX transforms this dramatically — water filling the surface texture is what creates the reflective wet road, so there is no need to anticipate it in the dry values.

12b. Asphalt — Grainy Old Tarmac Multilayer#

Parameter Value
ksAmbient 0.25
ksDiffuse 0.25
ksSpecular 0 (unused)
ksSpecularEXP 14
fresnelC 0.02
fresnelEXP 4.0
fresnelMaxLevel 0.16
tarmacSpecularMultiplier 0.65
magicMult 2.1

Why: Roughly half the shininess of new tarmac. magicMult is nudged up because old-tarmac detail textures tend to be lighter (exposed aggregate) and the mask-weighted blend pulls the result down further than on darker sets.

13. Billboard Trees (Leaves) — ksTree shader#

Parameter Value
ksAmbient 0.16
ksDiffuse 0.20
ksSpecular 0.00
ksSpecularEXP 1

Why: ksTree has no fresnel parameters at all — no cubemap, no reflection system. It also uses a hard-floored ambient model, AMBIENT_SIMPLE_FN(x) = saturate(y * 0.4 + 0.6) (recreated/ksTree_ps.fx:15), so ambient never drops below 60% of maximum no matter which way a leaf faces, and NO_EXTAMBIENT removes IBL entirely. That floor is why ksAmbient must sit below ksDiffuse here — it is the only way to stop shaded canopies from going flat and milky while still letting sunlit foliage read as sunlit. ksSpecular must be exactly 0: a billboard is a flat quad standing in for thousands of randomly-oriented leaves, and any coherent highlight instantly reveals it as a glossy plastic sheet — and the highlight genuinely renders if you leave a value in, because ksTree still runs reflectanceModel() in the normal path. See the gotchas page.

14. Natural Fabric — cotton, wool, felt (headliner, pillars, cloth seats)#

Parameter Value
ksAmbient 0.25
ksDiffuse 0.25
ksSpecular 0.02
ksSpecularEXP 10
fresnelC 0.015
fresnelEXP 4.0
fresnelMaxLevel 0.05
sunSpecular 0.01
sunSpecularEXP 14

Why: Cotton, wool, felt and linen are among the most diffuse materials that exist — irregular absorbent fibres scatter in every direction with essentially no specular return. Covers headliner felt, pillar trim, cloth seat inserts and wool carpet. Everything visually interesting comes from the diffuse texture and its ambient occlusion; the reflective parameters are set just high enough to avoid looking artificially dead at extreme grazing.

Note: dyed fabrics of any colour use the same parameters.

15. Synthetic Fabric — polyester, nylon, Alcantara (seats, door cards, sport trim)#

Parameter Value
ksAmbient 0.24
ksDiffuse 0.24
ksSpecular 0.06
ksSpecularEXP 20
fresnelC 0.025
fresnelEXP 4.0
fresnelMaxLevel 0.10
sunSpecular 0.025
sunSpecularEXP 32

Why: Extruded synthetic fibres are smooth and uniform in a way natural ones are not, and polyester’s IOR of ~1.5 gives a real if subtle sheen under direct light. Covers racing seat bolsters, Alcantara dash wraps, harness webbing, polyester door card inserts. Use the upper end for Alcantara; drop toward Natural Fabric (14) for coarse synthetic cloth.

16. Painted White Lines on Road#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.15
ksSpecularEXP 35
fresnelC 0.035
fresnelEXP 4.5
fresnelMaxLevel 0.22
sunSpecular 0.09
sunSpecularEXP 65

Why: Thermoplastic road paint and preformed tape both present a smoother, glass-bead-loaded surface than the tarmac around them, which is exactly why markings glint in headlights and at low sun. Slightly tighter and slightly brighter than the asphalt they sit on, so the line separates visually without becoming a light source. These represent moderately worn markings; freshly laid paint justifies pushing ksSpecular to ~0.19.

17. Rough Painted Surface (textured plastic, weathered metal, rough painted trim)#

Parameter Value
ksAmbient 0.23
ksDiffuse 0.23
ksSpecular 0.14
ksSpecularEXP 36
fresnelC 0.035
fresnelEXP 4.0
fresnelMaxLevel 0.18
sunSpecular 0.08
sunSpecularEXP 62

Why: Any rough substrate under paint: textured bumper trim, crinkle-finish panels, weathered guardrails, galvanised-then-painted fencing. The paint contributes the sheen the bare substrate lacks, but surface texture — not the substrate material — sets the highlight width. At reflBlur ≈4.4 the cubemap is a smear, so the grazing cap stays modest. For smooth substrates use Smooth Painted Surface (3c).

18a. Window Glass (windscreen, side windows, rear glass)#

Parameter Value
ksAmbient 0.08
ksDiffuse 0.04
ksSpecular 0.05
ksSpecularEXP 220
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 1.00
isAdditive 1
sunSpecular 0.40
sunSpecularEXP 500

Why: Window glass is a large flat surface, and Blinn-Phong on a large flat surface produces an enormous unphysical highlight blob — hence the deliberately tiny ksSpecular. What actually makes glass look like glass is the fresnel/cubemap term, so that is where the budget goes: F0 of 0.04 head-on ramping over a true Schlick exponent to full reflection at grazing. fresnelMaxLevel = 1.00 is physically correct and safe here precisely because isAdditive = 1 disables energy conservation — a window reflecting the sky must not darken the cabin behind it. ksDiffuse is near zero because clear glass barely colours transmitted light. Apply CSP’s Material_Glass on top where possible; these values are a good standalone fallback.

18b. Headlight / Tail Light Outer Glass (small curved lenses)#

Parameter Value
ksAmbient 0.08
ksDiffuse 0.04
ksSpecular 0.38
ksSpecularEXP 220
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 1.00
isAdditive 1
sunSpecular 0.45
sunSpecularEXP 500

Why: Optically identical to window glass (IOR ≈1.5, F0 ≈0.04) — the only meaningful difference is ksSpecular. On a small curved lens the Blinn-Phong highlight stays compact and tracks the curvature convincingly, so it can be allowed to be bright. This is purely a concession to the lighting model’s behaviour on different geometry, not a material difference.

18c. Gauge / Instrument Glass with Material_Glass#

Parameter Value
ksAmbient 0.30
ksDiffuse 0.30
ksSpecular 2.00
ksSpecularEXP 550
fresnelC 0.10
fresnelEXP 2.5
fresnelMaxLevel 0.70

Why: These are empirical values for the CSP glass extension specifically, not derived from the base shader model, and they will overexpose badly without Material_Glass applied. The extension runs its own energy conservation and fresnel on top of the base shader, subtracting energy at grazing angles; the well-above-neutral ksAmbient/ksDiffuse exist to stop opaque elements behind the glass (gauge faces, printed markings, vinyl stickers) from crushing to black. ksSpecularEXP 550 is far past the 255 divisor in the reflBlur formula, so it clamps to mirror-sharp — which is what makes scratches and surface wear catch light as crisp perturbations. Without Material_Glass, use 18b instead.

Note: tuned against a scratched, worn gauge glass with semi-transparent cracks and an opaque sticker. Clean pristine gauge glass will want lower ksAmbient/ksDiffuse and ksSpecular.

19. Refracted Glass (Tail Light Inner Patterned Glass)#

Parameter Value
ksAmbient 0.11
ksDiffuse 0.07
ksSpecular 0.26
ksSpecularEXP 90
fresnelC 0.04
fresnelEXP 4.5
fresnelMaxLevel 0.85
isAdditive 1
sunSpecular 0.22
sunSpecularEXP 180

Why: The moulded prismatic lens inside a tail light housing has clear glass’s IOR but a faceted macro-surface. Each facet is individually smooth, so a defined sun reflection survives, but the aggregate behaves much rougher than flat glass — hence ksSpecularEXP dropping from 220 to 90 (reflBlur ≈2.5, visibly blurrier). fresnelMaxLevel comes down from 1.00 because the faceting means only a fraction of the surface is at true grazing incidence at any moment. Diffuse is above clear glass since the pattern scatters some light back as a glow.

20. Frosted Glass (Modern Car Tail Lights)#

Parameter Value
ksAmbient 0.14
ksDiffuse 0.11
ksSpecular 0.13
ksSpecularEXP 45
fresnelC 0.035
fresnelEXP 4.0
fresnelMaxLevel 0.55
isAdditive 1
sunSpecular 0.07
sunSpecularEXP 70

Why: Smoked or etched glass on modern LED light bars. Still glass (IOR ≈1.5) but with a deliberately roughened surface, so ksSpecularEXP 45 gives reflBlur ≈4.1 — vague environmental brightness rather than distinct reflections. Diffuse is well above clear glass because translucent scattering gives frosted glass a visible body colour even unlit. isAdditive = 1 matters here: it is still transmissive, and the reflection must not darken the glow coming through. The apparent glow when the light is on comes from the emissive term, not from anything in this table.

21. Headlight / Tail Light / Indicator Reflector#

Parameter Value
ksAmbient 0.10
ksDiffuse 0.06
ksSpecular 0.85
ksSpecularEXP 235
fresnelC 0.82
fresnelEXP 2.0
fresnelMaxLevel 1.00
sunSpecular 0.90
sunSpecularEXP 550

Why: Vacuum-metallised plastic — a thin aluminium film on a moulded parabola, engineered to be as mirror-like as manufacturing allows. Optically a conductor: aluminium’s F0 is ≈0.91, so fresnelC 0.82 is the defining parameter and makes the reflector strongly reflective at every angle, not just at the edges. ksSpecularEXP 235 gives reflBlur ≈0.04, effectively a perfect mirror, which is what you see looking into a headlight. Diffuse is minimal; the little that remains carries the base tint. Unlike the glass sections, isAdditive stays 0 — a mirror genuinely does replace the diffuse, and the energy-conservation term is doing the right thing.

22. Blacked-Out Headlight Reflector (Glossy Black Painted)#

Parameter Value
ksAmbient 0.13
ksDiffuse 0.13
ksSpecular 0.38
ksSpecularEXP 160
fresnelC 0.04
fresnelEXP 5.0
fresnelMaxLevel 0.65
sunSpecular 0.33
sunSpecularEXP 320

Why: The crucial distinction from §21 is that this is a dielectric, not a conductor — you are looking at paint, whatever is underneath it. So fresnelC collapses from 0.82 back to the usual 0.04 while fresnelMaxLevel stays high: dark head-on, strongly reflective at the edges. That contrast is the piano-black look. Glossy black is the most revealing surface for reflections because the near-black diffuse never competes with them, so 0.65 reads as far more reflective than the number suggests. reflBlur ≈0.83 keeps reflections clean. Diffuse is moderate rather than near-zero — black paint still has visible body under ambient light.

23. Tyre Rubber — ksTyres shader#

ksTyres runs the CARPAINT_NM path, but it also defines FORCE_BLURREST_REFLECTIONS, which pins cubemap sampling to level 15 regardless of ksSpecularEXP (recreated/include_new/base/utils_ps.fx:504-505). Two consequences:

  • ksSpecularEXP controls only the sun highlight, never reflection clarity.
  • The cubemap contribution is always a flat averaged sky colour. On dark rubber that reads as a blue cast, so the fresnel values must stay well below what an equivalently-rough material on another shader could take.

The shader also scales specular by dirtyInv × txDiffuseValue.a (:83) — if the diffuse texture has no alpha channel, specular is completely unattenuated. These values assume no specular mask. Reflection strength is further scaled by saturate(normalW.y + 1) (:93), so the reflection naturally fades out on the underside of the tyre.

23a. Fresh Tyre with Tyre Shine#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.13
ksSpecularEXP 32
fresnelC 0.03
fresnelEXP 4.5
fresnelMaxLevel 0.10

Why: Silicone tyre dressing fills the rubber’s micro-texture with a slick dielectric film, producing a genuine wet-look gloss with a defined sun spot. ksSpecularEXP 32 gives that highlight — broader than plastic, much tighter than bare rubber — and costs nothing in reflection blur since blur is forced anyway. fresnelMaxLevel 0.10 buys a perceptible edge sheen while keeping the flat sky sample from tinting the sidewall.

23b. Worn Tyre without Tyre Shine#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.05
ksSpecularEXP 12
fresnelC 0.015
fresnelEXP 4.0
fresnelMaxLevel 0.04

Why: An abraded tyre has lost its mould-release agents and any dressing, exposing raw vulcanised compound — rough, matte, dark. ksSpecularEXP 12 spreads the highlight so wide it is barely distinguishable from diffuse shading, which is correct: worn rubber produces no recognisable sun spot. Reflection is held near zero so the sidewall stays flat and matte. Diffuse matches the fresh tyre deliberately — the entire fresh/worn difference should live in the specular response, not in a brightness change. (True black-rubber albedo is 0.02–0.05; if the sidewall reads too light, fix the texture, not these coefficients — see the gotchas page.)

24. Rubber Trim (weather strips, wipers, interior seals)#

Parameter Value
ksAmbient 0.225
ksDiffuse 0.225
ksSpecular 0.18
ksSpecularEXP 50
fresnelC 0.035
fresnelEXP 4.5
fresnelMaxLevel 0.20
sunSpecular 0.09
sunSpecularEXP 85

Why: Moulded EPDM and silicone seals never touch the road, so they keep their factory surface finish — much smoother and glossier than tyre rubber despite the similar IOR. You can see a clear sun reflection along a wiper blade or door seal. reflBlur ≈3.9. Optically this sits between rough plastic and satin plastic; treat smooth moulded rubber as a slightly soft plastic and the result looks right.


Summary Tables#

ksPerPixelReflection / ksPerPixelNM / ksPerPixelMultiMap#

The sunSpecular / sunSpecularEXP rows apply to ksPerPixelMultiMap only. All other rows apply to all three shaders unchanged.

Parameter Glossy Leather Matte Leather Coated Textured Glossy Plastic Satin Plastic Sm. Painted Surface Rough Plastic Smooth Metal Rough Metal
ksAmbient 0.225 0.24 0.225 0.225 0.225 0.225 0.235 0.14 0.16
ksDiffuse 0.225 0.24 0.225 0.225 0.225 0.225 0.235 0.09 0.11
ksSpecular 0.18 0.08 0.17 0.26 0.15 0.24 0.08 0.65 0.30
ksSpecularEXP 60 24 55 120 65 100 30 220 60
fresnelC 0.04 0.025 0.04 0.04 0.035 0.04 0.03 0.62 0.50
fresnelEXP 5.0 4.0 4.5 5.0 4.5 5.0 4.0 2.2 2.5
fresnelMaxLevel 0.28 0.12 0.25 0.50 0.28 0.45 0.14 0.98 0.38
sunSpecular 0.12 0.04 0.11 0.20 0.09 0.18 0.04 0.70 0.26
sunSpecularEXP 120 45 100 220 120 190 55 420 110
Parameter Grass Gravel Sand Raw Wood Rough Concrete Smooth Concrete Painted Rgh. Concrete Painted Concrete
ksAmbient 0.27 0.25 0.26 0.24 0.24 0.23 0.23 0.225
ksDiffuse 0.27 0.25 0.26 0.24 0.24 0.23 0.23 0.225
ksSpecular 0.03 0.06 0.08 0.07 0.05 0.11 0.12 0.15
ksSpecularEXP 10 12 16 18 12 32 26 38
fresnelC 0.015 0.02 0.025 0.025 0.02 0.03 0.03 0.035
fresnelEXP 4.0 4.0 4.0 4.0 4.0 4.5 4.0 4.5
fresnelMaxLevel 0.05 0.08 0.10 0.10 0.08 0.16 0.14 0.20
sunSpecular 0.015 0.03 0.04 0.03 0.02 0.05 0.06 0.08
sunSpecularEXP 16 22 28 30 20 48 42 65
Parameter Asphalt New Asphalt Old Natural Fabric Synthetic Fabric Road Lines Rgh. Painted Surface
ksAmbient 0.225 0.25 0.25 0.24 0.225 0.23
ksDiffuse 0.225 0.25 0.25 0.24 0.225 0.23
ksSpecular 0.14 0.07 0.02 0.06 0.15 0.14
ksSpecularEXP 28 14 10 20 35 36
fresnelC 0.035 0.02 0.015 0.025 0.035 0.035
fresnelEXP 4.0 4.0 4.0 4.0 4.5 4.0
fresnelMaxLevel 0.22 0.12 0.05 0.10 0.22 0.18
sunSpecular 0.09 0.035 0.01 0.025 0.09 0.08
sunSpecularEXP 60 26 14 32 65 62
Parameter Window Glass Light Glass Refracted Glass Frosted Glass Reflector Black Reflector Rubber Trim
ksAmbient 0.08 0.08 0.11 0.14 0.10 0.13 0.225
ksDiffuse 0.04 0.04 0.07 0.11 0.06 0.13 0.225
ksSpecular 0.05 0.38 0.26 0.13 0.85 0.38 0.18
ksSpecularEXP 220 220 90 45 235 160 50
fresnelC 0.04 0.04 0.04 0.035 0.82 0.04 0.035
fresnelEXP 5.0 5.0 4.5 4.0 2.0 5.0 4.5
fresnelMaxLevel 1.00 1.00 0.85 0.55 1.00 0.65 0.20
isAdditive 1 1 1 1
sunSpecular 0.40 0.45 0.22 0.07 0.90 0.33 0.09
sunSpecularEXP 500 500 180 70 550 320 85

Gauge/instrument glass under Material_Glass uses special empirical values — see §18c.

ksTree#

Parameter Value
ksAmbient 0.16
ksDiffuse 0.20
ksSpecular 0.00
ksSpecularEXP 1

No fresnelC / fresnelEXP / fresnelMaxLevel / sunSpecular — this shader has no reflection system.

ksTyres#

FORCE_BLURREST_REFLECTIONS means ksSpecularEXP controls only the sun highlight, never reflection blur.

Parameter Fresh + Tyre Shine Worn
ksAmbient 0.225 0.225
ksDiffuse 0.225 0.225
ksSpecular 0.13 0.05
ksSpecularEXP 32 12
fresnelC 0.03 0.015
fresnelEXP 4.5 4.0
fresnelMaxLevel 0.10 0.04

ksMultilayer_fresnel_nm (roads, terrain)#

Parameter New Tarmac Old Tarmac Concrete Grass Sand Gravel
ksAmbient 0.225 0.25 0.24 0.27 0.26 0.25
ksDiffuse 0.225 0.25 0.24 0.27 0.26 0.25
ksSpecular 0 0 0 0 0 0
ksSpecularEXP 28 14 10 10 14 12
fresnelC 0.035 0.02 0.02 0.015 0.025 0.02
fresnelEXP 4.0 4.0 4.0 4.0 4.0 4.0
fresnelMaxLevel 0.30 0.16 0.10 0.06 0.12 0.10
tarmacSpecularMultiplier 1.10 0.65 0.45 0.35 0.55 0.50
magicMult 2.0 2.1 2.0 2.0 2.0 2.0

ksSpecular is genuinely unused in this shader — L.specularValue is overwritten by the fresnel-derived intensity (recreated/ksMultilayer_fresnel_nm_ps.fx:88). tarmacSpecularMultiplier is the primary “how shiny overall” knob and the 0.35–1.10 range covers everything from fully matte grass to glinting fresh tarmac. Because there is no cubemap here, fresnelMaxLevel caps a sun-coloured highlight rather than an environmental reflection, so it can safely run higher than on ksPerPixelReflection for the same perceived roughness.

ksAmbient and ksDiffuse are paired deliberately in every column above, and that is a constraint rather than a stylistic choice. GrassFX samples these materials through the fxgrass pass, which compiles them with MODE_GRASSFXSIMPLEST_LIGHTING and collapses the entire material to txDiffuse × combined × magicMult × ksAmbient. ksDiffuse is never read there. Splitting the two to bias sun-versus-shade response — legitimate on most materials — desynchronises grass tint from ground tint here. magicMult is in that expression too, so it is a shared knob between the two passes rather than a terrain-only one.

Note also that MODE_GRASSFX is one of the nine modes excluded from the LCS build (.build/compile.js:204-214), so this pass always runs Gamma math regardless of the Weather FX dropdown, with flgGrass_cs_generation.fx:125 reconciling the result when the rest of the frame is linear.