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

网站建设分工网站友情链接有什么用

网站建设分工,网站友情链接有什么用,做网站去哪里做,郑州建站费用简而言之,步骤如下: 1.从灯光位置视点(阴影相机)创建深度图。 2.从相机的位置角度进行屏幕渲染,在每个像素点,比较由阴影相机的MVP矩阵计算的深度值和深度图的值的大小,如果深度图值小的话&…

简而言之,步骤如下:

1.从灯光位置视点(阴影相机)创建深度图。

2.从相机的位置角度进行屏幕渲染,在每个像素点,比较由阴影相机的MVP矩阵计算的深度值和深度图的值的大小,如果深度图值小的话,则表示该像素点有阴影,就在此处渲染阴影状态。

演示效果

1.创建深度图

基本上,从头开始做阴影贴图时,只需要准备三样东西:灯光位置、阴影相机和深度图。为了更方便理解,本文用ShadowMapViewer来将深度图进行可视化。

方向光(Directional Light)

首先创造一个光源。

const light = new THREE.DirectionalLight( 0xffffff, 1.0 );
light.position.set(-30, 40, 10);
scene.add(light);

DirectionalLight有一个shadow参数,因此附加一个从灯光位置观察的阴影相机和一个从阴影相机角度写入深度值的fbo(frame buffer object,帧缓存对象)。

阴影相机(Shadow Camera)

由于光线是定向的,因此使用OrthographicCamera(正视相机)作为阴影相机来创建平行投影的深度图。

最重要的是必须设置好相机范围(视锥体),如果阴影相机范围太宽,深度图会不准确,因此最好将其设置在尽可能渲染阴影的最小范围,不要太宽或太窄。

const frustumSize = 80;light.shadow.camera = new THREE.OrthographicCamera(-frustumSize / 2,frustumSize / 2,frustumSize / 2,-frustumSize / 2,1,80
);// 和灯光位置保持一致
light.shadow.camera.position.copy(light.position);
light.shadow.camera.lookAt(scene.position);
scene.add(light.shadow.camera);

深度图(Depth Map)

接下来,为阴影相机视点准备深度图。

深度图如果分辨率设置太低图像会很粗糙,所以这次我们将准备一个 2048 x 2048 的fbo。

一般为了尽可能以高精度写入深度值,通常使用16位或32位纹理,但由于WebGL尚不兼容尚不支持浮动纹理的设备,所以我们用8位纹理的所有四个通道来存储单个32位值(在本例中为深度值),我们将使用three.js的ShaderChunk,方便转换。

light.shadow.mapSize.x = 2048;
light.shadow.mapSize.y = 2048;const pars = { minFilter: THREE.NearestFilter,magFilter: THREE.NearestFilter, format: THREE.RGBAFormat
};light.shadow.map = new THREE.WebGLRenderTarget( light.shadow.mapSize.x, this.light.shadow.mapSize.y, pars );

用于渲染深度图的材质

const shadowMaterial = new THREE.ShaderMaterial({vertexShader: vertexShader,fragmentShader: shadowFragmentShader
});

顶点shader基本是一样的。

void main(){gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}

因为我们要写入的深度图是8bit纹理,但是要输入的数据是32bit。在这里可以用three.js的shaderChunk中使用packDepthToRGBA来存储使用rgba通道的深度值。

// https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/packing.glsl.js#L18
#include <packing>void main(){// gl_FragCoord.z contains depth values from 0 to 1 in the viewing frustum range of the shadow camera.// 0 for near clip, 1 for far clipgl_FragColor = packDepthToRGBA(gl_FragCoord.z);
}

写入深度值

shadowMaterial赋到mesh上,并渲染为深度图。

由于需要为阴影相机视点创建深度图,因此将深度图指定为“renderTarget”,将shadowCamera指定为“camera”。

// 更新每一帧
mesh.material = shadowMaterial;
renderer.setRenderTarget(light.shadow.map);
renderer.render(scene, light.shadow.camera);

这样的话我们就渲染了深度图,然后用我刚才说的ShadowMapViewer来查看深度图的调试效果。

// https://threejs.org/examples/?q=shadow#webgl_shadowmap_viewerconst depthViewer = new ShadowMapViewer(light);
depthViewer.size.set( 300, 300 );...
// render to canvas
renderer.setRenderTarget(null);
depthViewer.render( renderer );

越靠近阴影相机的地方,深度值越小(因为ShadowMapViewer对结果取反了,所以越是白的地方,深度值越小)。

2.比较深度并创建阴影

屏幕渲染材质

将光照位置和深度图放入uniform变量中,阴影相机投影矩阵和视图矩阵也放入uniform变量中,因为在阴影相机的 MVP矩阵中计算的深度也必须在这个着色器中计算并与深度图进行比较。

const uniforms = {uColor: {value: new THREE.Color(color)},uLightPos: {value: light.position},uDepthMap: {value: light.shadow.map.texture},uShadowCameraP: {value: light.shadow.camera.projectionMatrix},uShadowCameraV: {value: light.shadow.camera.matrixWorldInverse},
}
const material = new THREE.ShaderMaterial({vertexShader,fragmentShader,uniforms,
});

