Unity | Shader基础知识(第二十二集:两次渲染)
目录
一、前言
二、“渲染两次”
三、本次成品介绍
四、第一次渲染代码
五、第二次渲染代码
六、截止目前的所有代码
七、调整代码
八、总结
一、前言
之前一直讲的shader文件中,都只写了一次CG代码。
为了大家对这部分的整体理解,我们这次渲染两次。
二、“渲染两次”
这个词是我造的~不是定义。
什么叫渲染两次?
渲染就是画画的意思,渲染两次就是画两次。这里用画画举例。
第一次画画。(如图1所示)
这里如果用文字描述一下,就是画了一个绿色的三角形。
第二次画画。(如图2所示)
如果用语言形容就是,在中间画了一个橘黄色的圆形。
所以我们一套结构CG结构就是画了一幅画。(如图3所示)
不用太在意具体写的什么代码,主要注意一些标志
CGPROGRAM前面是一些准备工作,像之前的模版写入,深度写入之类的。
ENDCG就是结束了绘制
中间就是一些绘制过程,引入一些材料。
这个全过程就是一次画画的全过程。
渲染两次的意思是,我可以在一个shader文件中写两套这个东西。
三、本次成品介绍
我们这次先画一个模型的黑影,但是这个黑影要比模型本身大一点。这个做法参考上节课的代码。
Unity | Shader基础知识(第二十一集:应用-怪兽膨胀、顶点着色器和表面着色器合并)_unity 顶点膨胀shader-CSDN博客
然后再正常把模型渲染上去,就可以给模型做一个阴影或者说边框。(如图4所示)
四、第一次渲染代码
我们第一次先画一个模型的黑影(如图4所示),
备注:模型还是用上节课的模型。代码还是用的上节课的思路。
Properties{//模型的贴图_MainTex ("Texture", 2D) = "white" {}//边框的大小(膨胀的大了,边框就大,反之就小)_Outline ("Outline Width", Range(0.002,0.1)) = 0.005//边框的颜色,我们要做黑影,所以就先来个黑色_OutlineColor ("Outline Color", Color) = (0,0,0,1)}SubShader{CGPROGRAM//引用,同上一集#pragma surface surf Lambert vertex:vert//承接上面素材,略sampler2D _MainTex;float4 _OutlineColor;float _Outline;void vert(inout appdata_full v){//让原本的顶点在法线的方向上增加一点位置,这样影子就会变大v.vertex.xyz += v.normal * _Outline;}//其实目前代码里都没用到,但因为用了表面着色器,必须写struct Input{float2 uv_MainTex;};void surf(Input IN,inout SurfaceOutput o){//我们把颜色直接给到自发光//备注:这里给到贴图也是可以的,但自发光要更亮一点,可以自己试o.Emission = _OutlineColor.rgb;}ENDCG}
这样我们第一次渲染就画好了。
五、第二次渲染代码
到了ENDCG以后,就是这次画已经画完了,接下来我们再画模型真正的样子。
第二次不需要膨胀,所以顶点那部分就不用加了,直接把颜色上上去。这部分讲太多遍了,就不详解了。
CGPROGRAM#pragma surface surf Lambert struct Input{float2 uv_MainTex;};sampler2D _MainTex;void surf(Input IN, inout SurfaceOutput o){o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;}ENDCG}
六、截止目前的所有代码
Shader "Unlit/019"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Outline ("Outline Width", Range(0.002,0.1)) = 0.005_OutlineColor ("Outline Color", Color) = (0,0,0,1)}SubShader{//第一套渲染-------------------------------------CGPROGRAM#pragma surface surf Lambert vertex:vertstruct Input{float2 uv_MainTex;};sampler2D _MainTex;float4 _OutlineColor;float _Outline;void vert(inout appdata_full v){v.vertex.xyz += v.normal * _Outline;}void surf(Input IN,inout SurfaceOutput o){o.Emission = _OutlineColor.rgb;}ENDCG//第二套渲染--------------------------------------CGPROGRAM#pragma surface surf Lambert struct Input{float2 uv_MainTex;};sampler2D _MainTex;void surf(Input IN, inout SurfaceOutput o){o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;}ENDCG}
}
到这里我只是想证明给你们,渲染可以在后面加的,并不是只能写在那一个里面。
七、调整代码
到现在为止,我们渲染出来的结果。(如图5所示)
这并不是我们想要的样子,为什么会都是黑色,因为黑色部分是膨胀的,比彩色的大,所以被藏在里面了。(如图6所示)你可以通过增加膨胀的系数在缝隙里面看见。
解决方案:把深度写入关掉。
不管是你在外面还是里面,都画出来。
代码如下。(如图7所示)
到这里一步我们就可以得到(如图8所示)
但是下一步的麻烦就是,我把模型背面也渲染出来了。
解决方案:在渲染黑色自发光时,关掉深度写入,在渲染模型时(第二次画画时),打开深度写入。(如图9所示)

