unity之shader

Posted shirln

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity之shader相关的知识,希望对你有一定的参考价值。

1.渲染流水线

任务:从一个三维场景出发,生成(或者渲染)一张二维图像。即:计算机需要从一系列的定点出数据,纹理等信息出发,把这些信息最终转换程一张人眼可以看到的图像。而这个工作通常是由CPU和GPU共同完成的。

三个阶段:

(1)应用阶段(CPU):1.准备场景数据。2.粗粒度剔除工作。3设置模型的渲染状态,输出渲染所需要的几何信息.

应用阶段大致可以分为三个阶段:

1.把数据加载到显存中。

2.设置渲染状态。渲染状态:定义场景中的网格是怎样被渲染的。如:使用那个顶点着色器/片元着色器。

3.调用DrawCall。DrawCall是一个命令,发起方为CPU,接收方为GPU。

(2)几何阶段:把定点坐标变换到屏幕空间中,再交给光栅器进行处理。对输入的渲染图源进行多部处理后,将会输出屏幕空间的二维顶点坐标,每个定点对应的深度值,着色等相关信息。

(3)光栅化阶段:产生屏幕上的像素,并渲染最终的图像。光栅化的任主要是决定每个渲染图源中的那些像素应该被绘制再屏幕上。对上一阶段得到的逐定点数据进行插值,然后再进行逐像素处理。

为了避免我们看到的那些正在进行光栅化的图元,GPU会使用双重缓冲策略(前置缓冲,后置缓冲)。当场景被渲染到后置缓冲中,GPU会交换前后置缓冲中的内容,前置缓冲事之前显示在屏幕上的图像。

技术分享图片

(1)顶点着色器:处理单位是顶点,输入进来的每个定点都会调用一次定点着色器。顶点着色器本身不可以创建或者销毁任何顶点,而且无法得到顶点与顶点之间的关系。完成的工作主要由:坐标变换(把顶点坐标从模型空间转换到齐次裁剪空间如:mul(UNITY_MVP,v.postion))和逐顶点光照。

(2)裁剪:一个图元和摄像机事业的关系有三种:完全在视野内,部分在视野内,完全在视野外。

(3)屏幕映射:把每个图元的x,y坐标转换到屏幕坐标系下。

(4)三角形设置:计算光栅化一个三角网格所需要的信息。即:得到三角形的每个顶点,需要得到整个三角网格对像素的覆盖情况。

(5)三角遍历:检查每个像素是否被一个三角网络所覆盖。根据上一个阶段的计算结果来判断一个三角网格覆盖了那些像素,并使用三角网格3个顶点的顶点信息对整个覆盖区域的像素进行插值。

(6)片元着色器:采用的主要技术为纹理采样。在顶点着色器阶段输出每个顶点对应的纹理坐标,然后经过光栅化阶段对三角网格的3个顶点对应的纹理坐标进行插值,就可以得到其覆盖的片元的纹理坐标。

(7)逐片元操作:几个主要任务:

1.决定每个片元的可见性。涉及很多测试工作,如:深度测试,模板测试。

2.当某个片元通过了所有测试,就需要把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行合并(混合)。

开启混合功能:GPU会取出资源颜色和目标颜色,将两种颜色进行混合。

关闭混合功能:会直接使用片元的颜色覆盖掉颜色缓冲区中的颜色。

对于不透明的物体,即使关闭混合操作,片元着色器计算得到的颜色值可以直接覆盖掉颜色缓冲区中的像素值。但是对于半透明物体,就需要使用混合操作来使物体看上去湿透明的。

 2.Draw Call

(1)CPU和GPU是如何实现并行工作的?

  使用命令缓冲区。命令缓冲区包含了一个命令队列,由CPU向其中添加命令,而GPU从中读取命令,读取和添加命令是相互独立的。

(2)为什么Draw Call多了会影响帧率?

  每次调用Draw Call之前,CPU需要向GPU发送很多内容,包括数据,状态和命令等。

(3)如何减少Draw Call?

  批处理方法。把很多小的Draw Call合并成一个大的Draw Call 。

 在游戏开发过程中,为了减少Draw Call的开销,需要注意:

(1)避免使用大量很小的网格,当不可避免地需要使用很小的网格时,可以考虑是否可以合并。

(2)避免使用过多的材质。尽量在不同得网络之间共用同一个材质。、

3.Shader

1.使用流程:

(1)创建材质。

(2)创建一个Shader,并赋给(1)创建的材质。

(3)把材质赋给要渲染的对象

(4)在材质面板中调节shader的属性。

2.基础结构

技术分享图片

Shader "Custom/MyShader" {
    Properties {
        _Int ("Int", Int) = 2
        _Float("Float",Float) = 1.5
        _Range("Range",Range(0.0,5.0)) = 3.0
        _Color("Color",Color)=(1,1,1,1)
        _Vector("Vector",Vector)=(2,3,5,6)
        _2D("2D",2D) = "" {}
        _Cube("Cube",Cube) = "white" {}
        _3D("3D",3D) = "black" {}
    }
    SubShader {
        //真正意义上的Shader代码会出现在这里
        //表面着色器/顶点/片元/固定函数着色器
        ///可选
        //标签
        Tags { "RenderType"="Opaque" }
        //状态
        [RenderSetup]
        Pass{
            [Name]
            [Tags]
            [RenderSetup]
        }
        //other pass
    } 
    Fallback "name"
}

技术分享图片

Tag标签属性

技术分享图片

技术分享图片

技术分享图片

 53

以上是关于unity之shader的主要内容,如果未能解决你的问题,请参考以下文章

unity shader学习笔记 shader基础结构以及Properties面板

Unity 之 后处理实现界面灰度效果(PostProcessing实现 | Shader实现)

[Unity] Shader(着色器)之纹理贴图

Unity商业shader开发之高光RimColor,RimLight关键代码解析

Shader HLSL片段说明

Unity Shaders学习笔记之表面着色器