Прежде всего, для того, что вы, похоже, хотите сделать, рельефное отображение на самом деле является неправильным подходом: рельефное отображение - это изменение нормальной поверхности (в основном «вращение» пикселя в трехмерном пространстве), поэтому следуйте легким расчетам (например, отражение), вы видите вашу поверхность более сложной, чем она есть на самом деле (обратите внимание, что текстура этого пикселя остается на том же месте). Таким образом, рельефное отображение вовсе не изменяет положение текстуры мозаики океана, но изменяет то, что отражается океаном (например, путем изменения положения образца скайбокса,так что отражение неба в воде искажено). То, как вы его реализуете, больше похоже на «Что если мой экран будет океаном и будет отражать изображение плиток с текстурами океана».
Если вы действительно хотите использовать рельефное отображение, вам понадобится какой-то виддля текстуры большого неба, а затем , пока (не после) рисование плиток океана, вы вычислите примерное положение отражения этой текстуры неба (на основе положения плитки на экране) изатем измените эту позицию образца с помощью рельефного отображения. Все пока отрисовывают плитки, а не после отрисовки их к цели рендеринга.
Также возможно сделать это отложенным (более похоже на то, что вы делаете сейчас) - на самом деле, есть несколько способов сделать это - но в любом случае вам все равно нужно будет отобрать окончательный цвет с неба. текстура, не от цели рендеринга, на которой были нарисованы ваши плитки. Вместо этого цель рендеринга из ваших плиток будет содержать «мета» информацию (в зависимости от того, как именно вы хотите это сделать). Эта информация может быть цветом, который умножается на цвет текстуры неба (создавая «цветную» воду, например, для разных биомов или имитировать заходы / восходы солнца), или простым 1 или 0, чтобы указать, нет или нетлюбой океан, или карта рельефа на плитку (которую вы позволили бы применить «глобальный экран» и карту рельефа «на плитку» за один раз. Вам все равно нужен способ сказать «этот пиксель не океан»). не делайте ничего для этого "в цели рендеринга", или - если вы используете несколько целей рендеринга - все это одновременно. В любом случае, позиция выборки для цели (мишеней) рендеринга не , измененная с помощью рельефного отображения, только позиция выборки текстуры, которая отражается океаном. Таким образом, нет никакого смещения океана, так как мы вообще не касаемся позиций этого образца.
Теперь, чтобы создать вид, который больше похож на то, что вы, кажется, хотите (в зависимости от вашегоизображения), вы бы не использовали рельефное отображение, а вместо этого применили небольшой шум к позиции сэмпла в пиксельном шейдере (остальной код не нужно менять). Для этого ваш шейдер будет выглядеть примерно так:
texture noiseTexture;
sampler2D noiseSampler = sampler_state
{
Texture = <noiseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
float2 noiseOffset;
float2 noisePower;
float noiseFrequency;
VertexShaderOutput MainVS(in VertexShaderInput input)
{
VertexShaderOutput output = (VertexShaderOutput)0;
output.Pos = mul(input.Position, WorldViewProjection);
output.Color = input.Color;
return output;
}
float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : COLOR
{
float4 noise = tex2D(noiseSampler, (texCoord.xy + noiseOffset.xy) * noiseFrequency);
float2 offset = noisePower * (noise.xy - 0.5f) * 2.0f;
float4 color = tex2D(waterSampler, texCoord.xy + offset.xy);
return color;
}
Где noisePower будет (максимум) прибл. 1 по количеству горизонтальных / вертикальных плиток на экране, noiseOffset может использоваться для «перемещения» шума с течением времени на экране (должно быть в диапазоне [-1; 1]), а noiseFrequency является художественным параметром (я быначните с удвоенной максимальной мощности шума, а затем измените ее оттуда с более высокими значениями, делающими океан более искаженным). Таким образом, граница плиток искажается, но никогда не перемещается более чем на одну плитку в любом направлении (благодаря параметру noisePower). Также важно использовать правильный тип текстуры шума: белый шум, синий шум, возможно, текстура «не совсем шумная», построенная из синусоидальных волн и т. Д. Важно то, что «среднее» значение каждого пикселяоколо 0,5, поэтому смещения не происходит, а значения хорошо распределены в текстуре. Приблизительно, посмотрите, какой шум выглядит лучше для вас.
Примечание к коду шейдера: я не проверял этот код. Только то, что вы знаете, не то, чтобы было много места для ошибок.
Редактировать: В качестве бокового узла: Конечно, текстура неба не обязательно должна выглядеть как небо;)