GL Maxxing: PBR Material Composing with GHGL in Grasshopper

“Maxxing” — pursuing maximum output in a given domain — is a term that will date this post precisely to 2026. That’s fine. It fits.

GHGL continues to be one of the more quietly useful tools in the Grasshopper ecosystem. The ability to write and iterate on GLSL shaders directly inside a Grasshopper definition, with parameters wired live to sliders and toggles, makes real-time shading work genuinely accessible without leaving the modeling environment.

Looking ahead, if a DirectX path is introduced (GHLSL?) with a higher-level shader language interface, that would open things up further. GHGL does the job well and the workflow is generally solid and I have really enjoyed the power that it offers to Grasshopper visualizations.


Context and Intent

The subject geometry in my application is a helmet, being developed parametrically in Grasshopper. The goal was real-time PBR-quality shading in the Rhino viewport to support the design process, not to showcase it. The material palette was a deliberate constraint. Glossy, high-specular shaders create their own feedback loop: a shape that reads well under dramatic lighting can mask problems that a flatter, more diffuse material would surface immediately. The intent was to build a body of neutral, matte industrial materials with some historical grounding: styling clay number one, with scraping marks, paper materials, cardboard, plywood, while not physically accurate (edges and laminates), they communicate the basis of the form. Calm enough to judge form against, without the confidence in the geometry getting ahead of itself. The PBR setup gives precise control over that range through roughness and metallic values, keeping everything in credible, non-promotional territory while the shape is still being resolved.


Texture Projection

The shader supports both UV-based projection and triplanar mapping, toggled via a boolean uniform. Triplanar is the primary mode for this work. It projects texture data from three orthogonal world-space axes and blends by surface normal, which suits mesh geometry that doesn’t carry a clean UV unwrap at this stage of development. Tiling scale and rotation are exposed as Grasshopper-controlled parameters.

Side grain plywood, useful for visualizing orthograpic curvature.

Terracotta rough clay, earthy roughness.

Scratched up concrete.

Visual indicator for checking the coverage of the primary texture weight, one dot.

Visual indicator for checking the coverage of the secondary texture weighting, two dots.

Semi-worked wax clay.

Graph paper, grid size controllable.

Red wax styling clay.

Vertical cardboard.

Horizontal cardboard.

Surface edges are used as guides for material transitions, driving blend zones between material layers based on curvature and angle, which maps naturally onto helmet geometry where panel boundaries and edge conditions are meaningful design elements. I always liked the Blender method of accenting edges, it was good to be able to incorporate that here.


Shader Structure

The core lighting model is Cook-Torrance BRDF with a full PBR texture set, although I am only using base color, roughness, and normal maps.

A full library is maintained and can be updated during runtime. Indexed by main material and subset variations. Accessed through an OSC Pilot interface.

The system runs two material layers with edge- and angle-based transitions, plus a flaw texture overlay for surface imperfection detail. All parameters, including material blend thresholds, roughness, tiling, light positions, and flaw intensity, are wired as uniforms and controllable in real time from Grasshopper.

Lighting operates in world space with a 3-point rig, which keeps shading stable as the viewport camera moves. Key, fill, rim and ambient lighting controls.

Black point, white point, and gamma are built directly into the shader rather than handled as post-process image adjustments. In practice this made a meaningful difference. Being able to dial contrast and tone on individual materials, and across material combinations, in real time and in context, is a different experience than applying those corrections after the fact. What would normally be an export-and-adjust loop collapsed into a slider.

Here is the “maxxed” GL component, happy to provide a manual type, full specification if there is interest.

3 Likes