当前位置: 首页 > news >正文

Unity | Shader基础知识(第十四集:简单效果练习)

目录

前言

一、效果预览

1.弧形边缘光

二、效果制作

1. 制作弧形边缘光

2.弧形边缘光进阶

3.弧形边缘光调节渐变范围

4.边缘光突变

5.同心圆

 三、加入世界坐标做效果

1.绘制结界

2.斑马球

3.效果合并

 四、作者的碎碎念


前言

有粉丝建议说,让我继续更新Shader,我可以出一些简单常用的效果,带着大家写一下,我觉得这是个好主意。

换句话说,带着大家看一下,学到的知识,应该怎么去应用。

我会把常见的调节的一些细致过程逐步写下来,如果遇见没讲过的知识点,就详细讲解一下。

一、效果预览

1.弧形边缘光

这个效果是,对于圆形或者圆弧形的物体,在边缘发光。(如图1所示)

图1 边缘光

二、效果制作

1. 制作弧形边缘光

我们先统一一下思路,发光用到的语义是自发光,之前有讲过,详情看链接。

Unity | Shader基础知识(第十二集:颜色混合)_shade 颜色混合接口-CSDN博客

边缘发光就是当我们的视线和法线的点乘的值在0附近,或0以下的时候,就发光,也是之前讲的,看链接。(如图2所示)Unity | Shader基础知识(第十三集:编写内置着色器阶段总结和表面着色器的补充介绍)_unity viewdir-CSDN博客

图2 viewDir

后面写代码,讲太多遍的就不重新注释了,只注释没讲过的。

