D3D11地形渲染教程十三之PerturbedCloud(翻滚的云,或者扰乱云的形状)
2017-01-26 13:07
483 查看
上一节教程D3D11地形渲染教程十一之SkyDome(天空盒)我们实现了“会移动的云层”,但是上节教程的云是不具备翻滚效果的,真实世界的云应该有翻滚的效果,程序的结构如下:
这节教程的代码跟上节教程差不多,主要是Shader着色代码不一样和用的纹理不一样,上一节教程我们使用了两张云层纹理,这一节教程我们使用一张云层纹理和噪声纹理。
云层纹理如下:
噪声纹理(NoiseTexture)如下:(注意噪声纹理为灰度图,纹理上像素颜色的R值,G值,B值是相等的,是随机的量,能模拟自然现象的某些量)
程序运行结果:(这不是Gif,看不到云翻滚的动态效果,望见谅)
解释云翻滚的原因:假设在SkyPlane某一部分存在三个点A(0.6,0.6),B(0.5,0.5),C(0.4,0.4),又假设纹理纹理坐标移动速度(Speed)是0.1,在第一帧中Translation为0.1,则A像素对噪声纹理采样的坐标为(0.7,0.6),而B像素对噪声纹理采样的坐标为(0.6,0.5),,C像素对噪声纹理采样的坐标为(0.5,0.4),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.5,0.5);
在第二帧画面中,Translation变为0.2,则A像素对噪声纹理采样的坐标为(0.8,0.6),而B像素对噪声纹理采样的坐标为(0.7,0.5),,C像素对噪声纹理采样的坐标为(0.6,0.4),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.8,0.8),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6);。
这里我分析出:第一帧画面中,A像素的基础纹理坐标(outa.Tex.xy+Translation)为(0.7,0.7),而A像素对噪声纹理采样的坐标为(0.7,0.6)在第二张画面中,B像素基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.7,0.5)。一样的基础纹理坐标确有不同的噪声纹理采样坐标,获取的云层干扰量(噪声量)不一样,这样云层形态就无法维持稳定,也就是云层翻滚的本质所在。
当我把上面的代码改为下面的,云层就成了不会翻滚的.
解释云不翻滚的原因:假设在SkyPlane某一部分存在三个点A(0.6,0.6),B(0.5,0.5),C(0.4,0.4),又假设纹理纹理坐标移动速度(Speed)是0.1,在第一帧中Translation为0.1,则A像素对噪声纹理采样的坐标为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.6,0.6),,C像素对噪声纹理采样的坐标为(0.5,0.5),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.5,0.5);
在第二帧画面中,Translation变为0.2,则A像素对噪声纹理采样的坐标为(0.8,0.8),而B像素对噪声纹理采样的坐标为(0.7,0.7),,C像素对噪声纹理采样的坐标为(0.6,0.6),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.8,0.8),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6);。
这里我分析出:第一帧画面中,A像素的基础纹理坐标(outa.Tex.xy+Translation)为(0.7,0.7),而A像素对噪声纹理采样的坐标为(0.7,0.7)在第二张画面中,B像素基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.7,0.7)。一样的基础纹理坐标确有相同的噪声纹理采样坐标,获取的云层干扰量(噪声量)一样,这样云层形态就维持稳定,也就是云层不翻滚的本质所在。
以上都可以用我对(1)和(2)的分析方法分析出原因来。
另外注意一下,PerturbScale值的大小控制了干扰云层量的大小,也就是云翻滚的激烈程序。PerturbScale值大,则云翻滚激烈。反之,不激烈.
源代码的链接如下:
http://download.csdn.net/detail/qq_29523119/9744846
一,PerturbedCloud(翻滚的云)
PerturbedCloud(翻滚的云)的实现,可以参考教程D3D11教程二十三之Fire(摇动的火),我们再一次借用NoiseTexture(噪声纹理)来模拟云层翻滚的自然现象。其实,我觉得,由于纹理描述的对象的形状的些许改变,都能用NoiseTexture来模拟这种改变。比如火焰纹理的火焰的摇动效果,又如云层纹理的云朵的翻滚效果。这节教程的代码跟上节教程差不多,主要是Shader着色代码不一样和用的纹理不一样,上一节教程我们使用了两张云层纹理,这一节教程我们使用一张云层纹理和噪声纹理。
云层纹理如下:
噪声纹理(NoiseTexture)如下:(注意噪声纹理为灰度图,纹理上像素颜色的R值,G值,B值是相等的,是随机的量,能模拟自然现象的某些量)
二,Shader代码实现
Shader代码实现:(1)云层纹理往XY方向移动,并且进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x + Translation; Tex.y = outa.Tex.y; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 Tex.xy = outa.Tex.xy + Perturb.xy+ Translation; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
程序运行结果:(这不是Gif,看不到云翻滚的动态效果,望见谅)
解释云翻滚的原因:假设在SkyPlane某一部分存在三个点A(0.6,0.6),B(0.5,0.5),C(0.4,0.4),又假设纹理纹理坐标移动速度(Speed)是0.1,在第一帧中Translation为0.1,则A像素对噪声纹理采样的坐标为(0.7,0.6),而B像素对噪声纹理采样的坐标为(0.6,0.5),,C像素对噪声纹理采样的坐标为(0.5,0.4),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.5,0.5);
在第二帧画面中,Translation变为0.2,则A像素对噪声纹理采样的坐标为(0.8,0.6),而B像素对噪声纹理采样的坐标为(0.7,0.5),,C像素对噪声纹理采样的坐标为(0.6,0.4),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.8,0.8),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6);。
这里我分析出:第一帧画面中,A像素的基础纹理坐标(outa.Tex.xy+Translation)为(0.7,0.7),而A像素对噪声纹理采样的坐标为(0.7,0.6)在第二张画面中,B像素基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.7,0.5)。一样的基础纹理坐标确有不同的噪声纹理采样坐标,获取的云层干扰量(噪声量)不一样,这样云层形态就无法维持稳定,也就是云层翻滚的本质所在。
(2)云层纹理往XY方向移动,不进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x + Translation; Tex.y = outa.Tex.y + Translation; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 Tex.xy = outa.Tex.xy + Perturb.xy+ Translation; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
解释云不翻滚的原因:假设在SkyPlane某一部分存在三个点A(0.6,0.6),B(0.5,0.5),C(0.4,0.4),又假设纹理纹理坐标移动速度(Speed)是0.1,在第一帧中Translation为0.1,则A像素对噪声纹理采样的坐标为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.6,0.6),,C像素对噪声纹理采样的坐标为(0.5,0.5),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.5,0.5);
在第二帧画面中,Translation变为0.2,则A像素对噪声纹理采样的坐标为(0.8,0.8),而B像素对噪声纹理采样的坐标为(0.7,0.7),,C像素对噪声纹理采样的坐标为(0.6,0.6),并且A的基础纹理坐标(outa.Tex.xy+Translation)变为(0.8,0.8),B的基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),C的基础纹理坐标(outa.Tex.xy+Translation)变为(0.6,0.6);。
这里我分析出:第一帧画面中,A像素的基础纹理坐标(outa.Tex.xy+Translation)为(0.7,0.7),而A像素对噪声纹理采样的坐标为(0.7,0.7)在第二张画面中,B像素基础纹理坐标(outa.Tex.xy+Translation)变为(0.7,0.7),而B像素对噪声纹理采样的坐标为(0.7,0.7)。一样的基础纹理坐标确有相同的噪声纹理采样坐标,获取的云层干扰量(噪声量)一样,这样云层形态就维持稳定,也就是云层不翻滚的本质所在。
(3)云层纹理往XY方向移动,并且进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x ; Tex.y = outa.Tex.y + Translation; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 Tex.xy = outa.Tex.xy + Perturb.xy+ Translation; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
(4)云层纹理不移动,但进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x ; Tex.y = outa.Tex.y + Translation; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 Tex.xy = outa.Tex.xy + Perturb.xy; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
(5)云层纹理往Y方向移动,但不进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x ; Tex.y = outa.Tex.y + Translation; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 Tex.xy = Tex.xy + Perturb.xy; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
(6)云层纹理往X方向移动,并且进行翻滚
Texture2D CloudTexture1:register(t0); //纹理资源 Texture2D NoiseTexture:register(t1); //纹理资源 SamplerState SampleType:register(s0); //采样方式 //VertexShader cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; }; cbuffer CBSkyCloudPlane:register(b1) { float Translation; float brightness; float PerturbScale; float pad; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理可以用其它数字 }; struct VertexOut { float4 Pos:SV_POSITION; float2 Tex:TEXCOORD0; }; 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.Tex= ina.Tex; return outa; } float4 PS(VertexOut outa) : SV_Target { float4 color; float2 Tex; float4 Perturb; float4 TexColor; //计算移动后的纹理坐标 Tex.x = outa.Tex.x ; Tex.y = outa.Tex.y + Translation; //利用移动后的纹理坐标对噪声纹理进行采样 Perturb= NoiseTexture.Sample(SampleType, Tex); //利用PerturbScale对Perturb(扰乱)值进行缩放 Perturb = Perturb*PerturbScale; //利用Perturb值(扰乱值)对纹理采样坐标进行扰乱,以便制作翻滚云的效果 outa.Tex.x = outa.Tex.x + Translation; Tex.xy = outa.Tex.xy + Perturb.xy; //使用扰乱后的纹理坐标对云彩纹理进行采样 TexColor = CloudTexture1.Sample(SampleType, Tex); //用brightness调节颜色的亮度 color = brightness*TexColor; return color; }
以上都可以用我对(1)和(2)的分析方法分析出原因来。
另外注意一下,PerturbScale值的大小控制了干扰云层量的大小,也就是云翻滚的激烈程序。PerturbScale值大,则云翻滚激烈。反之,不激烈.
源代码的链接如下:
http://download.csdn.net/detail/qq_29523119/9744846
相关文章推荐
- D3D11地形渲染教程三之高度图(HeightMap)
- Spring Cloud架构教程 (十三)分布式配置中心【Dalston版】
- ArcGIS教程:地形渲染之彩色地形图
- Directx11地形渲染教程二十一之CubeMap实现SphereReflection(球面反射)
- ECharts官方教程(十四)【使用 Canvas 或者 SVG 渲染】
- Directx11地形渲染教程一之FirstCamera(第一人称相机)
- 使用GPUImage渲染图片教程
- ArcGIS制图技巧系列(2)地形渲染
- Scott Mitchell 的ASP.NET 2.0数据教程之十三:在DetailsView控件中使用TemplateField
- Android游戏开发教程之十三:Sensor感应实例
- 地形教程 - 法线的计算
- iOS绘图教程 绘图、变换、颜色管理、脱屏渲染,模板、渐变、
- 史上最简单的SpringCloud教程 | 第七篇: 高可用的分布式配置中心(Spring Cloud Config)
- Unity3D教程:无缝地形场景切换的解决方法
- WPF入门教程系列十三——依赖属性(三)
- 史上最简单的SpringCloud教程 | 第七篇: 高可用的分布式配置中心(Spring Cloud Config)
- 基于Angular4+ server render(服务端渲染)开发教程
- spring cloud教程之使用spring boot创建一个应用
- unity3d教程动态创建简单平面地形
- 微信小程序入门教程--列表渲染多层嵌套循环及wx:key的使用