Войти
ПрограммированиеФорумГрафика

Неправильное отображение Skybox'а

#0
10:18, 6 мая 2017

Привет всем! Ребят, помогите разобраться со Skybox'ом. Не могу никак реализовать. В принципе все правильно делаю, но получаю вот такое:


Видите? Как бы картинка Skybox'а двигается вместе с камерой. Не пойму почему. Вот код шейдера:
TextureCube cubeMap;
SamplerState SampleType;

cbuffer ConstantMatrix : register( b0 )
{
  matrix WorldViewProj;
};

struct VS_INPUT
{
    float3 PosL : POSITION;
};

struct PS_INPUT
{
    float4 PosH : SV_POSITION;
    float3 PosL : POSITION;
};

// Вершинный шейдер
PS_INPUT VS( VS_INPUT input )
{
      PS_INPUT output;
  
  output.PosH = mul( float4( input.PosL, 1.0f ), WorldViewProj ).xyww;  
      output.PosL = input.PosL;
    
     return output;
}

float4 PS(PS_INPUT input) : SV_Target
{
    return cubeMap.Sample( SampleType, input.PosL );
}

Вот обновление:

void BTSSkyboxSystem :: execute()
{
  _rasterizerState    -> enableState();
  _depthStencilState  -> enableState();

  _vertexBuffer.applyVertexBuffer();
  _indexBuffer.applyIndexBuffer();

  _shaderSkybox.applytShader();

  _currentComponent -> getCubeMapTexture() -> applyTexture( 0 );

  auto      scene      =  _systemManager -> getScene();
  const auto&  viewMatrix    =  scene -> getViewTransform();
  XMMATRIX    invViewMatrix    =  XMMatrixTranspose( XMMatrixInverse( &XMVECTOR(), viewMatrix ) );
  XMFLOAT3    globalCameraPosition  =  XMFLOAT3( invViewMatrix._41, invViewMatrix._42, invViewMatrix._43 );

  XMMATRIX      worldMatrix  =  XMMatrixTranslation( globalCameraPosition.x, globalCameraPosition.y, globalCameraPosition.z );
  const auto&    projMatrix    =  XMMatrixTranspose( scene -> getProjTransform() );

  // Устанавливаем константный буфер матриц
  scene -> setTranform( worldMatrix * viewMatrix * projMatrix );

  // Рисуем
  BTSGraphics :: getInstance() -> getDeviceContext() -> IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  BTSGraphics :: getInstance() -> getDeviceContext() -> DrawIndexed( _indexBuffer.getNumIndices(), 0, 0 );  

  _rasterizerState    -> disableState();
  _depthStencilState  -> disableState();
}

Что может быть здесь не так? Подскажите пожалуйста


#1
10:41, 6 мая 2017

Dronas,

отрисовал бокс

У меня сфера
Установил единичную матрицу

Так если я буду перемещать камеру, то нужно и сферу перемещать, следовательно единичная матрица не пойдет. Или не так?
#2
10:42, 6 мая 2017

bretbas
по коду все верно, но

XMFLOAT3    globalCameraPosition  =  XMFLOAT3( invViewMatrix._41, invViewMatrix._42, invViewMatrix._43 );
попробуй позицию камеры брать не из матрицы рассчитанной наверняка через XMMatrixLookToLH/XMMatrixLookToRH, а из самой камеры,
дело в том что позиция из видовой матрицы это не совсем то что тебе нужно, что-бы понять это посмотри код функции к примеру
D3DXMatrixLookAtLH https://msdn.microsoft.com/ru-ru/library/windows/desktop/bb205342(v=vs.85).aspx (аналог XMMatrixLookToLH).
#3
11:10, 6 мая 2017

Andrey, Ну теперь передаю позицию камеры объекта:

...
XMFLOAT3    globalCameraPosition  =  _currentComponent -> getCameraObject()-> getGlobalPosition();

XMMATRIX    worldMatrix    =  XMMatrixTranslation( globalPosition.x, globalPosition.y, globalPosition.z );
const auto&  projMatrix      =  XMMatrixTranspose( scene -> getProjTransform() );

scene -> setTranform( worldMatrix * viewMatrix * projMatrix );

...

тоже самое. Skybox крутится вместе с камерой...бред какой-то

#4
11:51, 6 мая 2017

Так, получилось кое-что. Итак, если пишу вот так:

...
XMFLOAT3    globalCameraPosition    =  _currentComponent -> getCameraObject()-> getGlobalPosition();
XMFLOAT3    globalCameraRotation  =  _currentComponent -> getCameraObject()-> getGlobalRotation();

