3D设计应用或游戏中常常需要准确的标识选中效果,轮廓线(描边)就是其中一种常用的选中态视觉表现效果。例如下图:

如上图所示,红色的轮廓线(描边)能让使用者更清晰的知道是选中了这个人体模型。但是这个选中效果存在一个缺点:模型的遮挡关系被忽略了,容易造成用户的误判。

如何在轮廓线上呈现遮挡关系呢?先看下图:

可以看得出来,上图中人体模型被遮部分的轮廓线颜色更淡一些(透明度更大),这样的效果有助于体现遮挡关系。

Demo(资源不少,可能加载会慢):Vox APP

这种轮廓线效果使用 post processing (后处理)的方式实现, 机制和模糊类似,具体实现步骤接下来详细说明(在OpenGL规范下实现)。

第一步: 设置好绘制 选中可渲染对象 的 material(作为当前渲染过程的全局material)。此material着色器关键代码:


// 顶点着色器关键代码
vec4 wpos = u_objMat * vec4(a_vs, 1.0);
gl_Position = u_projMat * u_viewMat * wpos;// 片段着色器关键代码, u_fillColor 设置为RGBA(1.0,0.0,0.0,0.0)
FragColor0 = u_fillColor;

第二步: 初始化FBO(Frame Buffer Object)。

第三步: 在各式为RGBA的RTT上绘制 选中可渲染对象(全部使用上述 material)。

第四步: 当前渲染状态 color mask 全部设置为 false, 当前FBO深度值重新设置为1.0。选中可渲染对象 设置为不可渲染。

第五步: 渲染和选中渲染对象可能相关(有视觉遮挡关系)的所有可渲染对象(仍然使用上述material)。

第六步: 当前渲染状态 color mask 为: 只有 GREEN 通道 为 true, 其他三个通道全部为false。选中可渲染对象 重新设置为可渲染。u_fillColor 的值设置为(0.0,1.0,0.0,0.0),也就是只绘制绿色到RTT。绘制 选中可渲染对象。

第六步: 恢复正常渲染状态(例如 color mask 全部设置为 true, 解除全局material使用状态等等)。

第七步: 利用前面步骤产生的纹理数据(RTT), 使用如下shader代码生成轮廓线(可以是整个画布大小也可以是四分之一画布大小), 绘制一个平铺于画布(viewport)区域的平面, 使用alpha混合在已经绘制好的3D渲染画面上。shader关键代码如下:


const float factor = 1.0 / 9.0;
const float floatReciprocalGamma = (1.0 / 2.2);
void main() {vec4 param = u_params[0];// param.xy: 纹理的实际宽高像素值// param.z: 强度值,可以取值1.3;// param.w: 像素值,可以取值为2.0, 这个值控制轮廓线的粗细// u_params[1]: (r,g,b,a) 颜色值// u_params[2].x: 被遮挡的轮廓线的透明控制系数// 为何用数组,是为了减少和GPU之间的通讯次数, 提升性能vec2 dv = param.ww / param.xy;vec4 srcColor = VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv );vec2 fc = srcColor.xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv + dv ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv - dv ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv + vec2(dv.x ,-dv.y) ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv + vec2(-dv.x ,dv.y) ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv + vec2(dv.x ,0) ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv + vec2(0 ,dv.y) ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv - vec2(dv.x ,0) ).xy;fc.xy += VOX_Texture2D( VOX_DIFFUSE_MAP, v_uv - vec2(0 ,dv.y) ).xy;fc.xy *= factor;float dis = abs(fc.x - srcColor.x);float fk = step(max(fc.y, srcColor.y), 0.0001);float fa = u_params[2].x;fa = (1.0 - fk) * (1.0 - fa) + fa;dis *= param.z;dis = pow(dis * dis * dis, floatReciprocalGamma);param = u_params[1];param.w *= dis * fa;FragColor0 = param;
}

至此,主要步骤结束。前六步的实例代码如下(由于每个人的渲染器实现不一样,这里供参考交流):

// step 1:
m_preMaterial.setRGB3f(1.0, 0.0, 0.0);
m_fboIns.setGlobalMaterial(m_preMaterial, false, true);
// step 2:
m_fboIns.runBegin();
m_fboIns.drawEntity(m_target);
// step 3:
m_fboIns.lockColorMask(RendererState.COLOR_MASK_ALL_FALSE);
m_fboIns.clearDepth(1.0);
m_target.setVisible(false);
// step 4:
m_fboIns.run(false, false, false);
// step 5:
m_fboIns.lockColorMask(RendererState.COLOR_MASK_GREEN_TRUE);
m_target.setVisible(true);
m_preMaterial.setRGB3f(0.0, 1.0, 0.0);
m_fboIns.updateGlobalMaterialUniform();
m_fboIns.drawEntity(m_target);
// step 6:
m_fboIns.runEnd();
m_fboIns.unlockRenderColorMask();
m_fboIns.unlockMaterial();

