adb 命令笔记

adb 命令

  • adb devices
    列出当前链接adb的设备

    1
    2
    3
    $ adb devices
    List of devices attached
    emulator-5558 device
  • adb pair {ip}:{port}
    配对指定ip和端口的adb设备,使用connect前需要先执行pair
    手机端需要打开 开发者选项 / 无线调试 / 使用配对码配对设备

    1
    2
    3
    $ adb pair 172.16.12.140:38617
    Enter pairing code: ******
    Successfully paired to 172.16.12.140:38617 [guid=adb-********-******]
  • adb connect {ip}:{port}
    连接指定ip和端口的adb设备

    1
    2
    $ adb connect 172.16.12.140:43357
    connected to 172.16.12.140:43357
  • adb disconnect
    断开所有连接adb的设备

    1
    2
    $ adb disconnect
    disconnected everything
  • adb -s {device id} {adb commond}
    指定要操作的adb设备

  • adb shell
    进入设备的shell命令行

    1
    2
    $ adb shell
    marlin:/ $
  • adb shell {commond}
    进入设备进入shell并执行命令{commond}

  • adb install-multiple {path1} {path2} … {pathN}
    安装多个APK可以用于手动安装xapk文件(低版本ADB可能不支持)

android shell 命令

  • pm list packages
    显示所有包名

    1
    2
    3
    4
    5
    6
    $ adb shell
    marlin:/ $ pm list packages
    package:com.android.providers.telephony
    package:com.android.providers.calendar
    package:com.android.providers.media
    ...
  • pm path {pachage name}
    显示指定包名安装包的路径(xapk会有多个路径)

    1
    2
    3
    $ adb shell
    marlin:/ $ pm path com.android.providers.media
    package:/system/priv-app/MediaProvider/MediaProvider.apk

Unity Hub 跳过登录

本方法参考 Uni-HubHacker 仓库(已和谐)

1. 原理说明

由于Unity Hub使用的是electron框架,所以其部分运行时js代码会存放在app.asar文件中。由于Unity Hub未对app.asar文件进行加密切未对其进行hash校验(但疑似会对文件大小校验),所以可以修改app.asar文件中登陆相关的代码,从而跳过登陆验证。由于.asar文件是归档文件,所以需要使用二进制工具打开,直接对代码进行明文修改。

2. 具体操作步骤

  • 找到Unity Hub安装目录下的Unity Hub/resources/app.asar文件使用二进制工具打开(这里以HxD为例,修改前请自行做好备份工作)。
  • 定为到以下文本并逐一替换
1
2
3
4
5
6
7
8
9
10
11
12
...
-const isFirstTimeOpen = yield promisify(jsonStorage.get)(IS_FIRST_TIME_OPEN_KEY);
+const isFirstTimeOpen = false;/*omisify(jsonStorage.get)(IS_FIRST_TIME_OPEN_KEY*/
...
-return this.getConfig(localSettings_1.default.keys.DISABLE_AUTO_UPDATE);
+return true;/*tConfig(localSettings_1.default.keys.DISABLE_AUTO_UPDATE*/
...
-return this.getConfig(localSettings_1.default.keys.DISABLE_SIGNIN);
+return true;/*tConfig(localSettings_1.default.keys.DISABLE_SIGNIN*/
...
-return this.getConfig(localSettings_1.default.keys.DISABLE_WELCOME_SCREEN);
+return true;/*tConfig(localSettings_1.default.keys.DISABLE_WELCOME_SCREEN*/
  • 修改完成后保存即可

Singleton - Unify Community Wiki

Singleton

From Singleton - Unify Community Wiki (archive.org)

[TOC]

Alternatives

Scriptable Objects

One excellent alternative to the singleton pattern in Unity is the use of ScriptableObjects as a type of global variable. Ryan Hipple from Schell Games gave a presentation at Unite Austin 2017 titled Game Architecture with Scriptable Objects that explains how to implement them and the many advantages over singletons.

Toolbox

The “Toolbox“ concept improves upon the singleton pattern further by offering a different approach that makes them more modular and improves testability.

Introduction

The singleton pattern is a way to ensure a class has only a single globally accessible instance available at all times. Behaving much like a regular static class but with some advantages. This is very useful for making global manager type classes that hold global variables and functions that many other classes need to access. However, the convenience of the pattern can easily lead to misuse and abuse and this has made it somewhat controversial with many critics considered it an anti-pattern that should be avoided. But like any design pattern, singletons can be very useful in certain situations and it’s ultimately up to the developer to decide if it’s right for them.

Advantages

  • Globally accessible. No need to search for or maintain a reference to the class.
  • Persistent data. Can be used to maintain data across scenes.
  • Supports interfaces. Static classes can not implement interfaces.
  • Supports inheritance. Static classes can not inherent for another class.

