在这一篇中会实现会介绍折射和反射,以及菲尼尔反射;并且实现镜子和玻璃效果;

这里和之前不同的地方在于取样的是一张CubeMap;

demo里的cubemap使用的一样,相机所在位置拍出来的周围环境图;

生成CubeMap的工具脚本

public class RenderCubemapWizard : ScriptableWizard {

	public Transform renderFromPosition;
public Cubemap cubemap; void OnWizardUpdate () {
helpString = "Select transform to render from and cubemap to render into";
isValid = (renderFromPosition != null) && (cubemap != null);
} void OnWizardCreate () {
// create temporary camera for rendering
GameObject go = new GameObject( "CubemapCamera");
go.AddComponent<Camera>();
// place it on the object
go.transform.position = renderFromPosition.position;
// render into cubemap
go.GetComponent<Camera>().RenderToCubemap(cubemap); // destroy temporary camera
DestroyImmediate( go );
} [MenuItem("GameObject/Render into Cubemap")]
static void RenderCubemap () {
ScriptableWizard.DisplayWizard<RenderCubemapWizard>(
"Render cubemap", "Render!");
}
}

1.反射

用反射方向在CubeMap上取样,_ReflectAmount控制反射程度,_ReflectColor反射颜色;

v2f vert (appdata v){
//计算反射向量
o.worldReflect = reflect(-o.worldViewDir,o.worldNormal);
...
} fixed4 frag (v2f i) : SV_Target{
//根据反射向量从cubemap纹理上取样
fixed3 reflection = texCUBE(_Cubemap,i.worldReflect).rgb * _ReflectColor.rgb; //混合反射和漫反射
return fixed4(ambient + lerp(diffuse,reflection,_ReflectAmount)*atten, 1.0);
}

2.折射

和反射几乎相同,将反射改成折射,计算公式改成折射计算公式;

v2f vert (appdata v){
//计算反射向量
o.worldRefract = refract(-normalize(o.worldViewDir),normalize(o.worldNormal),_RefractRatio);
...
} fixed4 frag (v2f i) : SV_Target{
//根据反射向量从cubemap纹理上取样
fixed3 refraction = texCUBE(_Cubemap,i.worldRefract).rgb * _RefractColor.rgb; //混合反射和漫反射
return fixed4(ambient + lerp(diffuse,refraction,_RefractAmount)*atten, 1.0);
}

成像是倒的;透过茶壶可以看到对面;

3.菲尼尔

反射光的强度与视线方向和法线方向的夹角有关,夹角越大反射光越强;最高90度,也就是边缘光最强;

Schlick菲尼尔公式:Fschlick(v,n) = F0 + (1-F0)(1- dot(v,n)) ^ 5;F0控制菲尼尔强度;

fixed4 frag (v2f i) : SV_Target{
...
//Schlick Fresnel——边缘光
fixed3 reflection = texCUBE(_Cubemap,i.worldRefl).rgb;
fixed3 fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldViewDir,worldNormal), 5); //菲尼尔系数控制反射强度
return fixed4(ambient + lerp(diffuse,reflection,saturate(fresnel)) * atten, 1.0);
}

4.玻璃效果

通过GrabPass{"_RefractionTex"} 抓取当前屏幕内容渲染到_RefractionTex贴图上

RefractionTex贴图用来取样折射纹理;_Distortion参数模拟法线扰动的程度;

GrabPass{"_RefractionTex"}

	...
//GrabPass纹理
sampler2D _RefractionTex;
//纹素大小
float4 _RefractionTex_TexelSize; fixed4 frag (v2f i) : SV_Target
{
//法线偏移扰动-模拟折射
fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw));
float2 offset = bump.xy*_Distortion*_RefractionTex_TexelSize.xy; //折射计算-屏幕坐标偏移后透视除法取样折射纹理
i.screenPos.xy = offset + i.screenPos.xy;
fixed3 refractColor = tex2D(_RefractionTex,i.screenPos.xy/i.screenPos.w).rgb; //矩阵计算世界法线
bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump))); //反射计算
fixed3 reflectDir = reflect(-worldViewDir,bump);
fixed4 texColor = tex2D(_MainTex,i.uv.xy);
fixed3 reflectColor = texCUBE(_Cubemap,reflectDir).rgb * texColor.rgb; //混合反射和折射_RefractAmount
return fixed4(reflectColor*(1-_RefractAmount)+refractColor*_RefractAmount, 1.0);
}

5.镜子

tex2Dproj(_ReflectionTex,UNITY_PROJ_COORD(i.refl));

UNITY_PROJ_COORD:given a 4-component vector, return a texture coordinate suitable for projected texture reads. On most platforms this returns the given value directly.