带遮挡效果的轮廓线(描边)在3D实时渲染中的一种实现相关推荐

  1. 3D实时渲染中的BSP树和多边形剔除

    原文<BinarySpace Partioning Trees and Polygon Removal in Real Time 3D Rendering> 第一章 介绍 背景 二叉空间分 ...

  2. 3D轮廓渲染中的几种轮廓边

    从左到右分别是: silhouette, contour, 和 suggestive contour边. 细节请见此文章:https://zhuanlan.zhihu.com/p/398383275

  3. 《安富莱嵌入式周报》第298期:迷你火星探测器,开源单片机3D实时渲染库, 开源USB工业相机,VS2022开始支持MarkDown,PC-lint 2.0发布

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

  4. Live Home 3D Pro - 用于公寓和房屋的室内设计,支持 3D 实时渲染

    Live Home 3D Pro - 用于公寓和房屋的室内设计,支持 3D 实时渲染 Live Home 3D Pro是一个直观的应用程序,用于公寓和房屋的室内设计,以及几乎任何复杂的景观.专业版提供 ...

  5. 【原】实时渲染中常用的几种Rendering Path

    [原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 -- polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...

  6. 【实时渲染】实时渲染中的光与颜色

    文章目录 光是一种电磁波 描述光的物理量 光谱功率分布 光度函数 光度测量 三色视觉理论 色光混合与颜色空间 用RGB色渲染 Gamma空间和线性空间 HDR 读书笔记,如有错漏,还望指正! 光是一种 ...

  7. 渲染路径-实时渲染中常用的几种Rendering Path

    http://www.cnblogs.com/polobymulberry/p/5126892.html?utm_source=tuicool&utm_medium=referral 回到顶部 ...

  8. 【实时渲染】RTR4 简要问答版

    第二章 图形渲染管线 (1)渲染管线可分为哪4个阶段? 第一个是应用程序阶段,第二个是几何处理阶段,第三个是光栅化阶段,第四个是着色阶段(Pixel Processing). (2)渲染管线分为几个阶 ...

  9. 【实时渲染】3DCAT实时渲染云助力游戏上云!

    随着社会的发展技术的提升,云计算技术得到越来越多人的重视.同时随着5G的落地,游戏产业也迎来了新的革命.一些游戏厂商为了寻求新的发展机会,推出基于云计算的游戏"云游戏",将游戏平台 ...

最新文章

  1. python使用matplotlib可视化、使用英文单次或者缩写指定使用的颜色、使用16进制的RGB字符串指定颜色、使用RGB或者RGBA数字元组指定颜色
  2. 迎战双十一,阿里集聚500多家外部合作伙伴进行系统压力测试
  3. 二叉树的层序遍历—leetcode102
  4. 程序员上帝视角解读“旅行青蛙”,你的呱真的在旅行嘛?
  5. 再写堆(堆的性质,向下调整,建堆,堆的插入删除初始化,堆排序,TopK问题)
  6. pytorch l2正则化_吴恩达深度学习 编程作业六 正则化(2)
  7. 服务发现系统consul-HTTP API
  8. 反爬虫策略的应对方法汇总
  9. Android------APP FPS测试
  10. 溢出的文字如何省略号显示
  11. OrCAD中PSpice K_Linear以及变压器的使用方法
  12. UCenter+云市场?开源用户中心2.0时代即将开启
  13. 微信公众号wifi链接php,TP路由器实现关注微信并认证后连接WIFI上网
  14. ​mybatis collection解析以及和association的区别
  15. 智能呼叫系统之客户互动中心
  16. 【Python】用字母生成图像
  17. MDPI论文投稿全流程实例讲解
  18. document.write
  19. 生成模型笔记预备知识笔记——概率分布变换
  20. 刘东明微信营销二十五式初探(一)

热门文章

  1. python绘制简单彩虹图_python绘制简单彩虹图
  2. POI导出word单元格合并
  3. tf.Keras.Model类总结
  4. 【51CTO学院三周年】通往程序猿艰辛历程,幸好遇到51CTO学院
  5. cdr 表格自动填充文字_极速office中表格的七个最常用技巧
  6. Ubuntu学习笔记6-ESP32接收并处理cmd_vel话题
  7. 我说CMMI2.0之:详细剖析(PQA)过程质量保证
  8. VMware设置静态IP
  9. ​区块链公链“三元悖论”专题系列之去中心化(Decentralization)
  10. html手机打不开是什么意思,html是什么意思