private void CalculateVertexStep(int instanceCount) { for (int i = 0; i < instanceCount; i++) { foreach (var instancedAttribute in InstancedAttributes[_activeVertexShader]) { SetAttribute(_activeVertexShader, instancedAttribute.Key, instancedAttribute.Value[i]); } for (int j = 0; j < RenderData[ActiveVAO].Count; j++) { foreach (var attribute in Attributes[_activeVertexShader]) { SetAttribute(_activeVertexShader, attribute.Key, attribute.Value[(int)RenderData[ActiveVAO][j]]); } _activeVertexShader.Main(); _vertexPositions.Add(_activeVertexShader.Position * (1 / _activeVertexShader.Position.W)); foreach (var outValue in _activeVertexShader.GetOutValues()) { if (_vertexValues.ContainsKey(outValue.Key)) { _vertexValues[outValue.Key].Add(outValue.Value); } else { _vertexValues.Add(outValue.Key, new List <object> { outValue.Value }); } } } } }
public void Draw(Matrix4x4 modelMat, Camera cam) { this.Cam = cam; var viewMat = Matrix4x4.GenEulerMat(cam.euler.x, cam.euler.y, cam.euler.z) * Matrix4x4.GenTranslateMat(cam.translate.x, cam.translate.y, cam.translate.z); var projMat = Matrix4x4.GenFrustum(cam.fov, cam.aspect, cam.near, cam.far); var mvpMat = projMat * viewMat * modelMat; // set built-in shader vairables:我们内置的shader变量,都可以再这输入 VertexShader.Mats[0] = mvpMat; // vs transformations, 顶点着色器处理,一般就将顶点坐标变换到:clip pos foreach (var vertex in Vertices) { VertexShader.dc = vertex; VertexShader.Main(); } // ndc pos : Normalized Device Coordinates position,直译为:归一化设备坐标,“设备”两字可去掉,重点就是“归一化”,所以又叫“归一化坐标” foreach (var vertex in Vertices) { // perspective divide : 透视除法,除了clipPos坐标,其他fragmentShader的输入参数,需要插值处理的,都处理透视除法 vertex.invCamZ = 1 / vertex.clipPos.w; // jave.lin : inverse camera z,因为在proj矩阵m[4,3]==-1,然后投影矩阵相乘后,可将camera space下的顶点的z存于clipPos.w中 vertex.ndcPos = vertex.clipPos * vertex.invCamZ; #if PC vertex.inColor = vertex.color * vertex.invCamZ; vertex.inUV = vertex.uv * vertex.invCamZ; #endif } // win pos:窗口坐标变换(或叫映射也行) foreach (var vertex in Vertices) { vertex.winPos = Vector4.Get( Viewport.X + (vertex.ndcPos.x * 0.5f + 0.5f) * Viewport.Width, Viewport.Y + (1 - (vertex.ndcPos.y * 0.5f + 0.5f)) * Viewport.Height, vertex.clipPos.w, // cam z 1); } // primitive assembly:图元装配,这里只支持三角形 triangleList.Clear(); for (int i = 0; i < Indices.Count; i += 3) { var idx0 = Indices[i]; var idx1 = Indices[i + 1]; var idx2 = Indices[i + 2]; var t = new Triangle { dc0 = Vertices[idx0], dc1 = Vertices[idx1], dc2 = Vertices[idx2] }; triangleList.Add(t); } // clip:简单的裁剪处理,正常的裁剪需要对图元不同类型做不同处理,处理部分在裁剪视椎外的需要剪掉,然后再视椎内边缘生成对应的新的顶点 foreach (var t in triangleList) { if (shouldClip(t.dc0.ndcPos) || shouldClip(t.dc1.ndcPos) || shouldClip(t.dc2.ndcPos)) { t.clip = true; continue; } } // facing-cull:面向剔除 foreach (var t in triangleList) { if (FaceCull && faceClip(t)) { t.clip = true; continue; } } // rasterize and fs:栅格化+片段着色器处理 foreach (var t in triangleList) { if (t.clip) { continue; } if (Wireframe) { Rasterizer.DrawLine(t.dc0, t.dc1, this); Rasterizer.DrawLine(t.dc1, t.dc2, this); Rasterizer.DrawLine(t.dc2, t.dc0, this); } else { Rasterizer.DrawTriangle(t, this); } } }