Shader "Custom/010"
{Properties{//设置自发光的颜色_Color("Color",Color)=(0,0.5,0.5,0)}SubShader{CGPROGRAM#pragma surface surf Lambertfloat4 _Color;struct Input{//直接获取viewDirfloat3 viewDir;};void surf(Input IN,inout SurfaceOutput o){//点乘后,如果接近1,说明在视线正中,接近0则在视线边缘          half dotp =dot(IN.viewDir,o.Normal);//设置自发光,我们需要当正中时没有颜色,就是*0,在边缘有颜色,就是*1//和上面的数字刚好相反,所以我们用(1-dotp)来得到上面的效果o.Emission =_Color.rgb*(1-dotp);}ENDCG}
}

 得到效果为(如图3所示)

图3 发光球

2.弧形边缘光进阶

大部分模型都是有自己贴图的,所以我们在发光的基础上,加上贴图

Shader "Custom/010"
{Properties{//放图片进入_MainTex("MainTex",2D)="white"{} //设置自发光的颜色_Color("Color",Color)=(0,0.5,0.5,0)}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;float4 _Color;struct Input{float2 uv_MainTex;//直接获取viewDirfloat3 viewDir;};void surf(Input IN,inout SurfaceOutput o){//这都是之前讲过的,不进行二次讲解了o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb;//点乘后,如果接近1,说明在视线正中,接近0则在视线边缘          half dotp =dot(IN.viewDir,o.Normal);//设置自发光,我们需要当正中时没有颜色,就是*0,在边缘有颜色,就是*1//和上面的数字刚好相反,所以我们用(1-dotp)来得到上面的效果o.Emission =_Color.rgb*(1-dotp);}ENDCG}
}

得到的效果为(如图4所示)

图4 弧形边缘光进阶

3.弧形边缘光调节渐变范围

大部分时候,上面的发光范围都是有点大了,所以我们需要加个参数进行调节。

数学知识:

_Color.rgb*(1-dotp)中的(1-dotp)是一个线性变化的数据,变化是平均的,就像数数一样:0.1,0.2,0.3......

我们怎么才能让它的增长变快?前面一直比较小,越往后越大。

有一个非常简单的方法:平方

{0.1^{2}}{0.2^{2}}{0.3^{2}}.......

如果你觉得平方变化不满意,可以是其他次方

 所以我们增加一个参数,来改变光范围。

函数知识:

次方的公式是pow(底数,次方)

Shader "Custom/010"
{Properties{_MainTex("MainTex",2D)="white"{} _Color("Color",Color)=(0,0.5,0.5,0)//边缘光范围参数_Power("Power",Range(0.8,8)) = 3}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;float4 _Color;//接入参数float _Power;struct Input{float2 uv_MainTex;float3 viewDir;};void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb;         half dotp =dot(IN.viewDir,o.Normal);//重新设置范围变化曲线o.Emission =_Color.rgb*pow((1-dotp),_Power);}ENDCG}
}

效果(如图5所示)

图5 弧形边缘光调节渐变范围
4.边缘光突变

截止到上图,虽然我们把边缘光可以锁定在非常边缘,但它的过度还是一个渐变的,如果我希望它不要渐变,而是突然出现,怎么办?

答:做条件判断(但在此之前,为了后面计算方便,我们对数据做一个简单的处理)

我们知道前面的乘积最终结果是(-1,1),但实际我们应用时,小于-1的部分,我们完全不需要,因为都是看不见的部分和0的效果一样。

函数知识:

当数据小于0时,直接取0,当数据大于1时,直接取1,其他数据不变。

saturate()

因为前面的代码没变,这里只复制修改过的代码块。(要么太长了)

    void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; //把小于0的数据都删掉half dotp =saturate(dot(IN.viewDir,o.Normal));o.Emission =_Color.rgb*pow((1-dotp),_Power);}

为了方便计算,我们把(1-dotp)也合并到上面。

    void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; //合并计算half dotp =1-saturate(dot(IN.viewDir,o.Normal));o.Emission =_Color.rgb*pow(dotp,_Power);}

我们可以进行突变判断,当dotp>0.8时,显示边缘光,反之不显示。

    void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; //合并计算half dotp =1-saturate(dot(IN.viewDir,o.Normal));//渐变边缘光(暂时废弃)//o.Emission =_Color.rgb*pow(dotp,_Power);//突变边缘光       //如果大于0.8,就等于1,反之等于0o.Emission =_Color.rgb*dotp>0.8?1:0;}

效果(如图6所示)

图6 突变边缘光

如果你还是希望有一点渐变,不太明显,哈哈~可以自己尝试。

        //有一点渐变o.Emission =_Color.rgb*dotp>0.8?dotp:0;
5.同心圆

同样继续利用这个规律,我们可以做出同心圆。打了注释的地方是有增加,其他地方不变。

Shader "Custom/010"
{Properties{_MainTex("MainTex",2D)="white"{} //外圈颜色_Color("Color",Color)=(0,0.5,0.5,0)//内圈颜色_Color2("Color2",Color)=(0,0.5,0.5,0)_Power("Power",Range(0.8,8)) = 3}SubShader{CGPROGRAM#pragma surface surf Lambertsampler2D _MainTex;//外圈声明float4 _Color;//内圈声明float4 _Color2;float _Power;struct Input{float2 uv_MainTex;float3 viewDir;};void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp =1-saturate(dot(IN.viewDir,o.Normal));//同心圆o.Emission =dotp>0.5?_Color.rgb:_Color2.rgb;}ENDCG}
}

效果(如图7所示)

图7 同心圆

备注:多层同心圆

//多层同心圆                                            //用了个绿色
o.Emission =dotp>0.8?_Color.rgb:dotp>0.5?_Color2.rgb:float4(0,1,0,0);
图8 多层同心圆

 三、加入世界坐标做效果

1.绘制结界

动画片里经常有那种从地底下穿越上来,东西就变色了,这里也可以做这种效果,不过,我们需要先加入世界坐标。

其他的代码还是用之前的,改了改了哪里下面就替换哪部分!!!

    struct Input{float2 uv_MainTex;float3 viewDir;//加入世界坐标float3 worldPos;};

当y>0时,变色~

    void surf(Input IN,inout SurfaceOutput o){o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp =1-saturate(dot(IN.viewDir,o.Normal));//绘制结界o.Emission =IN.worldPos.y>0?_Color:float4(1,1,1,1);}

效果(如图9所示)

图9 结界球
2.斑马球

 我们继续对世界坐标做文章,无论我们球的y坐标是多少,我们把奇数染成白的,偶数染成黑的。

数学知识:

整数位是偶数,除以2,结果的小数位在0~0.5之间

整数位是奇数,除以2,结果的小数位在0.5~1之间

备注:你们可以验证一下

3.2/2=1.6,因为3.2的整数位3是奇数,所以结果的小数位0.6,在0.5~1之间。

函数知识:

取小数的函数。

frac()

例:frac(16.89)=0.89

因为我们的球目前本来就不大,所以我们把y坐标都乘10,然后再计算。

    void surf(Input IN,inout SurfaceOutput o){half dotp =1-saturate(dot(IN.viewDir,o.Normal));//绘制斑马                                    //黑色        //白色o.Emission = frac(IN.worldPos.y*10/2)>0.5?float4(1,1,1,1):float4(0,0,0,0);}

效果(如图10所示)

图10 斑马球
3.效果合并

我们可以把之前的边缘光效果和贴图效果再打开。

    void surf(Input IN,inout SurfaceOutput o){//打开贴图o.Albedo =tex2D(_MainTex,IN.uv_MainTex).rgb; half dotp =1-saturate(dot(IN.viewDir,o.Normal));//绘制斑马o.Emission = frac(IN.worldPos.y*10/2)>0.5?//颜色乘了边缘光那会的数值    
float4(1,1,1,1)*dotp:float4(0,0,0,0)*dotp;}

效果(如图11所示)

图11 效果合并

是不是有那味了~ 

 四、作者的碎碎念

考虑到好多宝宝,学了功能也不知道怎么去用, 专门出了这个简单应用专题,供大家练习。

喜欢的话希望大家给我点赞,收藏加关注哦~ღ( ´・ᴗ・` )比心

相关文章:

Unity | Shader基础知识(第十四集:简单效果练习)

目录 前言 一、效果预览 1.弧形边缘光 二、效果制作 1. 制作弧形边缘光 2.弧形边缘光进阶 3.弧形边缘光调节渐变范围 4.边缘光突变 5.同心圆 三、加入世界坐标做效果 1.绘制结界 2.斑马球 3.效果合并 四、作者的碎碎念 前言 有粉丝建议说,让我继续更新…...

Vue48-ref属性

一、需求:操作DOM元素 1-1、使用原生的id属性 不太好! 1-2、使用 ref属性 原生HTML中,用id属性给元素打标识,vue里面用ref属性。 给哪个元素加了ref属性,vc实例对象就收集哪个元素!!&#xff0…...

【SpringCloud学习笔记】RabbitMQ(中)

1. 交换机概述 前面《RabbitMQ上篇》我们使用SpringAMQP来演示如何用Java代码操作RabbitMQ,当时采用的是生产者直接将消息发布给队列,但是实际开发中不建议这么做,更加推荐生产者将消息发布到交换机(exchange),然后由exchange路由…...

【C++】类和对象的引入

文章目录 前言一、类的定义二、类的访问控制与封装三、类的作用域四、类的实例化五、类的存储方式及大小计算六、隐藏的this指针 前言 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C是基于面向对象的&…...

11.5.k8s中pod的调度-cordon,drain,delete

目录 一、概念 二、使用 1.cordon 停止调度 1.1.停止调度 1.2.解除恢复 2.drain 驱逐节点 2.1.驱逐节点 2.2.参数介绍 2.3.解除恢复 3.delete 删除节点 一、概念 cordon节点,drain驱逐节点,delete 节点,在对k8s集群节点执行维护&am…...

Java中线程的创建方式

一、继承Thread类&#xff0c;重写run方法 public class MyThread{public static void main(String[] args) {Thread threadDome new ThreadDome();threadDome.start();} }class ThreadDome extends Thread{Overridepublic void run() {for (int i 0; i < 5; i) {try {Th…...

猫头虎推荐20个值得体验的通用大模型

猫头虎推荐20个值得体验的通用大模型 &#x1f680; 大家好&#xff0c;我是猫头虎&#xff0c;一名专注于科技领域的自媒体博主。今天是周一&#xff0c;新的开始&#xff0c;我们来深入探讨一下当前最值得体验的通用大模型。这些AI模型不仅功能强大&#xff0c;而且在各自领…...

Novartis诺华制药社招综合能力性格动机问卷入职测评笔试题库答案及包过助攻

【华东同舟求职】由资深各行业从业者建立的一站式人才服务网络平台&#xff0c;现阶段目标是“提升全市场各行业岗位信息的流动性和透明度”。我们接受众多行业机构的直接委托发布&#xff0c;并尽力通过各种方法搜寻高价值岗位信息。事实上&#xff0c;我们以发现不为人知的优…...

Adam优化算法

Adam优化算法 Adam&#xff08;Adaptive Moment Estimation&#xff09;是一种用于训练深度学习模型的优化算法&#xff0c;由Diederik P. Kingma和Jimmy Ba在2014年提出。Adam结合了动量和自适应学习率的方法&#xff0c;具有高效、稳定和适应性强的特点&#xff0c;被广泛应…...

MYSQL 三、mysql基础知识 7(MySQL8其它新特性)

一、mysql8新特性概述 MySQL从5.7版本直接跳跃发布了8.0版本 &#xff0c;可见这是一个令人兴奋的里程碑版本。MySQL 8版本在功能上 做了显著的改进与增强&#xff0c;开发者对MySQL的源代码进行了重构&#xff0c;最突出的一点是多MySQL Optimizer优化器进行了改进。不仅在速度…...

git error: does not have a commit checked out fatal: adding files failed

git add net error: net/ does not have a commit checked out fatal: adding files failed这个错误是因为尝试将一个尚未被提交的文件夹添加到Git中。解决这个问题的方法是先将文件夹中的文件提交到Git仓库中&#xff0c;然后再将文件夹添加到Git中。 首先&#xff0c;需要进…...

Java Websocket分片发送

一、分片发送和接收(复杂) 如果数据量太大&#xff0c;需要分多次发送&#xff0c; 需要考虑数据划分和重组的问题。 二、具体思路 每次发送和接收用一个布尔值变量指定是否为最后一个分片。 三、具体使用 (一)字符串分片发送&#xff1a; sendText(文本&#xff0c; 布尔值)…...

vivado NODE、PACKAGE_PIN

节点是Xilinx部件上用于路由连接或网络的设备对象。它是一个 WIRE集合&#xff0c;跨越多个瓦片&#xff0c;物理和电气 连接在一起。节点可以连接到单个SITE_&#xff0c; 而是简单地将NETs携带进、携带出或携带穿过站点。节点可以连接到 任何数量的PIP&#xff0c;并且也可以…...

JavaEE、SSM基础框架、JavaWeb、MVC(认识)

目录 一、引言 &#xff08;0&#xff09;简要介绍 &#xff08;1&#xff09;主要涉及的学习内容 &#xff08;2&#xff09;学习的必要性 &#xff08;3&#xff09;适用学习的人群&#xff08;最好有这个部分的知识基础&#xff09; &#xff08;4&#xff09;这个基础…...

【漏洞复现】飞企互联-FE企业运营管理平台 treeXml.jsp SQL注入漏洞

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外&#xff0c;支持企业B2B、C2B与020等核心需求&#xff0c;为不同行业客户的互联网转型提供支持。其特色在于提供…...

Android基础-运行时权限

一、引言 随着智能手机和移动互联网的普及&#xff0c;Android操作系统作为其中的佼佼者&#xff0c;其安全性问题日益受到关注。为了保障用户数据的安全和隐私&#xff0c;Android系统引入了权限机制来管理和控制应用程序对系统资源和用户数据的访问。特别是在Android 6.0&am…...

postman断言及变量及参数化

1&#xff1a;postman断言 断言&#xff1a;判断接口是否执行成功的过程 针对接口请求完成之后&#xff0c;针对他的响应状态码及响应信息进行判断,代码如下&#xff1a; //判断响应信息状态码是否正确 pm.test("Status code is 200", function () { pm.response.…...

安装和使用TrinityCore NPCBot

安装TrinityCore NPCBot 官网&#xff1a;GitHub - trickerer/Trinity-Bots: NPCBots for TrinityCore and AzerothCore 3.3.5 基本安装方法 Follow TrinityCore Installation Guide (https://TrinityCore.info/) to install the server firstDownload NPCBots.patch and put …...

Hvv--知攻善防应急响应靶机--Linux2

HW–应急响应靶机–Linux2 所有靶机均来自 知攻善防实验室 靶机整理&#xff1a; 夸克网盘&#xff1a;https://pan.quark.cn/s/4b6dffd0c51a#/list/share百度云盘&#xff1a;https://pan.baidu.com/s/1NnrS5asrS1Pw6LUbexewuA?pwdtxmy 官方WP&#xff1a;https://mp.weixin.…...

replaceAll is not a function 详解

先说说原因&#xff1a; 在chrome 浏览器中使用 replaceAll 报这个错误&#xff0c;是因为chrome 版本过低&#xff0c; 在chrome 85 以上版本才支持 用法 replaceAll(pattern, replacement)const paragraph "I think Ruths dog is cuter than your dog!"; console…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...