尝试MatCap类型shader
听说MatCap能在低端机上做出很漂亮的pbr效果,就尝试了一下。
MatCap全称MaterailCapture,里面存的是光照信息,通过法线的xy分量去采样matcap,得到在该方向法线的光照信息,因为不是实时光照,所以性能好,好不好看就看你的Matcap做得好不好了。下面是简单的matcap尝试:
Shader "Unlit/SimpleMatCapShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_MatCap("MatCap", 2D) = "white" {}
_MatCapFactor("MatCapFactor", Range(,)) =
_EnvTex("EnvTex (CubeMap)", Cube) = "_SkyBox" {}
_EnvFactor("EnvStrength", Range(,)) = 0.8
} SubShader
{
Tags { "RenderType"="Opaque" }
LOD Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
}; struct v2f
{
float4 twoUv : TEXCOORD0;//主纹理uv存xy,matCapUv存在zw,这算一种优化
float4 vertex : SV_POSITION;
float3 RefDir : TEXCOORD1;
}; sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _MatCap;
half _MatCapFactor;
samplerCUBE _EnvTex;
half _EnvFactor; v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.twoUv.xy = TRANSFORM_TEX(v.uv, _MainTex);
//matcap存的其实是:法线中xy分量作为uv,对应的光照颜色信息,即用xy去采样就好,注:xy必须是归一化法线中的分量,故z才没必要
o.twoUv.zw = UnityObjectToWorldNormal(v.normal).xy;
o.twoUv.zw = o.twoUv.zw * 0.5 + 0.5;//(-1,1)->(0,1)
float3 wolrdN = UnityObjectToWorldNormal(v.normal);
o.RefDir = reflect(-WorldSpaceViewDir(v.vertex), wolrdN);
return o;
} fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.twoUv.xy);
fixed4 mapCapCol = tex2D(_MatCap, i.twoUv.zw);
fixed4 reflection = texCUBE(_EnvTex, i.RefDir);
col.rgb = col.rgb * mapCapCol.rgb * _MatCapFactor + reflection.rgb * _EnvFactor;
return col;
}
ENDCG
}
}
}
各种效果如下:


matCap贴图的获取:
这边提供几个可以获取MatCap贴图的网址:
[1] https://www.pinterest.com/evayali/matcap/
[3]http://pixologic.com/zbrush/downloadcenter/library/#prettyPhoto
总结,如果matcap做得好,确实能得到非常漂亮的效果,关键是,只是多一张tex就能获得如此效果,不错不错。
许多资料都没有讲到,但我个人以为,matcap其实是缤纷多彩的高光效果。普通高光一般是单一的白色,或其他单色,matcap因为用图片存不同“斜率”的法线的高光颜色,所以可以做得更加漂亮,这个可以看下图:

