CrowPSXDocumentationv1.1.0Get CrowPSX ↗
Docs/Lighting & retro controls

MATERIAL WORKFLOWS

Lighting & retro controls

Lighting modes, vertex snapping, affine warp, outlines, and rendering.

PACKAGE VERSION 1.1.0
On this pageColor AdjustmentLightingRetro GeometryOutlineOutline normals (Baked Smooth UV4)RenderingGrunge and Emission

Color Adjustment#

Pre-lighting controls affect source Albedo before direct/indirect lighting. Post-lighting controls grade the final combined output. The bake toggle determines whether pre-lighting color correction is exported through the material meta pass.

Lighting#

Every lit surface, Nature and Vertex Painting shader has three Realtime Lighting Modes, plus direct and indirect intensity, ambient/probe intensity, minimum light, stepped lighting and final posterization. The Terrain shader offers Pixel and Vertex.

  • Pixel: lighting, falloff and shadows are all calculated per pixel, like a standard Unity material.
  • Vertex: the classic PS1 look. All realtime lighting, including each light's falloff, is calculated at the mesh vertices and blended across the triangle. It is unshadowed by default; Main Light Shadows adds the main directional light's shadow where the pipeline allows it (see below).
  • Vertex Hybrid: each light's shading, including PBR highlights, is calculated at the vertices, but its falloff and shadow are applied per pixel. You keep the vertex-lit look with clean light pools and crisp shadows. Each light is shadowed only by itself, so the sun's shadow never darkens a point or spot light.

Use ordinary Unity Lights. Their color, intensity, range, cone, culling mask and render mode are all respected, and no extra components, materials or setup are required.

Light limits. Vertex mode receives up to eight lights per object; CrowPSX picks the most important automatically (Important before Auto before Not Important, then the brightest and closest). On URP Forward, the URP asset's Per Object Limit for additional lights applies instead. In Vertex Hybrid, the four most important point and spot lights get per-pixel falloff and shadows; any beyond that are lit fully per vertex, like Unity's Not Important lights.

Shadows by pipeline.

Built-in URP Forward URP Forward+ / Deferred+
Pixel All lights All lights All lights
Vertex Unshadowed Main light (with Main Light Shadows) Unshadowed
Vertex Hybrid All lights All lights Main light only

In Vertex mode on Built-in and URP Forward+, all eight lights are blended into one value, so a single light's shadow cannot be separated out. In Vertex Hybrid on URP Forward+ and Deferred+, point and spot lights come from CrowPSX's own light list, which has no access to URP's shadow maps.

Batching. In Vertex mode on Built-in and URP Forward+, and in Vertex Hybrid on URP Forward+, each object receives its light selection through per-renderer data. GPU instancing still works, but those objects are not batched by the SRP Batcher. URP Forward uses Unity's own light lists and keeps SRP Batcher compatibility.

Retro Geometry#

Pixel snapping, affine warp, near-camera reduction, and optional snapped shadow casting. The visible VR / Stereo Comfort group provides Off, Comfort, Balanced, and Full profiles plus independent VR Snap and VR Affine strengths. Stereo rendering uses one shared snap displacement for both eyes to preserve binocular disparity across Multi-Pass, Single Pass Instanced, and Multiview.

Outline#

The six mesh-surface shaders (Default, Lite, PBR, and their Vertex Painting variants) provide an optional inverted-hull silhouette. Width can stay fixed in screen pixels or use physical world units, and an optional start/end distance fade shrinks and fades it out. A UV-transformable texture mask (luminance/R/G/B/A, optionally inverted) controls where the hull appears. Match Base Color blends toward the actual sampled surface color, including the blended layer result on Vertex Painting materials. The hull follows CrowPSX vertex wobble. Disabled materials have the outline pass switched off and submit no outline draw; enabled materials add one outline draw.

The outline uses the same renderer and material as the surface. Its pass runs after the surface pass and reads the depth it wrote. Separate renderers cannot guarantee this ordering.

Transparent surfaces cannot reliably occlude their own hull because they normally do not write depth; Opaque or Cutout is recommended. Nature is intentionally excluded: its common single-plane alpha cards need texture-silhouette dilation rather than an inverted hull.

Built-in draws the hull automatically in its forward queue through the LightMode = Always pass. No additional setup is required.

URP needs an explicit request to draw the outline after opaque geometry has written depth. CrowPSX uses LightMode = CrowPSXOutline at BeforeRenderingTransparents. Enable it in either of these ways:

  • CrowPSX Outline Feature on a Universal Renderer covers every camera using that renderer.
  • CrowPSX Outline Support on a camera covers one scene without touching any project asset, which is what lets a scene ship with outlines that work on import. It adds the URP-only injector at runtime and does nothing under Built-in.

