【Blender 水墨材质】实现过程剖析01
写在前面
想把Blender一位大佬演示的Blender水墨材质过程,在Unity用Shader重现,过程中会拿能拿到的节点代码举例(ShaderGraph或者UE的都会有)。第一步当然是要跟着人家做一遍!我会尽可能地分析一下每一步的原理~
教程:blender水墨材质制作演示
1 描边效果+内部颜色
节点一览:
Fresnel节点
这个节点其实实现的是菲涅尔效果,严格遵守“入射角越大,反射光越多”,直接拿n和v来判断(跟BRDF里的F项关系不大,F项是微观的vh),几乎都是用来计算视角边缘区域——以实现边缘光或者描边的效果。
UE里蓝图也有相似节点——Fresnel节点,节点代码:
half Fresnel(half Exponent, half BaseReflectionFraction)
{half NoV = max(dot(N, V), 0.0f);half Fres = pow(abs(1 - NoV), Exponent);Fres = Fres * (1 - BaseReflectionFracetion) + BaseReflectionFraction;return Fres;
}
其中F0是基础反射率,相当于(Exponent为5的情况):
ShaderGraph也有对应的Fresnel Effect节点,节点代码:
void Unity_FresnelEffect_float(float3 Normal, float3 ViewDir, float Power, out float Out)
{Out = pow((1.0 - saturate(dot(normalize(Normal), normalize(ViewDir)))), Power);
}
输入的Power相当于UE里的Exponent,用以控制边缘强度。
但是Blender只有IOR项。
IOR影响的是什么
我们先看看这张图,是把Fresnel放在自发光层为了让反射率可视化,Fresnel节点输入的IOR值越大,意味着每个像素的反射率越高(像素点越白),那么颜色过渡的范围就会缩小,IOR大到一定程度,菲涅尔效应就几乎没有了。
ColorRamp节点
你会发现虽然是ColorRamp,但输出的值仅仅是一个数Factor,去参与混合Shader,所以!这里的ColorRamp实际上只是在用黑白两个色去规范取值,原始的Fresnel值输出是这样的:
所以需要Ramp一下让边缘别这么太过渡,边缘硬一点、交界明显一点。
然后拿这个硬一点的结果,MixShader一下,两个Emission材质仅仅是用来给定内颜色和边缘颜色的。
那么第一部分,边缘,如果在Unity里实现,直接以nv判断边缘再ifelse条件去硬化边缘就行!
当然,实际上ColorRamp远不止这样,有时候还会有多个Factor+多个Color同时组成一个Ramp图,TA意识觉醒——要是能用代码方式实现一个ColorRamp
有大佬在Unity Shader实现了Color Ramp:[技术美术Demo]-小工具制作Ramp图
知乎上也发现了一篇:实现Unity 后处理特效 (3) _渐变 Ramp
以及:【Unity工具】使用Shader快速实时生成复合Ramp图
完美!后期复刻一个出来吧,作为实现水墨风小Demo的一个小分支,丰富自己作品的工作量。
2 滤波纹理添加勾线细节
节点一览:
这部分简单,就是用噪声纹理当作一张Bump Texture,然后连给Fresnel节点的Normal通道,相当于改变dot(n,v)计算的n,单独输出影响之后的Fresnel:
因为我们看到的东西中间都是纯色的、再加上水墨风格需要的颜色比较淡、所以说这里仅仅算是给描边做了一个细节遮罩,让他有一种笔触感,当然在实现的时候可以直接传入笔刷Texture,采样这张Texture后,改变worldNormal就行。
3 丰富内颜色
节点一览
单独预览Mix后的效果:
Layber Weight 层权重
这就是个神奇的节点!很多效果都有它的身影,我们一点一点看。
骨骼的权重
在骨骼动画里,权重值越高,该节骨骼对相应网格的影响便越大,由于存在多节骨骼对相同网格存在影响,此时便要通过权重值来决定优先级。所以骨骼绑定也叫做刷权重。( 解释参考自Unity骨骼动画的总结)
Shader中的权重
权重在Shader里指——两个系数A和B谁占比更多,比如Mix Shader:
权重就是Factor参数——Factor越小,代表Color1在输出中的占比越小。代码表示的话可以是:
float4 MixShader(float Fac, float4 Color1, float4 Color2){return Fac * Color1 + (1 - Fac) * Color2;
}
层的权重-Fresnel
Layer Weight本身节点如下:
Fresnel输出效果有点类似Fresnel?如果把上面实现描边的Fresnel换成Layer Weight看看有什么不同,


