1、Cubemap是啥

Cubemap,即立方体纹理,包含6张图像,每张图像对应立方体的一个面,跟二维纹理不同,我们使用三维坐标去对这种纹理进行采样, 在unity中,可以使用Cubemap来实现天空盒子以及环境映射,环境映射可以模拟出场景中周围的环境,使用了环境映射材质的物体可以反射出周围的环境,就像反光镜或者反光金属一样。
 

2、制作Cubemap

通常,制作Cubemap的方法大概有三种,第一种是提供一种具有特殊布局的纹理,类似全景图,然后将该纹理的Texture Shape设置为Cube;第二种方法是在Project面板创建一个Cubemap,然后提供6张纹理分别拖拽到它的属性面板中;前两种方法都需要我们提供立方体纹理的图片,我们这里使用第三种方案,用脚本来创建,把下面脚本放在editor文件夹中:

using UnityEngine;
using UnityEditor;
using System.Collections; public class RenderCubeMap : ScriptableWizard
{
public Transform renderPosition;
public Cubemap cubemap; void OnWizardUpdate()
{
isValid = (renderPosition != null) && (cubemap != null);
} void OnWizardCreate()
{
// 创建一个用来渲染的相机
GameObject go = new GameObject("CubemapCam");
go.AddComponent<Camera>();
go.transform.position = renderPosition.position;
// 将相机观察到的图像渲染到cubemap
go.GetComponent<Camera>().RenderToCubemap(cubemap);
// 销毁相机
DestroyImmediate(go);
} [MenuItem("GameObject/RenderCubemap")]
static void RenderCubemap()
{
ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
"RenderCubemap", "立即渲染");
}
}
在场景中创建一个空GameObj,并设置好合适的位置,在Project面板新建一个cubemap,并勾选Readable,然后点击菜单栏GameObject-RenderCubemap,将空gameObj以及新建的cubemap拖拽上去,点击立即渲染,就将6张图像渲染到了该cubemap中。

 

3、编写shader实现反射

Shader "yzpShader/Reflecte" {
Properties {
_Color ("Color Tint", Color) = (, , , )
_ReflectColor ("Reflection Color", Color) = (, , , )
_ReflectAmount ("Reflect Amount", Range(, )) =
_Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Geometry"} Pass {
Tags { "LightMode"="ForwardBase" } CGPROGRAM #pragma multi_compile_fwdbase #pragma vertex vert
#pragma fragment frag #include "Lighting.cginc"
#include "AutoLight.cginc" fixed4 _Color;
fixed4 _ReflectColor;
fixed _ReflectAmount;
samplerCUBE _Cubemap; struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
}; struct v2f {
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
fixed3 worldNormal : TEXCOORD1;
fixed3 worldViewDir : TEXCOORD2;
fixed3 worldRefl : TEXCOORD3;
SHADOW_COORDS()
}; v2f vert(a2v v) {
v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos); // 计算世界坐标空间下的反射方向
o.worldRefl = reflect(-o.worldViewDir, o.worldNormal); TRANSFER_SHADOW(o); return o;
} fixed4 frag(v2f i) : SV_Target {
//归一化
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed3 worldViewDir = normalize(i.worldViewDir);
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//漫反射
fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(, dot(worldNormal, worldLightDir)); //使用世界空间下的反射方向对cubemap采样
fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb * _ReflectColor.rgb; UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); //混合得到最终颜色
fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount) * atten; return fixed4(color, 1.0);
} ENDCG
}
}
FallBack "Reflective/VertexLit"
}

4、测试结果

新建材质,使用上面写好的shader,设置好属性,将材质赋予场景中的一个小球,可以看到,小球模拟反射出了周围的环境,效果看起来达到了预期,还不错。

5、缺点

当我们向场景中添加新物体、光源或者移动物体时,可以发现原来的cubemap反射效果并没有因为变动的环境而有所变化,这就需要重新生成cubemap;此外,立方体纹理仅能实现反射周围环境的效果,并不能反射自身,因此我们只能对凸面体使用cubemap反射,而不要在凹面体上使用。

