混合/光滑着色材料

时间:2014-02-19 20:20:08

标签: c# wpf

我正在使用GeometryModel3D在wpf c#中创建和绘制三角形网格。我一直试图弄清楚如何在三角形上创建平滑的阴影,就像经典的openGL平滑阴影三角形一样。

我想为每个顶点定义一种颜色,然后在脸上插入颜色,就像这样,假设三种颜色为红色,绿色和蓝色。

enter image description here

我以为我需要使用画笔,但我无法弄清楚如何使用。 所以任何帮助都会受到赞赏,或任何指向指南的指针都告诉我如何实现这一目标。

修改 我看了Triangular Gradient in WPF3D,它似乎部分地回答了这个问题,只是使用了xaml。 不幸的是,它似乎需要等边三角形。

第二次编辑 上面的答案使用RadialGradientBrushRadiusXRadiusY是否曾使其成为椭圆形而非圆形?

第三次编辑 好的,我很确定我可以使用RadialGradientBrush。我认为我能做的是,找到三角形外接圆的中心,并创建一个RadialGradientBrush RadiusXRadiusY等于半径,如果是外接圆。然后,我会使用RadialGradientBrushGradientOrigin的焦点移动到顶点。

GradientOrigin以两个双X,Y为中心,两者都在区间[0,1]。从我可以读到的是X = 0.0是左侧,X = 1.0是右侧,Y = 0.0是顶部,Y = 1.0是底部。我无法弄清楚的是,这个映射[0,1] x [0,1]是一个圆圈,还是一个正方形?从三角形顶点到[0,1] x [0,1]的映射取决于该区间所代表的形状。

2 个答案:

答案 0 :(得分:1)

你听说过WPF的Helix 3D Toolkit吗?

我没有达到你想要的程度,但我想通过查看 Surface Demo 示例是可能的:

enter image description here

答案 1 :(得分:1)

肯定有图书馆,但要提供一些简单的方法,搜索一些谷歌,http://www.geeksforgeeks.org/check-whether-a-given-point-lies-inside-a-triangle-or-not/

计算角落的距离,提供有关平滑颜色的信息。检查点是否为三角形。

float area(int x1, int y1, int x2, int y2, int x3, int y3)
        {
            return (float)Math.Abs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0);
        }

        bool isInside(int x1, int y1, int x2, int y2, int x3, int y3, int x, int y)
        {
            /* Calculate area of triangle ABC */
            float A = area(x1, y1, x2, y2, x3, y3);

            /* Calculate area of triangle PBC */
            float A1 = area(x, y, x2, y2, x3, y3);

            /* Calculate area of triangle PAC */
            float A2 = area(x1, y1, x, y, x3, y3);

            /* Calculate area of triangle PAB */
            float A3 = area(x1, y1, x2, y2, x, y);

            /* Check if sum of A1, A2 and A3 is same as A */
            return (A == A1 + A2 + A3);
        }


 for (int ii = 5; ii < 100; ii++)
          {
               for (int jj = 5; jj < 100; jj++)
                {
                        int distanceRed =0, distanceGreen =0,distanceBlue =0;
                        if (isInside(30, 50, 30, 90, 20, 70, ii, jj))
                        {
                              distanceRed = (int)Math.Sqrt(((ii - 30) * (ii - 30) + (jj - 50) * (jj - 50)));
                              distanceGreen = (int)Math.Sqrt(((ii - 30) * (ii - 30) + (jj - 90) * (jj - 90)));
                              distanceBlue = (int)Math.Sqrt(((ii - 20) * (ii - 20) + (jj - 70) * (jj - 70)));
                          }
                          else
                          {
                               distanceRed = 0; distanceGreen = 0; distanceBlue = 0;
                          }

                              ptr[(((int)jj) * 3) + ((int)ii) * stride] = (byte)(distanceRed % 256);
                              ptr[(((int)jj) * 3) + ((int)ii) * stride + 1] = (byte)(distanceGreen % 256);
                              ptr[(((int)jj) * 3) + ((int)ii) * stride + 2] = (byte)(distanceBlue % 256);

                           }
                       }

给出了结果:

enter image description here

无法适应红色。也许模数在这里是错误的。 sqrt也是效率低下的。