SoftRasterizer 渲染流程解析 概述 本文档详细分析 SoftRasterizer 的渲染管线实现,涵盖从模型加载到最终像素输出的完整流程。渲染管线主要分为初始化阶段和每帧渲染阶段。
核心渲染流程 1. 初始化阶段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Framebuffer framebuffer (width, height) ;Model model; model.loadFromObj ("resources/obj/african_head.obj" ); model.loadDiffuseTexture ("resources/diffuse/african_head_diffuse.tga" ); Camera camera (Vector3<float >(0 , 1 , 3 ), Vector3<float >(0 , 0 , 0 ), Vector3<float >(0 , 1 , 0 )) ;camera.setPerspective (45.0f , aspectRatio, near, far); Renderer renderer (framebuffer, camera) ;std::vector<Light> lights; auto shader = std::make_shared <BlinnPhongShader>();renderer.setShader (shader);
2. 每帧渲染阶段 1 2 3 4 5 6 7 8 9 currentShader->uniform_ModelMatrix = modelMatrix; currentShader->uniform_ViewMatrix = viewMatrix; currentShader->uniform_ProjectionMatrix = projectionMatrix; currentShader->uniform_MVP = projectionMatrix * viewMatrix * modelMatrix; currentShader->uniform_NormalMatrix = modelMatrix.inverse ().transpose (); currentShader->uniform_CameraPosition = cameraPosition; currentShader->uniform_Lights = lights; currentShader->uniform_Material = material;
2.2 顶点处理 1 2 3 4 5 6 7 8 virtual Varyings vertex (const VertexInput& input) = 0 ;
2.3 三角形组装与光栅化 1 2 3 4 5 6 7 8 9 10 11 12 float signedArea = (p1. x - p0. x) * (p2. y - p0. y) - (p2. x - p0. x) * (p1. y - p0. y);if (signedArea < 0 ) continue ;for (int y = yStart; y <= yEnd; ++y) { if (depth >= framebuffer.getDepth (x, y)) continue ; }
2.4 片段处理 1 2 3 4 5 6 7 8 virtual bool fragment (const Varyings& input, Vector3<float >& outColor) = 0 ;
2.5 帧缓冲更新 1 framebuffer.setPixel (x, y, fragmentColor, depth);
关键技术点 1. 透视校正插值 1 2 3 4 5 6 7 Varyings Renderer::interpolateVaryings (float t, const Varyings& start, const Varyings& end, float startInvW, float endInvW) { float currentInvW = startInvW + (endInvW - startInvW) * t; float currentW = 1.0f / currentInvW; }
2. 深度缓冲 1 2 3 4 5 screenVertices[j].z = (ndcPos.z + 1.0f ) * 0.5f ; if (depth >= framebuffer.getDepth (x, y)) continue ;
3. 光照计算优化 1 2 3 4 5 6 7 8 9 10 11 template <typename T>T fastPow (T base, int n) { T res = static_cast <T>(1 ); while (n) { if (n & 1 ) res = res * base; base = base * base; n >>= 1 ; } return res; }
渲染管线图示 1 2 3 4 5 6 7 8 9 10 graph TD A[模型加载] --> B[设置相机和光源] B --> C[设置着色器和材质] C --> D[顶点处理] D --> E[三角形组装] E --> F[光栅化] F --> G[片段处理] G --> H[深度测试] H --> I[帧缓冲更新] I --> J[输出图像]
性能优化
提前深度测试 :在片段着色器前进行深度测试
背面剔除 :减少约50%的三角形处理
快速幂算法 :优化高光计算
透视校正插值 :保证纹理和属性正确插值
后续改进计划
实现法线贴图支持
添加阴影计算
支持延迟渲染管线
实现多线程渲染