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

外销网站网络电商推广方案

外销网站,网络电商推广方案,那个网站做的刀比较好,网站建设工资 优帮云一、简介 本文介绍了 屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO) 的基本概念,实现流程和简单的代码实现。实现 SSAO 时使用到了 OpenGL 中的延迟着色 (Deferred shading)技术。 按照本文代码实现后,可以实现以下…

一、简介

本文介绍了 屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO) 的基本概念,实现流程和简单的代码实现。实现 SSAO 时使用到了 OpenGL 中的延迟着色 (Deferred shading)技术。
按照本文代码实现后,可以实现以下效果:

渲染结果

二、SSAO介绍以及实现流程

1. SSAO 介绍

(1). 什么是 Ambient Occlusion, AO

简单来说 Ambient Occlusion(AO) 是一种全局照明(Global Illumination,GI)中的根据环境光(Ambient Light)参数和环境几何信息来计算场景中任何一点的光照强度系数的算法。
AO 描述了表面上的任何一点所接受到的环境光被周围几何体所遮蔽的百分比, 因此使得渲染的结果更加富有层次感,对比度更高。
例如:对于下图中的车辆缝隙处(红色),会受到周边模型面片的遮挡,导致接收到的环境光 (Ambient light)较少,因此这些地方会更暗。而在车辆的边缘处(绿色),几乎不会受到周围模型面片的遮挡,接收到的环境光较多,因此这些地方会更亮。
AO示意图

(2). 什么是 Screen-Space Ambient Occlusion, SSAO

为了计算准确的 AO,可以使用光线跟踪算法。但是光线跟踪消耗计算资源太大,而 屏幕空间环境光遮蔽 (Screen-Space Ambient Occlusion, SSAO) 是一种仅仅基于屏幕信息(例如,屏幕上各像素对应 片元 的空间位置信息)快速估计 AO 的算法。

SSAO 算法的基本思想为:
对于目标着色点,在其周围的一个球(或者面向相机方向的半球)内采样多个采样点,如果采样点大多被模型的其他面片遮挡,那么说明该目标着色点的 Ambien Occlusion 比较大,因此该着色点理应较暗些。而反之,目标着色点周围得到的采样点大部分并不会被模型的其他面片遮挡,那么说明该着色点的 Ambient Occlusion 更小,因此会更亮。

以下图为例:
在图中的 红色着色点 附近的一个球内采样,得到 8 个采样点,其中只有两个采样点(白色采样点)相比模型中的其他面片更靠近相机,不会被模型面片遮挡。而其他 6 个采样点(灰色采样点)都会被模型中的其他面片遮挡,则红色目标着色点的 Ambient Occlusion 更大,渲染结果中此着色点会更暗。
而图中的 绿色着色点 附近的大多数采样点(白色采样点)都不会被模型面片遮挡,只有两个采样点(灰色采样点)会被遮挡,则绿色目标着色点的 Ambient Occlusion 更小,渲染结果中此着色点会更亮。

SSAO 示意图
在实现时也可以在朝向相机的半球内采样,理论上这样的结果会更加准确,而不是上图中所示的整个球内采样。在计算得到 各点的 AO 值后,也可以使用 滤波 操作对屏幕上各点的 AO 值进行滤波操作,平滑遮蔽效果,消除噪点。

2. SSAO 实现流程

实现 SSAO 主要分为 4 趟 pass。

(1). Geometry Pass

该 pass 对输入场景模型进行处理,将屏幕各像素对应片元的 texture_color, positon (in world space), normal 和 position (in view space) 输出到 GBuffer 中;

(2). Cal SSAO Pass

该 pass 根据 屏幕各像素对应片元(目标着色点)的 position (in view space) 信息,在各 片元 周围采样,得到采样点,根据采样点 是否会被模型遮挡计算目标着色点的 AO 值;

(3.) Blur SSAO Pass

该 pass 对 上趟流程中计算得到的 AO 进行滤波操作,的到滤波后的 blurredAO;

(4). Lighting (Shading) Pass

该 pass 根据 pass (1) 中得到的 texture_color, positon (in world space), normal 和 pass (3) 中得到的 blurredAO 计算各着色点的颜色值。使用 Phong 着色模型,公式如下:
I = I a ∗ b l u r r e d A O + I d + I s I=Ia * blurredAO + Id + Is I=IablurredAO+Id+Is

3. 主要代码讲解

(1). Geometry Pass Shader

geometryPassShader.vert:

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNor;
layout(location = 2) in vec2 aTexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;out vec3 vertexPos;
out vec3 vertexNor;
out vec2 textureCoord;
out vec4 vertexViewPos;void main() {textureCoord = aTexCoord;// 裁剪空间坐标系 (clip space) 中 点的位置gl_Position = projection * view * model * vec4(aPos, 1.0f);// 世界坐标系 (world space) 中 点的位置vertexPos = (model * vec4(aPos, 1.0f)).xyz;// 世界坐标系 (world space) 中 点的法向vertexNor = mat3(transpose(inverse(model))) * aNor;// 视图坐标系 (view space) 中 点的位置vertexViewPos = view * model * vec4(aPos, 1.0f);
}