一个matcap纹理图
(因为法线先x,y,z归一化(一个单位球体),后取其中的x,y采用,所以[x,y]必定束缚在圆中,
所以matcap都是圆,即使不是,也只有圆内纹理有效)
从上面shader可知我们先把法线从[-1,1]映射到[0,1]后再采样,这个是由于matcap坐标是从0开始的,为了更加直观的理解,我们反其道行之:
把matcap图片的坐标从[0,1]映射到[-1,1]。
则,明显地,图片中间就是[0,0],即普通笛卡尔坐标系的原点,此时,法线区间是[-1,1],matcap图的坐标区间也是[-1,1],一一对应,每个像素的法线根据其大小和方向在matcap图中取值,得到的就是这个像素的高光颜色,这样,matcap的效果也变得很直观了。
尝试MatCap类型shader的更多相关文章
- 【Unity Shader编程】之十六 基于MatCap实现适于移动平台的“次时代”车漆Shader
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/55803629 渲染本文配图使用的 ...
- Asp.net 面向接口可扩展框架之类型转化基础服务
新框架正在逐步完善,可喜可贺的是基础服务部分初具模样了,给大家分享一下 由于基础服务涉及面太广,也没开发完,这篇只介绍其中的类型转化部分,命名为类型转化基础服务,其实就是基础服务模块的类型转化子模块 ...
- Unity3d 着色器语法(Shader)
Shader "name" { [Properties] Subshaders [Fallback] } 定义了一个着色器.着色器拥有一个 Properties 的列表.着色器包含 ...
- WCF 已知类型和泛型解析程序 KnownType
数据协定继承 已知类型和泛型解析程序 Juval Lowy 下载代码示例 自首次发布以来,Windows Communication Foundation (WCF) 开发人员便必须处理数据协定继承方 ...
- (CLR-Via-C#) 类型基础
CLR要求每个类型最终都派生自System.Object Object提供的公共方法: Equals: 如果两个对象具有相同的值,就返回true GetHashCode: 返回对象的哈希码 ToStr ...
- 【Unity Shader实战】卡通风格的Shader(一)
写在前面 本系列其他文章: 卡通风格的Shader(二) 呜,其实很早就看到了这类Shader,实现方法很多,效果也有些许不一样.从这篇开始,陆续学习一下接触到的卡通类型Shader的编写. 本篇的最 ...
- 变量和基本类型——复合类型,const限定符,处理类型
一.复合类型 复合类型是指基于其他类型定义的类型.C++语言有几种复合类型,包括引用和指针. 1.引用 引用并非对象,它只是为一个已存在的对象所起的另外一个名字. 除了以下2种情况,其他所有引用的类型 ...
- CLR-基元类型以及溢出检查 (CLR-Via-C#) 类型基础
CLR-基元类型以及溢出检查 =========(CLR via C#阅读笔记)======== 基元类型(primitive type): 基元类型也不做过多的解释,举个例子即可清晰的辨别 在j ...
- Unity Built-In Shader造成的运行时内存暴涨
在某个PC项目中使用了大量的材质球, 并且都使用了自带的Standard Shader, 在编辑器运行的时候, 一切良好, 运行内存只在1G左右, 然而在进行AssetBundle打包之后, EXE运 ...
随机推荐
- ios签名app稳定不掉签技术详细教程详解
iOS签名是专门针对ios的APP内测的数字签名,是苹果面向开发者提出的一箱机制. 因为现在苹果APP下载渠道只有App Store,还可以加上一个内测用的testflight,也就是说,除了这两个官 ...
- linux查询操作系统信息,CPU物理个数,CPU核心数,逻辑CPU数,内存信息查询,硬盘信息查询
目录 一.前言 二.关于服务器基本配置 2.1 操作系统基本配置查询 2.2 CPU基本配置查询 2.3 内存基本配置查询 2.4 硬盘基本配置查询 一.前言 当我们接手了一台或者几台服务器的时候 ...
- PyTorch上路
PyTorch torch.autograd模块 深度学习的算法本质上是通过反向传播求导数, PyTorch的autograd模块实现了此功能, 在Tensor上的所有操作, autograd都会为它 ...
- GitLab 查看版本号
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
- 微信公众平台上如何上传excel表格?
微信公众平台上如何上传excel表格? 我们都知道创建一个微信公众号,在公众号中发布一些文章是非常简单的,但公众号添加附件下载的功能却被限制,如今可以使用小程序“微附件”进行在公众号中添加附件. ...
- 2020-03-27:JDK1.8中在数据结构上,对HashMap做了什么样的改进?为什么?
福哥答案2020-04-04:头插改尾插,解决链表成环的问题.链表改成链表和红黑树.
- 2020-04-14:mysql原子性和持久性怎么保证
1.Mysql怎么保证一致性的? OK,这个问题分为两个层面来说. 从数据库层面,数据库通过原子性.隔离性.持久性来保证一致性.也就是说ACID四大特性之中,C(一致性)是目的,A(原子性).I(隔离 ...
- C#LeetCode刷题之#387-字符串中的第一个唯一字符(First Unique Character in a String)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3939 访问. 给定一个字符串,找到它的第一个不重复的字符,并返回 ...
- golang中type关键字使用
type关键字使用 type是go语法里的重要而且常用的关键字,type绝不只是对应于C/C++中的typedef.搞清楚type的使用,就容易理解go语言中的核心概念struct.interface ...
- Mybatis中选择语句的使用:<choose>标签、分区排序 Row_num() over ()函数的使用呢
1.Mybatis中数据库语句的选择 使用: <choose> <when test="relationType=='L'"> ...