我(重新)学习DirectX并已进入HLSL编码。在使用我的自定义.fx文件之前,我为具有四边形顶点缓冲区的游戏创建了一个天空盒。一切都很好......纹理映射和包装精美。但是现在我已经有HLSL设置来管理顶点,那里有四边形的四边形接缝。纹理都正常排列我只是不能摆脱这个该死的缝!
我倾向于认为问题出在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();
}
}
答案 0 :(得分:1)
您需要使用setsampler状态来夹住纹理坐标以消除接缝。这个toymaker页面解释了这一点。 Toymaker是一个学习Direct3D的好网站,如果你有任何问题,你应该查看教程。
答案 1 :(得分:1)
您可能只想使用一个四边形来绘制天空盒。你需要的一切都是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);
不用担心任何接缝! :)
答案 2 :(得分:1)
为避免接缝,您需要在单个DrawIndexedPrimitive调用中绘制天空盒,最好使用三角形条。不要将每个面部绘制为单独的基元或单个矩阵转换的单独基元 - 您将获得接缝。如果由于某些无法解释的原因不希望对天空盒部件使用单个DrawIndexedPrimitive调用,则必须确保使用相同的矩阵(每个调用中使用的相同的世界+视图+投影矩阵)和角的相同坐标值绘制所有面顶点 - 即“顶部”面应该对“侧面”使用的角使用完全相同的矢量(位置)。
另一件事是你应该将天空盒存储为
或者 - 如果你对着色器很好,你可以使用着色器“光线追踪”天空盒。