在顶点着色器中添加一些代码。

uniform mat4 uShadowCameraP;
uniform mat4 uShadowCameraV;varying vec4 vShadowCoord;varying vec3 vNormal;void main(){vNormal = normal;vec3 pos = position;gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(pos, 1.0);// 阴影相机视点的坐标传递给片段着色器并与深度图进行比较vShadowCoord = uShadowCameraP * uShadowCameraV * modelMatrix * vec4(pos, 1.0);
}

vShadowCoord的结果是裁剪空间中的坐标,因此vShadowCoord.xyz / vShadowCoord.w 的范围从 (-1, -1, -1)到(1,1,1)。

vShadowCoord.z / vShadowCoord.w是深度值,所以让它在0和1之间转换并与深度图进行比较。并让vShadowCoord.xy / vShadowCoord.w在(0,0)和(1,1)之间转换为uv来参考深度图。之所以使用MVP矩阵计算得到的结果作为uv,是因为我们可以参考与生成深度图的像素相同点的深度值。

由于深度图值是较早通过在rgba中分配32位数据输入的,因此在引用时需要将其恢复为原始值。

此解码使用来自three.js中相同ShaderChunk的unpackRGBAToDepth

uniform vec3 uColor;
uniform sampler2D uDepthMap;
uniform vec3 uLightPos;varying vec3 vNormal;
varying vec4 vShadowCoord;// https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/packing.glsl.js#L24
#include <packing>void main(){vec3 shadowCoord = vShadowCoord.xyz / vShadowCoord.w * 0.5 + 0.5;float depth_shadowCoord = shadowCoord.z;vec2 depthMapUv = shadowCoord.xy;float depth_depthMap = unpackRGBAToDepth(texture2D(uDepthMap, depthMapUv));// Compare and if the depth value is smaller than the value in the depth map, then there is an occluder and the shadow is drawn.float shadowFactor = step(depth_shadowCoord, depth_depthMap);// check the result of the shadow factor.gl_fragColor = vec4(vec3(shadowFactor), 1.0);
}

在循环函数中,将屏幕渲染过程放在深度图渲染之后。

// 在循环函数中写入深度图
mesh.material = shaderMaterial;
renderer.setRenderTarget(light.shadow.map);
renderer.render(scene, light.shadow.camera);// 放置一个用于屏幕渲染的材质并将其渲染到画布上。
mesh.material = material;
renderer.setRenderTarget(null);
renderer.render(scene, camera);

调整深度值比较

当显示shadowFactor(比较深度值的结果)时,会生成阴影,但会显示出一些奇怪类似摩尔纹的图案,这种现象被称为shadow acne,必须通过减去这一点的bias来比较深度值。

void main(){...float cosTheta = dot(normalize(uLightPos), vNormal);float bias = 0.005 * tan(acos(cosTheta)); // cosTheta is dot( n,l ), clamped between 0 and 1bias = clamp(bias, 0.0, 0.01);float shadowFactor = step(depth_shadowCoord - bias, depth_depthMap);gl_fragColor = vec4(vec3(shadowFactor), 1.0);
}

乘以定向光,然后完成着色。

http://www.hengruixuexiao.com/news/31304.html

相关文章:

  • 网站的运营杭州百度推广代理公司哪家好
  • 做百度快照要先有网站吗企业推广方法
  • 安徽鑫华建设有限公司网站app数据分析软件
  • 聚震网站开发百度扫一扫
  • dede网站地图文章变量数字营销软件
  • 如何制作网站视频的软件优化防控措施
  • 成品网站管理系统源码建网站seo
  • 网络舆情分析报告模板seo和sem的联系
  • 做c语言的题目的网站seo权重查询
  • 怎么创建企业网站免费友情链接
  • 北票网站建设宁波技术好的企业网站制作
  • 网站改版建设主要网站alexa排名
  • 网站建设大概价格seo外包杭州
  • 百度推广 手机网站中国seo网站
  • 哪些网站可以做装修鹤壁搜索引擎优化
  • 上海做网站的公seo顾问服务 乐云践新专家
  • 微信 html5 网站正规推广平台有哪些
  • 武汉便宜做网站seo网站优化培训厂家报价
  • 什么是网站流量昆明网站seo服务
  • word怎么做网站导航栏市场调研报告万能模板
  • 网站建设相关推荐百度站长链接提交
  • 微信h5怎么制作广州网站营销seo费用
  • 南京门户网站建设网站策划是干什么的
  • 全国免费的分类信息网苏州首页排名关键词优化
  • 建设银行成都官网招聘网站seo分析及优化建议
  • 这么用自己的电脑做网站服务器站长联盟
  • 什么app可以制作价目表seo搜索引擎优化哪家好
  • 谈谈网站开发流程北京网站优化方法
  • 镇江建设局网站seo工程师是做什么的
  • 中国建设银行网站-公司机构客户网站如何让百度收录