Unity渲染(二):Shader着色器基础入门之渲染Image图片

article/2025/7/19 8:50:50

Unity渲染(二):图片渲染

通过这里,你会学习到怎么将一张图片渲染到UI的Image组件或者SpriteRenderer上,以及透明物体的渲染。

上一章:Unity渲染(一):着色器基础入门之纯色Shader

开发环境:Unity5.0或者更高


在这里插入图片描述

透明与不透明的最终效果

概述

1. Shader获取Image或者SpriteRenderer组件上的sprite
2. 图像采样
3. 透明物体渲染

1.1 开始

  • 创建场景并取名为Image并在场景中添加CameraImage2D Sprite Square

在这里插入图片描述

  • 创建MaterialShader 并在删除Shader中自带的代码写下如下代码

在这里插入图片描述

Asset 目录

代码解释:Unity渲染(一):着色器基础入门之纯色Shader

Shader "Toturial/Image"
{Properties{_MainTex("MainTex",2D) = "white"{}_Color("Color",Color) = (1,1,1,1)}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag fixed4 _Color;struct a2v{float4 vertex : POSITION;fixed4 color : COLOR;};struct v2f{float4 pos : SV_POSITION;fixed4 color : COLOR;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;return o;}fixed4 frag(v2f i) : SV_TARGET{return _Color;}ENDCG}}
}
  • 将材质给Image与SpriteRenderer 赋值
  • 将以下两张图给Image和SpriteRenderer设置

请添加图片描述

图1

请添加图片描述

图2

因为Shader最终返回白色所以 效果下图

在这里插入图片描述

效果图

接下来我们修改代码让图像显示出来。


1.2 图像采样

首先我们在CGPROGRAM ... ENDCG 中定义一个Sampler2D 类型的变量_MainTex用于获取Properties中的属性_MainTex,两者名称需要相同,这是Unity规定的,Properties类型与CGPROGRAM类型对应关系如下

PropertiesCGPROGRAM
Colorfloat4、half4、fixed4
Range、Floatfloat、half、fixed
2Dsampler2D
3Dsampler3D
CubesamplerCube

在struct a2v 上方添加如下代码:

...
sampler2D _MainTex;
...

接下来我们需要获取这个sampler2D上的每个像素颜色,最终从片元着色器输出,是怎么做到这步的呢?
首先我们需要获取到这张图像的UV,然后使用这个UV坐标对这个sampler2D 进行采样查询每个点的颜色最终输出。
上面这个过程我们可以使用tex2D(_MainTex,UV)函数来达到我们的目的

UV:可以理解为这张图像的每个像素点在屏幕上的坐标

  1. 我们在a2v结构体中添加float2 uv : TEXCOORD0; 用于获取Properties定义的第一个sampler2D的坐标,
...
struct a2v
{float4 vertex : POSITION;fixed4 color  : COLOR;float2 uv     : TEXCOORD0;
};
...
  1. 在 v2f结构体中添加float2 uv : TEXCOORD0;用于在顶点着色器将uv传递到片元着色器使用
...
struct v2f
{float4 pos   : SV_POSITION;fixed4 color : COLOR;float2 uv    : TEXCOORD0;
};
...
  1. 在vert函数中为v2f赋值,添加代码
...
v2f vert(a2v v)
{v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;o.uv = v.uv;return o;
}
...
  1. 修改frag函数的返回值为tex2D(_MainTex,i.uv);
...
fixed4 frag(v2f i) : SV_TARGET
{return tex2D(_MainTex,i.uv);
}
...

回到Unity发现第二张有透明部分的图片出现了异常

在这里插入图片描述

效果如图

1.3 透明物体渲染

首先我们先让图片正常渲染,在Pass中添加如下代码