geometryPassShader.frag:

#version 330 core
layout(location = 0) out vec4 FragColor;   // diffuse color
layout(location = 1) out vec3 FragPos;     // position in world space
layout(location = 2) out vec3 FragNor;     // normal in world space
layout(location = 3) out vec4 FragViewPos; // position in view spacein vec3 vertexPos;
in vec3 vertexNor;
in vec2 textureCoord;
in vec4 vertexViewPos;uniform sampler2D texture0;void main() {FragPos = vertexPos;FragNor = vertexNor;FragColor = texture(texture0, textureCoord);FragViewPos = vertexViewPos;
}

(2). Cal SSAO Pass Shader

calSSAOPassShader.vert

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNor;
layout(location = 2) in vec2 aTexCoord;
out vec2 textureCoord;
void main() {gl_Position = vec4(aPos, 1.0f);textureCoord = aTexCoord;
}

calSSAOPassShader.frag:

#version 330 core
out float AO;
in vec2 textureCoord;uniform mat4 projection;uniform sampler2D textureViewPos; // position (in view space)uniform vec3 gKernel[64]; // random position offset// 计算目标片段的 Ambient Occlusion (AO) 值
// AO in [0,1]
// 为了便于后续计算 代码中的 AO 规定为:
// AO 越接近 0,说明该片段被遮挡的越多(越暗)
// AO 越接近 1,说明该片段被遮挡的越多(越亮)
void main() {vec3 shadeViewPos = texture(textureViewPos, textureCoord).xyz; // 目标片段在 view space 中的坐标AO = 0.0;float gSampleRad = 1.5f;for (int i = 0; i < 64; i++) {vec3 sampleViewPos = shadeViewPos + gKernel[i]; // 在目标片段周围随机采样vec4 sampleProPos =vec4(sampleViewPos, 1.0); // 采样点 在 view space 中的坐标sampleProPos = projection * sampleProPos;sampleProPos.xy /= sampleProPos.w;// 采样点 投影到屏幕,再归一化到[0,1]的 xy 坐标 (即采样点对应的 uv 坐标)sampleProPos.xy = sampleProPos.xy * 0.5 + vec2(0.5, 0.5);// 相机-采样点 射线与场景相交点(场景表面点)对应的 z 值(在 view space 中)float surfaceDepth = texture(textureViewPos, sampleProPos.xy).z;if (abs(shadeViewPos.z - surfaceDepth) < gSampleRad) {// step(a,b) = if (a<b) return 1.0 else return 0.0;// 在 view sapce 中, camera position 为 (0,0,0)// 假如 abs(surfaceDepth) < abs(sampleViewPos.z) 说明 场景表面点 比// 采样点距离相机更近,那么 AO += 1// 假如 abs(surfaceDepth) >= abs(sampleViewPos.z) 说明 采样点 比// 场景表面点 距离相机更近,那么 AO += 0AO += step(abs(surfaceDepth), abs(sampleViewPos.z));}}// 前面 AO 记录的是 '采样点 被 场景表面 遮挡的次数'// 因此需要 令 AO = 1.0 - AO / (采样次数)// 最后得到的 AO 才是目标片段的 AO 值AO = 1.0 - AO / 64;
}

(3). Blur SSAO Pass Shader

blurSSAOPassShader.vert:

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNor;
layout(location = 2) in vec2 aTexCoord;
out vec2 textureCoord;
void main() {gl_Position = vec4(aPos, 1.0f);textureCoord = aTexCoord;
}

blurSSAOPassShader.frag:

#version 330 core
// out vec4 FragColor;
out float blurredAO;in vec2 textureCoord;uniform sampler2D textureAO;void main() {blurredAO = 0.0;float Offsets[4] = float[](-1.5, -0.5, 0.5, 1.5);float originAO = texture(textureAO, textureCoord).x;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {float AO = texture(textureAO, textureCoord).r;vec2 tc = textureCoord;tc.x = textureCoord.x + Offsets[j] / textureSize(textureAO, 0).x;tc.y = textureCoord.y + Offsets[i] / textureSize(textureAO, 0).y;blurredAO += texture(textureAO, tc).x;}}blurredAO /= 16.0;
}

(4). Lighting (Shading) Pass Shader

lightingSSAOPassShader.vert:

#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNor;
layout(location = 2) in vec2 aTexCoord;
out vec2 textureCoord;
void main() {gl_Position = vec4(aPos, 1.0f);textureCoord = aTexCoord;
}