XMMATRIX    translationMatrix     =  XMMatrixTranslation( globalCameraPosition  .x, globalCameraPosition.y, globalCameraPosition.z );
XMMATRIX    rotateMatrix       =   XMMatrixRotationRollPitchYaw( -globalCameraRotation.x, -globalCameraRotation.y, -globalCameraRotation.z );
XMMATRIX   worldMatrix       =  translationMatrix * rotateMatrix;

scene -> setTranform( worldMatrix * projMatrix );
...
то по оси Y когда начинаю камеру крутить, то Skybox прорисовывается правильно. По X и Z как было до этого - неправильно...

Тоесть я вообще убрал матрицу вида в передачу шейдера и еще вращаю Skybox обратно моей камеры. По Y все ровно:)

Есть мысли?:)

#5
13:12, 6 мая 2017

Итак, вроде сделал. Инвертирую матрицу вращения камеры и умножаю с матрицей позиции камеры:

...
XMFLOAT3    globalCameraPosition    =  _currentComponent -> getCameraObject()-> getGlobalPosition();
XMFLOAT3    globalCameraRotation  =  _currentComponent -> getCameraObject()-> getGlobalRotation();

XMMATRIX    translationMatrix     =  XMMatrixTranslation( globalCameraPosition  .x, globalCameraPosition.y, globalCameraPosition.z );
XMMATRIX    rotateMatrix       =  XMMatrixInverse( &XMVECTOR(), XMMatrixRotationRollPitchYaw( globalCameraRotation.x, globalCameraRotation.y, globalCameraRotation.z ) );
XMMATRIX   worldMatrix       =  translationMatrix * rotateMatrix;

scene -> setTranform( worldMatrix * projMatrix );
...
Исходя из этого, можно сказать, что матрицу, которую нужно передавать в шейдер, это инвертированная матрица Мира нашей камеры, а матрица Мира камеры - это инвертированная матрица Вида. Получил вот что:
void BTSSkyboxSystem :: execute()
{
  _rasterizerState    -> enableState();
  _depthStencilState  -> enableState();

  _vertexBuffer.applyVertexBuffer();
  _indexBuffer.applyIndexBuffer();

  _shaderSkybox.applyShader();

  _currentComponent -> getCubeMapTexture() -> applyTexture( 0 );

  auto      scene        =  _systemManager -> getScene();
  const auto&  viewMatrix      =  scene -> getViewTransform();
  XMMATRIX    worldMatrixCamera    =  XMMatrixTranspose( XMMatrixInverse( &XMVECTOR(), viewMatrix ) );
  XMMATRIX    invWorldMatrixCamera  =  XMMatrixInverse( &XMVECTOR(), worldMatrixCamera );

  scene -> setTranform( invWorldMatrixCamera * projMatrix );

  BTSGraphics :: getInstance() -> getDeviceContext() -> IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  BTSGraphics :: getInstance() -> getDeviceContext() -> DrawIndexed( _indexBuffer.getNumIndices(), 0, 0 );  

  _rasterizerState    -> disableState();
  _depthStencilState  -> disableState();
}

И все работает...это какое-то Вуду программирование:(

#6
18:37, 6 мая 2017

bretbas
> инвертированная матрица Мира нашей камеры, а матрица Мира камеры
Mira, тут опять без спросу твои матрицы трогают!

#7
18:57, 6 мая 2017

MrShoor, Я договорился :-D

#8
19:23, 6 мая 2017

bretbas
>И все работает...это какое-то Вуду программирование:(
может без инверсии попробовать? запутался немного в коде, бывает. Ты как танк рисуешь? матрицу мировую ставишь ему? вот мировая матрица неба содержит в себе позицию камеры только и всего. Просто позиция камеры у тебя та что нужна. Начни с того что поставь SkyBox там где танк.

#9
19:34, 6 мая 2017

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

#10
19:52, 6 мая 2017

Блин, что-то не то я написал, да :)
Бокс или сфера это не важно. главное поставить её в позицию камеры, но не вращать.

#11
9:08, 7 мая 2017

Dronas, так она почему-то начинает сама вращаться относительно камеры. Как будто привязана по SceneNode к ней, хотя это не так. Поэтому мне приходится ее вращать на матрицу, обратную матрицы вращения моей камеры. Чтобы это гребанная сфера не крутилась вместе с камерой, а оставалась на месте

#12
10:00, 7 мая 2017

bretbas
Поставь небо и не двигай работает? Танк кстати аналогично должен себя вести.
Если так, позицию камеры получаешь неверно

ПрограммированиеФорумГрафика

Тема в архиве.