The advantage of using singletons in Unity, rather than static parameters and methods, is that static classes are lazy-loaded when they are first referenced, but must have an empty static constructor (or one is generated for you). This means it’s easier to mess up and break code if you’re not careful and know what you’re doing. As for using the Singleton Pattern, you automatically already do lots of neat stuff, such as creating them with a static initialization method and making them immutable.

Disadvantages

  • Must use the Instance keyword (e.g. .Instance) to access the singleton class.
  • There can only ever be one instance of the class active at a time.
  • Tight connections. Modifying the singleton can easily break all other code that depends on it. Requiring a lot of refactoring.
  • No polymorphism.
  • Not very testable.

Implementation

The singleton pattern is commonly applied to multiple classes but the implementation is always the same. So creating a singleton base class others can inherit from is ideal because it eliminates the need to recreate the same code over and over again for each class that needs to be a singleton.

Notes:

  • This script will not prevent non singleton constructors from being used in your derived classes. To prevent this, add a protected constructor to each derived class.
  • When Unity quits it destroys objects in a random order and this can create issues for singletons. So we prevent access to the singleton instance when the application quits to prevent problems.

Singleton.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using UnityEngine;

/// <summary>
/// Inherit from this base class to create a singleton.
/// e.g. public class MyClassName : Singleton<MyClassName> {}
/// </summary>
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
// Check to see if we're about to be destroyed.
private static bool m_ShuttingDown = false;
private static object m_Lock = new object();
private static T m_Instance;

/// <summary>
/// Access singleton instance through this propriety.
/// </summary>
public static T Instance
{
get
{
if (m_ShuttingDown)
{
Debug.LogWarning("[Singleton] Instance '" + typeof(T) +
"' already destroyed. Returning null.");
return null;
}

lock (m_Lock)
{
if (m_Instance == null)
{
// Search for existing instance.
m_Instance = (T)FindObjectOfType(typeof(T));

// Create new instance if one doesn't already exist.
if (m_Instance == null)
{
// Need to create a new GameObject to attach the singleton to.
var singletonObject = new GameObject();
m_Instance = singletonObject.AddComponent<T>();
singletonObject.name = typeof(T).ToString() + " (Singleton)";

// Make instance persistent.
DontDestroyOnLoad(singletonObject);
}
}

return m_Instance;
}
}
}


private void OnApplicationQuit()
{
m_ShuttingDown = true;
}


private void OnDestroy()
{
m_ShuttingDown = true;
}
}

Requirements

The above script makes use of the custom extension method GetOrAddComponent which is not a part of Unity.

Usage

To make any class a singleton, simply inherit from the Singleton base class instead of MonoBehaviour, like so:

1
2
3
4
5
6
7
8
public class MySingleton : Singleton<MySingleton>
{
// (Optional) Prevent non-singleton constructor use.
protected MySingleton() { }

// Then add whatever code to the class you need as you normally would.
public string MyTestString = "Hello world!";
}

Now you can access all public fields, properties and methods from the class anywhere using <ClassName>.Instance:

1
2
3
4
5
6
7
public class MyClass : MonoBehaviour
{
private void OnEnable()
{
Debug.Log(MySingleton.Instance.MyTestString);
}
}

Categories:

牌手预演「七圣召唤」 国际服

原神国际服网页活动:

活动页面 【原神】牌手预演-参与「七圣召唤」卡牌先览活动获得原石等奖励!

文字版本

属性 角色
迪卢克香菱班尼特宵宫愚人众·火之债务处理人
[莫娜][link_莫娜]、[纯水精灵·洛蒂娅][link_纯水精灵·洛蒂娅]、[愚人众·藏镜仕女][link_愚人众·藏镜仕女]、[芭芭拉][link_芭芭拉]、[行秋][link_行秋]
[魔偶剑鬼][link_魔偶剑鬼]、[砂糖][link_砂糖]、[琴][link_琴]
[刻晴][link_刻晴]、[赛诺][link_赛诺]、[菲谢尔][link_菲谢尔]、[雷泽][link_雷泽]
[柯莱][link_柯莱]、[翠翎恐蕈][link_翠翎恐蕈]
神里绫华甘雨迪奥娜凯亚重云
[诺艾尔][link_诺艾尔]、[丘丘岩盔王][link_丘丘岩盔王]、[凝光][link_凝光]

图片版本

迪卢克
香菱
班尼特
宵宫
愚人众·火之债务处理人

[莫娜][link_莫娜]
[纯水精灵·洛蒂娅][link_纯水精灵·洛蒂娅]
[愚人众·藏镜仕女][link_愚人众·藏镜仕女]
[芭芭拉][link_芭芭拉]
[行秋][link_行秋]

[魔偶剑鬼][link_魔偶剑鬼]
[砂糖][link_砂糖]
[琴][link_琴]

