钢铁侠材质制作——2、线条轮廓部分的制作

news/2024/4/28 9:38:40/文章来源:https://blog.csdn.net/liweizhao/article/details/130031679

钢铁侠Unlit光照Shader,三种效果变化


返回目录

大家好,我是阿赵,这里是钢铁侠材质制作第二部分,线条轮廓部分的制作
在这里插入图片描述

为了实现这个效果,可以把细节拆分成以下几个部分:

1、轮廓光

在这里插入图片描述

1.效果分析

这是一个很基础的轮廓光实现,用到的就是法线和观察方向的点乘(NdotV)。

2.shader实现

Shader "azhao/IronManBodyCode"
{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);half4 col = _RimlCol* fresnelVal;return col;}ENDCG}}
}

3.说明

这个其实就是菲涅尔的标准算法,在1-NdotV后,乘以一个bias值控制边缘光的强度,再计算一个Pow运算,控制边缘光的边缘厚度。

2、添加横纹

在这里插入图片描述

1.效果分析

看到这个效果,可能很多人都在考虑怎样画这个横纹的贴图。其实这个实现方式很巧妙,只需要一张Noise噪声图就可以了。

2.shader实现

Shader "azhao/IronManBodyCode"
{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)_NoiseMap("NoiseMap",2D) = "black"{}_NoiseTiling("NoiseTiling",Vector) = (1,1,0,0)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;sampler2D _NoiseMap;float4 _NoiseTiling;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);float2 noiseUV = i.worldPos.xy *_NoiseTiling.xy + _NoiseTiling.zw;float4 noiseCol = tex2D(_NoiseMap, noiseUV);half4 col = _RimlCol * (fresnelVal+noiseCol.r);return col;}ENDCG}}
}

3.说明

这里多添加了一张Noise贴图
在这里插入图片描述

由于我们想要的横纹是永远水平于世界空间,并不是希望会随着角色的动作而变形的,所以我这里并没有使用模型本身的UV坐标来采样,而是使用了模型的顶点世界坐标的xy坐标来模拟了UV坐标,并且添加了一个Tiling值来控制Noise贴图的平铺次数。

如果不调整参数的情况下,添加Noise到材质球,会看到下面的效果。
在这里插入图片描述

虽然这个效果看起来也很cool,但并不是我想要的效果,所以再调整一下Tiling值
在这里插入图片描述

把平铺y值调大,这个时候,就可以看到,Noise图就变成了横纹了。
在这里插入图片描述

3、横纹动画

我希望在显示这个光线轮廓的过程中,身上的横纹是有一个慢慢上升的动画效果的
这个实现起来很简单,只需要给Noise图的uv做一个偏移就可以了,这里用到了_Time,根据时间来让UV偏移。
float2 noiseUV = i.worldPos.xy _NoiseTiling.xy + _NoiseTiling.zw;
noiseUV.y += frac(_Time.y)
_NoiseSpeed;
这里还加了一个frac函数,frac函数的作用是去掉数值的整数部分只保留小数部分。由于某些设备的数值精度支持范围有问题,如果_Time不停的累加,达到很大的值时,可能会出问题。所以加一个frac函数让它的值只使用小数部分。

4、完整shader

Shader "azhao/IronManBodyCode"
{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)_NoiseMap("NoiseMap",2D) = "black"{}_NoiseTiling("NoiseTiling",Vector) = (1,1,0,0)_NoiseSpeed("NoiseSpeed",float) = 0}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 worldPos :TEXCOORD0;float3 worldNormal : TEXCOORD1;};float _RimBias;float _RimPow;float4 _RimlCol;sampler2D _NoiseMap;float4 _NoiseTiling;float _NoiseSpeed;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}half4 frag (v2f i) : SV_Target{float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);float2 noiseUV = i.worldPos.xy *_NoiseTiling.xy + _NoiseTiling.zw;noiseUV.y += frac(_Time.y)*_NoiseSpeed;float4 noiseCol = tex2D(_NoiseMap, noiseUV);half4 col = _RimlCol * (fresnelVal+noiseCol.r);return col;}ENDCG}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283660.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C生万物 | 十分钟带你学会位段相关知识

结构体相关知识可以先看看这篇文章 —— 链接 一、什么是位段 位段的声明和结构是类似的,有两个不同: 位段的成员必须是 int、unsigned int 或signed int位段的成员名后边有一个冒号和一个数字 在下面,我分别写了一个结构体和一个位段&…

手动构建自己的docker容器镜像实战

前言 之前的实战中,我们实战中,我们使用的镜像都是镜像仓库已有的镜像。 已有的镜像都是别人已经开发好上传的。今天我们一起来看看如何构建自己的镜像并上传到镜像仓库中。 🏠个人主页:我是沐风晓月 🧑个人简介&…

【Python】字符串 ⑤ ( Python 字符串快速格式化 | 不考虑变量类型 | 不考虑精度控制 )

文章目录一、Python 字符串快速格式化1、语法说明2、代码示例 - 不考虑变量类型3、代码示例 - 不考虑精度控制4、快速格式化的优点一、Python 字符串快速格式化 1、语法说明 Python 字符串快速格式化 : 通过如下格式的代码 , 可以进行字符串的快速格式化 ; f"字符串内容{…

vscode代码片段生成

在刚学习vue的时候,有些代码片段是经常写的,在vscode中写一个代码片段可以帮助快速生成。 生成步骤: VSCode中的代码片段有固定的格式,所以我们一般会借助于一个在线工具来完成。 具体的步骤如下: 第一步,复制自己需…

