Model Viewer is a real-time 3D model loading and rendering tool, developed as part of a DirectX 11 graphics assignment. This project focuses on implementing an OBJ file loader, handling various model formats, and rendering objects with Phong shading and tangent space basis calculations. Through this, I gained hands-on experience with normal mapping, lighting models, and debugging rendering pipelines.
Key Features:
Custom OBJ Loader supporting vertex normals, UVs, and materials.
Implemented Phong shading with diffuse, specular, ambient, and emissive lighting.
Support for debug visualization of normals, tangents, and bitangents.
Scene controls for sunlight direction, material toggles and basic movement.
🔹 Technologies Used: C++, DirectX 11, HLSL, OBJ File Parsing, CPU/GPU Mesh Processing.
Project Overview
Key Concepts
Throughout the development of the Model Viewer, I focused on several core graphics programming concepts:
Efficient OBJ File Parsing: Handling faces, normals, and materials efficiently for real-time rendering.
Phong Shading Model: Implementing diffuse, specular, ambient, and emissive components in HLSL.
Tangent Space Calculations: Ensuring correct normal maps & smooth shading using TBN basis vectors.
GPU Mesh Optimization: Reducing redundant calculations and improving performance for rendering.
Debug Visualization: Rendering normals, tangents, and bitangents for verification and debugging.
Challenges & Lessons Learned
🔹 Challenge 1: Loading & Parsing OBJ Files Efficiently
Issue: The OBJ format allows different types of face definitions (triangles, quads, polygons), and parsing them efficiently while supporting materials (usemtl
, mtllib
) was difficult.
Solution:
Implemented a custom OBJ parser that correctly extracts vertex positions, normals, and UVs.
Converted quads into triangles for proper rendering.
Ensured that materials were properly linked and loaded.
🔹 Challenge 2: Implementing Phong Shading with Correct Normal Transformations
Issue: Initial models had incorrect lighting due to improper normal transformations.
Solution:
Ensured normals are transformed correctly by applying the inverse transpose of the model matrix.
Implemented Phong shading using ambient, diffuse, specular, and emissive lighting components.
🔹 Challenge 3: Debugging Tangent Space Basis Vectors
Issue: Normal maps require tangent space calculations, and incorrect tangents lead to broken shading.
Solution:
Implemented TBN (Tangent, Bitangent, Normal) calculations for all vertices.
Verified the correctness by rendering debug tangent-space vectors.
💡 This project reinforced my ability to debug graphical issues, optimize file parsing, and correctly implement shading techniques.
Implementation Breakdown
Implementation Breakdown (How I Solved It)
🔹 OBJ File Loading & Parsing
Implemented an OBJ file parser that extracts:
Geometric vertices (
v
)Texture coordinates (
vt
)Vertex normals (
vn
)Polygon faces (
f
)Material libraries (
mtllib
,usemtl
)
Converted quad faces into triangles for compatibility.
Added a new function SplitAndTrim to get rid of any excess spaces and still have lines that are just the results of splitting on a token.
Allowed dynamic loading of
.obj
or.xml
model files via file selection dialog.
🔹 Implementing Phong Shading in HLSL
To achieve realistic shading, I implemented Phong shading with the following lighting components:
Ambient - Constant low-level lighting (background light)
DiffuseLight - reflected evenly across the surface
SpecularShininess - or highlight effect based on camera angle
EmissiveSelf - lit surfaces, glowing effect
This also required an update to my lightConstants that i was using to achieve debug use.