工程GIT地址:https://gitee.com/yaksue/yaksue-graphics
问题
在《图形API学习工程(21):使用CubeMap纹理》中我实现了CubeMap,然而有个问题:每次采样CubeMap的时候,都需要对采样方向的轴向进行重排:
vec3 SampleDir = vec3(LightDir.x,-LightDir.z,LightDir.y);
fColor = texture(ourCubeMap, SampleDir);
观察与思考
在RenderDoc中观察看到,我作为“top”的贴图实际是作为了Y+方向。 但是在C++代码中,我计算视角矩阵时的向上方向指定的是(0,0,1),即Z轴。 这造成了不匹配。
那么,是该调整传入的贴图顺序,还是调整计算视角矩阵时的向上方向?
首先我尝试调整贴图顺序,但是却让生成的CubeMap方向错误导致边缘不匹配: 我在OpenGL中创建时的代码为:
for (unsigned int i = 0; i < FaceImageFiles.size(); i++)
{
...
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
...
}
而 立方体贴图 - LearnOpenGL CN 也指出方向是:
项目 | Value |
---|
GL_TEXTURE_CUBE_MAP_POSITIVE_X | 右 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X | 左 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y | 上 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y | 下 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z | 后 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z | 前 |
这和我当前工程中创建的顺序一致,所以我想,也许修正计算视角矩阵时的向上方向是更合适的。
实施调整
因此,我在计算视角矩阵的时候,将向上方向改为了+Y。 同时,相机移动的逻辑也随之需要调整。
随后,模型的向上方向也需要调整。
最后,shader中CubeMap的采样方向便不需要再重排轴向了。
现在,天空盒中采样的shader代码如下:
float4 Main( VS_OUTPUT input ) : SV_Target
{
float3 SampleDir = input.WorldPosition;
return skyboxCubeMap.Sample( ourSampler, SampleDir );
}
测试反射的shader代码如下:
float4 Main( VS_OUTPUT input ) : SV_Target
{
float3 EyeDir = eyePosition.xyz - input.WorldPosition;
float3 LightDir = reflect(normalize(EyeDir),normalize(input.Normal));
float3 SampleDir = -LightDir;
return ourCubeMap.Sample( ourSampler, SampleDir );
}
可以看到轴向不需要之前的重排。而结果也是对的:
|