shader实例(二十二)TexGen-球面贴图SphereMap
http://blog.sina.com.cn/s/blog_89d90b7c0102vfqz.html
球面贴图一般用于环境反射,如下图(左边为球面贴图,右边为正常贴图),一个镜面水晶球在这只猫的前方,而这只猫也正看着这个水晶球,效果是这只大头猫的头变的更大了。
原理:
1.将顶点转换到摄像机空间
2.根据该顶点的摄像机【入射向量 I 】和【法线向量N】计算【反射向量R】
3.将【反射向量R】与【摄像机向量(0,0,1)】相加,计算出【过渡向量m】
4.求【过渡向量m】单位向量,再将值映射为uv的值域上,求得纹理坐标
如图:
基础知识:
求反射向量 http://www.cnblogs.com/graphics/archive/2013/02/21/2920627.html
代码和详细分析如下:
}
<span style="background-color: rgb(255, 255, 255);">Shader "Custom/球面贴图" {
   Properties {
        _Reflectivity ("Reflectivity", Range (0,1)) = 0.5
        _MainTex("Base", 2D) = "white"
        _Environment ("Environment", 2D) = "white"
    }
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
            sampler2D _Environment;
            float4 _MainTex_ST;
            float _Reflectivity;
            struct v2f {
                float4  pos : SV_POSITION; // 输出的坐标信息
                float2  uv : TEXCOORD0; // 输出的主材质纹理信息
                float2  uv2:TEXCOORD1; // 输出的球面纹理信息
            } ;
            // 求反射向量。这个底层有封装,拆开就是这样的
            float3 reflect(float3 I,float3 N)
            {
                return I - 2.0*N *dot(N,I);
            }
            float2 GetUV(float3 r)
            {
                // 开根号对过渡向量m求模(反射向量r+摄像机向量(0,0,1)为过渡向量m)
                float m = sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0));
                // 求过渡向量m的单位向量
                float3 n = float3(r.x / m, r.y / m, r.z / m);
                // 顶点值域为[-1,1],转为UV的值域[0,1]
                // 在边缘处UV信息也是更靠近图片里面,才形成镜面水晶球的效果吧
                return float2(0.5 * n.x + 0.5,0.5 * n.y + 0.5);
            }
            v2f vert (appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
                // 将顶点信息转换到摄像机坐标
                float3 posEyeSpace = mul(UNITY_MATRIX_MV,v.vertex).xyz;
                // 获取摄像机的入射向量
                float3 I = posEyeSpace - float3(0,0,0);
                // 将顶点的法线向量转换到摄像机坐标
                float3 N = mul((float3x3)UNITY_MATRIX_MV,v.normal);
                // 求法线单位向量
                N = normalize(N);
                // 根据入射向量和法线向量求反射向量
                float3 R = reflect(I,N);
                // 根据反射向量获取最终的UV信息
                o.uv2 = GetUV(R);
                return o;
            }
            float4 frag (v2f i) : COLOR
            {
                float4 reflectiveColor = tex2D(_Environment,i.uv2);
                float4 decalColor = tex2D(_MainTex,i.uv);
                float4 outp = lerp(decalColor,reflectiveColor,_Reflectivity);
                return outp;
            }
            ENDCG
        }
    }</span>												
											shader实例(二十二)TexGen-球面贴图SphereMap的更多相关文章
- Bootstrap <基础二十二>超大屏幕(Jumbotron)
		Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ... 
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
		原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ... 
- 二十二. Python基础(22)--继承
		二十二. Python基础(22)--继承 ● 知识框架 ● 继承关系中self的指向 当一个对象调用一个方法时,这个方法的self形参会指向这个对象 class A: def get(s ... 
- JAVA基础知识总结:一到二十二全部总结
		>一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ... 
- 使用Typescript重构axios(二十二)——请求取消功能:收尾
		0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ... 
- [分享] IT天空的二十二条军规
		Una 发表于 2014-9-19 20:25:06 https://www.itsk.com/thread-335975-1-1.html IT天空的二十二条军规 第一条.你不是什么都会,也不是什么 ... 
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】
		<Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ... 
- 二十二、OGNL的一些其他操作
		二十二.OGNL的一些其他操作 投影 ?判断满足条件 动作类代码: ^ $ public class Demo2Action extends ActionSupport { public ... 
- VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池
		VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ... 
- Bootstrap入门(二十二)组件16:列表组
		Bootstrap入门(二十二)组件16:列表组 列表组是灵活又强大的组件,不仅能用于显示一组简单的元素,还能用于复杂的定制的内容. 1.默认样式列表组 2.加入徽章 3.链接 4.禁用的列表组 5. ... 
随机推荐
- Grid++Report设置显示固定行数
			一.要实现的功能打印的报表显示固定的行数,并且设置字段的文字可以自动换行二.设置步骤1.鼠标左键单击“明细网格”栏,在右侧属性窗口中设置“追加空白行”属性值为:是:“追加空白行在后”属性值为:是.2. ... 
- java内部类和静态内部类的区别
			1 相同点 使用的时候,import的时候,除了包名,还要带外部类. 2 不同点 2.1 对象创建的方式不同 静态内部类创建对象的时候,独立于外部类及其对象,就好像它是一个独立的类,可以和外部类一样使 ... 
- 把tomcat写到Windows系统服务器的服务中
			首先准备一个免安装的tomcat服务器,和一个Windows系统. 在“C:\Windows\SysWOW64”中找到cmd.exe的执行文件,以管理员身份启动: 进入到tomcat的bin文件夹, ... 
- Android 属性动画ObjectAnimator和ValueAnimator讲解
			区别: ObjectAnimator 是直接对某个view进行更改. ValueAnimator 根据 TimeInterpolator 在不断产生相应的数据,来传进view ,view自己做改变. ... 
- 在windows下把Mongodb设置系统服务
			把Mongodb Server 设置为系统,方便启动与停止 今天一时兴起在本地安装了下Mongodb服务,安装完后,创建了配置文件为数据库服务指明在哪里存储数据库原始文件,随即就启动了mongo se ... 
- php遍历统计文件目录和文件
			function total($dirname, &$dirnum, &$filenum){ $dir=opendir($dirname); readdir($dir)."& ... 
- "未预编译文件 因此不能请求该文件"问题处理
			手里一个项目重新编译后发布,访问时提示未预编译文件“default.aspx”, 因此不能请求该文件.综合网上的解决方法,做了如下操作: 1.重新安装了AJAX Extension: 2.项目添加引用 ... 
- Python GIL、线程锁、信号量及事件
			GIL是什么? GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码.有名的编 ... 
- EnumDescription
			using System; using System.Reflection; using System.Collections; using System.Collections.Generic; n ... 
- linux文件查找(find,locate)
			文件查找: locate: 非实时,模糊匹配,查找是根据全系统文件数据库进行的: # updatedb, 手动生成文件数据库 速度快 find: 实时 精确 ... 