这样我们就可以得到我们想要的结果了。
八、总结
本节想表达的重点:
1.渲染可以写好几次
2.每次渲染之前,可以去调节后面渲染的一些方式。本次案例用深度写入为例子。
相关文章:
Unity | Shader基础知识(第二十二集:两次渲染)
目录 一、前言 二、“渲染两次” 三、本次成品介绍 四、第一次渲染代码 五、第二次渲染代码 六、截止目前的所有代码 七、调整代码 八、总结 一、前言 之前一直讲的shader文件中,都只写了一次CG代码。 为了大家对这部分的整体理解,我们这次渲…...
鸿蒙Harmony实战开发:Arkts构造函数
构造函数 类声明可以包含用于初始化对象状态的构造函数。 构造函数定义如下: constructor ([parameters]) {// ... } typescript 如果未定义构造函数,则会自动创建具有空参数列表的默认构造函数,例如: class Point {x: numbe…...
@vueuse/core使用useColorMode实现主题颜色切换
useColorMode 是一个在前端开发中常用的自定义钩子(Hook),尤其在需要支持深色模式和浅色模式切换的场景下。这个钩子可以根据用户的选择或系统设置动态调整页面样式。 一、安装和引入 npm install vueuse/core # 或者 yarn add vueuse/…...
生信分析入门:从基础知识到实践操作的全方位指南
随着生物学研究的数字化转型,生物信息学(简称生信)分析已经成为现代生命科学研究中的关键工具。对于刚开始接触生信分析的初学者来说,这个领域可能看起来复杂而陌生。然而,通过系统的学习和实践,生信分析可…...
【STM32 FreeRTOS】内存管理
除了FreeRTOS提供的动态内存管理方法,标准的C库也提供了函数malloc()和函数free()来实现动态的申请和释放内存。 为啥不用标准的C库自带的内存管理算法?因为标准C库的动态管理方法有如下缺点: 占用大量的代码空间,不适合用在资源…...
vue3+vite+cesium配置参考
在vite项目中使用Cesium的配置 关键: 资源目录的复制;CESIUM_BASE_URL的正确配置 //vite.config.js // ... // 安装打包复制资源插件,手动复制不需要 // npm i vite-plugin-static-copy import { viteStaticCopy } from vite-plugin-static-c…...
WEB应用服务器TOMCAT
知识点 一 、WEB技术 1、前端三大核心技术 1.1 HTML HTML ( HyperText Markup Language )超文本标记语言,它不同于一般的编程语言。超文本 即超出纯文本的范畴,例如:描述文本颜色、大小、字体等信息,或使…...
maven打包jar后运行提示“没有主清单属性”问题的几种解决方案
常用的几种maven项目打包后,jar运行提示“没有主清单属性”问题的解决方案,大部分都是要修改pom.xml文件,同时有几种自己常用的配置文件,主要供自用,勿喷。 第一种: <build><plugins><plug…...
计算机毕业设计选题推荐-民宿可视化分析-Python爬虫-随机森林算法
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...
WKWebView加载项目中网页的资源图片路径异常
问题原因,将含有html的文件通过如下方式引入到工程中: 这种处理方式,当应用程序变以后,引入的文件会被全部放在Resources目录下,而忽略你原本的文件路径信息。因此导致出问题。 解决方案: 采用如下方式引…...
算法全面剖析
算法 查找算法: 顺序查找: 基本思想: 顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功&am…...
tp5php7.4配置sqlserver问题汇总
先修改database.php文件 查看php版本选择sqlserver扩展 通过百度网盘分享的文件:sqlserver 链接:https://pan.baidu.com/s/1zrIV8VWQZM9miLpyH01Aww?pwdxdgx 提取码:xdgx 通过我的分享链接复制自己需要的dll到php的ext下 在php.ini里添加扩…...
C语言随笔:字面量
字面量(Literal)是指程序源代码中直接写出的固定值。字面量用于表示数据常量,它们在程序编译时被直接解析并用于程序运行。 常见的字面量类型 整数字面量(Integer Literals) 描述:表示整数值。示例&#x…...
chainlit的基本概念聊天对话中的元素
文本消息是聊天机器人的组成部分,但我们通常希望向用户发送的不仅仅是文本,还包括图像、视频等。 这就是元素出现的地方。每个元素都是一段内容,可以附加到Message或Step 并显示在用户界面上。 chainlit支持的元素如下: 文本元…...
【LeetCode:3】无重复字符串的最长子串(Java)
题目链接 3. 无重复字符串的最长子串 题目描述 给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: s “bbb…...
C#对字典使用Linq查询
Dictionary<int, int> dic new Dictionary<int, int>();dic.Add(1, 2);dic.Add(2, 3);dic.Add(3, 4);dic.Add(4, 5);dic.Add(5, 6);//筛选键var keys dic.Where(item > item.Key > 2).Select(item > item.Key);foreach (var item in keys){Console.Writ…...
【Vue】Vue基础
系列文章目录 第二章 Vue基础(1) 文章目录 系列文章目录第一节:Vue介绍一、Vue介绍二、Vue项目创建三、项目结构介绍 第二节:组合式API一、基本介绍二、setup介绍三、setup上指定组件名称 第三节:响应式变量一、使用r…...
贪心 + 分层图bfs,newcoder 76652/B
目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 https://ac.nowcoder.com/acm/contest/76652/B 二、解题报告 1、思路分析…...
如何在Linux上部署Java Web应用程序
在Linux上部署Java Web应用程序是一个常见的任务,本文将介绍一种常用的方法,分为以下几个步骤: 准备服务器 首先,你需要准备一台运行Linux操作系统的服务器。你可以选择使用各种不同的Linux发行版,如Ubuntu、CentOS等…...
SpringBoot 整合 Excel 轻松实现数据自由导入导出
01、背景介绍 在实际的业务系统开发过程中,操作 Excel 实现数据的导入导出基本上是个非常常见的需求。 之前,我们有介绍一款非常好用的工具:EasyPoi,有读者提出在数据量大的情况下,EasyPoi 会占用内存大,…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
