【问题标题】:Cubemap texturing issue (D3D11, C++)立方体贴图纹理问题(D3D11,C++)
【发布时间】:2016-01-01 23:24:43
【问题描述】:

我正在渲染的立方体贴图存在纹理问题,似乎无法弄清楚。我已经使用直接 x 的纹理工具生成了一个立方体贴图,然后使用

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

立方体贴图纹理根本不是高质量的,它看起来真的被拉伸/扭曲了。我可以肯定地说,用于立方体贴图的图像匹配正确,但目前还不是很好

我不确定为什么会这样。是因为我的纹理太大/太小还是其他原因?如果是由于纹理的大小,推荐的纹理大小是多少?我使用的是球体作为立方体贴图而不是立方体。

编辑:

着色器:

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);
    }
}

画:

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);

最初我打算使用这个 sn-p 来更新着色器中的 TextureCube 变量

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

但似乎没有任何效果,事实上,如果没有下面的行,我用于立方体贴图纹理的球体与场景中的另一个对象一起使用的纹理,所以也许这里发生了一些事情?我不确定是什么。

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

编辑:可能不是上面的,意识到如果不更新,旧纹理将被应用,因为它在每次绘制后都不会被擦除。

编辑:尝试使用球体和立方体的立方体贴图,仍然是相同的纹理问题。

编辑:尝试以不同方式加载着色器资源视图

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);

仍然产生相同的输出,有什么想法吗?

编辑:尝试增加 zfar 距离,无论我输入什么值,纹理都保持完全相同。

第二个纹理的例子,增加了视距。

此纹理用于我场景中的另一个对象并且效果很好。

编辑:我一直试图弄乱纹理/对象的缩放

为了实现这一点,我使用了 vin.position = vin.position * 50.0f;

这开始看起来有点像它应该的样子,但是,当我转动相机角度时,图像消失了,所以我显然知道这是不正确的,但如果我可以按像素或每个顶点缩放图像好吧,我相信我能得到最终的结果。

编辑:

我可以确认立方体贴图正在正确渲染,我忽略了视图/投影空间,只是使用世界并设法得到了这个,这是我所追求的高质量图像,只是不正确。是的,面部是不正确的,但我现在对此并不大惊小怪,交换它们很容易,我只需要在正确的空间中以这种质量渲染它。

在相机空间中是否会考虑它是否在球体的外部/内部?如果我的纹理在球体的外部,而我从内部看到,它看起来就不一样了?

【问题讨论】:

  • 您是否尝试在您的Sample() 调用中使用pin.spherePosition.xyz,因为它要求位置是float3
  • @NicoSchertler 是的,我已经尝试过了,仍然产生相同的结果,或者非常相似。
  • 我想到了两个快速的猜测:你没有用D3DX11_DEFAULT 初始化D3DX11_IMAGE_LOAD_INFO loadSMInfo 的所有未使用的成员,这可能会导致加载立方体贴图时出错。或者可能是 mipmapping 问题并且使用了最粗糙的 mipmap,您可以尝试使用 SampleLevel 和 LOD=0 进行测试,并将 SMViewDesc 设置为 null,以获取视图的整个资源。
  • @Gnietschow 感谢您的回复。都没有奏效。我不知道发生了什么。纹理具有相当高的分辨率,并且生成的立方体贴图不使用 mipmap,因此应该可以正常工作。
  • 我已经用正确渲染的立方体贴图更新了我的帖子,只有在放入视图/投影空间时才会搞砸。

标签: c++ directx textures


【解决方案1】:

问题在于你的纹理大小,它很小,你将它应用在更大的表面上,用更多的像素制作更大的纹理

它确认 zfar 和缩放与它无关。

【讨论】:

  • 我不确定,我尝试了多种不同尺寸的纹理,它们看起来都一样。如果您查看我帖子中的第二张图片,则该纹理实际上是从我场景中的另一个对象中获取的,并且渲染得非常好。只有当应用于立方体贴图时,它才会扭曲。感谢您的回复!
【解决方案2】:

终于找到问题了,愚蠢的错误。

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

【讨论】:

    猜你喜欢
    • 2014-05-06
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-22
    • 2012-11-24
    • 2018-07-29
    • 1970-01-01
    • 2019-06-03
    相关资源
    最近更新 更多