惊,只要参数正确,效果是一样的,且Blender参数在(0,1),调整起来比IOR更容易一些。
层的权重-Facing
面朝向输出,我们如果单独输出Facing值:
对于球来说,越到边缘越白(亮),中间越黑(暗),事实上由于球的表面是平滑过渡的,法线也是平滑的,中间相当于视线垂直于面(n和v夹角为0),边缘相当于掠射(夹角为90°)。
啊,这时候就有疑问了——感觉和菲涅尔输出差不多意思,掠射为白,垂直为黑?
球简直是个个例,我们给球法线扰动一下,然后加上ColorRamp去对比一下输出Fresnel和输出Facing的区别:
左为Fresnel,右为Facing,为了对比更明显Blend参数都设置为0.5,给了噪声贴图传入Bump作为Normal输入,测试节点大概长这样:
对比下来你会发现,Facing更贴近于通过n去影响最终的占比,v越是掠射,越是贴近ColorRamp的最后一个色值,v越是垂直,越贴近第一个色值,而角度处于中间部分,就开始在色值上面均匀取色。
而Fresnel很大程度就是在扮演菲涅尔效应的角色,变化永远围绕着那个菲涅尔效应的光环去实现影响:
想看更加清晰的对比,我们把ColorRamp提升到三个色值变化(啊啊颜色随便取的,意在做测试,有点丑orz):
仍旧是左边Fresnel右边Facing,这样差别就超级明显了!!Fresnel边缘一点,Facing是全局的变化。
可以参考这篇文章,相信你会对面权重节点有更加清晰的认识:Blender着色器节点教程 —— Layer Weight
层权重-Facing节点其实在Blender是很常用的,怎么在代码里用函数表示呢?实际上就是一个将n*v值原原本本作为一个影响因子输出了,比较下来Fresnel输出公式需要有额外的乘法去拟合菲涅尔效应。感兴趣的话可以关注我后面的uniyt shader实现篇!
接着回到我们的水墨节点部分。
擅用Noise和ColorRamp
首先,层权重输出面朝向+ColorRamp:
和NoiseTexture,
二者Add一下:
这很好理解吧,白的通道都是1,黑的0,0+0=0,0+1=1,所以中间白起来了!
接着ColorRamp一下,给他边缘颜色加深,当作遮罩:
接着又老操作,NoiseTexture+ColorRamp搞了两个颜色:
用上面的遮罩Mix这两个效果Color,暗一点的作为第一个Color,亮一点的第二个,效果的话就会是遮罩黑色部分(0)完全取第一个Color,白色部分完全取第二个Color,中间的取二者mix的过渡,最后的效果就会是:
和描边效果混合
还记得最开始的两个Emission,一个是内色、一个是秒变色:
把上面实现的颜色作为内色,最后的效果就是:
有那味儿了有那味儿了!
4 加内描边
再次复用菲涅尔节点,拉个ColorRamp一下,内描边就有啦:
这其实才是整个视频的前3min半,后面还涉及到了着色,打算先在Unity里做一遍看看!再继续。
相关文章:

【Blender 水墨材质】实现过程剖析01
写在前面 想把Blender一位大佬演示的Blender水墨材质过程,在Unity用Shader重现,过程中会拿能拿到的节点代码举例(ShaderGraph或者UE的都会有)。第一步当然是要跟着人家做一遍!我会尽可能地分析一下每一步的原理~ 教程…...
代码随想录算法训练营第五十六天|583. 两个字符串的删除操作、72. 编辑距离
LeetCode 583 两个字符串的删除操作 题目链接:https://leetcode.cn/problems/delete-operation-for-two-strings/ 思路: 方法一:两个子串同时删除元素 dp数组的含义 dp[i][j]dp[i][j]dp[i][j]代表以i-1为结尾的字符串word1,和以j-1位结…...

【ArchLinux】【KDE】Archlinux的安装与使用
文章目录开头前言所需环境演示环境相关链接安装教程在Windows环境下制作启动盘进入ArchLinux Live环境安装为硬盘分区如何新建分区?分区表格式化分区分区完成,开始安装挂载分区切换镜像源安装基本系统设置将Live环境(当前)挂载信息…...

Go语言精修(尚硅谷笔记)第六章
六、函数、包和错误处理 6.1 函数概念 不用函数的弊端 1)写法可以完成功能, 但是代码冗余 2 ) 同时不利于代码维护 概念:为完成某一功能的程序指令(语句)的集合,称为函数。 在Go中,函数分为: 自定义函数、系统函数 基本语法 //函数的基本语法 fu…...
Photoshop的功能
Photoshop是一款功能强大的图片编辑软件,它提供了数百种不同的工具和特效,让您可以编辑图片、创建图形和设计网页等。 以下是Photoshop的一些主要功能: 1.图层:Photoshop允许您创建多个图层,让您可以在每一个图层上进…...

