最终效果

思路

伪体渲染

通常体渲染是模拟射线在模型中逐步判断,每个像素需要for循环若干次逐步递进,然后对每个路过的像素进行加工,步距决定精度,最终输出。
消耗相当高,但如果我们绘制的是可预测的规则模型,我们就可以预先算出射线的位置来进行判断。
优点是:效率极快,几乎可以避免逻辑判断和for循环。
缺点是:比较繁杂,不能实现象射线递进那样完全真实和自由的效果。

快速判断射线位置

关于求向量的投影大家自行百度,这里用了张百度搜的图片讲解。
我们知道视线的角度normalize(u),和 视线和球心的距离u`(_SpherePos - _CameraPos)
通过投影的逆运算,我们能求出视角U未来在球心垂面上的点位置。
即: p = normalize(U) · normalize(U`) * |U|
未来的位置为:视角法向量 点乘 视角和球心的法向量 乘以 视角和球心的模长,推导公式学了投影向量自然就会了,这里不累述。
然后通过对比 p和球心的长度是否小于半径,就可以实现简单的画圆。

快速求出球面法线向量

如果要在球体上使用光照模型,必然需要知道法线向量。
我们知道了坐标和半径的比值,通过反sin或者反cos值得到弧度,然后求弧度在π/2的比例就可以得出法向量的差值,进行视角向量和位置向量的插值运算即可。
这里贴张网络图片以供参考。

源代码

Shader "QQ/Volume/Sphere"
{Properties{_Color("Color",Color) = (0.5,0.5,0.5,1)_Radius("radius",Range(0,1)) = 0.4_Smoothness("smoothness",Range(0.1,1)) = 0.5}SubShader{Tags { "RenderType" = "Opaque"}LOD 100Pass{Tags{"LightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"uniform fixed4 _Color;uniform float _Radius;uniform float _Smoothness;uniform fixed4 _LightColor0;struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 wPos:TEXCOORD0;float3 normal : TEXCOORD1;};v2f vert(a2v v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.wPos = mul(unity_ObjectToWorld,v.vertex);o.normal = v.normal;return o;}inline float3 ToLocal(float3 pos){return mul(unity_WorldToObject, float4(pos, 1.0)).xyz;}fixed4 frag(v2f i) : SV_Target{fixed4 col;float3 pos = ToLocal(i.wPos);float3 nor = UnityObjectToWorldNormal(i.normal);float _i = length(pos) / _Radius;if (_i > 1){float3 camera = ToLocal(_WorldSpaceCameraPos.xyz);float3 dir = normalize(pos - camera);float len0 = distance(pos, camera);float len1 = length(camera) * dot(dir, normalize(-camera));if (len1 > len0){pos = dir * len1 + camera;_i = length(pos) / _Radius;float3 dir0 = normalize(pos);float3 dir1 = normalize(camera);nor = UnityObjectToWorldNormal(normalize(lerp(dir1, dir0, asin(_i) / UNITY_PI * 2)));}}if (_i <= 1){float3 wPos = mul(unity_ObjectToWorld, pos);float LdotN = max(dot(_WorldSpaceLightPos0.xyz, nor), 0);float3 Half = normalize(normalize(_WorldSpaceLightPos0.xyz) + normalize(_WorldSpaceCameraPos.xyz - wPos));float spec = pow(max(dot(nor, Half),0), _Smoothness * _Smoothness * 1000);col = _Color * fixed4(UNITY_LIGHTMODEL_AMBIENT.rgb, 1.0) + (LdotN + spec) * fixed4(_LightColor0.rgb,1.0);}else{discard;}return col;}ENDCG}}
}

