Files
racing/graphics.md
2026-08-16 23:04:02 +05:00

4.0 KiB
Raw Permalink Blame History

BRIEF: NFS 2015-Style Wet Perma-Night Scene Setup (Raylib / C)

1. Goal

Transform an existing basic 3D scene (containing car model, road surfaces, and city building meshes with flat albedo textures) into a high-contrast, moody, wet perma-night aesthetic inspired by Need for Speed (2015).


2. Technical Stack Context

  • Framework: Raylib (C/C++)
  • Core APIs: Custom GLSL Shaders (Shader / Fragment Shaders), RenderTexture2D (FBOs), rlgl for state/texture management.
  • Goal Output: Modular shader code and pass-management architecture that runs efficiently on Raylib's forward renderer.

3. Implementation Roadmap & Execution Tasks

Phase 1: Material & Wetness Shader (wet_road.fs)

Modify the primary object shader used for terrain/road surfaces to support a wetness model.

  • Inputs Needed:
    • texture0 (Albedo / Diffuse)
    • texture1 (Normal Map)
    • texture2 (Roughness Map or Puddle Noise Mask)
    • Uniform float u_wetness (Range: 0.0 to 1.0)
  • Shader Logic Requirements:
    • Albedo Darkening: Darken base albedo by ~3040% on wet areas (porous surfaces darken when saturated).
    • Roughness Modulation: Force surface roughness down to near-mirror levels (~0.02 - 0.1) based on u_wetness and the puddle mask.
    • Normal Flattening for Puddles: In high-puddle mask areas, lerp surface normals toward vec3(0.0, 1.0, 0.0) to simulate smooth standing water.

Phase 2: Lighting & Emissive Setup

Configure scene lights and emissive materials for night contrast.

  • Global Ambient Light: Lower global ambient color to a dark, cool navy (RGB: 10, 15, 30).
  • Emissive Material Handling:
    • Add support for an emissive map/uniform on neon signs, building windows, and car light meshes.
    • Multiply emissive output by an intensity factor (> 2.0) to ensure they trigger the Bloom threshold in post-processing.
  • Point & Spot Lights:
    • Implement dynamic point lights for streetlights and headlights with quadratic distance attenuation (1.0 / (att_const + att_linear * d + att_quad * d * d)).

Phase 3: Post-Processing Framebuffer Pipeline (main.c)

Set up offscreen rendering to enable screen-space passes.

  • Render Texture Setup:
    • Create a master RenderTexture2D targetScene FBO matching screen resolution.
    • Create a secondary RenderTexture2D pingPongBlur[2] FBO pair for downscaled bloom processing.
  • Render Loop Flow:
    1. BeginTextureMode(targetScene) \rightarrow Render all 3D geometry using object shaders.
    2. EndTextureMode()
    3. Extract bright pixels from targetScene to bloom FBO via threshold shader (luminance > 0.7).
    4. Perform horizontal and vertical blur passes on the bright map.
    5. Composite original scene + blurred bloom + final color grading onto the screen.

Phase 4: Color Grading & Anamorphic Bloom Shader (post_process.fs)

Apply the final cinematic "lens" pass over the scene texture.

  • Heavy / Anamorphic Bloom:
    • Scale horizontal blur kernel radius larger than vertical to simulate anamorphic lens flares from streetlights and wet ground reflections.
  • High-Contrast Night LUT / Grading:
    • Crushed deep blacks (#050508).
    • Cool cyan/teal shadows and warm orange/amber highlights for light sources.
  • Vignette & Lens Effects:
    • Radial vignette intensity dropping at screen edges.
    • Subtle chromatic aberration (offset Red/Blue channels slightly near screen borders).

Phase 5: Simple Reflection Pass (Ground / Car)

  • Implement a basic planar reflection pass or sample a low-resolution cubemap probe inside the wet_road.fs fragment shader to give wet surfaces mirror-like reflections of the ambient sky and light sources.

4. Deliverables Checklist

  1. wet_material.fs / wet_material.vs: Shader handling albedo darkening, normal mapping, and specular puddle blending.
  2. post_process.fs: Screen-space shader combining Bloom, Color Grading, Vignette, and Chromatic Aberration.
  3. Updated Raylib C loop establishing the RenderTexture2D pipeline and uniform bindings.