0
votes

I have a texture problem with the cubemap I'm rendering and can't seem to figure it out. I've generated a cube map with direct x's texture tools and then read it using

D3DX11CreateShaderResourceViewFromFile(device, L"cubemap.dds", 0, 0, &fullcubemap, 0);

The cubemap texture is not high quality at all and it looks really stretched/distorted. I can definitely tell that the images used for the cubemap match correctly, but it's not great at all at the moment

enter image description here

I'm not sure why this is happening. Is it because my textures are too large/small or is it something else? If it's due to the size of the textures, what is a recommended texture size? I am using a sphere for the cubemap not a cube.

Edit:

Shader:

cbuffer SkyboxConstantBuffer {
    float4x4 world;
    float4x4 view;
    float4x4 projection;
};

TextureCube gCubeMap;

SamplerState samTriLinearSam {
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

struct VertexIn {
    float4 position : POSITION;
};

struct VertexOut {
    float4 position : SV_POSITION;
    float4 spherePosition : POSITION;
};

VertexOut VS(VertexIn vin) {
    VertexOut vout = (VertexOut)0;

    vin.position.w = 1.0f;

    vout.position = mul(vin.position, world);
    vout.position = mul(vout.position, view);
    vout.position = mul(vout.position, projection);

    vout.spherePosition = vin.position;

    return vout;
}

float4 PS(VertexOut pin) : SV_Target {
    return gCubeMap.Sample(samTriLinearSam, pin.spherePosition);//float4(1.0, 0.5, 0.5, 1.0);
}

RasterizerState NoCull {
    CullMode = None;
};

DepthStencilState LessEqualDSS {
    DepthFunc = LESS_EQUAL;
};

technique11 SkyTech {
    pass p0 {
        SetVertexShader(CompileShader(vs_4_0, VS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0, PS()));

        SetRasterizerState(NoCull);
        SetDepthStencilState(LessEqualDSS, 0);
    }
}

Draw:

immediateContext->OMSetRenderTargets(1, &renderTarget, nullptr);

XMMATRIX sworld, sview, sprojection;
SkyboxConstantBuffer scb;
sview = XMLoadFloat4x4(&_view);
sprojection = XMLoadFloat4x4(&_projection);
sworld = XMLoadFloat4x4(&_world);

scb.world = sworld;
scb.view = sview;
scb.projection = sprojection;

immediateContext->IASetIndexBuffer(cubeMapSphere->getIndexBuffer(), DXGI_FORMAT_R32_UINT, 0);
ID3D11Buffer*  vertexBuffer = cubeMapSphere->getVertexBuffer();
//ID3DX11EffectShaderResourceVariable * cMap;
////cMap = skyboxShader->GetVariableByName("gCubeMap")->AsShaderResource();
immediateContext->PSSetShaderResources(0, 1, &fullcubemap);//textures
//cMap->SetResource(fullcubemap);
immediateContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
immediateContext->VSSetShader(skyboxVertexShader, nullptr, 0);
immediateContext->VSSetConstantBuffers(0, 1, &skyboxConstantBuffer);
immediateContext->PSSetConstantBuffers(0, 1, &skyboxConstantBuffer);
immediateContext->PSSetShader(skyboxPixelShader, nullptr, 0);

immediateContext->UpdateSubresource(skyboxConstantBuffer, 0, nullptr, &scb, 0, 0);
immediateContext->DrawIndexed(cubeMapSphere->getIndexBufferSize(), 0, 0);

Initially I was planning to use this snippet to update the TextureCube variable in the shader

ID3DX11EffectShaderResourceVariable * cMap;
cMap = skyboxShader->GetVariableByName("gCubeMap")->AsShaderResource();
cMap->SetResource(fullcubemap);

But it seems that has no effect, and in fact, without the following line, the sphere I'm using for the cubemap textures with a texture used with another object in the scene, so perhaps there's something going on here? I'm not sure what though.

immediateContext->PSSetShaderResources(0, 1, &fullcubemap);//textures

Edit: Probably not the above, realised that if this wasn't updated, the old texture would be applied as it's never wiped after each draw.

Edit: Tried the cubemap with both a sphere and a cube, still the same texture issue.

Edit: Tried loading the shader resource view differently

D3DX11_IMAGE_LOAD_INFO loadSMInfo;
loadSMInfo.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;

ID3D11Texture2D* SMTexture = 0;
hr = D3DX11CreateTextureFromFile(device, L"cubemap.dds",
    &loadSMInfo, 0, (ID3D11Resource**)&SMTexture, 0);

D3D11_TEXTURE2D_DESC SMTextureDesc;
SMTexture->GetDesc(&SMTextureDesc);

D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = SMTextureDesc.Format;
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = SMTextureDesc.MipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;

hr = device->CreateShaderResourceView(SMTexture, &SMViewDesc, &fullcubemap);

Still produces the same output, any ideas?

Edit: Tried increasing the zfar distance and the texture remains the exact same no matter what value I put.

Example with second texture with increased view distance. enter image description here

This texture is used on another object in my scene and comes out fine.

Edit: I have been trying to mess with the scaling of the texture/object enter image description here

To achieve this I used vin.position = vin.position * 50.0f;

This is beginning to look sort of like how it should, however, when I turn my camera angle, the image disappears so I obviously know this isn't correct, but if I could just scale the image per pixel or per vertex properly, I'm sure I could get the end result.

enter image description here

Edit: enter image description here

I can confirm the cubemap is rendering correctly, I was ignoring the view/projection space and just using world and managed to get this, which is the high quality image i'm after, just not correct. Yes the faces are incorrect, but I'm not fussed about that now, it's easy enough to swap them around, I just need to get it rendering with this quality, in the correct space.

When in camera space does it take into account whether or not it's the outside/inside of the sphere? If my textures were over the outside of the sphere and I have the view from the inside, it's not going to look the same?

2
Have you tried to use pin.spherePosition.xyz in your Sample() call since it requires the location to be a float3? - Nico Schertler
@NicoSchertler Yes I have tried, still produces the same result, or very similar. - kbz
Two quick guesses coming into my mind: You didn't initialized all not used members of D3DX11_IMAGE_LOAD_INFO loadSMInfo with D3DX11_DEFAULT, which maybe lead to errors loading the cube map. Or maybe it is a mipmapping issue and the most coarse mipmap is used, you could try to test it with SampleLevel and LOD=0 and set SMViewDesc to null, to take to whole resource for the view. - Gnietschow
@Gnietschow thanks for the reply. Neither worked. I have no idea what's happening. The textures are fairly high res and the cubemap generated doesn't use mipmaps, so it should work fine. - kbz
I have updated my post with a correctly rendered cube map, only when put into view/projection space does it mess up. - kbz

2 Answers

0
votes

Issue is with your texture size, its small, you are applying it on larger surface, Make larger textures with more pixels

Its confirm that zfar and scaling has nothing to do with it.

0
votes

Finally found the issue, silly mistake.

scb.world = XMMatrixTranspose(sworld);
scb.view = XMMatrixTranspose(sview);
scb.projection = XMMatrixTranspose(sprojection);