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

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 OneMinusSrcAlpha
            CGPROGRAM
            
            #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
        }
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中,Shader是用来定义物体表面的着色和渲染效果的一种程序。在Unity5.2及以上的版本中,Unity提供了四种Shader模板供我们选择。其中,Standard Surface Shader会产生一个包含了标准光照模型的表面着色器模板;Unity Shader会产生一个不包含光照(但包含雾效)的基本顶点/片元着色器Image Effect Shader为我们实现各种屏幕后处理效果提供一个基本模板;Computer Shader则产生一种特殊的Shader文件,用于进行一些与常规渲染流水线无关的计算。一个单独的Unity Shader不能单独发挥作用,必须要和材质结合起来使用。 每一个Unity Shader文件可以包含多个SubShader语义块,但最少要有一个。当Unity需要加载一个Unity Shader时,会扫描所有的SubShader语义块,然后选择第一个能够在目标平台上运行的SubShader。如果都不支持的话,Unity会使用Fallback语义指定的Unity Shader。这是因为不同的显卡具有不同的能力,一些旧的显卡仅能支持一定数目的操作指令,而一些更高级的显卡可以支持更多的指令数。因此,我们希望在旧的显卡上使用计算复杂度较低的着色器,而在高级的显卡上使用计算复杂度较高的着色器,以提供更出色的画面效果。 SubShader的标签是一个键值对,它的键和值都是字符串类型。这些键值对是SubShader渲染引擎之间的沟通桥梁,用来告诉Unity渲染引擎应该以怎样的方式和何时渲染这个对象。具体情况可以查看相关的表格。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值