6.6视差贴图

关于视差贴图,我的理解是微调获得凹凸感。

材料:1,颜色纹理,2,法线纹理,3,高度纹理。

其他需要参数:视点位置

类比下大地基准面,大地基准面模拟地球表面。同样,大地基准面+深度信息纹理 = 地球表面。

就是说,要把白菜吃出鸡腿的味道,那就只能加佐料,这个佐料就是深度信息纹理。当然,白菜不是真正的鸡腿,所以只能偶尔吃吃,就像小时候吃的人造肉,偶尔解解馋还行,真把人造肉当肉吃,那就营养不良了。

这个视点位置作用,就是我要四处看看到底像不像真实物体。东咬一口,嗯,是这个味道,西咬一口,好像还是这个味道,于是,成功被骗了。

好,那么看看这个高度纹理,首先,这肯定是模型坐标系中的数值,记录模型的某个位置与实际位置的高度差。

在vs里,需要将世界坐标变换到模型空间的变换矩阵
    float3x3 matWorldToModel = float3x3( mul(In.Tanget, g_matWorld ).xyz, mul( cross(In.Tanget, In.Normal), g_matWorld ).xyz, mul(In.Normal, g_matWorld).xyz );
    float4 Position = mul(In.Position, g_matWorld );

然后计算高度差
    Output.vLookAt = mul( matWorldToModel, normalize(Position - g_vEyePosition ));   

看过了高度,再看纹理,如何对应上。因为与视角相关,所以计算视差贴图时,就要考虑视角因素,也就是vs里计算出来的高度差。(模型坐标系),当然,颜色自然是在Ps中考虑了

//计算视差贴图的偏移
    float3 viewDir = normalize(In.vLookAt);

//根据偏移采样高度纹理,得到一个系数因子
    float3 h = tex2D(MeshHeightSampler, In.TextureUV ).y;

有个简化公式,

offsetUV = offsetUV + float2(viewDir.x, viewDir.y) * v2Scale;

在Ps中就体现为

    offsetUV += float2(-viewDir.x, viewDir.y) * ( h * 0.04 - 0.02 );

这里就体现出了纹理坐标的偏移,从而感到了纹理坐标的凹凸起伏
    return tex2D(MeshTextureSampler, offsetUV);

从vs里看,要保证切线空间可用,因此在c++程序里,需要加上判断

//计算切向量
    hr = D3DXComputeTangent(m_pMeshSysMemory, 0, 0, 0, TRUE, NULL);
    if (FAILED(hr))
    {
        return hr;
    }

发布了673 篇原创文章 · 获赞 18 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/directx3d_beginner/article/details/104051300
6.6