基础概念

在3D游戏引擎中,球体、立方体以及所有其它复杂的集合体都是由三角面片组成的。引擎只会渲染物体的表面,比如球体,半透明物体等.整个世界由各种空壳构成.

立体渲染(Volumetric Rendering)的基本概念:模拟光线在物体内部的传送,从而实现更震撼也更真实的视觉效果。
片段着色器最后返回的对象,是从特定角度看过去特定位置的颜色。
这种方式计算的颜色是完全随意的,因此返回的内容可以不必匹配几何体的真实渲染情况。
下图展示了一个3D立方体的例子。当片段着色器检测到立方体表面的颜色时,模拟光线传送,使得结果如同一个球体

立体射线投射 Volumetric Raycasting

用一个函数判断光线与自定义的几何体相交的问题,限制较大,只能模拟简单几何体比如球,圆柱等。

固定步长立体光线追踪 Volumetric Raymarching with Constant Step

不依赖相交函数的,基于迭代的,可以模拟任意几何体
一步一步的检测光线是否已经投射到红色球体

bool raymarchHit (float3 position, float3 direction)
{for (int i = 0; i < STEPS; i++){if ( sphereHit(position) )return true;position += direction * STEP_SIZE;}return false;
}bool sphereHit (float3 p)
{return distance(p,_Centre) < _Radius;
}

距离辅助的光线追踪 Distance Aided Raymarching

固定步长的光线追踪非常低效,需要一种方法估算在遇到几何体之前需要走多远,
比如之前的sphereHit函数,不是返回bool值,而是距离球面的距离

float sphereDistance (float3 p)
{return distance(p,_Centre) - _Radius;
}

该函数就是一个有向距离函数(signed distance function),正数在几何体外,负数在几何体上,0在几何体表面
距离辅助的光线追踪实现代码:

fixed4 raymarch (float3 position, float3 direction)
{for (int i = 0; i < STEPS; i++){float distance = sphereDistance(position);if (distance < MIN_DISTANCE)return i / (float) STEPS;position += distance * direction;}return 0;
}

在一个比较复杂的场景运行的效果如下

STEPS 最大步数,需要根据图像形状调整
MIN_DISTANCE 不能是0,给一个比较合适的误差值0.01左右

SDF Signed Distance Fields(Functions) 有向距离场(函数) 组合

可以用组合的方式做出比较复杂的图形,例如那个很出名的蜗牛
简单来说 min返回并集,max返回交集
可以用类似Alpha混合的方式做多个形状的混合 as1 + (1-a)s2
还有很多种别的合并方式,如光滑合并

float sdf_smin(float a, float b, float k = 32)
{float res = exp(-k*a) + exp(-k*b);return -log(max(0.0001,res)) / k;
}

法线预估

Íñigo Quílez的方法是对周围其它点的距离场进行取样,来估算局部表面的曲率

float3 normal (float3 p)
{const float eps = 0.01; return normalize( float3 (map(p + float3(eps, 0, 0) ) - map(p - float3(eps, 0, 0)),map(p + float3(0, eps, 0) ) - map(p - float3(0, eps, 0)),map(p + float3(0, 0, eps) ) - map(p - float3(0, 0, eps))) );
}

更多

ShaderToy中有很多效果很好的例子
MERCURY团队创建的hg_sdf库,有很多元物件与操作

一个简单的实例Unity Shader