〖Python网络爬虫实战⑨〗- 正则表达式基本原理

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,目前专栏免费订阅,在转为付费专栏前订阅本专栏的,可以免费订阅付…

Mac PicGo可以上传GitHub但是不能显示

Mac PicGo可以上传到GitHub但是本地不能显示(已经加载的)图片 背景:使用Typora PicGo GitHub 图床。 文章目录Mac PicGo可以上传到GitHub但是本地不能显示(已经加载的)图片1. Bug表现2. 解决方法(1&…

【好书推荐】认知觉醒:开启自我改变的原动力

书籍信息 书名:认知觉醒:开启自我改变的原动力 作者: 周岭 出版社: 人民邮电出版社 认知觉醒的基础 重新认识大脑 在我们的大脑里,由内到外至少有三重大脑:年代久远的本能脑、相对古老的情绪脑和非常年…

【C语言深入】逐汇编详解函数栈帧的创建和销毁过程

【C语言深入】逐汇编详解函数栈帧的创建和销毁过程一、图解大概过程二、函数栈帧的创建过程1、简介一些需要用到的汇编指令和寄存器2、调用main函数的函数3、局部变量的初始化4、形成临时拷贝5、函数调用6、形成栈帧7、提取临时拷贝8、return返回三、函数栈帧的销毁过程1、释放…

python:异常处理与文件操作(知识点详解+代码展示)

文章目录一、异常处理1、try...except语句2、finally语句二、断言1、定义2、举例例一:例二:三、文件操作1、写文件操作2、读文件操作(当你心情低落时候,记得外面还有美好的风景!) 学习目标: 1、…

堆相关的面试题

文章目录1. 距离不超过k的推排序2. 最大线段重合问题1. 距离不超过k的推排序 题目:已知一个几乎有序的数组。几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离一定不超过k,并且k相对于数组长度来说是比较小的。 请选择一…

WinRAR压缩解压文件

使用WinRAR压缩管理器压缩解压文件详细步骤如下: ■ 压缩文件 ① 鼠标右键需要压缩的文件,点击“添加到压缩文件”,具体操作步骤如图所示: ② 压缩后的对应文件压缩包会显示在桌面,如图所示: ■ 解压文件 …

如何设计一个高并发系统

目录 如何理解高并发系统 1. 分而治之,横向扩展 2. 微服务拆分(系统拆分) 3. 分库分表 4. 池化技术 5. 主从分离 6. 使用缓存 7. CDN——加速静态资源访问 8. 消息队列——削锋 9. ElasticSearch 10. 降级熔断 11. 限流 12. 异步…

【OpenLayers】VUE+OpenLayers+ElementUI加载WMS地图服务

【OpenLayers】VUEOpenLayersElementUI加载WMS地图服务准备工作安装vue创建vue项目安装OpenLayers安装ElementUI加载wms地图服务准备工作 需要安装好nodejs,nodejs下载地址,下载对应的版本向导式安装即可。 安装完成后,控制台输入node -v&a…

【CentOS 7安装MySQL 8的教程指南】

CentOS 7安装MySQL 8 添加MySQL官方源 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm sudo rpm -ivh mysql80-community-release-el7-3.noarch.rpm安装MySQL 8 sudo yum install mysql-community-server安装失败执行下面的命令并再次执行安装…

进程与线程的区别和联系

进程与线程的区别和联系🔎进程🔎线程🔎进程与线程的联系🔎进程与线程的区别🔎总结🔎 结尾🔎进程 进程简单来说就是运行着的程序 如果不太理解可以参考一下这篇文章 进程 🔎线程 …

【MySQL--01】数据库基础

文章目录1.什么是数据库2.主流数据库2.1 MySQLMySQL架构实例3.基本使用3.1 MySQL的安装3.2 连接服务器3.3服务器管理4.服务器,数据库,表之间的关系5.使用数据库6.SQL分类7.存储引擎查看存储引擎存储引擎对比1.什么是数据库 数据库是用来存储数据的。那么…

Java BigDecimal学习

文章目录Java BigDecimal不损失精度的方法Java BigDecimal的几种舍入模式1、UP(BigDecimal.ROUND_UP)2、DOWN(BigDecimal.ROUND_DOWN)3、CEILING(BigDecimal.ROUND_CEILING)4、FLOOR(BigDecimal.ROUND_FLOOR)5、HALF_UP(BigDecimal.ROUND_HALF_UP)6、HALF_DOWN(BigDecimal.ROUN…

QMake宏定义常量和字符串或带空格的字符串(在代码中使用)

答案 宏定义常量 DEFINES EXPIR_TIME123宏定义字符串(不带空格) DEFINES NIHAO\\\"nihao\\\"宏定义字符串(带空格也适用于不带空格的情况) 推荐 DEFINES NIHAO\"\\\"ni" "hao\\\"\"QMAKE宏定义常量 环境: visual studio 2018 …

Java基础之List

文章目录一、List介绍二、List常用方法 List应知应会2.1 调用add()方法增添数据(可指定位置添加)2.2 调用remove()方法删除指定位置元素并返回被删除元素2.3 调用set()方法修改指定位置元素并返回初始数据2.4 调用get()方法返回指定位置元素三、List可重…

SQL注入写入文件方法(获取webshell)

数据库写入文件条件 1、当前数据库用户为 root 权限2、知道当前网站的绝对路径3、secure_file_priv 的参数必须为空或目录地址4、PHP的 GPC 为 off状态;(魔术引号,GET,POST,Cookie)用 sqli-labs 测试查看当前用户权限Python sqlma…