Both options can be present: the renderer feature skips cameras already handled by the support component. Both support Unity 6 Render Graph, Compatibility Mode, and earlier URP versions. Keep the custom outline tag; using SRPDefaultUnlit would draw the hull before the surface, allowing later opaque draws to overwrite it.

Code toggling the outline at runtime has to set both LightMode names through Material.SetShaderPassEnabled, which matches on that tag, alongside the _OutlineEnabled property.

Outline normals (Baked Smooth UV4)#

Hard edges are duplicated vertices. A cube corner is three vertices at the same position, each carrying its own axis-aligned normal, so an inverted hull extrudes each face along a different axis and comes apart into disjoint quads. On screen that reads as short strokes floating near the corners while the rest of the silhouette is missing. Rounded meshes hide the problem, because a smooth normal field still closes the hull.

Smoothing the mesh's own normals would fix the hull and flatten the shading with it. Normal Source > Baked Smooth UV4 instead uses a second set of normals that only the outline pass reads.

What the bake produces. CrowPSX copies the mesh, groups vertices that share a position, averages their distinct normals, and writes the result to UV4, TEXCOORD3 in the shaders. Welding is positional, with a tolerance scaled to the mesh bounds. Positions, lighting normals, vertex colors and lightmap UVs are untouched, so shading is unchanged; the extra channel is read only while Normal Source is set to Baked Smooth UV4, and ignored everywhere else.

How the normal is stored. Each normal is stored in the vertex's tangent frame and marked with w = 2. This keeps the outline aligned during static batching and GPU skinning, which transform NORMAL and TANGENT while preserving UV data. CrowPSX generates missing tangents on the mesh copy. Vertices with unusable tangents fall back to an object-space direction marked with w = 1. Older bakes also use w = 1; the inspector flags them for re-baking.

Baking and restoring. In the material inspector, Source Renderer defaults to the selected object's renderer and only appears while Normal Source is Baked Smooth UV4. Bake Outline Normals bakes that renderer in place: the generated mesh is assigned to it and its materials are switched to Baked Smooth UV4. Restore Source Mesh puts the recorded original back without deleting the generated asset. Below the buttons the section reports which mesh is being drawn, or warns that it has no UV4 or carries the older encoding. Tools > CrowPSX > Outline Normals runs the same two actions across every MeshFilter and SkinnedMeshRenderer under the current selection.

Generated assets. Each mesh is written beside its source model as <model>_<mesh>_OutlineNormals.asset. Two labels record the original mesh reference and the source's dependency hash. Restore resolves the original through the first; re-baking reuses the existing asset when both still match, and updates that same asset in place when the model changed, so bake/restore cycles never accumulate numbered duplicates.

Requirements and limits. Enable Read/Write in the model importer. Baking requires an imported mesh asset so CrowPSX can save the copy beside its model and retain a source reference for Restore. Scene-only and procedural meshes cannot be baked. Positional welding also averages surfaces that touch, which can join outline regions you intended to keep separate.

Rendering#

Opaque/Cutout/Transparent modes; source alpha and separate Alpha Map; Bake Transparency Map; alpha contrast/power/bias, clipping, and dithering; Cull, Z Write, Z Test, depth bias, queue, stencil, and GPU instancing.

Grunge and Emission#

Available only on shaders that declare the corresponding properties. The inspector hides unsupported sections automatically.

The Grunge layer and the Grunge Mask each choose a Projection Type, presented the same way as the Depth Volume decal's:

Type Cost Behavior
UV 1 fetch Follows the mesh texture coordinates. The default.
Planar 1 fetch Projects from one direction (X, Y, or Z). Surfaces facing away from it stretch.
Biplanar 2 fetches Blends the selected pair (XY, XZ, or YZ) using the surface normal.
Triplanar 3 fetches Blends all three directions using the surface normal.

Planar and Biplanar sample only their enabled axes, so they are genuinely cheaper than Triplanar rather than Triplanar with some weights zeroed. Projection Blend Sharpness applies to Biplanar and Triplanar only; Planar has nothing to blend between. Use Local Position stays available in every mode, because the breakup and streak noise are driven from that position even under UV mapping.

Grunge follows height parallax in every projection type. UV mapping follows it through the displaced texture coordinates; the projected types are addressed by position instead, so parallax additionally publishes its displacement in world space and the projection position picks it up. This also covers the breakup and streak noise, which are position-addressed even under UV mapping.

CrowPSX 1.1.0 · CrowBite
Shader reference and setup guides.