fdkhb 2020-05-27 14:49 采纳率: 0%
浏览 155
已结题

D3D9(DirectX)烘焙LightMap过程中,输出纹理坐标Y翻转后纹理不完整

最近尝试采用D3D9的UVAtlas+TextureGutterHelper+effect(v_2_0)进行模型的lightmap烘焙,在写effect文件的vertexshader时遇到一个奇怪的问题,使用UVAtlas展开UV后,计划按照纹理的UV坐标输出贴图的position,.fx文件中完整代码如下:

//Vertexshader输入
struct VS_INPUT
{
    float4  Pos             : POSITION;
    float3  Normal          : NORMAL;
    float2  Tex0            : TEXCOORD0;
};
//Vertexshader输出与PixelShader输入
struct PSUVIn
{
    float4 Pos          : POSITION;
    float2 Tex0          : TEXCOORD0;
    float4 Clr0             : COLOR0;
};

PSUVIn VSRenderToUV(VS_INPUT input, uniform bool bPtLight, uniform bool bSpecular)
{
    PSUVIn output = (PSUVIn)0;

    float2 screenTex = input.Tex0*float2(2, 2) - float2(1, 1);
    output.Pos = float4(screenTex, 0.5, 1);

    // 转换顶点到世界坐标
    float4 vPosWorld = mul(input.Pos, g_mWorld);

    // 将法线转换到世界坐标系
    float3 vNormalWorld = mul(input.Normal, (float3x3)g_mWorld);

    //将纹理坐标直接输出,传递给pixelshader
    output.Tex0 = input.Tex0;

    // 计算光线方向向量
    float3 vLight;
    if (bPtLight) //是点光源
        vLight = normalize(g_vLightPosition - vPosWorld.xyz);
    else  //方向光
        vLight = normalize(g_vLightDirection);

    // 计算光照度
    output.Clr0.rgb = g_vLightColor * g_vMaterialAmbient;
    output.Clr0.rgb += g_vLightColor * g_vMaterialDiffuse * saturate(dot(vLight, vNormalWorld));

    // 计算镜面光
    if (bSpecular)
    {
        float3 vCamera = normalize(vPosWorld.xyz - g_vCameraPosition);
            float3 vReflection = reflect(vLight, vNormalWorld);
            float  fPhongValue = saturate(dot(vReflection, vCamera));

        output.Clr0.rgb += g_vMaterialSpecular * pow(fPhongValue, g_nMaterialShininess);
    }

    output.Clr0.a = g_fMaterialAlpha;

    return output;
}

float4 PSRenderToUV(PSUVIn input, uniform bool bTexture) : COLOR0
{
//将vertexshader计算的光照直接输出渲染为纹理
    float4 colorOut = input.Clr0;

    return colorOut;
}

在vertexshader函数VSRenderToUV中,以下代码部分负责将贴图的UV坐标换算为输出纹理的xy坐标

    float2 screenTex = input.Tex0*float2(2, 2) - float2(1, 1);
    output.Pos = float4(screenTex, 0.5, 1);

测试过程使用了d3d的示例模型,模型样式和纹理如下两图
图片说明
图片说明
采用上述effect代码,输出纹理样式为
图片说明
可以看出烘焙后的纹理图与原始贴图坐标不一致,在Y方向上发生了翻转,为此改变UV换算代码为

    float2 screenTex = input.Tex0*float2(2, -2) - float2(1, -1);
    output.Pos = float4(screenTex, 0.5, 1);

希望将输出纹理的y坐标翻转过来,然而测试后发现,只能输出如下图像
图片说明
可以发现翻转y以后模型面部、腿部等部分纹理没有输出,求教各位大神问题出在哪里,如何解决?谢谢~

  • 写回答

1条回答 默认 最新

  • 关注
    评论

报告相同问题?

悬赏问题

  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数