lightingSSAOPassShader.frag:

#version 330 core
out vec4 FragColor;in vec2 textureCoord;uniform int state;uniform vec3 lightPos;uniform vec3 cameraPos;
uniform vec3 k;uniform sampler2D textureColor;     // color
uniform sampler2D texturePos;       // position (in world space)
uniform sampler2D textureNor;       // normal (in world space)
uniform sampler2D textureBlurredAO; // blurredAOvoid main() {vec3 vertexPos = texture(texturePos, textureCoord).xyz;vec3 vertexNor = texture(textureNor, textureCoord).xyz;vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);// Ambient// Ia = ka * Lafloat ambientStrenth = k[0];vec3 ambient = ambientStrenth * lightColor;float blurredAO = texture(textureBlurredAO, textureCoord).x;if (state == 0) {// Rendering scene with SSAO on.ambient = ambient * vec3(blurredAO);} else if (state == 1) {// Rendering scene with SSAO off.} else {// Rendering AO.FragColor = vec4(blurredAO);return;}vec3 diffuse = vec3(0, 0, 0);vec3 specular = vec3(0, 0, 0);// Diffuse// Id = kd * max(0, normal dot light) * Ldfloat diffuseStrenth = k[1];vec3 normalDir = normalize(vertexNor);vec3 lightDir = normalize(lightPos - vertexPos);diffuse = diffuseStrenth * max(dot(normalDir, lightDir), 0.0) * lightColor;// Specular (Phong)// Is = ks * (view dot reflect)^s * Lsfloat specularStrenth = k[2];vec3 viewDir = normalize(cameraPos - vertexPos);vec3 reflectDir = reflect(-lightDir, normalDir);specular = specularStrenth * pow(max(dot(viewDir, reflectDir), 0.0f), 2) *lightColor;// Specular (Blinn-Phong)// Is = ks * (normal dot halfway)^s Ls// float specularStrenth = k[2];// vec3 viewDir = normalize(cameraPos - vertexPos);// vec3 halfwayDir = normalize(lightDir + viewDir);// vec3 temp_specular = specularStrenth *//                      pow(max(dot(normalDir, halfwayDir), 0.0f), 2) *//                      lightColor;diffuse = clamp(diffuse, 0.0, 1.0);specular = clamp(specular, 0.0, 1.0);// Obejct colorvec3 objectColor = texture(textureColor, textureCoord).xyz;// Color = Ambient + Diffuse + Specular// I = Ia + Id + IsFragColor = vec4((ambient + diffuse + specular) * objectColor, 1.0f);
}

4. 全部代码及模型文件

使用OpenGL实现 屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO) 的全部代码以及模型文件可以在 OpenGL实现屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO) 中下载。程序运行后按下 空格 键在使用SSAO渲染场景直接渲染场景渲染AO值三种模式中切换。
渲染结果如下:
渲染结果

三、参考

[1].ogl-tutorial45 Screen Space Ambient Occlusion
[2].游戏后期特效第四发 – 屏幕空间环境光遮蔽(SSAO)

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

相关文章:

  • 湖南星大建设集团有限公司网站专业seo站长工具全面查询网站
  • dedecms做网站注意事项廊坊seo排名收费
  • 海南网站建设报价方案长沙网站seo排名
  • 怎么做网站自动采集数据库种子库
  • 成都网站建设服务密需湖南岚鸿案例网络营销专业可以干什么工作
  • 大神自己做的下载音乐的网站做企业网站建设的公司
  • 大连日文网站设计职业培训机构排名前十
  • 地税网站建设管理百度知道提问
  • 网站页面的滑动怎么做的五行seo博客
  • 电子商务网站建设怎么做win10优化大师好用吗
  • 郑东新区网站开发微信scrm
  • 个人博客网站建设方案seo搜索引擎优化费用
  • 天津做网站优化哪家好最火的网络销售平台
  • 网站源码地址怎么看软文模板300字
  • 网站建设和营销搜索引擎营销特点是什么
  • 做网站测试怎么样个人接外包项目平台
  • 专业网站开发设计网站搭建谷歌seo
  • 东莞网站建设 烤活鱼搜索引擎优化排名案例
  • 北京网站建设公司收购北京网站优化常识
  • 方正宽带网络服务有限公司标题优化方法
  • 乐清市疫情电子商务沙盘seo关键词
  • 响应式网站seo视频广告联盟平台
  • 国家发改委网站储气能力建设免费推广网站2023mmm
  • 新加坡政府网站建设特点今日时事新闻
  • 网站视频做背景游戏推广员拉人技巧
  • 跳转到手机网站台州seo排名优化
  • 邹城网站建设西地那非片的功能主治和副作用
  • 网站委托建设合同百度推广充值必须5000吗
  • 网站素材站百度知道问答首页
  • 佛山格尔做网站的公司推广途径有哪些