Chapter 7-It’s Getting Hot in Here之Cube Map

       在Render Monkey中使用CubeMap让我困扰了很长时间,请原谅我没有在DirectX的程序中学习好这个而直接跳到了这里。

       这里我想说几个我当时使用CubeMap时几个疑问。我觉得用Q&A的方式来写比较好,就不用罗列不必要的东西了。

       Q1:单位球不是半径为1吗?为什么茶壶半径差不多单位也为1,却始终显示在单位球体以内呢???

       A1:这个是绘制单位球中关闭Z-buffer及禁止写入Z-buffer的功劳,我们把球心设置在了相机位置,这样不管我们怎样前后左右移动,球体始终是不变的,因为它随着相机的变动而变动。如果我们旋转的话,球体也会跟着旋转。关闭Z-buffer及禁止写入Z-buffer,我们绘制茶壶时,茶壶始终是绘制在单位球上的,这样就给我们一个错觉,单位球是无限远的,而茶壶的远近是可以移动的(非常聪明的一个方法)。

       Q2:如果我们把绘制单位球Pass中的Render State中的D3DZB_ENABLE及D3DZB_WRITEENABLE分别设置为D3DZB_TRUE和TRUE会怎么样???

       A2:如果我们把绘制单位球Pass中的Render State中的D3DZB_ENABLE及D3DZB_WRITEENABLE分别设置为D3DZB_TRUE和TRUE,就会出现我们以往碰见的现象了,如球体挡住茶壶,或者茶壶跑到球体后边去了,当然,这不是我们想要的,我们要的就是错觉!!(以下图是我们在渲染状态D3DZB_ENABLE及D3DZB_WRITEENABLE分别设置为D3DZB_TRUE和TRUE下的渲染结果

      

       注意这里的遮挡是非常严重的,因为茶壶跟单位球体的尺寸是差不多的,茶壶如果想要遮挡球体,必然遮住了屏幕的一大部分。

       如果你的茶壶只有很小一部分被球体遮挡了,那个不是被单位球遮挡了,是被视棱锥裁剪了。如下图,请注意,这两种情况是不同的。

      

       Q3:代码问题?  

1 VS_OUTPUT vs_main( VS_INPUT Input )
2 {
3    VS_OUTPUT Output;
4 
5    Output.Position = mul( float4(Input.Position.xyz + vViewPosition.xyz,1.0f), matViewProjection );
6    Output.Tex = Input.Position.xyz;
7    return( Output );
8 }
View Code

      A3:关键之处在于  

      Output.Position = mul( float4(Input.Position.xyz + vViewPosition.xyz,1.0f), matViewProjection );

  加上vViewPosition的目的是把球体移动到视点位置,其实就是一个球体世界坐标变换。


      Output.Tex = Input.Position.xyz;

      就是把球体上每一个点的视点向量计算出来,视点位置为vViewPosition,经过变换后的球体上的点的坐标为Input.Position.xyz + vViewPosition.xyz,要计算视点为起点,重点在球体点的向量,直接用Input.Position.xyz + vViewPosition.xyzvViewPositionInput.Position.xyz,这就直接解释了第二行代码。

      Q4:添加RenderTarget时,注意RenderTarget属性的设置,第一个球体Pass中必须要清理颜色和深度,第二个绘制茶壶的Pass中则不需要清除颜色及深度。好好理一下这是为什么??

      A4:其实跟在back buffer绘制是一个道理,只不过back buffer的颜色及深度清除使系统自己做的,而RenderTarget的颜色及深度清除要我们在第一个Pass中设置。

      //end

原文地址:https://www.cnblogs.com/infintyward/p/3235834.html