当前位置: 首页 > news >正文

蔚县网站建设公司软件外包企业排名

蔚县网站建设公司,软件外包企业排名,网站开发 请示,买了两台服务器可以做网站吗webgl_gpgpu_birds 是一个 three.js 的官方样例,这个例子模拟了鸟群的运动,是一个群组动画,并且动画的帧率也很高;鸟群的运动很自然,非常值得研究。类似的群组动画还有鱼群,boid是‘类鸟群’的英文 大概两…

webgl_gpgpu_birds 是一个 three.js 的官方样例,这个例子模拟了鸟群的运动,是一个群组动画,并且动画的帧率也很高;鸟群的运动很自然,非常值得研究。类似的群组动画还有鱼群,boid是‘类鸟群’的英文

大概两年前,第一次看这个例子时,很枯燥,看不懂,有很多地方不知道是什么意思。第一次看这个例子时,才知道原来 纹理 texture 可以这样来使用,这个例子可以作为一个通用的并行计算框架的例子来看待。

这个例子的鸟群中一共有 32 x 32 共 1024 只鸟。鸟群中的每只鸟的位置是一个三维坐标,保存在一张 32 x 32 像素的纹理图片缓存中,初始化时,fillPositionTexture函数负责为 每只鸟 赋予一个 [-400, 400] 闭区间内的一个随机值。鸟的位置的x y z 分量都在 -400 到 400内取随机值。

鸟群中的每只鸟的速度是一个三维向量,保存在另外一张 32 x 32 像素的纹理图片缓存中,初始化时,fillVelocityTexture函数负责为 每只鸟 的速度的x y z分向量都赋予一个 [-5, 5] 闭区间内的一个随机值。每只鸟的速率和方向都是不同的。

例子中的 GPUComputationRenderer 负责在每一帧渲染前,都去以一定的规律 或 计算模式去更新鸟群的位置纹理 和 速度纹理。这两个纹理的分辨率都是 32 x 32 像素,对于渲染器来说,分辨率很小。渲染器更新的纹理的分辨率一般都是屏幕分辨率,1024 * 768 等;所以,更新这两张贴图对于渲染器来说很轻量,写这两张纹理对应的片元着色器代码时,不用过于考虑效率问题。
第一次看这个例子时,差不多就知道这些。片元着色器和顶点着色器的代码完全看不懂。
这个例子一共有四个着色器。
a. 片元着色器 birdFS,负责更新鸟群中每只鸟的颜色,最简单
b. 顶点着色器birdVS,负责更新鸟群中每只鸟的姿态和位置坐标,第二难理解
c. 片元着色器fragmentShaderVelocity,负责更新鸟群中每只鸟的速度,相对来说最难理解,
d. 片元着色器fragmentShaderPosition,负责更新鸟群中每只鸟的三维坐标,第二简单
这四个着色器,是透彻理解这个例子绕不过去的。

着色器先放一放,先来讲场景构建,BirdGeometry其实名称不确切,应该叫BirdFlockGeometry.因为这个几何体实际上是描述鸟群的。vertices 属性保存每只鸟的几何顶点,birdColors属性保存每只鸟的顶点颜色,references 属性保存每只鸟在鸟群中的编号,可以通过这个编号找到每只鸟的在纹理图片中的三维坐标和三维速度向量。birdVertex属性保存一只鸟的顶点编号,每只鸟由三个三角面组成,每个三角面又由三个顶点组成。一只鸟就有九个顶点。这个编号就是从 0 到 8,每只鸟都是 0 到 8,这个birdVertex属性 只用于 birdVS 顶点着色器,用于找到鸟翅膀的两个顶点,修改两个顶点 y 坐标,这样每只鸟的一双翅膀就上下扇动起来了。

BirdGeometry的构造函数中,定义了每只鸟的形状;每只鸟顶点颜色,是从深灰到浅灰的不同数值

