zoukankan      html  css  js  c++  java
  • unity shader入门(二)语义,结构体,逐顶点光照

    下为一个逐顶点漫反射光照shader

    Shader "study/Chapter6/vertexShader"{
    Properties{
    _Diffuse("Diffuse",Color)=(1, 1, 1, 1)//材质的漫反射属性
    //声明一个Color类型的属性 } SubShader{ Pass{ Tags{"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag
              //unity的内置文件,为了可以使用unity的一些内置变量,如后面的——LightColor0 #include "Lighting.cginc"
              //匹配属性的变量,关于属性和变量的匹配,下面有 fixed4 _Diffuse; //顶点着色器输入结构体,结构体下面有 struct a2v{ float4 vertex:POSITION;//存储模型顶点 float3 normal:NORMAL; //存储模型顶点法线 }; //顶点着色器输出结构体,同时也是片元着色器输入结构体 struct v2f{ float4 pos:SV_POSITION; fixed3 color:COLOR;//将顶点着色器计算的光照颜色传递给片元着色器 }; //顶点着色器 v2f vert(a2v v){ v2f o; //将顶点从模型空间转化到裁剪空间 o.pos=UnityObjectToClipPos(v.vertex); //获取外部项,通过unity内置函数UNITY_LIGHTMODEL_AMBIENT获取环境光部分 fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz; //将法线从模型空间转化到世界空间 fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject)); //光源方向,_WorldSpaceLightPos0假设场景中只有一个平行光源才能得到正确方向 fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz); //_LightColor0为unity内置变量访问该Pass处理的光源的颜色和强度信息
                  //下面给出漫反射计算公式 fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight)); o.color=ambient+diffuse; return o; }
              //片元着色器 fixed4 frag(v2f i):SV_TARGET{ return fixed4(i.color,1.0); } ENDCG } } //把这个unity shader的回调设置为内置的Diffuse FallBack "Diffuse" }

     首先下边是Unity支持的语义

    现在来看看顶点输入结构体
    struct a2v{ float4 vertex:POSITION;//存储模型顶点 float3 normal:NORMAL; //存储模型顶点法线 };
    这个叫a2v的结构体包含了顶点着色器需要的模型数据,a2v表示application to vertex shader,把数据从应用阶段传递到顶点着色器中
    一个结构体的格式如下
    struct structname{
    Type(数据类型) Name(变量名):Semantic(语义);
    Type(数据类型) Name(变量名):Semantic(语义);
    Type(数据类型) Name(变量名):Semantic(语义);
    ......
    };
    我们一般是从顶点着色器输出一些数据比如模型的法线,坐标纹理等给片元着色器就需要通过上述代码中的v2f结构体来实现两者通信。
    顶点着色器是逐顶点调用的,片元着色器是逐片元调用的。片元着色器实际上是吧顶点着色器的输出进行差值后得到的结果。
    在顶点着色器中做的就是把顶点着色器输入结构体作为(上为a2v)中顶点的一些信息经过一顿操作转换为v2f(就是个函数),然后将这个v2f丢到片元着色器中再
    一顿操作,然后输出一个颜色

    下面是属性与变量匹配关系

    比如你在properties中声明了一个2D属性,在CG中你就要声明一个sample2D变量来匹配这个2D属性,声明的属性名必须与变量名一致,
    比如上面都是_Diffuse。取值范围上fixed<half<float,在移动端平台上需要注意下。


    我们看到的光=环境光/自发光+漫反射+高光反射
    漫反射计算公式
    漫反射=(光源颜色*材质的漫反射颜色)max(0,表面法线*光源的单位矢量)

    为了防止法线和光源方向点乘的结果为负值,需要使用去最大值函数
    将其截取到0,以防止物体被从后面的光源照亮。

    得到的材质球效果如下

    
    
  • 相关阅读:
    三元运算
    sys and os
    print.format
    while loop
    线段树模板
    Round #431 (Div.2)
    D. Make a Permutation!
    Round #411 (Div.2)
    Round #432 (Div.2)
    Round #433 (Div.2)
  • 原文地址:https://www.cnblogs.com/lanrenqilanming/p/7699516.html
Copyright © 2011-2022 走看看