C++初阶——内存管理
目录 1. C/C内存分布 2. C语言中动态内存管理方式:malloc/calloc/realloc/free 3. C内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 4. operator new与operator delete函数 重要 4.1 operator new与operator delete函数(…...

uds服务汇总
还有一些服务列举在下面: RequestDownload(服务ID为0x34)和RequestUpload(服务ID为0x35):这两个服务用于在ECU和诊断器之间进行数据传输。通过 RequestDownload服务,诊断器可以请求ECU接收一些数…...
【深度学习】2023李宏毅homework1作业一代码详解
研一刚入门深度学习的小白一枚,想记录自己学习代码的经过,理解每行代码的意思,这样整理方便日后复习也方便理清自己的思路。感觉每天时间都不够用了!!加油啦。 第一部分:导入模块 导入各个模块࿰…...

【软件测试】基础知识第二篇
文章目录一. 开发模型1. 瀑布模型2. 螺旋模型3. 增量和迭代模型3.1 增量模型3.2 迭代模型3.3 增量和迭代模型的区别4. 敏捷模型4.1 敏捷宣言4.2 scrum模型二. 开发模型V 模型W 模型一. 开发模型 1. 瀑布模型 瀑布模型在软件工程中占有重要地位,是所有其他模型的基…...
Java中File类以及初步认识流
1、File类操作文件或目录属性 (1)在Java程序中通过使用java.io包提供的一些接口和类,对计算机中的文件进行基本的操作,包括对文件和目录属性的操作、对文件读写的操作; (2)File对象既可以表示…...

【C语言】文件操作详细讲解
本章要分享的内容是C语言中文件操作的内容,为了方便大家学习,目录如下 目录 1.为什么要使用文件 2.什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 3.文件的打开和关闭 3.1文件指针 3.2打开和关闭 4.文件的顺序读写 4.1顺序读写函数介绍…...

爱奇艺万能联播使用教程
众所周知,爱奇艺是百度旗下的一款产品,所以今天用爱奇艺万能联播的方法实现下载百度网盘,并没有破解百度网盘,是官方正版下载渠道。软件是官方版本,大家双击安装即可。 安装完成以后,在软件中就有了“访问网…...

真题讲解-软件设计(三十七)
数据流图DFD(真题讲解)-软件设计(三十六)https://blog.csdn.net/ke1ying/article/details/129803164 在网络安全管理中,加强内防内控可采取的策略是? 终端访问权限,防止合法终端越权访问。加强…...

Android 上的协程(第一部分):了解背景
本系列文章 Android 上的协程(第一部分):了解背景 Android 上的协程(第二部分):入门 Android上的协程 (第三部分): 实际应用 Android 上的协程(第一部分):了解背景 这篇…...
【H3C】VRRP2 及Vrrp3基本原理 华为同用
文章目录VRRP2基本概念报文格式主备选举规则(优先级)0和255双Master原因VRRP认证VRRP状态机抢占模式VRRP主备切换状态项目场景VRRP3H3C参考致谢VRRP2 基本概念 VRRP路由器(VRRP Router):运行VRRP的设备,它…...

【数据库】SQL语法
目录 1. 常用数据类型 2. 约束 3. 数据库操作 4. 数据表操作 查看表 创建表格 添加数据 删除数据 修改数据 单表查询数据 多表查询数据 模糊查询 关联查询 连接查询 数据查询的执行顺序 4. 内置函数 1. 常用数据类型 整型:int浮点型:flo…...

JavaEE简单示例——文件的上传和下载
文件的上传和下载的实现原理的简单介绍 表单的构成 首先,我们先来介绍我们的需要用到的表单,在这个表单中,首先值得我们注意的就是,在type为file的input标签中.这个控件是我们主要用来选择上传的文件的, 除此之外,我们要想实现文件的上传,还需要将method的属性的值设置为post…...

【C语言督学训练营 第五天】数组字符串相关知识
文章目录前言一、数组的定义1.一维数组①.如何定义②.声明规则③.内存分布④.初始化方法2.二维数组3.高维数组二、访问数组元素相关问题1.访问越界2.数组的传递三、Scanf与字符数组1.字符数组初始化2.scanf读取字符四、字符数组相关函数前言 今天的C语言训练营没有安排高维数组…...

GPT-4 免费体验方法
POE 在Quora上非常受欢迎的手机聊天机器人Poe App已经集成ChatGPT助手!除了最初集成的三个聊天机器人Sage、Claude和Dragonfly外,Poe现在还加入了第四位ChatGPT。由于使用了ChatGPT API,因此Poe拥有真正的ChatGPT。 现在更是第一批集成了GP…...
中断-屏蔽位
1.中断控制器(PIC:适用于单处理器、APIC) 1.定义 中断控制器可以看作是中断服务的代理,外设五花八门,如果没有一个中断的代理,外设想要给cpu发送中断信号来处理中断。那么只能是外设连接在cpu引脚上,由于cpu引脚很宝贵,所以不可能拿出那么多引脚来供外设连接,所以就有…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...