场景构建时,这行代码要留意一下 camera.position.z = 350; 摆在了正对着世界坐标的 xy 平面,并且世界坐标的原点位于屏幕的正中心。函数 fillPositionTexture 和 fillVelocityTexture 分别用于初始化每只鸟的位置和速度。

在绘制每一帧前都要调用gpuCompute.compute(),去更新两张 32 x 32像素的纹理图片,每只鸟的位置和速度就变化起来了。这两张纹理然后再传递给 鸟群的顶点着色器birdVS ,更新每只鸟的位置和姿态。

birdFS 中根据每只鸟的位置 z 坐标,来更新鸟的灰度,

varying vec4 vColor;
varying float z;uniform vec3 color;void main() {// Fake colors for nowfloat z2 = 0.2 + ( 1000. - z ) / 1000. * vColor.x;gl_FragColor = vec4( z2, z2, z2, 1. );}

z 越接近相机,越接近350,颜色边深,变暗,超过350,飞到相机后面,看不见了。

birdVS中,

if ( birdVertex == 4.0 || birdVertex == 7.0 ) {// flap wingsnewPosition.y = sin( tmpPos.w ) * 5.;
}

使每只鸟的翅膀上下扇动起来

velocity.z *= -1.;
float xz = length( velocity.xz );
float xyz = 1.;
float x = sqrt( 1. - velocity.y * velocity.y );float cosry = velocity.x / xz;
float sinry = velocity.z / xz;float cosrz = x / xyz;
float sinrz = velocity.y / xyz;

根据速度向量,求方位角 cosry sinry 和俯仰角 cosrz sinrz
假设 velocity 等于 (0, 0, 1.0), 那么 sinry == 1.0;表示需要绕 y轴 旋转90°,进行偏航;
在 BirdGeometry 中对单只鸟的形状构建,可以看到单只鸟的原始朝向就是 (0, 0, 1.0),也就是,velocity 等于 (0, 0, 1.0)时,其实不应该有 偏航;代码中的 576行,birdMesh.rotation.y = Math.PI / 2;
又把这种不一致纠正回来。

newPosition =  maty * matz * newPosition;
newPosition += pos;

每只鸟的每个顶点,先绕z轴 (俯仰角)旋转,再绕y轴(方位角)旋转

fragmentShaderPosition片元着色器负责更新每只鸟的三维坐标,其中的 phase 保存在 w 分量中,用于在之后的 birdVS 顶点着色器中使用,来更新翅膀的摆动幅度,期望速率越大时,摆动的幅度也越大,频率也越快, 其中的 62.83 约等于 PI 的20倍。

uniform float time;
uniform float delta;void main()	{vec2 uv = gl_FragCoord.xy / resolution.xy;vec4 tmpPos = texture2D( texturePosition, uv );vec3 position = tmpPos.xyz;vec3 velocity = texture2D( textureVelocity, uv ).xyz;float phase = tmpPos.w;phase = mod( ( phase + delta +length( velocity.xz ) * delta * 3. +max( velocity.y, 0.0 ) * delta * 6. ), 62.83 );gl_FragColor = vec4( position + velocity * delta * 15. , phase );}

最后一个最复杂,代码最多的fragmentShaderVelocity片元着色器,更新每只鸟的速度向量。
可以看到优先级最高的是规避 捕食者,让鸟群远离捕食者一定的距离;
可以看作是来自捕食者的排斥力,这是有条件的,只有鸟靠近捕食者一定距离,才会收到这种斥力,
第二优先级是,使鸟始终向着屏幕的中心移动,这些鸟始终都受到来自屏幕中心的引力;如果没有这个力,鸟群就散开了,很快飞到相机看不见的位置了。
紧接着是一个32 * 32的二重循环,来对鸟群中每只鸟应用 来自其他鸟的排斥力,吸引力,偏向力

if ( dist < 0.0001 ) continue;

表示如果当前像素就是自己,直接跑完这次循环

if ( distSquared > zoneRadiusSquared ) continue;

表示这只鸟 离当前自己太远,不会对我产生排斥力,偏向力,吸引力,直接跑完这次循环,忽略掉。
接下来,就是 if … else if … else … 三个分支,其实可以想象一个三个大小不同的圆组成一个同心圆环。最内层的圆表示,如果我自己和其他鸟的距离小于圆半径,则我受到来自这只鸟的排斥力;
如果我自己和其他鸟的距离在最小圆半径 和 次小圆半径之间,则我受到来自这只鸟的偏向力;我的飞行姿态要向这只鸟看齐,如果我自己和其他鸟的距离在次小圆半径 和最大圆半径之间,则受到来自这只鸟的吸引力。

排斥力,偏向力,吸引力三个力是鸟群之间的相互作用力。三个力是互斥的,鸟A 只能受到 鸟B三个力中的一种,也可能 鸟A 和 鸟B之间完全没有相互作用力。三个力的优先级是 排斥力 > 偏向力 > 吸引力。

separationDistance 定义排斥力半径, separationDistance + alignmentDistance的次圆面积 减去 半径为 separationDistance的最小圆面积,得到一个圆环区域;以我自己为圆心,如果其他鸟在这个圆环区域内,则我向这只鸟看齐,受到来自只鸟的偏向力;最大圆的半径是 separationDistance + alignmentDistance + cohesionDistance;最大圆 减去 次小圆又是另一个圆环;这个圆环内小鸟对我产生吸引力

// Attraction / Cohesion - move closer
float threshDelta = 1.0 - alignmentThresh;
float adjustedPercent;
if( threshDelta == 0. ) adjustedPercent = 1.;
else adjustedPercent = ( percent - alignmentThresh ) / threshDelta;f = ( 0.5 - ( cos( adjustedPercent * PI_2 ) * -0.5 + 0.5 ) ) * delta;velocity += normalize( dir ) * f;

上面代码里还考虑了除零异常。cohesionDistance是允许为零的,为零时,f = 1.5 * delta;
delta表示前一帧和当前帧之间流逝了多少时间,以毫秒为单位;

代码中当 cohesionDistance == 0, 并且 alignmentDistance == 0,当percent == 1时,直接进入else分支,这时鸟群之间没有偏向力,只有吸引力和排斥力两种。

http://www.khdw.cn/news/4262.html

相关文章:

  • 公司网站优化推广方案软文营销的写作技巧有哪些
  • 在上阿里云做网站百度seo课程
  • 余姚网站推广公司西安网站seo排名优化
  • 网站图标素材图片网站平台推广
  • 湘潭网站建设网站推广今日热点新闻排行榜
  • wordpress 留言 插件北京百度seo排名公司
  • 网站片头动画用什么软件做的seo站长之家
  • 深圳做企业网站的湖南网络推广机构
  • 服务器网站路径问题厦门人才网
  • 涿州网站建设有限公司线上营销
  • 有新浪的域名怎么做网站百度云网盘搜索引擎
  • 网络管理系统设备seo工作流程
  • 自己做时时彩网站营销策划案的模板
  • 做幼儿园网站软文广告100字
  • 公司网站改版要怎么做绍兴seo排名收费
  • 做团购网站需要注册哪些商标百度快照怎么做
  • 烟台专业做网站公司有哪些网站制作开发
  • 什么网页游戏可以赚钱seo推广优化公司哪家好
  • 成都设计公司名字seo是什么单位
  • ps做网站要求高吗软件开发交易平台
  • 350做网站深圳市场推广外包团队
  • 设计模板修饰演示文稿qq关键词排名优化
  • 如何做情趣网站网站网络营销
  • 上海营销网站建设定制服务营销网站建设培训学校
  • 集团公司做网站的好处有什么qq群怎么优化排名靠前
  • dede网站qq类源码发布悬赏任务的推广平台
  • 工程项目备案信息查询seo全称是什么
  • 怎么给网站做301谷歌seo引擎优化
  • 网站删除代码网络营销策划书总结
  • wordpress同步微信素材烟台seo外包