Результат:
Вот результат выполнения шейдера с использованием «Усилительный шейдер» :
Решение:
Сначала мы назовем зеленый куб "пересечением" , а красный куб "межсекретным" .
Итаккак и в случае с плоскостью, вырез работает, потому что задняя поверхность пересечения показана, когда она находится внутри интерсекрета, а передняя сторона межсекретария показана, когда она находится внутри пересекателя.
Создание шейдера (который используется обоими кубами) и сложите их в два отдельных материала - примените отдельные материалы к каждому кубу. После этого мы можем перейти к фактическому шейдерному узлу.
Сначала нам нужно убедиться, что «Режим отбраковки» выключен (Выходной узел> Режим отбраковки> выключен). Это обеспечит фактическую визуализацию задней грани (это можно оптимизировать в зависимости от того, где находится куб в пересечении).
Далее нам нужно получить точку поверхности в пространстве объектов:
Большинство переменных будут определены в скрипте . Матрица вращения используется для поворота точки . Тем не менее, он инвертируется, так как матрица вращения поворачивает куб в мировое пространство, поэтому, инвертируя это, можно повернуть точку мирового пространства в пространство объекта. Мы также получаем "_ Cubepos", которая является позицией куба для пересечения (например, это будет пересечение, если шейдер находится на промежуточном объекте). Это вычитается миром pos, поскольку матрица вращения вращается вокруг начала координат. После этого он добавляется обратно, чтобы быть в правильном положении.
Это приводит к следующему разделу, где экстенты добавляются и вычитаютсяна "_ Cubepos" и "_ CubeExtent" для поиска минимального и максимального экстентов.
К сожалению, у шейдера Amplify нет хорошего способа проверить, лежит ли вектор в двух векторах. Поэтому мы должны разбить его на компоненты. (Я призываю вас научиться писать шейдеры). Каждое сравнение с диапазоном возвращает 1, если точка в пространстве объекта находится в пределах экстентов для каждой оси. Если возвращается 0, мы используем последний узел умножения, чтобы убедиться, что конечный результат будет 0.
Наконец, мы получаемпоследняя часть шейдера. «IsIntersector» устанавливается в сценарии равным 1 или 0 в зависимости от того, используется ли куб, на который мы ссылаемся, для пересечения или является межсекретным. В зависимости от сценария, здесь мы устанавливаем маску непрозрачности на 1 или 0.
После этого мы должны определить скрипт для присоединения к каждому объекту. Добавьте новый скрипт и введите следующее:
[ExecuteInEditMode]
public class SetVar : MonoBehaviour
{
//Transform of opposite cube
public Transform intersectingCube;
//Is this an intersector or intersectee
public bool isIntersector;
//Material of object
public Material mat;
// Start is called before the first frame update
void Start()
{
//Get material
mat = GetComponent<Renderer>().material;
}
// Update is called once per frame
void OnRenderObject()
{
//Calculate rotation matrix
Matrix4x4 m = Matrix4x4.TRS(-intersectingCube.position, intersectingCube.rotation, Vector3.one);
//Set shader variables
mat.SetMatrix("RotationMatrix", m);
mat.SetVector("_Cubepos", intersectingCube.position);
mat.SetVector("_CubeExtent", intersectingCube.localScale / 2.0f);
mat.SetFloat("_IsIntersector", (isIntersector) ? 0 : 1);
}
}
Затем мы можем установить правильные значения инспектора в зависимости от того, является ли куб пересечением или межсекретным. Вот пример для куба пересечения:
Убедитесь, что IsIntersector отмечен галочкой, в зависимости от того, является ли кубявляется пересечением или нет.
Вот ссылка на шейдер: http://paste.amplify.pt/view/raw/4b248bc3. Также сделать это для любой сетки очень сложная операция - слишком сложная для узлов. Узнайте о коде шейдера и используйте алгоритм лучевого вещания, чтобы определить, находится ли точка внутри куба.
Кроме того, альтернативно для любой выпуклой формы. Вы можете рассчитать каждую плоскость, а затем, используя уже используемый метод, можете проверить, работает ли точка мирового положения для каждой плоскости. Для куба было бы 6 плоскостей, однако он немного медленнее, чем описанный выше метод (так как он оптимизирован для куба).