技术标签: UnityShader反射效果 Unity镜面效果 Shader效果 Shader菲涅儿反射 Unity环境反射效果 UnityShader镜面反射
菲尼尔反射原理:
通过计算得到的反射值,采样CubeMap,得到环境反色颜色。
核心算法:
反射核心算法:Reflect(-viewDir,worldNormalDir)
折射核心算法:Refact(-viewDir,worldNormalDir)
菲涅尔反射算法: FresnelInstenisty-(1-fresnelIntensity)*dot(-viewDir,worldNormalDir)
CubeMap创建:
通过右键 创建Light—Refection Probe 创建完成之后点击烘培,即可得到烘培好的CubeMap。
注意:要烘培的物体必须勾上Refection Probe Static 同静态批处理一个道理,否则无法正常烘培到CubeMap。
注意:Refecition Probe的位置要与最终效果的相机位置相同,且Y轴相反,否则达不到下图想要的效果。
首先参观一下镜湖的效果,真的是湖田一色,美丽至极!
思考:
这种效果是怎么实现的呢?
首先名字叫做镜湖,镜湖,不就是镜面吗?对,可以把湖面看做以面镜子,镜子反射出了照到的影像,出现了上图效果,可以理解为镜像。
在深入一下,镜子,镜像,那镜子是什么原理呢?对,就是反射,镜像反射。
所以,我们有两种实现方式:
1.镜面。
2.反射。
博主这里先介绍第二中实现方式,反射。
反射实现的原理:
计算反射值,通过反射值采样烘培环境得到的CubeMap,得到反射的颜色值,最后输出最终颜色。
菲尼尔反射效果:
下图只是单纯的菲涅尔反射效果,如果想要达到和镜湖类似的效果,后期还需要加上水效果,在水的效果上进行菲尼尔反射效果。
下图均是菲涅尔系数为1的效果
效果一:
效果二:
下图是菲涅尔系数为0的效果
菲尼尔值变化演示动态效果:
附上源代码:
//菲尼尔反射
Shader "Custom/FresnelReflec"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {
}
_Color ("Color", Color) = (1, 1, 1, 1)
_CubeMap ("CubeMap", Cube) = "_Skybox" {
}
_ReflectionColor ("RelfctionColor", Color) = (1, 1, 1, 1) //反射颜色
_FresnelReflec ("FresnelReflec", Range(0, 1)) = 0.5 // 菲尼尔反射
}
SubShader
{
Tags {
"Renderer" = "Opaque" }
LOD 100
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
sampler2D _MainTex;
fixed4 _MainTex_ST;
fixed4 _Color;
samplerCUBE _CubeMap;
fixed4 _ReflectionColor;
half _FresnelReflec;
struct v2f
{
float4 vertex: SV_POSITION;
float2 uv: TEXCOORD0;
float3 worldNormal: TEXCOORD1;
float3 worldView: TEXCOORD2;
float3 worldLight: TEXCOORD3;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
fixed3 worldPos = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldView = UnityWorldSpaceViewDir(worldPos);
o.worldLight = UnityWorldSpaceLightDir(worldPos);
return o;
};
fixed4 frag(v2f i): SV_TARGET0
{
fixed3 worldNormalDir = normalize(i.worldNormal);
fixed3 worldViewDir = normalize(i.worldView);
fixed3 worldLightDir = normalize(i.worldLight);
fixed3 reflection = reflect(-worldViewDir, worldNormalDir);
fixed fresnel = _FresnelReflec - (1 - _FresnelReflec) * dot(-worldViewDir, worldNormalDir);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 diffuse = tex2D(_MainTex, i.uv).rgb * _Color.rgb * dot(worldNormalDir, worldLightDir);
fixed3 reflectionColor = texCUBE(_CubeMap, reflection).rgb * _ReflectionColor.rgb;
fixed3 color = ambient + lerp(diffuse, reflectionColor, fresnel);
return fixed4(color, 1);
}
ENDCG
}
}
FallBack "Diffuse"
}
优化的空间还很大,目前只是一个静态烘培的菲尼尔反射效果,后期可考虑加上动态反射,以及水效果,以达到更好的效果。
下面是正常的反射效果:
参数调节:
文章浏览阅读1.9k次,点赞2次,收藏6次。浅学一下Swift,这篇笔记做个记录//引入UIKit框架 import UIKit //定义一个变量,赋值为字符串“hello,playground” var greeting = "Hello, playground"_swift 学习
文章浏览阅读1.6w次。在使用Office进行文件操作时,经常会出现如图下所示office运行时错误,部分系统文件可能丢失或已损坏(错误代码:0x80040154)出现这种情况多数是由于Office的安全机制导致的解决步骤:打开左上角 文件 菜单找到 选项 菜单打开后找到 信任中心 同时点击 信任中心设置找到 受保护的视图 ,将右侧选项全部取消勾选即可..._0x80040154
文章浏览阅读266次。给你一个整数数组nums,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。返回的解集中,子集可以按任意顺序排列。_给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂
文章浏览阅读1.1w次,点赞20次,收藏162次。Object:执行 布线前的检查和设置使用 route_auto 布线signal nets报告 修复 DRC 的违例优化设计使用route_opt布线阶段的目标 (routing phase goal)布局和时钟树综合此时应该是完成的;可接受的拥塞 setup/hold time 以及逻辑DRCs时钟树网络已经被布线了;布线阶段的目标是:在最小化物理DRC违例情况下 将所有的signal nets 布线选择性的执行 布线后的 时钟树优化或者CCD;优化数据路径逻辑的 时序 DRC_icc2中绕线时flash的pin和net总是交错导致short
文章浏览阅读1k次。简言之, 官方例程中的Twister程序, 略加修改添加了一个中文变量, 运行成功!def start() 速度 = 120 ... chassis_ctrl.set_rotate_speed(速度) gimbal_ctrl.set_rotate_speed(速度)...略长版本如下.首先, 当然是激动人心的第一次启动. 因为头朝后, 碰到后装甲, 各种手..._机甲大师python编程
文章浏览阅读469次。环境ubuntu16.04jmeter5.1.1(尽量使用新版本)配置原理:slaver(执行机)配置安装jmeter,官网下载并解压提取(此处不进行详细说明)修改配置文件/apache-jmeter-5.1.1/bin/jmeter.properties修改本机host文件sudo vim /etc/hosts # 修改当前IP为非回环地址,127.0.0.1即为回环..._ubuntu jmeter分布式服务
文章浏览阅读6k次,点赞2次,收藏56次。12位是相对于二进制数来说,也就是“111111111111”,转换为十进制就是4095,其实是0-4095,实际上是4096个数,STM32F103的引脚电压是0-3.3V,12位的ADC就会把0-3.3V切割成4096份。因为采用两个通道,所以需要两个缓冲保存数据,100*2=200,DMA在运行是就会采集200个ADC值保存在数组中,100个通道4的值,100个通道5的值。对于STM32F103来说,它的ADC是12位,一共18个通道,其中16个外部通道,2个内部通道。我这里只用了双通道,所以为2..
文章浏览阅读9.9k次,点赞4次,收藏6次。.npz文件的内容是怎样的,怎么打开?加载.npz文件时,出现错误:OSError: Failed to interpret file ‘xxx.npz’ as a pickle首先了解pickle的定义:pickle: 用于python特有的类型和python的数据类型间进行转换pickle提供四个功能:dumps,dump,loads,loadpickle可以存储所有python支持的原生类型(bool,int,float,string,byte,none等),由任何原生类型组成的列表、元_as a pickle
文章浏览阅读1k次。错误:stack around the variable “XX” was corrupted.,中文翻译就是“在变量XX周围的堆栈已损坏”。后面在上网看了很多技术资料,发现大多数网站都有这样的文章:Code:把 project->配置属性->c/c++->代码生成->基本运行时检查 为 默认值 就不会报本异常。具体原因正在研究中。。。 如果改为其他就有e_stack around the variable 'dataitem' was corrupted.
文章浏览阅读236次。https://www.infoq.cn/article/pSV6tZ1SbUC8qJpo_v8H在奥斯汀举行的SciPy 2018年特别会议上,大量开源 Python 可视化工具的代表分享了他们对 Python 数据可视化未来的展望。我们看到了Matplotlib、Plotly、VisPy等许多库的更新。我作为PyViz、GeoViews、Datashader、Panel、hvPl..._python的ae库
文章浏览阅读1.4k次,点赞9次,收藏17次。接口测试可以在没有前端界面下进行测试后端的功能校验在前端很难进行测试,因为前端已经有初步校验控制,所以接口测试可以发现很多在前端无法发现的问题提升测试效率,降低人工回归测试的人力成本与时间成本,缩短测试周期。真正的业务逻辑核心是后端。例子说明:有个登录页面,你要登上网站,就需要输入你的账号密码,把账号密码作为请求参数打登录接口,这时客户端会给服务器发个登录请求,服务器鉴权和校验通过之后,就登上去了。到这里就完成了一次接口的请求,或者说跑完了一条接口测试用例。_测试自动化脚本怎么写
文章浏览阅读1.1k次。问题描述:在安装cdh元数据myslq高可用时,使用的是myslq主主复制+keepalived实现。期间发现切换时,出现如下异常信息!花了很长时间寻找问题的原因。因为切换的时候,使用本机命令行是可以连接的,但是夸服务器就无法连接,没有去这方面的尝试,后来使用navicate无法连接后,就推测是mysql高可用切换的问题导致的。问题分析:如果不重启keepalived,是无法实现切换和连接..._e0103: could not load service classes, cannot create poolableconnectionfacto