Directx11教程十六之ClipPlane(裁剪面)
2016-10-13 19:18
253 查看
看看本节的教程,本节介绍有关裁剪面的使用,先看看本节教程的结架吧,跟DiffuseLight那节教程的结架差不多
3D空间平面的方程式为 ax+by+cz+d=0;
(a,b,c)为平面的法向量,d为一个参数,具体推导参照3D平面的通用公式
随便提一下,XNAMATH库的平面用XMVECTOR(a,b,c,d)来表示。
假设一个点为(x1,y1,z1)
(1)当a*x1+b*y1+c*z1+d=0时 代表这个点在这个平面上。
(2)当a*x1+b*y1+c*z1+d<0时,代表这个点在这个平面的后面(面法向量的反向)。
(3)当a*x1+b*y1+c*z1+d>0时,代表这个点在这个平面的前面(面法向量的正向)。
那么平面的前面和后面怎么区别呢?这得根据法向量的方向,在法向量方向那一边的为前面,反之为后面,看下面图就知道了:
假设裁剪面为(ClipPlane)为ax+by+cz+d=0;,用float4表示为(a,b,c,d), 将3D几何体上位于
a*x1+b*y1+c*z1+d<0 空间的点剔除
//在世界空间,对于乘以裁剪面小于零的进行裁剪,裁剪不满足条件的几何体部分
outa.ClipValue = dot(mul(float4(ina.Pos, 1.0f), World), ClipPlane);
注意关键字:
float ClipValue : SV_ClipDistance0;其中“
SV_ClipDistance0”代表裁剪值,在VertexShader进行计算得到的值小于0的被裁剪,跟PixelShader的函数Clip(Clip用于在PixelShader裁剪像素)有相似的功能。
我设定的裁剪面为:(0.0f,-1.0f,0.0f,0.0f),即在Y面以上的空间元素被裁剪。
最后我设定光栅化状态为不进行背面剔除,并且将相机位置往上平移
rasterDesc.CullMode = D3D11_CULL_NONE; //背面剔除
程序运行结果如下:
没裁剪面的时候程序运行如下:
最后我的源代码链接如下:
http://download.csdn.net/detail/qq_29523119/9667258
第一,ClipPlane的简介和公式。
裁剪面既然说了“面”,本节的教程涉及的面为平面,而非曲面,3D空间一个平面可以将空间分为两半,熟知的有X平面,Y平面,Z平面等等。3D空间平面的方程式为 ax+by+cz+d=0;
(a,b,c)为平面的法向量,d为一个参数,具体推导参照3D平面的通用公式
随便提一下,XNAMATH库的平面用XMVECTOR(a,b,c,d)来表示。
假设一个点为(x1,y1,z1)
(1)当a*x1+b*y1+c*z1+d=0时 代表这个点在这个平面上。
(2)当a*x1+b*y1+c*z1+d<0时,代表这个点在这个平面的后面(面法向量的反向)。
(3)当a*x1+b*y1+c*z1+d>0时,代表这个点在这个平面的前面(面法向量的正向)。
那么平面的前面和后面怎么区别呢?这得根据法向量的方向,在法向量方向那一边的为前面,反之为后面,看下面图就知道了:
假设裁剪面为(ClipPlane)为ax+by+cz+d=0;,用float4表示为(a,b,c,d), 将3D几何体上位于
a*x1+b*y1+c*z1+d<0 空间的点剔除
Texture2D ShaderTexture:register(t0); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; matrix WorldInvTranspose; }; cbuffer CBLight:register(b1) { float4 DiffuseColor; float3 LightDirection; float pad; }; cbuffer CBClipPlane:register(b2) { float4 ClipPlane; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 float3 Normal:NORMAL; }; struct VertexOut { float4 Pos:SV_POSITION; float ClipValue : SV_ClipDistance0;//裁剪值关键字 float2 Tex:TEXCOORD0; float3 W_Normal:NORMAL; //世界空间的法线 }; VertexOut VS(VertexIn ina) { VertexOut outa; //将顶点变换到齐次裁剪空间 outa.Pos = mul(float4(ina.Pos,1.0f), World); outa.Pos = mul(outa.Pos, View); outa.Pos = mul(outa.Pos, Proj); //将顶点法线量变换到世界空间 outa.W_Normal = mul(ina.Normal, (float3x3)WorldInvTranspose); //此事世界逆转置矩阵的第四行本来就没啥用 outa.W_Normal = normalize(outa.W_Normal); outa.Tex= ina.Tex; //在世界空间,对于乘以裁剪面小于零的进行裁剪,裁剪不满足条件的几何体部分 outa.ClipValue = dot(mul(float4(ina.Pos, 1.0f), World), ClipPlane); return outa; } float4 PS(VertexOut outa) : SV_Target { float4 TexColor; //采集的纹理颜色 float LightFactor; //灯光因子 float4 color = {0.0f,0.0f,0.0f,0.0f}; //最终输出的颜色 //第一,获取采样颜色 TexColor = ShaderTexture.Sample(SampleType, outa.Tex); //第二,求出灯光因子 float3 InvLightDir = -LightDirection; LightFactor = saturate(dot(InvLightDir,outa.W_Normal)); //第三,求出灯光照射颜色 if (LightFactor>0) { color += LightFactor*DiffuseColor; //saturate(float1*float4) } color = saturate(color); //第四,用灯光颜色调节纹理颜色 color = color*TexColor; return color; }
//在世界空间,对于乘以裁剪面小于零的进行裁剪,裁剪不满足条件的几何体部分
outa.ClipValue = dot(mul(float4(ina.Pos, 1.0f), World), ClipPlane);
注意关键字:
float ClipValue : SV_ClipDistance0;其中“
SV_ClipDistance0”代表裁剪值,在VertexShader进行计算得到的值小于0的被裁剪,跟PixelShader的函数Clip(Clip用于在PixelShader裁剪像素)有相似的功能。
我设定的裁剪面为:(0.0f,-1.0f,0.0f,0.0f),即在Y面以上的空间元素被裁剪。
最后我设定光栅化状态为不进行背面剔除,并且将相机位置往上平移
rasterDesc.CullMode = D3D11_CULL_NONE; //背面剔除
程序运行结果如下:
没裁剪面的时候程序运行如下:
最后我的源代码链接如下:
http://download.csdn.net/detail/qq_29523119/9667258
相关文章推荐
- 裁剪平面ClipPlane
- SDL入门教程(八):1、裁剪精灵图片(Clip Blitting and Sprite Sheets)
- SDL入门教程(八):1、裁剪精灵图片(Clip Blitting and Sprite Sheets)
- CSS裁剪属性clip使用的实例教程
- osgEarth矢量裁剪案例 38. feature_clip_plane.earth
- Directx11教程三十七之FrustumCulling(视截体裁剪)上半节教程
- Directx11教程三十八之Pick(拾取技术)
- ArcGIS教程:地理处理服务示例(裁剪与发送)(一)
- Android高手进阶教程(十六)之---Android中万能的BaseAdapter(Spinner,ListView,GridView)的使用!
- PHP类实例教程(十六):PHP5中的常量
- Directx11教程(66) D3D11屏幕文本输出(1)
- DirectX11教程
- 使用Drawable资源之使用ClipDrawable资源(十六)
- Directx11教程四十四之CascadeShadowMap(层级阴影)(下)---解决阴影丢失和阴影抖动问题
- Directx11教程十一之AlphaMap(混合贴图)
- 【OpenCV入门教程之十六】OpenCV角点检测之Harris角点检测
- 按行政区域范围下载并裁剪卫星地图数据教程
- Unity3D Shader官方教程翻译(十六)----Shader语法 GrabPass
- 深入浅出CSS3 background-clip,background-origin和border-image教程
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制