
path-tracing-reverse
by letta-ai
A shared repository for skills.
SKILL.md
name: path-tracing-reverse description: Guidance for reverse engineering graphics rendering programs (ray tracers, path tracers) from binary executables. This skill should be used when tasked with recreating a program that generates images through ray/path tracing, particularly when the goal is to achieve pixel-perfect or near-pixel-perfect output matching. Applies to tasks requiring binary analysis, floating-point constant extraction, and systematic algorithm reconstruction.
Path Tracing Reverse Engineering
Overview
This skill provides a systematic approach to reverse engineering graphics rendering binaries (ray tracers, path tracers, renderers) with high-fidelity output matching requirements. The primary challenge is achieving pixel-perfect or near-pixel-perfect reproduction (>99% similarity), which requires precise extraction of algorithms, constants, and rendering parameters rather than approximation.
Critical Success Factors
When high similarity thresholds (>99%) are required:
- Exact constant extraction is mandatory - Guessing or approximating floating-point values will fail
- Complete algorithm reconstruction - Partial understanding leads to systematic errors across large pixel regions
- Component isolation - Each rendering component (sky, ground, objects, lighting) must be verified independently
- Binary comparison strategy - Identify exactly which pixels differ and trace differences to specific algorithm components
Systematic Approach
Phase 1: Initial Analysis and Output Characterization
Before examining the binary internals:
- Run the program and capture output - Determine image dimensions, format (PPM, PNG, etc.), and general content
- Analyze the output image systematically:
- Sample pixels at regular intervals across the entire image
- Identify distinct regions (sky, ground, objects, shadows)
- Note color distributions and transitions
- Map out approximate boundaries between rendering components
- Extract string information - Use
stringsto find function names, file paths, and embedded text that hints at the algorithm
Phase 2: Comprehensive Constant Extraction
Extract ALL floating-point constants before writing any code:
- Dump the rodata section -
objdump -s -j .rodata binaryorreadelf -x .rodata binary - Identify float patterns - Look for 4-byte sequences that decode to reasonable float values (0.0-1.0 for colors, larger values for positions)
- Create a constant map - Document every extracted constant with its address
- Cross-reference with disassembly - Determine which function uses each constant
Example extraction approach:
# Dump rodata and decode floats
objdump -s -j .rodata binary | grep -E "^\s+[0-9a-f]+" | while read addr data; do
# Parse and decode 4-byte float sequences
done
Phase 3: Function-by-Function Reverse Engineering
Identify and completely reverse engineer each function:
- List all functions - Use
nmorobjdump -tto identify symbols - Map the call graph - Understand which functions call which
- Prioritize rendering functions - Focus on functions like:
sphere_intersect,ray_intersect(geometry intersection)vector_normalize,vector_dot,vector_cross(math utilities)shade,illuminate,reflect(lighting calculations)trace,cast_ray(main rendering loop)
- Translate each function to pseudocode - Do not skip to implementation until each function is fully understood
Phase 4: Component-by-Component Implementation
Implement and verify each component separately:
- Start with the simplest component - Usually the sky/background gradient
- Verify against the original output before moving to the next component
- Test intersection routines independently - Create test cases that verify geometry calculations
- Add lighting last - Lighting errors compound with geometry errors
Phase 5: Binary Comparison and Debugging
When output doesn't match:
- Compute per-pixel differences - Create a difference map showing exact deviations
- Identify systematic vs. random errors:
- Systematic errors in one region = algorithm error for that component
- Off-by-one patterns = rounding or precision difference
- Color tint across objects = lighting model error
- Trace errors to specific constants or formulas - A wrong constant produces predictable error patterns
Common Pitfalls
Pitfall 1: Trial-and-Error Constant Adjustment
Problem: Making small adjustments to constants (0.747 → 0.690) based on visual comparison without understanding why values differ.
Solution: Extract exact constants from the binary. If a value doesn't match expectations, re-examine the disassembly rather than guessing.
Pitfall 2: Premature Implementation
Problem: Starting to write code before fully understanding the algorithm leads to incorrect assumptions being baked in.
Solution: Complete Phase 3 (full function reverse engineering) before writing implementation code.
Pitfall 3: Focusing on Easy Components While Ignoring Hard Ones
Problem: Spending effort perfecting the sky gradient (simple) while the sphere rendering (complex) remains completely wrong.
Solution: Identify all components early and allocate effort proportionally. A perfect sky with a broken sphere still fails similarity thresholds.
Pitfall 4: Assuming Simple Lighting Models
Problem: Assuming diffuse-only lighting when the binary uses more complex materials (specular, reflection, subsurface).
Solution: Analyze object colors carefully. Unexpected color tints (e.g., red tint on sphere: (51, 10, 10) vs expected gray) indicate material properties not accounted for.
Pitfall 5: Incomplete Scene Analysis
Problem: Missing objects in the scene due to incomplete analysis. Multiple gray values in color distribution may indicate multiple spheres.
Solution: Systematically analyze the entire output image. Count distinct object regions and verify each is accounted for.
Pitfall 6: Abandoning Disassembly Analysis
Problem: Starting disassembly of key functions but not following through to complete understanding.
Solution: For each identified function, create complete pseudocode before moving on. Mark functions as "fully understood" or "needs more analysis."
Verification Strategies
Strategy 1: Ground Truth Pixel Sampling
Sample specific pixels from the original output and verify the implementation produces identical values:
# Test critical pixels across different components
test_pixels = [
(0, 0), # Corner - likely sky
(400, 0), # Top center - sky
(400, 500), # Bottom center - ground
(400, 300), # Center - likely object
]
for x, y in test_pixels:
original = get_pixel(original_image, x, y)
generated = get_pixel(generated_image, x, y)
assert original == generated, f"Mismatch at ({x},{y}): {original} vs {generated}"
Strategy 2: Component Isolation Testing
Test each rendering component in isolation by masking other components:
- Sky-only test: Verify pixels in regions with no objects
- Ground-only test: Verify checkerboard or ground pattern without objects
- Object-only test: Compare pixels within object boundaries
Strategy 3: Difference Image Analysis
Generate a visual difference image to identify error patterns:
# Per-pixel absolute difference
diff_image = abs(original - generated)
# Highlight pixels exceeding threshold
error_mask = diff_image > threshold
Strategy 4: Statistical Comparison
Track multiple similarity metrics:
- Exact pixel match percentage - Should be very high (>95%) for success
- Mean absolute error - Identifies average deviation
- Max error - Identifies worst-case pixels for debugging
- Cosine similarity - Overall structural similarity (but can mask localized errors)
Ray Tracing Specific Knowledge
Common Ray Tracer Structure
Most simple ray tracers follow this pattern:
for each pixel (x, y):
ray = generate_ray(camera, x, y)
color = trace_ray(ray, scene, depth)
write_pixel(x, y, color)
trace_ray(ray, scene, depth):
hit = find_closest_intersection(ray, scene)
if no hit:
return background_color(ray)
return shade(hit, ray, scene, depth)
Key Constants to Extract
- Image dimensions: Width, height (often in rodata or hardcoded)
- Camera parameters: FOV, position, look-at direction
- Object definitions: Sphere centers, radii, colors/materials
- Light positions: Point light locations, colors, intensities
- Material properties: Diffuse/specular coefficients, shininess
Floating-Point Precision
- Binary may use
float(32-bit) ordouble(64-bit) - Check instruction suffixes in x86:
movss/addssfor float,movsd/addsdfor double - Ensure implementation uses same precision as original
Workflow Summary
- Characterize output - Dimensions, format, visual content
- Extract all constants - Complete rodata analysis
- Map all functions - Names, purposes, call relationships
- Reverse each function - Full pseudocode translation
- Implement by component - With verification at each step
- Binary comparison - Identify and fix remaining discrepancies
- Iterate - Use difference analysis to guide fixes
Avoid: Premature coding, constant guessing, partial function analysis, ignoring complex components.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon