初识Shader

作者: _凉笙 | 来源:发表于2017-03-21 00:05 被阅读275次

    HLSL

    高阶着色器语言(High Level Shader Language,简称HLSL),由微软拥有及开发的一种语言,HLSL 独立的工作在 Windows 平台上,只能供微软的Direct3D使用。 HLSL是微软抗衡GLSL的产品,同时不能与OpenGL标准兼容。

    GLSL

    OpenGL着色语言(OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。

    图片2.png

    CG

    Paste_Image.png

    GPU语言

    由于GPU采用不同于CPU的运行运算结构,因此需要一种适用于GPU的编程语言。
    1、微软基于Direct3D图形库的HLSL(High Level Shading Language)
    2、OpenGL ARB定义基于OpenGL图形库的GLSL(OpenGL Shading Language)
    3、NVIDIA(英伟达)与微软合作研发的Cg(C for Graphics).

    Cg能够同时兼容Direct3D和OpenGL图形接口。

    Unity所有的渲染都需要shader来完成,内置的着色器超过80个,可以轻松利用其内置的着色器来完成各种画面效果,并且还提供了自定义shader,方便扩展。Unity使用shaderLab开发语言来组织shader内容,并会针对不同的平台进行编译,类似微软的FX文件或者NAIDIA的CgFX.

    Shader,可以分为VertexShader 和PixelShader/FragmentShader两部分,简称VS,PS。学名顶点着色器和像素着色器。一旦你使用了VS和PS,则渲染过程会将VB(顶点缓冲)的数据按照IB索引(顶点索引缓冲)将每个顶点结构值分量传入VS,VS进行相应的计算和顶点变化,并将VS返回的结果再交由PS进行像素着色,输出相应的图像。概念上来说 FragmentShader会比PixelShader大很多..
    这两个东西由于DX用PixelShader的缘故,其实是一个东西

    Unity中可以编写3种不同的着色器:表面着色器(Surface Shader)、顶点和片段着色器(Vertex and Fragment Shaders)和固定功能管线着色器(Fixed Function Shaders).
    Unity5.0,内建了基于物理渲染的StandardShader,同时还引入了完全延迟着色(FullDeferredRendering)和烘焙反射探头(Baked Reflection Probes)用于以真实环境为基础的镜面高光

    物理着色:PBS (physically Based Shading):新的工业标准,用于电影产品
    遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。


    Paste_Image.png

    Standard Surface Shader (Instanced):标准表面材质(实例化)
    Unlit Shader:未点燃的材质
    Image Effect Shader:图像效果材质
    Compute Shader:计算着色器
    Shader Variant Collection:着色器变量集合

    内建Shader介绍

    4.X版本提供超过80个内建Shader、包括顶点光照效果到高光、发现、反射等游戏常用的材质效果。

    内建Shader分类:
    普通(Normal):用于不透明对象
    透明(Transparent):用于半透明和全透明对象
    透明镂空效果(TransparentCutOut):用于完全透明和完全不透明部分组成(不含半透明部分)的对象,像栅栏一样。
    自发光(Self-llluminated shader Family):用于能反射环境立方体贴图的不透明对象
    反射(Reflective Shader Family):用于能反射环境立方体贴图的不透明对象

    每个类别下包含若干复杂性各异的shader


    Paste_Image.png

    以光照效果计算开销从低到高排序:
    Unlit : 仅使用纹理,不受光照影响
    VertexLit:顶点光照
    Diffuse:漫发射
    Specular: 在漫反射基础上增加高光计算
    Nomal Mapped : 法线贴图,增加了一张法线贴图和几个着色器指令。
    Nomal Mapped Specular : 带高光法线贴图
    Parallax Nomal Mapped : 视差法线贴图,增加了视差贴图计算开销
    Parallax Nomal Mapped :带高光视差法线贴图

    5.X版本新增加了一种基于物理着色的内建着色器,即StandardShader(标准着色器)
    物理着色:PBS (physically Based Shading):新的工业标准,用于电影产品
    遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。


    Paste_Image.png
    Paste_Image.png

    StandardShader是基于物理的着色器,也就是说不管你选择什么样的贴图都会与光照产生反应,这些贴图可以是同一张图片,Unity会使用必要的资源进行计算。

    原理:
    遵从了Conservation of Energy(能量守恒定律),只有这样才能够正真让场景里面的光源依据能量传递的方式,产生一种自然和谐的光照效果。
    表面反射的光线不会比它们收到的更多
    光滑的表面会有更强的反射
    醋糟的表面反射会更弱一些
    高光强度会随着漫反射的强度而改变
    所有的表面从某一特定角度看上去会有或多或少的高光
    所有的表面在掠射角会有更多的反射

    图片3.png 能量守恒:光能=漫反射+反射+折射

    编写自己的Shader(详细解答Shader的各种属性及用法)

    Shader "Custom/firstsharder" {//这里是Shader的名字
        Properties {//着色器属性
            _Color ("Color", Color) = (1,1,1,1)
            //在输入贴图时候,必须要写一个什么都不含的{}
            //需要打开特定选项时可以把其写在这对花括号内.
            //如果需要同时打开多个选项,可以使用空白分隔
            _MainTex ("Albedo (RGB)", 2D) = "white" {}
            _Glossiness ("Smoothness", Range(0,1)) = 0.5
            _Metallic ("Metallic", Range(0,1)) = 0.0
        }
    
        SubShader {
        //表面着色器可以被若干的标签(tags)所修饰
        //硬件将通过判定这些标签来决定什么时候调用该着色器
            Tags { "RenderType"="Opaque" }//标签内部就是告诉系统渲染非透明的物体调用我们
            //Tags { "RenderType"="Transparent" }//渲染透明物体调用
            //Tags { "IgnoreProjector"="True" }//不被Projectors影响
            //Tags{ "ForceNoShadowCasting"="True" }//不产生阴影
            //指定渲染队列(下面有系统预设的队列)
            //Tags{ "Queue"="Geometry" }
            //Background--最早被调用的渲染,用来渲染天空盒或者背景
            //Geometry--默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
            //AlphaTest--用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
            //Overlay--用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
            //Transparent--以从后往前的顺序渲染透明物体
    
            //预设的队列本质就是定义的整数(有点像枚举值)
            //Background=1000,Geometry=2000,AlphaTest=2450
            //Transparent=3000,最后Overlay=4000
    
            //如何自定义列表
            Tags{ "Queue"="Transparent+100" }//通过调用Queue值,确保渲染的先后顺序
    
            //Unity的内建Diffuse着色器的设定值,这个数值决定了我们能用什么样的Shader
            //这个数值可以在unity中的质量设定中设定
            LOD 200//着色器的设定值
            //关于VertexLit及其系列 = 100
            //Decal, Reflective VertexLit = 150
            //Diffuse = 200
           //Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
          //Bumped, Specular = 300
          //Bumped Specular = 400
         //Parallax = 500
         //Parallax Specular = 600
    
    
            //Shader字体:也就是将输入转变成输出的代码部分
            CGPROGRAM//开始CG语言的编写
            // Physically based Standard lighting model, and enable shadows on all light types
            //surface:申明的是一个表面着色器
            //surf:着色器代码的方法的名字,下方的代码有这个函数
            //Standard:标准
            //fullforwardshadows:光照模型
            #pragma surface surf Standard fullforwardshadows
    
            // Use shader model 3.0 target, to get nicer looking lighting
            #pragma target 3.0
            //在CG中,sampler2D就是和texture所绑定的一个数据容器接口
            //其实就是内存存储的RGB通道,sampler2D:就是GLSL中的2D贴图的类型
            //其他类型:sampler1D,sampler3D,samplerCube
            // 图片
            sampler2D _MainTex;
            // 用来获取MainTex的UV信息
            struct Input {
                float2 uv_MainTex;//float2:浮点数的float后面紧跟一个数字2
                vec2 coordinate;//float和vec都可以在之后加入一个2到4的数字,来表示被打包在一起的2到4个同类型数
                float4 color;
            };
    
            half _Glossiness;//half指的是半精度浮点数,精度最低,运算性能相对比高精度浮点数高一些
            half _Metallic;
            // 颜色属性
            fixed4 _Color;
            // SurfaceOutputStandard 表面着色器输出一个标准的结构体
            //着色器的工作核心,着色器就是给定了输入,然后给出输出进行着色的代码,第一个参数是Input结果,第二个参数是一个inout的SurfaceOutput结构
            void surf (Input IN, inout SurfaceOutputStandard o) {
                // Albedo comes from a texture tinted by color
                // 获取图片 * 我们选定的颜色
                //fixed4:定点书:整形数据类型,作用就是把所有数进行转换,得到相应类型的整形表达
                fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                // 输出的像素的颜色 = 图像的颜色(RGB)
                o.Albedo = c.rgb;
                // Metallic and smoothness come from slider variables
                // 输出的颜色效果(金属方面) = 设定的金属值
                o.Metallic = _Metallic;
                // 输出的光滑粗糙程度 = 设置的光滑粗燥程度
                o.Smoothness = _Glossiness;
                // 输出的透明通道 = 图像的透明通道
                o.Alpha = c.a;
            }
            ENDCG//结束CG语言的编写
        }
        FallBack "Diffuse"
    }
    
    642887-57f1485a1e706ea0.png

    参考

    https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
    https://onevcat.com/2013/08/shader-tutorial-2/
    http://www.tuicool.com/articles/JvYJ3em
    http://www.itnose.net/detail/6143450.html

    CG语言基础知识:

    内置元类型
    Float : 32bit浮点类型
    Half: 16bit浮点
    Int : 32bit整形
    Fixed : 12bit定点
    Bool : 布尔值
    Sampler:纹理对象的句柄
    String:不是每个都支持

    cg提供内置的向量数据类型(build-in vector data types)
    float1、float4,
    bool2, bool3,
    float1x1
    float2x3
    类型转换跟C是一样的,用强制转化。
    类型定义的时候可以在常量后跟后缀,如2.0f,1.0h,3x。目前值有f,h,x(fixed)三种。

    支持类型
    1、数组
    float a[10];
    float4 b[10];
    int length = a.length; //获取长度,上面两个返回都是10
    
    float b[2][3] = { { }, { } };
    int length1 = b.length; // length1 = 2;
    int length2 = b[0].length; // length = 3;
    
    2、结构
    以struct开始,紧跟名字,内容用{};包住。不要忘记最后的分号。
    结构中可以带function,是C++中的用法。
    结构不支持继承。
    
    3、特定关键字
    in , out , inout,
    uniform (被修饰的变量从外部传入), const ,
    4、输入语义关键字
    Vertex Shader的输入:
    
    POSITION, NORMAL, BINORMAL, BLENDINDICES, BLENDWEIGHT, TANGENT, PSIZE, TEXCOORD0 ~ TEXCOORD7
    
    如:in float4 modelPos: POSITION
    
    Vertex Shader的输出, 也就是Pixel Shader的输入
    POSITION, PSIZE, FOG,COLOR0 ~ COLOR1, TEXCOORD1 ~ TEXCOORD7
    Pixel Shader的输出:
    
    COLOR
    
    5、入口函数
    通过观察程序的输入输出语义绑定,就可以区分入口函数对应到顶点程序还是片段程序。
    
    6、内置函数库
    reflect 求发射向量
    refract 求折射向量
    mul 矩阵相乘
    normalize 归一化
    

    CG语言的学习资料:

    http://blog.csdn.net/liu_lin_xm?viewmode=contents
    https://developer.nvidia.com/cg-toolkit

    相关文章

      网友评论

        本文标题:初识Shader

        本文链接:https://www.haomeiwen.com/subject/gxninttx.html