[刻晴][link_刻晴]
[赛诺][link_赛诺]
[菲谢尔][link_菲谢尔]
[雷泽][link_雷泽]

[柯莱][link_柯莱]
[翠翎恐蕈][link_翠翎恐蕈]

神里绫华
甘雨
迪奥娜
凯亚
重云

[诺艾尔][link_诺艾尔]
[丘丘岩盔王][link_丘丘岩盔王]
[凝光][link_凝光]

牌手预演「七圣召唤」

活动页面 【原神】牌手预演-参与「七圣召唤」卡牌先览活动获得原石等奖励!

文字版本

属性 角色
迪卢克香菱班尼特宵宫愚人众·火之债务处理人
莫娜纯水精灵·洛蒂娅愚人众·藏镜仕女芭芭拉行秋
魔偶剑鬼砂糖
刻晴赛诺菲谢尔雷泽
柯莱翠翎恐蕈
神里绫华甘雨迪奥娜凯亚重云
诺艾尔丘丘岩盔王凝光

图片版本

迪卢克
香菱
班尼特
宵宫
愚人众·火之债务处理人

莫娜
纯水精灵·洛蒂娅
愚人众·藏镜仕女
芭芭拉
行秋

魔偶剑鬼
砂糖
琴

刻晴
赛诺
菲谢尔
雷泽

柯莱
翠翎恐蕈

神里绫华
甘雨
迪奥娜
凯亚
重云

诺艾尔
丘丘岩盔王
凝光

Aseprite 白嫖编译指南

本文参考:Aseprite终极白嫖教程

0. 前言

  叠甲:以下会有一大段介绍(其实就是废话时间)。如果前期准备都完成了,想直接看编译指南的话可以跳转到编译部分,本文仅包含Windows的编译(别问,问就是买不起Mac)。

aseprite-logo

Aseprite是一种专有的,源可用的图像编辑器,主要用于像素画图和动画。它可以在Windows,macOS和Linux上运行,并具有用于图像和动画编辑的不同工具,例如图层,框架,tilemap支持,命令行界面,Lua脚本等。
原文来自:Aseprite 维基百科

  • 使用Aseprite可以更便捷的做出像素风格的图片及Gif

aseprite-icon

1. 准备阶段

1.0 Aseprite

  • 首先需要在Github上Clone或下载Release版的Aseprite代码,下载地址:

  • 由于一些国情原因GitHub访问速度一直不太稳定Git经常链接断断续续,外加不是所有人都会用Git。这里推荐下载Release版。至于速度问题网上有很多解决方案如油猴插件之类的个人一直使用serctl的加速。

  • 下载完解压,这里以解压到D:\Aseprite,这里以Aseprite-v1.3-beta16-Source.zip为例解压后根目录结构如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
