Unity Shader基础

Unity Shader基础

先上代码,代码一般是这样的。

void Initialization(){
    //先从硬盘加载代码再加载到GPU中
    string vertexShaderCode = LoadShaderFormFile(VertexShader.shader);
    string fragmentShaderCode = LoadShaderFormFile(FragmentShader.shader);
    LoadVertexShaderFromString(vertexShaderCode);
    LoadVertexShaderFromString(fragmentShaderCode);
    //设置各种属性输入
    SetVertexShaderProperty("vertexPosition", vertices);
    SetVertexShaderProperty("MainTex", someTexture);
    SetVertexShaderProperty("MVP", MVP);
    Disable(Blend);         /关闭混合
    Enable(ZText);          //设置深度测试
    SetZTextFunction(LessOrEqual);
    //其他
}
void Onrendering(){
    //调用渲染命令
    DrawCall();
}

VertexShader.shader

in float3 vertexPosition;
in sampler2D MainTex;
in Mateix4x4 MVP;

out float4 position;

void main(){
    position = MVP * vertexPosition;
}

FragmentShader.shader

in float4 position;

out float4 fragColor;

void main(){
    fragColor = float4(1.0, 1.0, 1.0, 1.0);
}

Unity Shader 概述

Unity中shader需要和材质(Material)】配合使用才能达到需要的效果,一般流程:

  • 创建一个材质
  • 创建一个Unity Shader,并把它赋给上一步的材质
  • 把材质赋给给需要渲染的对象
  • 在材质面板中调整Unity Shader的属性,以得到满意的效果

单独的shader是无法发挥任何作用的,它必须和材质结合起来,才能产生效果。

ShaderLab

ShaderLab 是Unity提供的一种专门为Unity Shader服务的语言。

一般结构如下:

 Shader "Example/Diffuse Simple" {
    Properties {
        //属性
    }
    SubShader {
        //显卡A使用的子着色器
    }
    SubShader {
        //显卡B使用的子着色器
    }
    Fallback "Diffuse"
}

材质和Unity Shader 的桥梁:Properties

Properties语义块的定义通常如下:

Properties {
    _Name ("Display Name", PropertyType) = DefaultValue
}

_Name 是属性的名字,在Shader中访问,通常以一个下划线开始。
"Display Name" 是显示的名称,会在材质面板中显示。
PropertyType 是指定它的类型,类型表如下:

属性类型默认定义语法例子
Intnumber_Int("Int", Int) = 2
Floatnumber_Float("Float", Float) = 1.5
Range(min, max)number_Range("Range", Range(0.0, 5.0)) = 3.0
Color(number,number,number, number)_Color("Color", Color) = (1.0, 1.0, 1.0, 1.0)
Vector(number,number,number, number)_Vector("Vector", Vector) = (2, 3, 4, 5)
2D"defaulttexture"{}_2D("2D", 2D) = "white" {}
Cube"defaulttexture"{}_Cube("Cube", Cube) = "white" {}
3D"defaulttexture"{}_3D("3D", 3D) = "white" {}

SubShader语义块

定义模板:

SubShader {
    [Tags] //可选

    [RenderSetup]

    Pass {
    }
}

** 状态设置 **

ShaderLab中常见渲染状态设置选项

状态名称设置指令解释
CullCull Back/Front/Off设置提出模式:剔除背面/正面/关闭剔除
ZTestZTest Less Greater/LEqual/GEqual/NotEqual/Always设置深度测试时使用的函数
ZWriteZWriteON/Off开启/关闭深度写入
BlendBlend SrcFactor DstFactor开启并设置混合模式

** SubShader **

SubShader的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型。
标签的结构如下:

Tags { "TagNamel" = "Valuel" "TagName2" = "Value2" }

SubShader的标签列表:

标签类型说明例子
Queue控制渲染顺序Tags { "Queue" = "Transparent" }
RenderType对着色器分类Tags { "RenderType" = "Opaque" }
DisableBatchingUnity的SubShader批处理功能Tags { "DisableBatching" = "True"}
ForceNoShadowCasting控制使用该SubShader的物体是否投射阴影Tags { "ForceNoShadowCasting" = "True"}
IgnoreProjector使SubShader的物体不受Projector影响。通常用于半透明物体Tags { "IgnoreProjector" = "True"}
CanUseSpriteAtlas用于精灵时,设为falseTags { "CanUseSpriteAtlas" = "False"}
PreviewType指明材质面板将如何预览该材质Tags { "PreviewType" = "Plane"}

** 注意 ** 上述标签仅能在SubShader中声明,而不能在Pass中声明。Pass的标签与SubShader不同。

** Pass语义块 **

定义:

Pass {
    [Name]
    [Tags]
    [RenderSetup]
    //其他
}

Pass的标签类型:

标签类型说明例子
LightMode定义该Pass在Unity的渲染流水线中的角色Tags { "LightMode" = "ForwordBase"}
RequireOptions用于指定当满足某些条件时才渲染该Pass,它的值是由空格分隔的字符串。目前,Unity只支持SoftVegetationTags { "RequireOptions" = "SoftVegetation"}

** Fallback **

在SubShader后面的是一个Fallback指令,如果上面的SubShader在显卡上都不能运行,就运行这个最低级的Shader。相当于一个保险。

Unity Shader的形式

一般有三种Shader:

  • 表面着色器(Surface Shader)
  • 顶点着色器(Vertex Shader)
  • 固定函数着色器(Fixed Funtion Shader)

表面着色器

原来学OpenGL的时候,没听说个有什么表面着色器,因为这是Unity自己创建的一种着色器代码类型。

来看看官网的一个表面着色器代码:

Shader "Example/Diffuse Simple" {
    SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
        #pragma surface surf Lambert
        struct Input {
            float4 color : COLOR;
        };
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = 1;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

这段代码将材质的表面设置为白色。

CGPROGRRAM 和 ENDCG之间的代码是使用CG/HLSL编写的,这里需要将CG/HLSL语言嵌套在ShaderLab语言中。值得注意的是,这里的CG/HLSL语言跟原生的CG/HLSL语言有着细微的不同,例如有些原生的函数和用法Unity并没有支持。

顶点着色器

格式:

Shader "VertexAndFragment Shader" {
      Pass {
          // ... the usual pass state setup ...
          
          CGPROGRAM
          // compilation directives for this snippet, e.g.:
          #pragma vertex vert
          #pragma fragment frag
          
          // the Cg/HLSL code itself
          
          ENDCG
          // ... the rest of pass setup ...
      } 
}

固定函数着色器

格式:

Shader "Basic" {
    Properties{
        _Color("Color", Color) = (1.0, 0.5, 0.5, 1.0)
    }
    SubShader {
        Pass {
            Material {
                Diffuse [_Color]
            }
            Lighting On
        }
    }
}

结束语:

Unity SHader 的选择:

  • 除非你有非常明确的需求必须要使用固定函数着色器,否则别用。
  • 如果要和各种灯光打交道,可能更需要表面着色器,但需要小心它在移动平台的性能表现。
  • 如果需要使用的光照数目非常少,顶点着色器是首选。
  • 最重要的是,如果有很多自定义的渲染效果,那么请选择顶点着色器。

转载于:https://www.cnblogs.com/yoyo-sincerely/p/7898373.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值