立方体贴图纹理问题(D3D11、C++)
Cubemap texturing issue (D3D11, C++)
我正在渲染的立方体贴图存在纹理问题,似乎无法解决。我用 direct x 的纹理工具生成了一个立方体贴图,然后使用
读取它
D3DX11CreateShaderResourceViewFromFile(device, L"cubemap.dds", 0, 0, &fullcubemap, 0);
立方体贴图质量一点都不高,看起来真的stretched/distorted。我可以肯定地说用于立方体贴图的图像正确匹配,但目前一点也不好
我不确定为什么会这样。是因为我的贴图太large/small还是别的原因?如果是由于纹理的大小,建议的纹理大小是多少?我为立方体贴图使用的是球体,而不是立方体。
编辑:
着色器:
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);
最初我打算使用这个片段来更新着色器中的 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 距离,无论我输入什么值,纹理都保持完全相同。
第二个纹理的例子增加了视距。
此纹理用于我场景中的另一个对象,效果很好。
编辑:我一直试图搞乱 texture/object 的缩放比例
为此我使用了
vin.position = vin.position * 50.0f;
这开始看起来有点像它应该的样子,但是,当我转动相机角度时,图像消失了,所以我显然知道这是不正确的,但是如果我可以按像素缩放图像或每个顶点都正确,我相信我能得到最终结果。
编辑:
我可以确认立方体贴图渲染正确,我忽略了 view/projection space 并且只是使用世界并设法得到这个,这是我想要的高质量图像,只是不正确。是的,面孔不正确,但我现在并不为此烦恼,交换它们很容易,我只需要以正确的 space.
以这种质量渲染它
在相机中时space是否考虑它是否是球体的outside/inside?如果我的纹理在球体的外部,而我从内部看到,它看起来会不一样吗?
问题在于你的纹理尺寸,它很小,你将它应用在更大的表面上,用更多的像素制作更大的纹理
确认zfar和scaling与它无关。
终于找到问题了,愚蠢的错误。
scb.world = XMMatrixTranspose(sworld);
scb.view = XMMatrixTranspose(sview);
scb.projection = XMMatrixTranspose(sprojection);
我正在渲染的立方体贴图存在纹理问题,似乎无法解决。我用 direct x 的纹理工具生成了一个立方体贴图,然后使用
读取它D3DX11CreateShaderResourceViewFromFile(device, L"cubemap.dds", 0, 0, &fullcubemap, 0);
立方体贴图质量一点都不高,看起来真的stretched/distorted。我可以肯定地说用于立方体贴图的图像正确匹配,但目前一点也不好
我不确定为什么会这样。是因为我的贴图太large/small还是别的原因?如果是由于纹理的大小,建议的纹理大小是多少?我为立方体贴图使用的是球体,而不是立方体。
编辑:
着色器:
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);
最初我打算使用这个片段来更新着色器中的 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 距离,无论我输入什么值,纹理都保持完全相同。
第二个纹理的例子增加了视距。
此纹理用于我场景中的另一个对象,效果很好。
编辑:我一直试图搞乱 texture/object 的缩放比例
为此我使用了 vin.position = vin.position * 50.0f;
这开始看起来有点像它应该的样子,但是,当我转动相机角度时,图像消失了,所以我显然知道这是不正确的,但是如果我可以按像素缩放图像或每个顶点都正确,我相信我能得到最终结果。
编辑:
我可以确认立方体贴图渲染正确,我忽略了 view/projection space 并且只是使用世界并设法得到这个,这是我想要的高质量图像,只是不正确。是的,面孔不正确,但我现在并不为此烦恼,交换它们很容易,我只需要以正确的 space.
以这种质量渲染它在相机中时space是否考虑它是否是球体的outside/inside?如果我的纹理在球体的外部,而我从内部看到,它看起来会不一样吗?
问题在于你的纹理尺寸,它很小,你将它应用在更大的表面上,用更多的像素制作更大的纹理
确认zfar和scaling与它无关。
终于找到问题了,愚蠢的错误。
scb.world = XMMatrixTranspose(sworld);
scb.view = XMMatrixTranspose(sview);
scb.projection = XMMatrixTranspose(sprojection);