[体渲染]渲染一个球体相关推荐

  1. 计算机图形学 | 实验四:绘制一个球体

    计算机图形学 | 实验四:绘制一个球体 计算机图形学 | 实验四:绘制一个球体 封装Shader 为什么要封装Shader 如何使用 绘制球模型 球面顶点遍历 构造三角形图元 开启线框模式 开启面剔除 ...

  2. 在OpenGL中创建一个球体动画,使球体在窗口内做自由落体运动,并在撞击地面后能够返回原来高度

    这是计算机图形学基础的一道单元练习题,看题的时候觉得没什么,写出来才发现其中大有门道,其中有几个值得关注的地方: 首先如果你是以窗口底部为地面的话,你会发现小球在第二次下落时无法回弹,这就很恶心了,做 ...

  3. 渲染与云渲染——渲染行业的新趋势

    可能很多人想不到,即使到了现在,CGI(电脑三维动画)设计师们有时仍可能需要等待近1个月的时间完成一秒钟视频的渲染,或者用24小时来等一张静态图片的渲染. 虽然CGI渲染在工业设计.电脑游戏.建筑和电 ...

  4. 结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

    结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占 ...

  5. 2-结构体的最后一个成员的定义-C语言中的柔性数组-

    深入浅出C语言中的柔性数组 在日常的编程中,有时候需要在结构体中存放一个长度动态的字符串,一般的做法,是在结构体中定义一个指针成员,这个指针成员指向该字符串所在的动态内存空间,例如: [cpp] vi ...

  6. 1---结构体中最后一个成员为[0]长度数组的用法

     结构体中最后一个成员为[0]长度数组的用法 2012-04-27 16:03:58 分类: C/C++ 这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:  1.不需要初始 ...

  7. c++ new一个结构体_C语言结构体,又一个纸老虎,纯干货讲解(附代码)

    来源:网络,排版整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy)结构体的定义结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构.结构体和其他类型基础数 ...

  8. kopernio显示无效程序_daz 无法渲染/没有渲染/渲染不显示/渲染无效?

    daz studio 无法渲染/没有渲染/渲染不显示/渲染无效? 显卡不支持opencl怎么办 报错提示 a valid opencl 1.2 device could not be found. s ...

  9. python如何画球体_用python绘制一个球体的轨道轨迹

    如何在(384400,0,0)的位置放置半径为1737的球体? 这个球体就是我轨道上的月亮. 其他代码都很好,我只是不知道如何在那个半径的位置添加一个球体.import numpy as np fro ...

  10. C/C++ 学习笔记:结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

    结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占 ...

最新文章

  1. 使用Ubuntu 12.04作为日常电脑环境
  2. Silverlight入门系列]使用MVVM模式
  3. http1.0和http1.1和http2.0有什么区别
  4. python自动化教程_Python 任务自动化工具 tox 教程
  5. 电商大厂面试都有哪些套路?
  6. 求阶乘的和(信息学奥赛一本通-T1091)
  7. HashMap的hash()
  8. Day6-HTML 特殊字符-实体
  9. 网络工程师交换试验手册之二十五:详细讲授利用xmodem来恢复IOS
  10. qt禁止拖动_[Qt]QMdiArea,无框架窗口的拖动
  11. 这也许是你不曾留意过的 Mybatis 细节 1
  12. 超级实用springBoot学习
  13. Win10 AMD平台无法开启SVM虚拟化
  14. 论文|完整空间多任务模型(Entire Space Multi-Task Model)
  15. webpack搭建pixi.js开发环境
  16. Huawei 华为云 机器翻译调用 详解
  17. 数据文化 | Uber的数据治理
  18. D435i+vins-Fusion+ego-planner+yolo无人机避障实测
  19. 没有金三银四,又要迎接所谓的金九银十,今年大环境这么差,Java岗必备面试题及答案学习还是得学
  20. h3c服务器设置管理ip配置文件,H3C 开局设置

热门文章

  1. 当今的BIOS(UEFI)
  2. 使用SQL语句创建数据库和数据库表
  3. 使用DGL实现基于闲鱼图进行边分类算法
  4. 写作论文文献导入方法
  5. [转贴]关于理工科学生应聘非本专业职位的一些建议
  6. 学习笔记-Speed-Linux
  7. C# 正则计算中文,数字,英文字数统计方法
  8. 关于Axure的基本框架
  9. Tableau阈值设置及其使用
  10. Stratifyd入驻腾讯云市场,AI赋能品牌数字化升级