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. 通过NuGet安装和配置ODP.NET(Oracle Data Provider for .NET)

    前言 本文涉及ODP.NET.ODP.NET的托管(managed)驱动.Entity Framework的托管驱动 这三部分的下载.安装.配置. 1.简介 NuGet 是.NET的软件开发包管理工具 ...

  2. Jmeter——参数化的9种方法

    本文由作者张迎贞授权网易云社区发布. 一.用户定义的变量 1.右键快捷菜单中选择 添加-配置元件-用户自定义变量. 用户自定义变量中的定义的所有参数的值在测试计划的执行过程中不能发生取值的改变,因此一 ...

  3. 1047 行 MySQL 详细学习笔记

    https://blog.csdn.net/baidu_25310663/article/details/86517610 Windows服务   -- 启动MySQL   net start mys ...

  4. Mac OS 10.12 - 安装任何来源软件!!

    今天想安装一个从网上下载的软件到Mac OS 10.12中,结果没有想到Mac告诉我那个软件已经损坏,害得我删除了!! 最后通过热心网友的帮助,顺利解决了这个安装问题,重新安装并且使用上了这款软件,下 ...

  5. Xshell连接不上Linux

    用Xshell连接Linux的时候报错了: Connecting to 192.168.79.147:22...Could not connect to '192.168.79.147' (port ...

  6. java求三角形面积以及周长---封装

    /*时间: 2012-10-08作者: 烟大程序要求: 1.封装一类三角形对象Triangle,该类对象具有三条边的属性, 具有初始化三角形的功能.修改边长的功能.判断三条边能否构成三角形的功能. 求 ...

  7. leetcode-166-分数到小数(用余数判断有没有出现小数的循环体)

    题目描述:   给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入: n ...

  8. bzoj 3027: [Ceoi2004]Sweet (生成函数)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3027. 题目大意:有$n$种数,每种有$C_i$个,问你在这些数中取出$[l,r]$个 ...

  9. Linux Cluster环境下批量分发执行补丁

    转自:http://blog.csdn.net/napolunyishi/article/details/18219867 这两天做了一个需求,因为上一个版本的/tmp空间默认只分配了5G,而升级程序 ...

  10. Restore HBase Data

    方法 1: Restoring HBase data by importing dump files from HDFS The HBase Import utility is used to loa ...