2012-05-05 2 views
2

Я изучаю DirectX и перешел в кодирование HLSL. До того, как я использовал свой собственный .fx-файл, я создал skybox для игры с вершинным буфером quads. Все отлично работало ... текстура сопоставлена ​​и завернута красиво. Однако теперь, когда у меня есть настройка HLSL для управления вершинами, есть отличительные швы, где встречаются квадроциклы. Текстуры все выстраиваются правильно, я просто не могу избавиться от этого проклятого шва!Проблемы с HLSL и DX Skybox (создает швы)

Я склонен думать, что проблема связана с texCube ... или, скорее, с информацией о текстурировании. Я текстурирую квадратики в DX ... может быть, я все еще не совсем понимаю связь между этими двумя ... не уверен. В любом случае спасибо за помощь заранее!

Хереса .fx файла:

float4x4 World; 
float4x4 View; 
float4x4 Projection; 

float3 CameraPosition; 

Texture SkyBoxTexture; 

samplerCUBE SkyBoxSampler = sampler_state 
{ 
    texture = <SkyBoxTexture>; 
    minfilter = ANISOTROPIC; 
    mipfilter = LINEAR; 
    AddressU = Wrap; 
    AddressV = Wrap; 
    AddressW = Wrap; 
}; 

struct VertexShaderInput 
{ 
    float4 Position : POSITION0; 
}; 

struct VertexShaderOutput 
{ 
    float4 Position : POSITION0; 
    float3 TextureCoordinate : TEXCOORD0; 
}; 

VertexShaderOutput VertexShaderFunction(VertexShaderInput input) 
{ 
    VertexShaderOutput output; 

    float4 worldPosition = mul(input.Position, World); 
    float4 viewPosition = mul(worldPosition, View); 
    output.Position = mul(viewPosition, Projection); 

    float4 VertexPosition = mul(input.Position, World); 
    output.TextureCoordinate = VertexPosition - CameraPosition; 

    return output; 
} 

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 
{ 
    return texCUBE(SkyBoxSampler, normalize(input.TextureCoordinate)); 
} 

technique Skybox 
{ 
    pass Pass1 
    { 
     VertexShader = compile vs_2_0 VertexShaderFunction(); 
     PixelShader = compile ps_2_0 PixelShaderFunction(); 
    } 
} 

ответ

1

Чтобы избежать швов, вам необходимо нарисовать свой skybox в одиночном вызове DrawIndexedPrimitive, предпочтительно используя полосу треугольника. НЕ рисуйте каждую грань как отдельный примитив, преобразованный с помощью отдельной матрицы или что-то в этом роде - вы получите швы. Если вы по какой-то необъяснимой причине не хотите использовать одиночный вызов DrawIndexedPrimitive для частей skybox, вы должны убедиться, что все лица рисованы с использованием той же матрицы (матрица одинакового мира + вид + проекция, используемая в каждом вызове) и одинаковые значения координат для угла вершины - то есть «верхняя» грань должны использовать точно такие же векторы (положение) для углов, которые используются «боковыми» гранями.

Другое дело, что вы должны хранить или скайбокса в

  1. cubemap (выглядит как то, что вы делаете) - сделать только 8 вершин для скайбоксе, рисовать их как индексированные примитивно.
  2. Или развернутая текстура «атласа», в которой заполнены неиспользуемые области. с границей цвет.

Или - если вы в порядке с шейдерами, вы можете «raytrace» skybox использовать шейдер.

1

Вы должны зажать координаты текстуры с setsampler состояния избавиться от шва. На этой странице toymaker объясняется это. Toymaker - отличный сайт для изучения Direct3D, вы должны проверить учебники, если у вас возникнут проблемы.

+0

Я понимаю концепцию зажима ... и, как сказано, у меня нет никаких проблем с этим skybox вне HLSL ... настройка состояния рендеринга после рендеринга квадрантов отлично работает. Проблема в том, что я использую шейдеры, поэтому проблема исходит из файла .fx. Теперь я использовал параметр CLAMP для координат tex, но он не работает ... wrap (то, что im использует здесь) работает, но я получаю швы. Я предполагаю, потому что я построил коробку из квадрациклов, но я использовал функцию texCUBE в HLSL. Значит, реальная проблема в том, что я должен использовать вместо этого?(при условии, что я прав) –

+0

FYI Я просто попробовал свой шейдер, и он работал без швов. – CarlJohnson

+0

+1 для томакера. – Jono

1

Вам может понравиться нарисовать skybox, используя только один квад. Все, что вам нужно, это обратная матрица World * View * Proj, то есть (World * View * Proj)^(- 1).

Вершины квадроцикла должны быть: (1, 1, 1, 1), (1, -1, 1, 1), (-1, 1, 1, 1), (-1, -1 , 1, 1).

Затем вычислить координаты текстуры в VS:

float4 pos = mul(vPos, WorldViewProjMatrixInv); 
float3 tex_coord = pos.xyz/pos.w; 

И, наконец, вы образец текстуры в PS:

float4 color = texCUBE(sampler, tex_coord); 

Нет беспокоиться о каких-либо швов! :)

+0

Помните, что преобразование Мира должно быть переводом на позицию камеры. – miloszmaki