java图形gouraud阴影

时间:2013-04-22 19:25:24

标签: java graphics

我想用gouraud阴影填充三角形 我计算了每个顶点的法线并使用了以下代码,但它无法正常工作 我使用这些公式对y进行内插颜色

  Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
  Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
  Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;

使用

反对x方向
 rr =  r2- (r2-r1)*(Xs2-j)/dxs;
方法drawCurrentTriangle(Graphics2D g)中的

如何从插值顶点法线计算颜色(场景中没有灯光(只有三角形颜色))

public boolean convert(Triangle triangle) {

    ensureCapacity();
    clearCurrentScan();

    triangle.getVlist()[0].r = triangle.normals[0].x;
    triangle.getVlist()[0].g = triangle.normals[0].y;
    triangle.getVlist()[0].b = triangle.normals[0].z;
    triangle.getVlist()[1].r = triangle.normals[1].x;
    triangle.getVlist()[1].g = triangle.normals[1].y;
    triangle.getVlist()[1].b = triangle.normals[1].z;
    triangle.getVlist()[2].r = triangle.normals[2].x;
    triangle.getVlist()[2].g = triangle.normals[2].y;
    triangle.getVlist()[2].b = triangle.normals[2].z;
    for (int i = 0; i < 3; i++) {
        Vector3d v1 = triangle.getVlist()[i];
        Vector3d v2;
        if (i == 2) {
            v2 = triangle.getVlist()[0];
        } else {
            v2 = triangle.getVlist()[i + 1];
        }


        // ensure v1.y < v2.y
        if (v1.y > v2.y) {
            Vector3d temp = v1;
            v1 = v2;
            v2 = temp;
        }
        double dy = v2.y - v1.y;

        Ir1 = v1.r;
        Ig1 = v1.g;
        Ib1 = v1.b;
        Ir2 = v2.r;
        Ig2 = v2.g;
        Ib2 = v2.b;

        // ignore horizontal lines
        if (dy == 0) {
            continue;
        }

        int startY = Math.max(FastMath.ceil(v1.y), minY);
        int endY = Math.min(FastMath.ceil(v2.y) - 1, maxY);
        top = Math.min(top, startY);
        bottom = Math.max(bottom, endY);
        double dx = v2.x - v1.x;

        double Ir;
        double Ig;
        double Ib;
        double Ic;
        double Ia;
        double Yc;
        // special case: vertical line
        if (dx == 0) {
            int x = FastMath.ceil(v1.x);
            // ensure x within view bounds

            x = Math.min(maxX + 1, Math.max(x, minX));
            for (int y = startY; y <= endY; y++) {
                Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
                Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
                Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;

                scans[y].setBoundary(x, Ir, Ig, Ib);
            }
        } else {
            // scan-convert this edge (line equation)
            double gradient = dx / dy;

            // (slower version)
            for (int y = startY; y <= endY; y++) {
                int x = FastMath.ceil(v1.x + (y - v1.y) * gradient);
                // ensure x within view bounds
                x = Math.min(maxX + 1, Math.max(x, minX));
                Ir = Ir2 - (Ir2 - Ir1)* (v2.y -y)/dy;
                Ig = Ig2 - (Ig2 - Ig1)* (v2.y -y)/dy;
                Ib = Ib2 - (Ib2 - Ib1)* (v2.y -y)/dy;
                scans[y].setBoundary(x, Ir, Ig, Ib);
            }

            // check if visible (any valid scans)
            for (int i = top; i <= bottom; i++) {
                if (scans[i].isValid()) {
                    return true;
                }
            }
            return false;

        }
    }
}

protected void drawCurrentTriangle(Graphics2D g) {
    int y = scanConverter.getTopBoundary();
    double Xs1 = 0;
    double Xs2 = 0;
    double dxs = 0;
    double r1 = 0;
    double g1 = 0;
    double b1 = 0;
    double r2 = 0;
    double g2 = 0;
    double b2 = 0;
    double rr = 0;
    double gg = 0;
    double bb = 0;
    while (y <= scanConverter.getBottomBoundary()) {
        GouraudTriangleScanConverter.Scan scan = scanConverter.getScan(y);
        if (scan.isValid()) {

            r1 = scan.rL;
            g1 = scan.gL;
            b1 = scan.bL;

            r2 = scan.rR;
            g2 = scan.gR;
            b2 = scan.bR;

            Xs1 = scan.left;
            Xs2 = scan.right;
            dxs = Xs2-Xs1;

            for (int j = scan.left; j < scan.right; j++) {

                rr =  r2- (r2-r1)*(Xs2-j)/dxs;
                gg = g2- (g2-g1)*(Xs2-j)/dxs;
                bb = b2- (b2-b1)*(Xs2-j)/dxs;

                if(rr > 255) rr = 255;
                if(gg > 255) gg = 255;
                if(bb > 255) bb = 255;
                g.setColor(new Color((int)rr, (int)gg, (int)bb));
                g.drawLine(j,y,j,y);
            }
            //g.drawLine(scan.right,y,scan.right,y);
        }
        y++;
    }

}


public static class Scan {
    public int left;
    public int right;
    public double rL = -1;
    public double gL = -1;
    public double bL = -1;
    public double rR = -1;
    public double gR = -1;
    public double bR = -1;

    /**
     * Sets the left and right boundary for this scan if
     * the x value is outside the current boundary.
     */
    public void setBoundary(int x, double r, double g, double b) {
        if (x > max)
            max = x;

        if (x < left) {
            left = x;
            rL = r;
            gL = g;
            bL = b;
        }
        if (x - 1 > right) {
            right = x - 1;
            rR = r;
            gR = g;
            bR = b;
        }

    }


    /**
    * Determines if this scan is valid (if left <= right).
    */
    public boolean isValid() {
        return (left <= right);
    }

}

我怎样才能将颜色应用于网格。当我进去的时候 修复颜色(无光照)

0 个答案:

没有答案