体渲染(一)渲染一个球体
来源:互联网 发布:sql语句update用法 编辑:程序博客网 时间:2024/04/28 00:57
最终效果
思路
伪体渲染
通常体渲染是模拟射线在模型中逐步判断,每个像素需要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}}}
0 0
- 体渲染(一)渲染一个球体
- OpenGL-渲染光照球体
- 《OpenGL编程指南》示例笔记(1)--渲染光照球体
- 卡通渲染进展(一)
- 非真实渲染(一)
- CEGUI文本渲染(一)
- Ogre 渲染队列(一)
- 渲染
- 渲染
- 渲染
- 渲染
- 实时渲染(一)——图形渲染管线
- 三维场景的渲染优化(一)
- Clutter的图形渲染BackEnd(一)
- WebCore中的渲染机制(一):基础知识
- WebCore中的渲染机制(一):基础知识
- WebCore中的渲染机制(一):基础知识
- WebCore中的渲染机制(一):基础知识
- eclipse添加了tomcat插件后无tomcat图标出现
- java 遍历String数组的值比较
- SVM手写数字的识别---python
- 我们不需要纸了么?
- 优化,测试自己的代码
- 体渲染(一)渲染一个球体
- 17 - 02 - 24 计算机网络(45)(DoS攻击、IP地址欺骗 概述)
- 这家法国收视率最高的电视台,做了一个大胆的举动!
- 紫书 例题7-8 Uva 10603 BFS
- json-lib之jsonConfig详细使用
- 在二叉树中打印出从某个节点(r)开始和为定值(sum)的所有路径
- spring的aspectj简介
- FineReport(帆软)部署到Linux的tomcat7上报错
- JS 手机浏览器唤醒手机QQ