Подтвердить что ты не робот

OpenGL/OpenTK Fill Interior Space

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

Предположим на мгновение, что вы можете физически разбить голову на бетонную стену, логически вы увидите только темноту. В OpenGL, однако, когда вы это делаете, мир естественным образом пуст и прозрачен из-за отбраковки и из-за того, как рисуется геометрия. Я хочу имитировать тьму/цвет/текстуру внутри него.

Я знаю, что некоторые игры делают это, накладывая текстуру/цвет непосредственно на hud - поэтому ослепляя игрока.

Есть ли другой способ сделать это? Предположим, что игрок стоит наполовину в воде; они могут частично видеть ниже волн. Как бы вы его заполнили, чтобы они не могли четко видеть, что сейчас находится на половине экрана?

Что называется этой концепцией?

4b9b3361

Ответ 1

Проблема с методом текстуры в передней части камеры - это текстура 2D, но вы хотите визуализировать срез трехмерного тома. В первую очередь, о чем вы говорите, идея "голова внутри стены", я укажу вам на "текстуру 3D/объем" . Для стоячего полу-в-воде вы после "объемного рендеринга" с "поглощением" (обсуждается @user3670102).

3D-текстурирование

Общая идея здесь заключается в том, что у вас есть функция, которая определяет цвет везде в трехмерном пространстве, а не только на поверхности (как при регулярном сопоставлении текстур). Это приятно, потому что вы можете поместить геометрию где угодно и покрасить ее в шейдер фрагмента на основе 3D-позиции. Подумайте о том, чтобы взять кусочек объема и посмотреть на цвет пересечения.

Для эффекта "голова в стене" вы можете нарисовать полноэкранный многоугольник перед игроком (прямо на ближней плоскости отсечения, хотя вам может понадобиться немного надавить вперед, чтобы его было не слишком мало) и цвет его основан на 3D-функции. Теперь он будет выглядеть достаточно прочным и перемещать объявление, которое игрок делает, а не нравится, что вы дешево застряли текстуру над экраном.

enter image description here

Фактическая функция может быть определена с помощью 3D-текстуры, но это очень интенсивно. Вместо этого вы можете изучить либо процедурный трехмерный цвет (примерный деревянный или кирпичный шейдер довольно распространен в качестве примера). Даже если предположить, что 2D-текстура "экструдируется" через громкость, будет работать или, еще лучше, весит 3 текстуры (по одной для каждой оси) в зависимости от угла пересечения/поверхности, на которой вы рисуете.

Обнаружение пересечения с геометрией и плоскостью ближнего отсечения, вероятно, самое сложное здесь. Если бы я был вами, я бы посмотрел на трюки с z-буфером и не заставлял рисовать все как сплошную несамопересекающуюся геометрию. Простая идея может заключаться в том, чтобы отрисовывать обратные лица только после того, как рисует все с лицевыми гранями. Если вы видите задние лица, что часть ближней плоскости должна быть внутри чего-то. Для этих пикселей вы могли бы вычислить положение плоскости отсечения в мировом пространстве и применить трехмерную текстуру. Хотя я подозреваю, что есть более быстрые способы, чем рисовать все дважды.

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

Поглощение

Звучит намного сложнее, чем есть на самом деле. Если у вас есть прозрачное твердое тело, что весь один цвет ( "однородный" ), то он удаляет свет, который должен пройти через него. Подумайте о многих альфа-прозрачных поверхностях, возьмите предел, и у вас есть экспоненциальная. Оставшийся свет близок к 1/exp(dist) или exp(-dist). Google "Закон о пиве". Из здесь,

vec3 Absorbance = WaterColor * WaterDensity * -WaterDepth;
vec3 Transmittance = exp(Absorbance);

Отличный способ найти расстояние через что-то - это сделать задние лица (или дно/водный пол) аддитивным смешением, используя шейдер, который рисует расстояние до текстуры с плавающей точкой. Затем переключитесь на субтрактивное смешение и сделайте все передние поверхности (или поверхность воды). Вы оставили текстуру, содержащую расстояния/глубину для вышеуказанного уравнения.

Обрезка тома

Объединяя две идеи, материал является прозрачным, но цвет (и, возможно, плотность) изменяется по всему объему. Это начинает усложняться, если у вас большое количество данных и вы хотите, чтобы они были быстрыми. Прямой способ сделать это состоит в том, чтобы численно интегрировать луч через трехмерную текстуру (или процедурную функцию, независимо от того, что вы используете), в то же время применяя функцию поглощения. Базовая интеграция Эйлера с грубой силой может начинать луч для каждого пикселя на ближней плоскости, а затем двигаться вперед на равных расстояниях. На каждом шаге, пока вы маршируете, вы предполагаете, что цвет остается постоянным и применяет абсорбцию, отслеживая, сколько света у вас осталось. Быстрый google поднимает этот.

Ответ 2

Это похоже на просмотр того, что называется "участвующими СМИ". На менее экстремальном конце у вас будет легкий туман или дымчатая дымка. В середине может быть, скажем, грязная вода. И крайний случай был бы вашим примером "голова в стене".

Выполнение этого физически точным способом не является тривиальным, поскольку эффект затемнения более выражен, когда толщина среды больше.

Но вы можете подделать это, сделав некоторые предположения и сделав внутреннюю геометрию (под водой или внутри стены) темнее благодаря уменьшенному освещению или темным цветам. Если вы заботитесь об эффекте глубины, посмотрите на OpenGL и туман.

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

Если вы действительно хотите сходить с ума, посмотрите на Kajia Rendering Equation. Это охватывает все (включая материал, который светится), но в целом нуждается в упрощении и приближении, чтобы быть более полезным.