Unity Shader之使用Cubemap实现反射效果的更多相关文章

  1. 【Unity Shader】(五) ------ 透明效果之半透明效果的实现及原理

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题 [Unity Shader学习笔记](三) -- ...

  2. Unity Shader 菲涅尔环境反射

    菲涅尔反射描述了一种光学现象,当光照到物体表面时,一部分发生反射,另一部分则进入物体内部,发生折射或散射:相比直接的反射和折射计算,菲涅尔反射更接近真实情况. 可用下面的等式近似计算这种反射效果: F ...

  3. Unity3D学习(八):《Unity Shader入门精要》——透明效果

    前言 在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道. Unity中通常使用两种方法来实现透明 :(1)透明度测试(AlphaTest)(2)透明度混合(AlphaBlend).前者往 ...

  4. 【Unity Shader】四、高光反射Specular Shader例子

    http://www.cnblogs.com/guxin/p/unity-diffuse-shader-demo.html 在上文中已经学习了漫反射Diffuse Shader和环境光,现在再在此基础 ...

  5. 【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...

  6. 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现

    [Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...

  7. 【Unity Shader】(八) ------ 高级纹理之立方体纹理及光线反射、折射的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题.    [Unity Shader](三) -- ...

  8. Unity Shader入门精要学习笔记 - 第15章 使用噪声

    转载自 冯乐乐的 <Unity Shader 入门精要> 消融效果 消融效果常见于游戏中的角色死亡.地图烧毁等效果.这这些效果中,消融往往从不同的区域开始,并向看似随机的方向扩张,最后整个 ...

  9. 【Unity Shader】(四) ------ 纹理之法线纹理、单张纹理及遮罩纹理的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...

随机推荐

  1. golang array, slice, string笔记

    本来想写一篇关于golang io的笔记,但是在学习io之前必须了解array, slice, string概念,因此将在下篇写golang io.   array: 数组的长度是该数组类型的一部分, ...

  2. Apache Geode with Spark

    在一些特定场景,例如streamingRDD需要和历史数据进行join从而获得一些profile信息,此时形成较小的新数据RDD和很大的历史RDD的join. Spark中直接join实际上效率不高: ...

  3. Java泛型与Restlet客户端

    写一个与restlet服务器通信的客户端类,用于测试通信是否成功,并且进行交互.为了方便其他人使用,于是,写一个通用的方法封装起来,可是中途却放生了一些问题. 按照正常写法,顺序走下来是这样的: pu ...

  4. python 判断是否为中文

    python在执行代码过程是不知道这个字符是什么意思的.是否是中文,而是把所有代码翻译成二进制也就是000111这种形式,机器可以看懂的语言. 也就是在计算机中所有的字符都是有数字来表示的.汉字也是有 ...

  5. Windows下常用的100个CMD指令以及常见的操作

    gpedit.msc—–组策略 2. sndrec32——-录音机 3. Nslookup——-IP地址侦测器 ,是一个 监测网络中 DNS 服务器是否能正确实现域名解析的命令行工具. 它在 Wind ...

  6. 记录.NET Core通过Docker部署到Linux

    1.现在CentOS安装Docker环境(参考地址:https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/) 我这 ...

  7. BitAdminCore框架更新日志20180523

    20180523更新内容 本次更新两个内容,一是增加视频处理功能,二是增加定时服务功能. 视频处理 定时服务 BitAdminCore框架,用最少的代码,实现最多的功能 本次新暂未发布,后续有空发布 ...

  8. C#winfrom最简DBHelp(数据库连接操作)

    代码如下: //需引用命名空间 using System.Data; using System.Data.SqlClient; class DBHelper { //定义数据库连接语句,连接语句书写方 ...

  9. 无废话网页重构系列——(3)Web重构前的分析

    本篇讲重构前的分析.从“工作状态.工作环境和工作角色”和具体重构工作两方面分析. 凡是经过考验的朋友,就应该把他们紧紧地团结在你的周围 比较理想的工作状态:制定了各种设计和开发规范,各团队之间邮件.团 ...

  10. day 57 Bootstrap 第一天

    一 .bootstrap是什么  http://v3.bootcss.com/css/#grid-options(参考博客) 是一个前端开发的框架. HTML CSS JS 下载地址:https:// ...