效果如下,在Cube内绘制了一个球

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'Shader "Unlit/VolumetricText"
{Properties{_BaseColor ("Base Color", Color) = (1,1,1,1)_SphereColor ("Sphere Color", Color) = (1,0,0,1)_SphereCentre("Sphere Centre",Vector) = (0,0,0)_ShpereRange ("Sphere Range", Range(0.1,2)) = 0.8}SubShader{Tags { "RenderType"="Opaque" "LightMode" = "ForwardBase" }LOD 100Pass{CGPROGRAM#include "Lighting.cginc"#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;    };struct v2f{float4 vertex : SV_POSITION;float3 wPos : TEXCOORD0; //世界坐标};float4 _BaseColor;float4 _SphereColor;float3 _SphereCentre;fixed _ShpereRange;//有向距离函数float SphereDistance(float3 p){return distance(p, _SphereCentre) - _ShpereRange;}//光线追踪fixed Raymarch(float3 position, float3 direction){float STEPS = 10;float MIN_DISTANCE = 0.01;for (int i = 0; i < STEPS; i++){float distance = SphereDistance(position);if (distance < MIN_DISTANCE)return i / (float)STEPS;position += distance * direction;}return 0;}//法线模拟_简单球形测试float3 NormalEstimation_Sphere(float3 p){return normalize(p - _SphereCentre);}v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = _BaseColor;float3 viewDirection = normalize(i.wPos - _WorldSpaceCameraPos);fixed rayHit = Raymarch(i.wPos, viewDirection);if (rayHit >= 0.01)col = _SphereColor;//丢弃不在形状内的,测试,不在的改为白色clip(col.a - 0.01);fixed3 normal = NormalEstimation_Sphere(i.wPos);//简单处理下光照fixed3 lightDir = _WorldSpaceLightPos0.xyz; // Light directionfixed3 lightCol = _LightColor0.rgb; // Light colorfixed NdotL = max(dot(normal, lightDir), 0);col.rgb = col * lightCol * NdotL;return col;}ENDCG}}
}

参考网页

Unity教程|立体渲染
Unity3D体积烟雾制作思路分享
梯度下降法
comprehensive guide to volume rendering

转载于:https://www.cnblogs.com/Hichy/p/9584068.html

立体渲染 Volumetric Rendering相关推荐

  1. 游戏中的Volumetric Rendering

    总结下游戏中常见的Volumetric Rendering的实现方法 1. 一些理论知识 快速简要地介绍一些理论知识. 光打到粒子上之后的效果: 光在介质上的散射,入射光分为吸收,透射,外散射三个部分 ...

  2. 【理解】神经立体渲染,NeRF

    https://www.zhihu.com/question/528913695/answer/2568694310 2020年是神经立体渲染(neural volume rendering)爆发的一 ...

  3. OpenGL 分层渲染Layered Rendering的实例

    OpenGL 分层渲染Layered Rendering 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <string> #incl ...

  4. OpenGL 文本渲染Text Rendering

    OpenGL文本渲染Text Rendering 文本渲染Text Rendering简介 经典文本渲染:位图字体 现代文本渲染:FreeType 着色器 渲染一行文本 更进一步 文本渲染Text R ...

  5. CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率

    CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率 当场景中有比较复杂的模型时,条件渲染能够加速对复杂模型的渲染. 条件渲染(Conditio ...

  6. 延迟渲染(Deferred Rendering)

    什么是延迟渲染?( Deferred Rendering) 在计算机图形学中,延迟渲染( Deferred Rendering) ,即延迟着色(Deferred Shading),是将着色计算延迟到深 ...

  7. 实例渲染Instanced Rendering

    实例渲染Instanced Rendering 0.前言 在此之前红宝书已经介绍了不少关于缓存和绘制的命令,并给出了用同样的顶点绘制几个三角形的例程,但是此前的例程实现起来非常麻烦,每个三角形要指定一 ...

  8. UE4 Medical Data Volumetric Rendering

    UE4 Medical Data Volumetric Rendering TBRaymarchPlugin - UE4 Medical Data Volumetric Rendering (Raym ...

  9. 一种快速制作立体渲染效果地形图方法

    概述 制作立体渲染地形图的方法网上有很多,常见的方法就是在ArcToolbox中使用山体阴影工具制作山体阴影,再调整透明度,这里给大家介绍另外一种方法,该方法更加的快速. 数据来源 本教程所使用的数据 ...

最新文章

  1. 用C#生成随机中文汉字验证码的基本原理
  2. IBM大裁70% 员工,撕掉了国内大批伪AI企业最后一块遮羞布!
  3. apache解析php的方法
  4. 三菱plc编程实例3000_三菱PLC十字路口的红绿灯编程实例
  5. python中代理模式分为几种类型_代理模式
  6. MyBatis(四)MyBatis插件原理
  7. 学习JavaScript的24条实用建议
  8. 【SQL语句】MySql、SqlServer查询近期记录
  9. Java数据库篇9——备份与还原、忘记密码
  10. 下岗工人到达退休年龄,养老保险未缴纳满15年,补缴合适吗?
  11. 寻找开发区块链协议的完美编程语言
  12. Ubuntu安装网易云音乐
  13. 鸿蒙曰意心养翻译,文言文情话及翻译
  14. 基于51单片机的多点8路温度采集系统 proteus仿真程序原理图设计
  15. 计算机技术对人脸识别的作用,人脸识别技术有什么功能特点
  16. Intel显卡跑ROS与CUDA总结(MacBook Pro 11.6.3)
  17. 还在用ES查日志吗,快看看石墨文档 Clickhouse 日志架构玩法
  18. 【现成工具】java获取国家法定节假日包含指定月份节假日和周末
  19. 搭建K8S 的dashboard的坑the server could not find the requested resource
  20. PnPUtil (PnPUtil.exe) 是一个命令行工具,使管理员可以执行以下操作驱动程序包

热门文章

  1. php阿拉伯数字转汉字,php 阿拉伯数字转中文汉字
  2. 用matlab刻度尺,刻度尺如何使用
  3. java写一个查询详情接口_旅游景点api 景区详细信息查询服务
  4. 【English】Enjoy your April
  5. linux下Gaussian16安装
  6. android 百度地图高德地图开发
  7. 42㎡小户型变形记,为一对程序员情侣,改造时尚复古小宅
  8. 用java分析班级成绩
  9. 全球全年地表温度演变图
  10. IntelliJ IDEA修改系统缓存目录解决开发Java项目C盘爆满的坑