传入Vector4,返回一张用来投影取样的纹理,大部分平台直接返回给定值;

镜子直接传入屏幕顶点坐标获得投影纹理,再通过投影取样获得颜色,和最终结果混合;

但是上面效果和局限性都比较大,所以找了个大佬写的镜子效果;

使用相机和RenderTexture,底层原理差不多,效果要好了很多;

Unity镜子效果制作教程

Unity——ShaderLab实现玻璃和镜子效果的更多相关文章

  1. Unity镜子效果的实现(无需镜子Shader)

    Unity镜子效果制作教程 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...

  2. Unity ShaderLab学习总结

    http://www.jianshu.com/p/7b9498e58659 Unity ShaderLab学习总结 Why Bothers? 为什么已经有ShaderForge这种可视化Shader编 ...

  3. ShaderLab实现Vignette过场动画效果

    实现Vignette过场动画效果 postprocessing中有渐晕效果(Vignette),镜头可以由边缘往中间慢慢变黑: 但是我打包WebGL的时候提示我postprocessing,GPU不支 ...

  4. 使用Unity创造动态的2D水体效果

    者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染器,触发器以及粒子的混合体来创造这一水体效果,最终得到可运用于你下款游戏的水纹和 ...

  5. Unity的NGUI插件篇——入场效果

    Unity的NGUI插件篇--入场效果 入场效果 入场效果须要借助于NGUI提供的TweenPosition类来完毕.为了说明此类的用法.本节将使会解说两个演示样例.本文选自  大学霸 <NGU ...

  6. Unity Shaderlab: Object Outlines 转

    转 https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/ Unity Shader ...

  7. unity之自制玻璃啤酒瓶shader

    客户的要求如下 步骤: 1.进行玻璃瓶效果分析 效果如下:高光,类次表面散射(里层通透而外层较为暗淡),外层白色勾勒轮廓. 高光:unity内部提供光滑度参数,越光滑则高光效果越明显,啤酒瓶材质是属于 ...

  8. 【转】如何使用Unity创造动态的2D水体效果

    原文:http://gamerboom.com/archives/83080 作者:Alex Rose 在本篇教程中,我们将使用简单的物理机制模拟一个动态的2D水体.我们将使用一个线性渲染器.网格渲染 ...

  9. Unity shader学习之屏幕后期处理效果之高斯模糊

    高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...

随机推荐

  1. SpringMVC(4):文件上传与下载

    一,文件上传 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理 ...

  2. 基于war的Spring Boot工程

    一.简介 前面创建的Spring Boot工程最终被打为了Jar包,是以可执行文件的形式出现的,其使用了Spring Boot内嵌的Tomcat作为Web服务器来运行web应用的.新版Dubbo的监控 ...

  3. BeanDefinitionLoader spring Bean的加载器

    spring 容器注册bean , 会把bean包装成beanDefinition 放进spring容器中,beanDefinitionLoader就是加载bean的类 . 一.源码 class Be ...

  4. 【C/C++】习题3-2 分子量/算法竞赛入门经典/字符串

    给出一种物质的分子式,求分子量.只包含4种原子,分别为C,H,O,N. [知识点] 1.ASCII码 [阿拉伯数字]48~57 [大写字母]65~90 [小写字母]97~122 2.输入循环到n-1的 ...

  5. collection库更新1.4.0版本

    collection库更新1.4.0版本 collection库一直在使用中,周末集合github上的反馈以及contributor的修改,更新了1.4.0版本. 这个版本做了几个事情: 增加了三种类 ...

  6. C#中继承和多态

    1.继承的概念 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用已存在的类的功能. 为了提高软件模块的可复用性和可扩充性,以便提高软件的开发效率,我们总 ...

  7. pipeline配置前端项目

    vue pipeline { agent { label 'master'} options { timestamps() disableConcurrentBuilds() buildDiscard ...

  8. 模糊C均值算法

    Fuzzy C-Means读书笔记 一.算法简介 很显然,图中的数据集可分为两个簇.借鉴K-Means算法的思想,利用单个特殊的点(质心)表示一个簇.因此,我们用\(C_1\)和\(C_2\)分别表示 ...

  9. [BUUCTF]PWN——[V&N2020 公开赛]warmup

    [V&N2020 公开赛]warmup 附件 步骤: 例行检查,64位程序,除了canary,其他保护都开 本地运行一下,看看大概的情况 64位ida载入,从main函数开始看程序 看到程序将 ...

  10. android jni-dlerror报undefined symbol: JNI_OnLoad

    以下是很简单的一个官方的jni方法,在MainActivity的onCreate中调用 extern "C" JNIEXPORT jstring JNICALL Java_com_ ...