反射

反射的原理在之前的文章中已有,在此不再赘述,这里主要讲一下天空盒子纹理的采集
主要看代码中有注释的部分,其中在 texCUBE 中没有对i.worldRefl进行归一化,是因为仅仅是传递方向变量给 texCUBE ,因此无需归一化

Shader "Unity Shaders Book/Chapter 10/Reflection" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)_ReflectColor ("Reflection Color", Color) = (1, 1, 1, 1)_ReflectAmount ("Reflect Amount", Range(0, 1)) = 1//天空盒子的属性定义_Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}}SubShader {Pass { Tags { "LightMode"="ForwardBase" }CGPROGRAM#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;};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);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(0, dot(worldNormal, worldLightDir));//天空盒子的采样方式fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb * _ReflectColor.rgb;//将反射图和漫反射混合fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount);return fixed4(color, 1.0);}ENDCG}}FallBack "Reflective/VertexLit"
}

折射

光的折射与光的反射一样都是发生在两种介质的交界处,只是反射光返回原介质中,而折射光则进入到另一种介质中,由于光在在两种不同的物质里传播速度不同,故在两种介质的交界处传播方向发生变化,这就是光的折射。

Shader "Unity Shaders Book/Chapter 10/Refraction" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)_RefractColor ("Refraction Color", Color) = (1, 1, 1, 1)_RefractAmount ("Refraction Amount", Range(0, 1)) = 1_RefractRatio ("Refraction Ratio", Range(0.1, 1)) = 0.5_Cubemap ("Refraction Cubemap", Cube) = "_Skybox" {}}SubShader {Pass { Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;fixed4 _RefractColor;float _RefractAmount;fixed _RefractRatio;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 worldRefr : TEXCOORD3;};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.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal), _RefractRatio);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(0, dot(worldNormal, worldLightDir));//通过折射光方向采样天空盒子纹理fixed3 refraction = texCUBE(_Cubemap, i.worldRefr).rgb * _RefractColor.rgb;//混合折射颜色和漫反射fixed3 color = ambient + lerp(diffuse, refraction, _RefractAmount);return fixed4(color, 1.0);}ENDCG}} FallBack "Reflective/VertexLit"
}




涅菲尔效应

何为菲涅尔效应?
视线垂直于表面时,反射较弱,而当视线非垂直表面时,夹角越小,反射越明显。如果你看向一个圆球,那圆球中心的反射较弱,靠近边缘较强。

Shader "Unity Shaders Book/Chapter 10/Fresnel" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)_FresnelScale ("Fresnel Scale", Range(0, 1)) = 0.5//反射系数_Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}}SubShader {Pass { Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;fixed _FresnelScale;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;};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);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 reflection = texCUBE(_Cubemap, i.worldRefl).rgb;//计算菲涅尔系数fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldViewDir, worldNormal), 5);fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0, dot(worldNormal, worldLightDir));fixed3 color = ambient + lerp(diffuse, reflection, saturate(fresnel));return fixed4(color, 1.0);}ENDCG}} FallBack "Reflective/VertexLit"
}

上述新的东西只有一个公式,如下图第一个公式

抽象解释:
近处湖面反射较弱,湖底物体的光进入眼睛占主要,因此看到的是湖底的情景;
远处湖面反射较强,湖面上物体的反射光进入眼睛占主要,因此看到的是湖面上物体的倒影;
公式解释:
以公式一为例,主要影响因素就是 v·n
①湖面,无论远近,湖面的 n 保持不变,随着视角看向湖面远处 n、v的夹角变大 (1- n·v )5 ,当湖面接近无限远的时候, v、n的夹角趋于90 ,公式整体的值就越接近1,即越接近反射
②球体,看向一个球,人的视角 v 保持不变,随着靠近球边缘, n、v的夹角变大 (1- n·v )5 ,当到达球体边缘的时候, v、n的夹角为90 ,公式整体的值为1,即完全反射 (查看下面的gif可以看到边缘的反射十分明显)

PS.内容整合自 《UnityShader 入门精要》,并加入自己的理解

