Пример #1
0
        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
                            });
                        }
                    }
                }
            }
        }
Пример #2
0
        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);
                }
            }
        }