D:\Aseprite
├─.github
├─cmake
├─data
├─docs
├─laf
├─src
├─third_party
├─.clang-format
├─.clang-tidy
├─.gitignore
├─.gitmodules
├─CMakeLists.txt
├─CODE_OF_CONDUCT.md
├─CODEOWNERS
├─CONTRIBUTING.md
├─EULA.txt
├─INSTALL.md
└─README.md
  • 在根目录找到INSTALL.md,这个文件是官方推荐的安装教程(只是写的过于专业,程序员可能比较容易理解,对小白不太友好)。

  • 其中对编译准备阶段比较重要的就是这段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # Dependencies

    To compile Aseprite you will need:

    * The latest version of [CMake](https://cmake.org) (3.16 or greater)
    * [Ninja](https://ninja-build.org) build system
    * And a compiled version of the `aseprite-m102` branch of
    the [Skia library](https://github.com/aseprite/skia#readme).
    There are [pre-built packages available](https://github.com/aseprite/skia/releases).
    You can get some extra information in
    the [*laf* dependencies](https://github.com/aseprite/laf#dependencies) page.

    ## Windows dependencies

    * Windows 10 (we don't support cross-compiling)
    * [Visual Studio Community 2022](https://visualstudio.microsoft.com/downloads/) (we don't support [MinGW](#mingw))
    * The [Desktop development with C++ item + Windows 10.0.18362.0 SDK](https://imgur.com/a/7zs51IT)
    from the Visual Studio installer
  • 我们分别需要准备公共依赖环境和打包平台依赖环境,这里只介绍Windows平台上的依赖

  • 根据上文我们需要准备以下依赖(多数都是GitHub库):

1.1 CMake

  • 官网:https://cmake.org

  • 根据文档要求3.16以上的版本,无脑下最新的就行了。下载地址:

  • 安装时千万记得要选择全局添加Path,默认是不添加Path的,当然程序员可以自行添加{安装目录}\bin下到Path

  • 安装目录没啥要求这里以D:\Program Files\CMake为例

1
2
3
4
5
D:\Program Files\CMake
├─bin
├─doc
├─man
└─share

1.2 Ninja

  • 官网:https://ninja-build.org/

  • 下载ninja-win.zip文件,地址:

  • 下载后解压Ninja.exe到某个地方方便寻找即可,这里以D:\AsepriteDependencies为例

1
2
D:\AsepriteDependencies
└─Ninja.exe

1.3 Skia

  • 这里需要下载Aseprite魔改后的Skia库:https://github.com/aseprite/skia

  • 下载Skia-Windows-Release-x64.zip文件,地址:

  • 下载后解压到一个空的文件夹中即可,这里以D:\AsepriteDependencies\Skia为例

1
2
3
4
5
6
D:\AsepriteDependencies\Skia
├─include
├─modules
├─out
├─src
└─third_party

1.4 Visual Studio

  • 官方推荐2022的版本,经测试VS2019完全可以,如果本地有其他版本可以先尝试一下,不行再使用其他版本。

  • 官方下载渠道:Visual Studio 最新版本,另外也可以在MSDN I tell you进行下载。白嫖用户推荐下载社区版(免费的)

  • 下载完会得到的是一个1.xMB左右的下载器文件VisualStudioSetup.exe,安装Visual Studio Installer

pic_vs_install

  • 工作负荷中选择使用C++的桌面开发,并且在安装详细信息中去除不必要的可选项。Windows 10 SDK相关可以删除(下一步会提到需要选择指定的版本),用于Windows的C++ CMake工具适用于最新v142生成工具C++ ATL(x86)建议保留

pic_cpp

  • 单个组件中搜索并添加Windows 10 SDK (10.0.18362.0)
    • 一定要选这个版本!
    • 一定要选这个版本!!
    • 一定要选这个版本!!!
    • 别问我为啥这样强调,都是心酸都是泪啊😭

pic_win10_sdk

  • 安装位置可以自行决定这里以C:\Program Files (x86)\Microsoft Visual Studio\2022\Community为例

编译

  • 这里推荐将所有编译用到的命令做成一个Bat文件方便Aseprite进行更新(理论上只需要替换Aseprite工程目录即可)

  • 新建一个bat文件命令如下,小白可以直接新建一个记事本文件将其后缀改为bat,以build.bat为例

  • 将一下bat指令全部拷贝至build.bat并且保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
:: !!请用管理员权限运行!!
@echo off
:: ============配置部分自行修改============
:: VsDevCmd.bat文件位置
set VSDEVC="C:\Program Files (x86)\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat"
:: (Aseprite)[https://github.com/aseprite/aseprite/releases]
set ASEPRITE="D:\Aseprite"
:: (Skia)[https://github.com/aseprite/skia/releases]
set DSKIA="D:\AsepriteDependencies\Skia"
:: (Ninja)[https://github.com/ninja-build/ninja/releases]
set NINJA="D:\AsepriteDependencies"
:: ============分割线============


:: ============以下谨慎修改============
set PATH=%NINJA%;%PATH%
call %VSDEVC% -arch=x64
cd /d %ASEPRITE%
if exist build rd /s /q build
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLAF_BACKEND=skia -DSKIA=%DSKIA% -DSKIA_LIBRARY_DIR=%DSKIA%\out\Release-x64 -DSKIA_LIBRARY=%DSKIA%\out\Release-x64\skia.lib -G Ninja ..
ninja aseprite
echo Finish
if exist bin explorer bin
pause
  • 分别替换VSDEVCASEPRITEDSKIANINJA的路径

  • 右键用管理员权限执行build.bat

pic_admin

  • 等待编译完成,如果成功会打开bin目录,执行aseprite.exe就能愉快的使用了,你可以将整个bin目录移动并重命名到任意位置,方便使用。

  • 可以愉快的玩耍了

pic_aseprite


更新日志:

2022/07/07:添加解压后的目录结构

【叠加模式】Photoshop图层混合模式的计算公式

转自:https://www.cgspread.com/3551.html
原作者:weijer
原标题:【叠加模式】Photoshop图层混合模式的计算公式
本文经过重新排版,仅供学习参考,严谨商用

  PS和Nuke的叠加模式计算算法相差甚远,最近想在Nuke中模拟ps叠加模式。老外已经有个gizmo了么免费的功能少,得付费购买,先百度找了下PS的图层混合模式的计算公式收藏慢慢想想怎么在Nuke中实现最好。

psnuke1

原图

注释:

  1. 混合模式的数学计算公式,另外还介绍了不透明度。
  2. 这些公式仅适用于RGB图像,对于Lab颜色图像而言,这些公式将不再适用。
  3. 在公式中
    A 代表下面图层的颜色值;
    B 代表上面图层的颜色值;
    C 代表混合图层的颜色值;
    d 表示该层的透明度。

C_{RGBi} = Max(A_{RGBi}, B_{RGBi}) 2指X颜色的RGB任意分量 \bar {X} 指X的反色 \bar {X} = 255 - X

1. Opacity 不透明度

C_{RGBi}=dA_{RGBi}+(1-d)B_{RGBi}

相对于不透明度而言,其反义就是透明度。
这两个术语之间的关系就类似于正负之间的关系:100%的不透明度就是0%的透明度。
该混合模式相对来说比较简单,在该混合模式下,
如果两个图层的叠放顺序不一样,其结果也是不一样的(当然50%透明除外)。
该公式也应用于层蒙板,在这种情况下,d代表了蒙板图层中给定位置图层的亮度(d=颜色值/255),
下同,不再叙述。

2. Darken 变暗

C_{RGBi} = Min(A_{RGBi}, B_{RGBi})

该模式通过比较上下层像素后取相对较暗的像素作为输出,
注意,每个不同的颜色通道的像素都是独立的进行比较,色彩值相对较小的作为输出结果。
下层表示叠放次序位于下面的那个图层,
上层表示叠放次序位于上面的那个图层,下同,不再叙述。

3. Lighten 变亮

MATHJAX-SSR-2

该模式和前面的模式是相似,不同的是取色彩值较大的(也就是较亮的)作为输出结果。

4. Multiply 正片叠底

C_{RGBi} = \frac {A_{RGBi} \times B_{RGBi}}{255}
该效果将两层像素的标准色彩值(基于0..1之间)相乘后输出
其效果可以形容成:两个幻灯片叠加在一起然后放映,
透射光需要分别通过这两个幻灯片,从而被削弱了两次。

5. Screen 滤色

C_{RGBi} = 255 - \frac {\bar A_{RGBi}\times \bar B_{RGBi}}{255}

该模式和上一个模式刚好相反,
上下层像素的标准色彩值反相后相乘后输出,
输出结果比两者的像素值都将要亮
(就好像两台投影机分别对其中一个图层进行投影后,然后投射到同一个屏幕上)。
从右边公式中我们可以看出,如果两个图层反相后,采用Multiply模式混合,
则将和对这两个图层采用 Screen模式混合后反相的结果完全一样。

6. Color Burn 颜色加深

C_{RGBi} = A_{RGBi} - \frac {\bar A_{RGBi}\times \bar B_{RGBi}} {B_{RGBi}}

该模式和上一个模式刚好相反。
如果上层越暗,则下层获取的光越少,
如果上层为全黑色,则下层越黑,
如果上层为全白色,则根本不会影响下层。
结果最亮的地方不会高于下层的像素值。

7. Color Dodge 颜色减淡

C_{RGBi} = A_{RGBi} + \frac {A_{RGBi} \times B_{RGBi}}{\bar B_{RGBi}}

该模式下,上层的亮度决定了下层的暴露程度。
如果上层越亮,下层获取的光越多,也就是越亮。
如果上层是纯黑色,也就是没有亮度,则根本不会影响下层。
如果上层是纯白色,则下层除了像素为255的地方暴露外,
其他地方全部为白色(也就是255,不暴露)。
结果最黑的地方不会低于下层的像素值。

8. Linear Burn 线形加深

C_{RGBi} = A_{RGBi} + B_{RGBi} - 255

如果上下层的像素值之和小于255,输出结果将会是纯黑色。
如果将上层反相,结果将是纯粹的数学减。

9. Linear Dodge 线形减淡

C_{RGBi} = A_{RGBi} + B_{RGBi}

将上下层的色彩值相加。结果将更亮。

10. Overlay叠加

C_{RGBi} = \left\{\begin{matrix} \frac{A_{RBGi} B_{RGBi} }{128} &A_V\leq 128\\255- \frac{\bar A_{RGB} \times \bar B_{RGB}} {128}&A_V>128\end{matrix}\right.

依据下层色彩值的不同,该模式可能是Multiply (正片叠底),也可能是Screen (滤色)模式。
上层决定了下层中间色调偏移的强度。
如果上层为50%灰,则结果将完全为下层像素的值。
如果上层比50%灰暗,则下层的中间色调的将向暗地方偏移,
如果上层比50%灰亮,则下层的中间色调的将向亮地方偏移。
对于上层比50%灰暗,下层中间色调以下的色带变窄(原来为02×0.4×0.5,现在为02×0.3×0.5),
中间色调以上的色带变宽(原来为2×0.4×0.51,现在为2×0.3×0.51)。
反之亦然。

11. Hard Light 强光

C_{RGBi} = \left\{\begin{matrix} \frac {A_{RBGi} \dot\times B_{RGBi}}{128} &B_V\leq 128\\ 255 - \frac {\bar A_{RBGi} \dot\times \bar B_{RGBi}}{128} &B_V>128\end{matrix}\right.

该模式完全相对应于Overlay (叠加)模式下,两个图层进行次序交换的情况。
如过上层的颜色高于50%灰,则下层越亮,反之越暗

12. Soft Light柔光

C_{RGBi} = \left\{\begin{matrix} \frac {A_{RBGi} \dot\times B_{RGBi}}{128} +(\frac{A_{RGBi}}{255})^2\times(255-2B_{RGBi}) &B_V\leq 128\\ \frac{A_{RGBi}\times \bar B_{RGBi}}{128} +\sqrt{\frac {A_{RGBi}}{255}} \times(2B_{RGBi}-255) &B_V>128\end{matrix}\right.

该模式类似上层以Gamma值范围为2.0到0.5的方式来调制下层的色彩值。
结果将是一个非常柔和的组合。

13. Vivid Light 亮光

C_{RGBi} = \left\{\begin{matrix} A_{RGBi} - \frac{\bar A_{RGBi}\times (255-2B_{RGBi})}{2B_{RGBi}} &B_V\leq 128 \\ A_{RGBi}+\frac{A_{RGBi}\times (255-2B_{RGBi})}{2\bar B_{RGBi}} &B_V>128\end{matrix}\right.

该模式非常强烈的增加了对比度,特别是在高亮和阴暗处。
可以认为是阴暗处应用Color Burn和高亮处应用Color Dodge。

14. Linear Light 线形光

C_{RGBi}=A_{RGBi}+2B_{RGBi}-255

其类似于Linear Burn,只不过是加深了上层的影响力。

15. Pin Light 点光

C_{RGBi} = \left\{\begin{matrix} Min(A_{RGBi}, 2B_{RGBi}) &B_V\leq 128 \\ Min(A_{RGBi}, 2B_{RGBi}-255) &B_V>128\end{matrix}\right.

该模式结果就是导致中间调几乎是不变的下层,
但是两边是Darken(变暗)和Lighten(变亮)模式的组合。

16. Hard Mix 实色混合

C_{RGBi} = 255 \times step(A_{RGBi}+B_{RGBi},255)

该模式导致了最终结果仅包含6种基本颜色,每个通道要么就是0,要么就是255。

17. Difference 差值

C_{RGBi} = |A_{RGBi}-B_{RGBi}|

上下层色调的绝对值。
该模式主要用于比较两个不同版本的图片。
如果两者完全一样,则结果为全黑。

18. Exclusion 排除

C_{RGBi} = A_{RGBi} + B_{RGBi} - \frac{A_{RGBi} \times B_{RGBi}}{12}

亮的图片区域将导致另一层的反相,很暗的区域则将导致另一层完全没有改变。

19. Hue 色相

\left(\begin{matrix}C_H\\C_S\\C_V\end{matrix}\right) = \left(\begin{matrix}B_H\\A_S\\A_V\end{matrix}\right)

输出图像的色调为上层,饱和度和亮度保持为下层。
对于灰色上层,结果为去色的下层。

20. Saturation 饱和度

\left(\begin{matrix}C_H\\C_S\\C_V\end{matrix}\right) = \left(\begin{matrix}A_H\\B_S\\A_V\end{matrix}\right)

输出图像的饱和度为上层,色调和亮度保持为下层。

21. Color 颜色

\left(\begin{matrix}C_H\\C_S\\C_V\end{matrix}\right) = \left(\begin{matrix}B_H\\B_S\\A_V\end{matrix}\right)
输出图像的亮度为下层,色调和饱和度保持为上层。

22. Luminosity 亮度

\left(\begin{matrix}C_H\\C_S\\C_V\end{matrix}\right) = \left(\begin{matrix}A_H\\A_S\\B_V\end{matrix}\right)

输出图像的亮度为上层,色调和饱和度保持为下层。

23. Dissolve 溶解

该模式根本不是真正的溶解,因此并不是适合Dissolve(溶解)这个称谓,其表现仅仅和Normal(正常)类似。
其从上层中随机抽取一些像素作为透明,使其可以看到下层,
随着上层透明度越低,可看到的下层区域越多。
如果上层完全不透明,则效果和Normal(正常)不会有任何不同。

Surface Shaders in Unity

Unity中Shader表面着色器基础

Unity云中客

2016.04.17 22:01
转载:http://www.jianshu.com/p/b17503c056de

写与灯光交互的Shader是很复杂的,因为有不同的灯光类型(light Type),不同的阴影选项(Shadow Options),不同的渲染路径(renderingPath:forward,deferred rendering),所以Shader应该以某种方式来处理所有的复杂情况。

Unity中的==Surface Shaders==是一种比使用底层的顶点/像素着色器程序(vertex/pixel shader programs)写起来更为简单通用的方式。 surfaceShaders 也是用Cg/hlsl来写。

How It Works

首先你需要定义一个”Surface”函数来获取任何uv信息或者你需要的数据作为输入,最后会填充在输出结构体”SurfaceOutput”里,SurfaceOutput是对表面属性的基本描述(例如Albedo,Normal,Emission,Specular等等),你可以将这些代码写在cg/hlsl里。
然后Surface Shaders计算编译需要哪些输入数据,以及哪些输出被填充等等,然后生成原生的vertex/pixed shaders,同时渲染通道会去处理forward和deferred渲染。
标准的表面着色器输出结构:

1
2
3
4
5
6
7
8
9
struct SurfaceOutput
{
fixed3 Albedo; // diffuse color /反射颜色
fixed3 Normal; // tangent space normal, if written(法向量)
fixed3 Emission;//自发光颜色
half Specular; // specular power in 0..1 range//镜面反射度
fixed Gloss; // specular intensity(光泽度)
fixed Alpha; // alpha for transparencies(透明度)
};

在Unity5中,SurfaceShader也可以使用光照模型的基本物理属性。内置的”Standard“和”StandardSpecular“光照模型分别使用下面的输出结构体:

(Standard和StandardSpecular光照模型对应普通没有物理的的Lambert何BlinnPhong光照模型)

1
2
3
4
5
6
7
8
9
10
struct SurfaceOutputStandard
{
fixed3 Albedo; // base (diffuse or specular) color
fixed3 Normal; // tangent space normal, if written
half3 Emission;
half Metallic; // 0=non-metal, 1=metal,金属度
half Smoothness; // 0=rough, 1=smooth,光滑度
half Occlusion; // occlusion (default 1),遮挡率
fixed Alpha; // alpha for transparencies
};
1
2
3
4
5
6
7
8
9
10
struct SurfaceOutputStandardSpecular
{
fixed3 Albedo; // diffuse color
fixed3 Specular; // specular color
fixed3 Normal; // tangent space normal, if written
half3 Emission;
half Smoothness; // 0=rough, 1=smooth
half Occlusion; // occlusion (default 1)
fixed Alpha; // alpha for transparencies
};

对比SurfaceOutput和SurfaceOutputStandard,会发现前者的结构中Specular和Gloss被替换成在后者的结构中的Metallic,Smoothness,Occlusion三个属性。这三个属性就是Unity5里新加的物理属性。同样比较SurfaceOutputStandard和SurfaceOutputStanaedSpecular结构体,发现Metallic属性被Specular属性替换掉。

所以Unity5.x基于光照模型添加的基本物理属性应该是在Specular镜面发射上做了一些处理,添加了遮挡和粗糙度的属性以及混合Specular而形成的Metallic属性,使物体表面具有更加接近真实的物理光泽效果,从而减轻开发者自己书写相似效果的工作量。

##Surface Shader compile directives(表面着色器编译指令)**

表面着色器和其它Shader一样被放在CGPROGRAM……ENDCG块中执行,不同的是:

  • 代码必须写在子着色器块(SubShader)而不是通道(Pass)中,表面着色器会自己把它编译到多个通道里。
  • 代码必须使用#pragma surface … 指令去指示它的表面着色器。

“#Pragma surface” 指令是:

#pragma surface surfaceFunction lightModel [optionalparams]

必要参数

  • surfaceFunction - 含有表面着色器代码的cg函数。这个函数必须是void surf(Input IN,inout SurfaceOutput o)的形式,Input是一个自己定义的结构体,Input结构体里应该包含一些纹理坐标和其它的surface函数需要的其它的可以被自动识别的变量(autonmatic variables)。
  • lightmodel - 使用的光照模型。内置一些基于物理的StandardStandardSpecular光照模型,以及一些没有基于物理的Lambert(Diffuse)和BlinnPhong(specular)光照模型,当然也可以自己写光照模型(参见:自定义光照模型
  • Standard光照模型使用SurfaceOutputStandard作为输出结构体,对应Unity中的Standard(Metallic workflow)Shdaer。
  • StandardSpecular光照模型使用SurfaceOutputStandardSpecular作为输出结构体,对应Unity中的Standard(Specular workflow)Shader
  • Lambert和BlinnPhong光照模型是不基于物理的(大部分在Unity4.x中),但是在低端设备上使用会更加快,性能更好。

可选参数

Transparency和Alpha testing是由alpha和alphatest指令控制。不透明度主要分为两种:传统的alpha混合(一般用于淡出物体)或更加看似物理的“premultiplied blending”(允许半透明表面保留适当的镜面反射效果)。使半透明能够使用生成的表面着色器代码包含blending指令,而能够让alpha基于已有的变量剔除被生成的pixed shader丢弃的片段。

  • alpha 或者 alpha:auto: 将会为简单的光照函数挑出淡出透明度(就像alpha:fade),并且为基于物理的光照函数预乘透明度(就像 alpha:premul)。
  • alpha:fade:使用传统的淡出透明。
  • alpha:premul:使用预乘alpha透明度。
  • alphatest : variableName:使用alpha裁剪透明度。剔除值是一个浮点型变量variableName,你可能也会想使用addshadow指令去生成适当的阴影接受通道(shadow caster pass)。
  • keepalpha:默认不透明(Opaque)选项,不管输出结构的Alpha或者光照函数的返回值都将表面着色器将Alpha通道值设置为1.0。使用这个选项允许保持光照函数的返回alpha值,即使使用的是不透明表面着色器。
  • decal:add: 额外的贴花着色器(例如,terrian AddPass),这意味着物体在其它表面之上使用additive blending。
  • decal:blend:半透明贴花着色器,这意味物体可以在其它物体表面使用alpha blending。

自定义函数可以被用来改变或计算来自顶点的数据,或者改变最后计算得出的片段颜色。

  • vertex:VertexFunction,用户自定义的顶点修改函数。这个函数会在生成的顶点着色器开始被调用,并且可以修改或计算每个顶点的数据。
  • finalcolor:ColorFunction,自定义的最终颜色修改函数。

Shadows and Tessellation(阴影和镶嵌花纹),可以控制如何处理阴影和镶嵌花纹的额外指令。

  • addshadow,生成一个阴影投射通道,通常被用在自定义顶点修改函数中,因为阴影投射也获得程序顶点动画。通常shaders不需要任何特殊的shadows处理,因为可以使用它们FallBack里的阴影投射通道。
  • fullforwardshadows,支持正向渲染路径(forward render path)的所有的灯光阴影。默认的着色器仅支持来自directional light的正向渲染(为了节省内部着色器变量数量),如果需要point light和spotlight在正向渲染中的阴影,可以直接使用这个。
  • tessellate:TessFunction,使用DX11 GPU Tessellation,函数计算镶嵌纹理因子。

Code Generation(代码生成) 选项,通过默认生成的表面着色器代码试图去处理各种可能的lighting/shadowing/lightmap情况,然而有些情况下你不需要他们中的一些内容,这里你就可以调整代码生成去跳过它们。这样的结果会使你的shader更小并且被更快的加载。

  • exclude_path:deferred,forward,prepass.不要为已经给的渲染路径生成pass,
  • noshadow,不支持阴影接收。
  • noambient,不适用于环境光或者light probes。
  • novertexlights,不适用于正向渲染(forward rendering)的任何light probes或者逐顶点光照。
  • nolightmap,不支持光照贴图。
  • nodynlightmap,不支持动态的全局光照。
  • nodirlightmap , shader不支持定向光照贴图。
  • nofog,不支持所有的内置雾效。
  • nometa,不生产”meta“通道,常被用于lightmapping和动态全局照明去提取表面信息。
  • noforwardadd,不适用正向渲染额外的通道。这个使shaders支持一个全局光,而使用其它灯光逐顶点计算。可以使shader更小更有效率。

其它

  • softvegetation,使表面着色器仅仅在软植被上的时候被渲染。
  • interpolateview,计算在顶点着色器上视觉方向并且进行差值来代替在像素着色器中计算。可以使像素着色器更快,但是会使用多张贴图进行差值。
  • halfasview,通过half-direction向量进入光照函数来代替视角方向,half-direction会被逐顶点计算并归一化。这会更快,但并不总是正确。
  • approxview,Unity5中移除了,使用interpolateview代替。
  • dualforward,在正向渲染路径中使用贴花光照贴图。

表面着色器输入结构

在输入结构体Input中通常会有一些shader使用需要的纹理坐标。纹理坐标必须以uv命名开头,后面街上纹理名称(或者以uv2开头,使用第二个纹理坐标)。

其它可以被放到Input结构中的值有:

  • float3 viewDir,将含有视角方向,用于计算视差效果,边缘光照等。

  • float4加上COLOR语意绑定,将会包含差值的逐顶点颜色。

  • float4 screenPos,将包含屏幕空间位置,用于反射后屏幕空间效果。

  • float3 worldPos,包含世界空间位置信息。

  • float3 worldRef1,如果表面着色器没有写给o.Normal,将包含世界反射向量。

  • float3 worldNormal,如果表面着色器没有写给o.Normal,将包含世界法向量。

  • float3 worldRef1;INTERNAL_DATA,如果表面着色器没有写给o.Normal,将包含世界反射向量。使用WorldReflectionVector (IN, o.Normal)基于逐顶点法线贴图获取反射向量。

  • float3 worldNomal;INTERANT_DATA,如果表面着色器没有写给o.Normal,使用WorldReflectionVector (IN, o.Normal)基于逐顶点法线贴图获取法线向量。

现在有部分表面着色器编译管线不支持DX11上特殊的HLSL语法,所以如果你使用HLSL一些特性,比如StructuredBuffers,RWTextures和其它的DX9没有的特性,可以使用宏包裹住。