Я пытался реализовать учебник по ландшафту во «Введении в программирование игр» Фрэнка Луны. Мне удалось реализовать это с помощью файла эффекта.
Когда я пытаюсь разделить вершинный, корпусной, доменный и пиксельный шейдеры, я получаю очень странное поведение в текстурах ландшафта. После отладки понял, что проблема в вычислении координат UV-текстуры в доменном шейдере.
Вот как я вычисляю UV-координаты.
[domain("quad")]
DomainOut main(PatchTess patchTess,
float2 uv : SV_DomainLocation,
const OutputPatch<HullOut, 4> quad)
{
DomainOut dout;
// Bilinear interpolation.
dout.PosW = lerp(
lerp(quad[0].PosW, quad[1].PosW, uv.x),
lerp(quad[2].PosW, quad[3].PosW, uv.x),
uv.y);
dout.Tex = lerp(
lerp(quad[0].Tex, quad[1].Tex, uv.x),
lerp(quad[2].Tex, quad[3].Tex, uv.x),
uv.y);
// Tile layer textures over terrain.
dout.TiledTex = dout.Tex * 50.0f;
dout.TiledTex = dout.Tex*50.0f;
// Displacement mapping
dout.PosW.y = gHeightMap.SampleLevel(samHeightmap, dout.Tex, 0).r;
// NOTE: We tried computing the normal in the shader using finite difference,
// but the vertices move continuously with fractional_even which creates
// noticable light shimmering artifacts as the normal changes. Therefore,
// we moved the calculation to the pixel shader.
// Project to homogeneous clip space.
dout.PosH = mul(float4(dout.PosW, 1.0f), gViewProj);
return dout;
}
Я использую quads для шейдера домена.
После отладки с помощью графического анализатора я понял, что в доменном шейдере данные отличаются от файла эффекта доменного шейдера, который я реализовал, хотя в обоих файлах используется один и тот же код.
В чем может быть проблема?


У меня есть обновление, которым я хочу поделиться с вами. Поток данных, поступающий в шейдер домена, отличается от файла эффекта из отдельных файлов. Это не уравнение для расчета.
Что отличает поток данных, есть ли способ изменить порядок патчей, поступающих в шейдер предметной области из шейдера корпуса.
Это код пиксельного шейдера:
Texture2DArray gLayerMapArray : register(t3);
Texture2D gBlendMap : register(t1);
SamplerState samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
};
struct DomainOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float2 Tex : TEXCOORD0;
float2 TiledTex : TEXCOORD1;
};
float4 main(DomainOut pin) : SV_Target
{
//
// Texturing
//
float4 c0 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 0.0f));
float4 c1 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 1.0f));
float4 c2 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 2.0f));
float4 c3 = gLayerMapArray.Sample(samLinear, float3(pin.TiledTex, 3.0f));
// Sample the blend map.
float4 t = gBlendMap.Sample(samLinear, pin.Tex);
// Blend the layers on top of each other.
float4 texColor = c0;
texColor = lerp(texColor, c1, t.r);
texColor = lerp(texColor, c2, t.g);
texColor = lerp(texColor, c3, t.b);
return texColor;
}
Я добавил ссылки в исходный вопрос для изображений проблемы. Спасибо за поддержку.
Имеют ли ваши входные четырехугольники действительные координаты текстуры? Похоже, что все они равны нулю.
Да, четырехъядерный uv имеет значения (0,0), (0,03125,0), (0, 0,03125), (0,03215, 0,03215)
Вы можете это как-то проверить? Например. сопоставьте координаты текстуры с цветом. Возможно, существует неработающая ссылка, из-за которой координаты текстуры не достигают шейдера. Можете ли вы показать часть фрагментного шейдера, которая сэмплирует текстуру?
После дальнейшей отладки в доменном шейдере я обнаружил, что данные из файла эффекта находятся именно в файле эффекта и в файле доменного шейдера. Вы правы, проблема может быть связана с выборкой в пиксельном шейдере. Я обновил вопрос файлом пиксельного шейдера.
Код выглядит вполне нормально. Вы видите, что вы получаете, когда возвращаете pin.TiledTex из пиксельного шейдера? Если это выглядит странно, попробуйте pin.Tex. Если это все еще выглядит странно, попробуйте передать quad[0].Tex и т. д.
Я пробовал все это, я нашел проблему, но я не знаю, как ее решить. Проблема в выборке. Я сделал еще один новый проект, используя файл эффекта, и я умножил текс-корд на 10 в вершинном шейдере и позволил ратеризации интерполировать его, текстура повторяется 10 раз на простом поле. Когда я сделал тот же тест с моим отдельным кодом вершинного и пиксельного шейдера, текстура была подключена. Я не знаю почему. Добавляет ли файл эффекта некоторые значения по умолчанию в выборку. Я не знаю.
Итак, координаты текстуры, которые вы получаете в пиксельном шейдере, в порядке? Это то, что подтвердили ваши тесты? Я предполагаю, что координаты текстуры постоянны, так что сэмплер берет самый высокий уровень мип. Можете ли вы явно запросить нулевой уровень (используя SampleLevel)?
Я уже пробовал пробный уровень, но не работает
Спасибо, Нико, за поддержку. Вы очень помогли мне найти ответ.





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