Beispiel #1
0
        public PSOutput FragShader(VSOutput v)
        {
            //invert uv
            if (shaderContext.invertTexture)
            {
                //v.texcoord = new Vector2(1 - v.texcoord.X, 1 - v.texcoord.Y);
                v.texcoord = new Vector2(v.texcoord.X, 1 - v.texcoord.Y);
                //v.texcoord = new Vector2(1 - v.texcoord.X, v.texcoord.Y);
            }

            PSOutput OUT = new PSOutput();
            Vector4  col = v.color;

            if ((shaderContext.shadeMode == ShadeMode.Lighting ||
                 shaderContext.shadeMode == ShadeMode.NDotL) &&
                shaderContext.light != null)
            {
                Vector3 normalWorld = v.normalWorld;
                normalWorld = Vector3.Normalize(normalWorld);
                Vector3 lightDir = shaderContext.light.lightDirForShader;

                //Lambert Lighting
                float NDotL = Vector3.Dot(normalWorld, lightDir);
                NDotL = Utils.Clamp(NDotL, 0, 1);
                if (shaderContext.shadeMode == ShadeMode.Lighting && texture != null)
                {
                    Vector4 tex = texture.Tex2D(v.texcoord, shaderContext.textureFilterMode);
                    col = tex * (NDotL * shaderContext.light.lightColor + shaderContext.ambient);
                }
                else
                {
                    col = new Vector4(NDotL, NDotL, NDotL, 1f);
                }
            }
            else if (shaderContext.shadeMode == ShadeMode.Texture && texture != null)
            {
                col = texture.Tex2D(v.texcoord, shaderContext.textureFilterMode);
            }
            //col = new Vector4(v.texcoord.X, v.texcoord.Y, 0, 1 );
            OUT.color = col;
            return(OUT);
        }
Beispiel #2
0
        public void BarycentricRasterizeTriangle(VSOutput v0, VSOutput v1, VSOutput v2)
        {
            int     width  = context.frameSize.Width;
            int     height = context.frameSize.Height;
            Vector2 xy0    = new Vector2(v0.posScreen.X, v0.posScreen.Y);
            Vector2 xy1    = new Vector2(v1.posScreen.X, v1.posScreen.Y);
            Vector2 xy2    = new Vector2(v2.posScreen.X, v2.posScreen.Y);
            float   z0     = v0.posScreen.Z;
            float   z1     = v1.posScreen.Z;
            float   z2     = v2.posScreen.Z;

            //求包围盒
            float xmin = Math.Min(Math.Min(xy0.X, xy1.X), xy2.X);
            float xmax = Math.Max(Math.Max(xy0.X, xy1.X), xy2.X);
            float ymin = Math.Min(Math.Min(xy0.Y, xy1.Y), xy2.Y);
            float ymax = Math.Max(Math.Max(xy0.Y, xy1.Y), xy2.Y);
            //像素坐标包围盒
            int x0 = Utils.Clamp((int)xmin, 0, width - 1);
            int y0 = Utils.Clamp((int)ymin, 0, height - 1);
            int x1 = Utils.Clamp((int)xmax, 0, width - 1);
            int y1 = Utils.Clamp((int)ymax, 0, height - 1);



            for (int y = y0; y <= y1; ++y)
            {
                for (int x = x0; x <= x1; ++x)
                {
                    //加0.5取像素的中间位置的坐标
                    Vector2 pixel = new Vector2(x + 0.5f, y + 0.5f);
                    Vector3 w = BarycentricCoordinates(pixel, xy0, xy1, xy2);
                    float   w0 = w.X; float w1 = w.Y; float w2 = w.Z;
                    if (!(w0 >= 0 && w1 >= 0 && w2 >= 0))
                    {
                        //像素点不在三角形内
                        continue;
                    }

                    context.statics.fragmentCount += 1;


                    //深度测试
                    float depth = w0 * z0 + w1 * z1 + w2 * z2;
                    if (context.depthBuffer[x, y] < depth)
                    {
                        continue;
                    }

                    Color col;
                    if (context.drawMode == DrawMode.Depth)
                    {
                        Vector4 depthColor = new Vector4(depth, depth, depth, 1);
                        col = Utils.VectorToColor(depthColor);
                    }
                    else
                    {
                        //正常渲染

                        //插值UV等顶点属性
                        float fInvW = w0 * v0.position.W + w1 * v1.position.W + w2 * v2.position.W;
                        //由于position.W是1/W = 1/-Z_Eye
                        float   Z_Eye = 1f / fInvW;
                        Vector2 uv    = w0 * v0.texcoord + w1 * v1.texcoord + w2 * v2.texcoord;
                        uv *= Z_Eye;

                        Vector4 color = w0 * v0.color + w1 * v1.color + w2 * v2.color;
                        color *= Z_Eye;

                        Vector3 normalWorld = w0 * v0.normalWorld + w1 * v1.normalWorld + w2 * v2.normalWorld;

                        if (shader != null)
                        {
                            VSOutput fragment = new VSOutput();
                            //v.position =
                            fragment.normalWorld = normalWorld;
                            fragment.texcoord    = uv;
                            fragment.color       = color;

                            PSOutput OUT = shader.FragShader(fragment);
                            if (OUT.isDiscard)
                            {
                                continue;
                            }
                            col = Utils.VectorToColor(OUT.color);
                        }
                        else
                        {
                            col = Utils.VectorToColor(color);
                        }
                    }

                    context.depthBuffer[x, y] = depth;
                    DrawPixel(x, y, col);
                }
            }
        }