UnityShader_天空盒子中的反射、折射、聂菲尔效应相关推荐

  1. unity3D 添加天空盒子

    Unity添加天空盒子Sky box 对于3D游戏来说 必不可缺的就是天空的颜色 那我们该如何给游戏加上天空嘞 首先点击Main Camera主相机 你会发现右边出现Inspector的面板 点击最下 ...

  2. Cesium与STK中的天空盒子(skybox)

    天空盒子是计算机图形学中的概念,用于在3D展示中,显示观测者上下左右前后的全景图像. 星空图介绍 在STK和Cesium中,常常以地球为中心天体,背景就是宇宙星空,观测者超哪个方向看,就可以看到对应方 ...

  3. Opengl-立方体贴图(天空盒子)

    立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体.你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独 ...

  4. Unity shader Note :高级纹理(CubeMap反射折射菲涅尔,Rendermap镜子玻璃,程序纹理)

    1.Cubemap–反射折射 使用脚本来创建Cubemap ①通过Camera.RenderToCubemap 把任意位置观察到的场景图制作成一张Cubemap之中 ②脚本使用自定义编译窗体的命令 – ...

  5. 【Unity3D】立方体纹理(Cubemap)和天空盒子(Skybox)

    1 立方体纹理(Cubemap) 本文完整资源见 → 立方体纹理(Cubemap)和天空盒子(Skybox) . 1)立方体纹理简介 立方体纹理是指由上.下.左.右.前.后 6 张纹理组成的立方体结构 ...

  6. Unity3D - 使用天空盒子(Using Skyboxes)

    在场景中,天空盒子(skybox)是代表天空或是远景的全景纹理图片. 理解天空盒子(Understanding skybox) 天空盒是一个全景视图,分为六个纹理,表示沿主轴(上,下,左,右,前,后) ...

  7. OpenGL应用:天空盒子(SkyBox)

    天空盒子(skyBox) SkyBox 制作3D游戏的一个经典技术应用. 原理 SkyBox 是基于正方体模型的渲染技术.将6个方向拍下来的天空图片分别贴在正方体的对应面上,从内部观察正方体就可以得到 ...

  8. Unity如何调整天空盒子

    Unity如何调整天空盒子 首先在: unity Asset store里找到合适的天空盒子,如下所示. 然后在window->package manager->my assets中找到刚 ...

  9. unity3d场景怎么添加天空盒子?

    unity3d场景中想要添加天空盒子,该怎么添加呢?下面我们就来看看详细的教程. 1.先下载组成天空盒子的天空图片 2.把天空图片拖进unity3d中创建的文件夹 3.新建一个材质球 4.把材质球的s ...

最新文章

  1. python 同步 事件 event 简介
  2. Memcache工作原理总结
  3. java 日志使用_Java日志正确使用姿势
  4. .net:设计一个web应用
  5. 基于ZigBee 自组网模块的路灯控制网络
  6. C语言 VS快速输入main函数
  7. element 动态加载下拉框_动态增加select框(elementUI 框架)
  8. Bailian4128 单词序列【BFS】
  9. 新浪新规:9点关灯,公司加班要交空调费:1600元/小时
  10. 20.深入浅出:功率放大电路——参考《模拟电子技术基础》清华大学华成英主讲
  11. 渗透测试中遇到的Adminer任意文件读取漏洞
  12. Java 多态练习题之愤怒的小鸟,会飞会叫
  13. m基于matlab的光通信误码率仿真,分别对比了OFDM+BPSK和OFDM+4QAM的误码率和星座图
  14. Linux系统中的管道通信
  15. 深度学习入门 ---稀疏自编码器
  16. Linux Command tc 模拟网络延迟和丢包
  17. 【JZOJ1758】过河
  18. 中国iaas产业2012年度点评
  19. 不眠的硅谷——Just For Fun
  20. 基于Canal的MySQL=>ES数据同步方案

热门文章

  1. Vue文件内动态加载JS
  2. 阿里云服务器是干什么用的?
  3. Xftp无法与192.168.xx.xx连接 SSH服务器拒绝了密码。请再试一次。
  4. 试验设计类毕业论文文献有哪些?
  5. Java:现实世界中最流行的10个Java应用程序示例
  6. 如何使用【亿愿专利下载器】批量下载美国专利的PDF全文
  7. 在职场,光有技术是不行的,18年老程序员职场宝贵经验分享
  8. flv + livego + obs 实现简易直播平台(windows版+Linux版)
  9. 支持 C++11/14/17 功能(现代 C++
  10. 推荐 7 个牛哄哄的电商项目