Pass
{Blend SrcAlpha OneMinusSrcAlpha
...

回到Unity 看到结果已经正常了
在这里插入图片描述

代码说明

Shader混合模式: Blend SrcAlpha OneMinusSrcAlpha,用于将当前要渲染的颜色(挂上此Shader的物体)与已经渲染的颜色(叫背景或者叫颜色缓冲区)进行混合,最终输出到屏幕上
当要渲染的物体的像素是不透明时,alpha值取要渲染的物体的alpha
当要渲染的物体的像素时全透明时,alpha值取颜色缓冲区的颜色的alpha
当要渲染的物体的像素时半透明时,alpha值取要渲染的物体的alpha,颜色取
缓冲区颜色*要渲染的物体alpha +要渲染的物体颜色*(1-要渲染物体的alpha )
例如有一个半透明红色的点Color(1,0,0,0.8),背景为不透明的蓝色Color(0,0,1,1)
则最终颜色=(1,0,0) 0.8 +(0,0,1)(1 - 0.8) = (0.8,0,0.2)

1.4 完整代码

Shader "Toturial/Image"
{Properties{_MainTex("MainTex",2D) = "white"{}_Color("Color",Color) = (1,1,1,1)}SubShader{Pass{Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag fixed4 _Color;sampler2D _MainTex;struct a2v{float4 vertex : POSITION;fixed4 color  : COLOR;float2 uv     : TEXCOORD0;};struct v2f{float4 pos   : SV_POSITION;fixed4 color : COLOR;float2 uv    : TEXCOORD0;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.color = v.color;o.uv = v.uv;return o;}fixed4 frag(v2f i) : SV_TARGET{return tex2D(_MainTex,i.uv);}ENDCG}}
}

http://chatgpt.dhexx.cn/article/Y8OsRWNQ.shtml

相关文章

unity 渲染性能分析工具

目标 既然要优化,肯定要有个目标: pc上一般要求:一秒渲染60帧 移动端:一秒渲染30帧 这应该是最低的要求,如果游戏运行时,游戏帧率有变化,人眼能够明显的感觉到帧率下降。 优化的首要规则是找到…

unity 渲染环境设置

环境光分为两种,一种是环境光漫反射SH(球谐光照),另一种是环境光的镜面反射IBL(基于图像的渲染)。 光照的配置位置可以在 窗口 -> 渲染 -> 光照 打开。 环境照明对应的就是环境漫反射,环…

【流程向】模型复原与Unity渲染

项目简述 简单记录下学校里的一个项目,涉及到对/何家村遗宝/的模型复原,记录一下模型制作的全流程,同时涉及到Unity中一些优化画面的技术点。项目中渲染效果优先,没有怎么考虑性能。 流程:Blender高低模与展UV ->…

Unity中的物体渲染顺序

big seven 文章目录 前言 一、摄像机渲染 二、划分渲染队列 三、不透明物体的渲染 四、透明物体的渲染 五、UGUI元素的渲染 总结 前言 Unity中物体的渲染顺序 提示:以下是本篇文章正文内容,下面案例可供参考 一、摄像机渲染 Unity中的渲染顺序首先是…

Unity渲染流程概述

本篇的任务是回答:在Untiy的渲染流程中CPU和GPU分别做了什么。 渲染到设备屏幕显示的每一帧的画面,都经历几个阶段的加工过程: 应用程序阶段(CPU):识别出潜在可视的网格实例,并把他们及其材质…

Unity_渲染_灯光_前向渲染

前向渲染路径 前向渲染的作用和意义场景内有多个灯光,如何渲染每个灯光对物体的影响 前向渲染的作用和意义 前向渲染的作用:处理多光源的渲染,多光源渲染在unity 有2中渲染方式 前向渲染和延时渲染 .延时渲染主要用于主机,PC平台,不在本次讨论范围.主要来研究前向渲染前向渲染…

【Unity渲染】前向渲染和延迟渲染的区别及切换

前向渲染和延迟渲染通道的区别,主要在对于光源的处理上。 Unity默认是前向渲染通道,如果光源特别多,可以使用延迟渲染。 前向渲染 使用前向渲染路径时,被照亮的对象将在单独的通道中进行渲染。根据场景中的光源数量以及它们是否…

从FrameDebugger看Unity渲染

从FrameDebugger看Unity渲染(一) Unity如何渲染一个3D2D的游戏画面,今天通过FrameDebugger来看下Unity内置渲染管线的渲染策略, 后续再出一些URP渲染管线相关的文章。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白&#xff0c…

UnityShader入门精要——Unity中的渲染优化技术(二)

减少DrawCall数目 最常见的优化技术——批处理。实现原理为减少渲染每一帧所需的drawcall数目。使用同一个材质的物体可以一起处理。 优点缺点动态批处理切处理都是Unity 自动完成的,不需要我们自己做任何操作,而且物体是可以移动的限制很多&#xff0c…

Unity渲染顺序(2)

Camera 除了Screen Space - Overlay(屏幕空间覆盖模式)下的Canvas,场景中的其他物体需要渲染到屏幕中,都需要在指定的相机的绘制下。场景中可以创建多个相机,每个相机所拍摄的内容可能并不相同,在场景中有多相机的情况,不同的相机…

Unity渲染顺序(1)

添加排序层级 在Unity编辑器的右上角选择Layers 按钮,在下拉菜单中点击Edit Layers…选项,将显示当前Unity的Tags, Sorting Layers,和Layers 编辑选项。 Sorting Layers是Unity中对排序的层级的定义块,在面板中越靠后的排序层级越…

Unity的渲染流程

Unity中坐标空间的转换: Unity的渲染流程: 渲染到设备屏幕的每一帧画面都要经历如下几个阶段: 应用程序阶段(CPU):将材质和模型数据发送给GPU 几何阶段(GPU):进行顶点…

Unity 渲染原理

1 渲染流程 应用程序阶段(CPU):识别出潜在可视的网格实例,并把他们及其材质提交给 GPU 以供渲染。几何阶段(GPU):进行顶点变换等计算,并将三角形转换到齐次空间并进行裁剪。光栅化阶…

Unity标准化的场景渲染流程

笔者用的unity版本为2020.3.30f1c1,开一个HDRP模板场景,OK开始我们的操作。 第一步:删除场景中的所有东西只留下竹林玻璃房作为展示场景,将所有物体勾选Static,新增一个摄像机,如下图: 第二步&a…

Unity3D性能优化——渲染篇

大渣好,我又来了。 之前的文章中,我们了解了Profiler工具,以及在实际项目中unity的CPU优化分析及方法,本文我们主要了解在我们的项目中GPU的性能分析,以及对GPU性能进行优化的相关技术。 渲染优化 在了解优化渲染前&a…

Unity中的灯光和渲染

一:Unity中的灯光 ——Directional Light:模拟太阳光。它与位置无关,是平行光,可以调整旋转角度模拟昼夜 ——Spot Light:模拟车灯、手电筒的光、舞台灯光 ——Point Light:模拟灯泡 ——Area Light&#…

execv 函数的应用

execv函数族:系统来调用某程序模块 int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char * const envp[]); int ex…

Linux 0.11-execve函数-35

Linux 0.11-execve函数-35 execve函数读取文件开头 1KB 的数据解析这 1KB 的数据为 exec 结构判断是脚本文件还是可执行文件准备参数空间设置 eip 和 esp,完成摇身一变累了吧,休息会 转载 execve函数 书接上回,上回书咱们说到,进…

Linux内核Hook系统调用execve

资源下载地址:linux内核hook系统调用execve函数-Linux文档类资源-CSDN下载 (已在内核为 4.19.0-amd64-desktop版本uos编译通过,并成功达到目的) 在Linux系统中,用户层程序无法直接控制系统内核,只能通过系…

执行新程序 execve()

新程序的执行 一:execve() 之所以叫新程序的执行,原因是这部分内容一般发生在fork()和vfork()之后,在子进程中通过系统调用execve()可以将新程序加载到子进程的内存空间。这个操作会丢弃原来的子进程execve()之后的部分,而子进程…