Материал для смешивания/гладко-затенения

Я создаю и рисую треугольную сетку в wpf С#, используя GeometryModel3D. Я пытался выяснить, как создать гладкое затенение над треугольниками, например, классический гладкий затушеванный треугольник openGL.

Я хотел бы определить цвет для каждой вершины, а затем, используя цвета, интерполированные по лицу, как это, предполагая три цвета, в которых красный, зеленый и синий.

Я предположил, что мне нужно будет использовать кисть, но я не смог понять, как это сделать. Поэтому любая помощь будет оценена, или любой указатель на руководство, которое покажет мне, как достичь этого.

EDIT: Я посмотрел на Треугольный градиент в WPF3D, который, похоже, частично отвечает на вопрос, просто используя xaml. К несчастью, похоже, что нужны равносторонние треугольники.

2nd EDIT Ответ выше, использует RadialGradientBrush. Используются ли RadiusX и RadiusY, чтобы сделать его эллиптическим вместо кругового?

3rd EDIT Хорошо, я уверен, что могу использовать RadialGradientBrush. Я думаю, что могу сделать, найти центр окружности треугольников и создать RadialGradientBrush с RadiusX и RadiusY, равным радиусу, если окружность. Затем я переместил бы фокусную точку RadialGradientBrush в вершины с помощью GradientOrigin.

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 ответа

Конечно, для этого есть библиотеки, но для того, чтобы дать простой способ, поиск через некоторые google, 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);
 }
 }

дает результат:

Не удалось установить красный цвет. Может быть, modulo здесь не так. Также sqrt неэффективен.


Слышали ли вы о Helix 3D Toolkit для WPF?

Я не заходил так далеко, как вам хотелось бы, но я предполагаю, что это возможно, посмотрев пример Surface Demo:

licensed under cc by-sa 3.0 with attribution.