IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> unityShader入门了解 -> 正文阅读

[游戏开发]unityShader入门了解

我之前的写过一个关于渲染流水线,接下来聊聊shader。
shader的数据类型和c#是有一些相似的,我下面的Properties里面写了几个类型(这个函数里面写的类型都会在unity里面以显示的形式展现出来,下面一个图片就是在unity界面里面所展示的一个效果),只是列举了几个常用的类型。然后它还有一些其他的类型,我写在Pass函数里面,因为这些类型是不去显示的。
首先在unity里面定义一个shader,在Proect中右键选择Shader下的StandardSurfaceShader这个shader是基本的shader框架,其他的几个都是不同的shader框架,所有我们选择基本就可以。
shader有两个必须有的函数Properties只能定义一个,它是用来和用户进行一个交互方式存在,可以显示在Inspector里面,让用户进行选择以及设置一些值,还有一个是SubShader,这个函数可以定义很多个,但一般情况下是只用一个,如果定义多个的情况下就是当前显卡不支持第一个SubShader,然后一次筛选后面的SubShader选择当前电脑显卡所支持的SubShader。然后还会有一个备用的显示方式–Fallback “VertexLit”。我在下面也加了备注,这是一种后备方案。

Shader "MyShaderOne"
{
    //属性块只能有一个
    Properties{
        _Color("color",Color)=(1,1,1,1)//float4
        _Verctor("Verctor",Vector)=(1,2,3,4)//float4
        _Int("Int",Int)=123//float
        _Float("Float",Float)=4.5//float
        _Range("Range",Range(1,20))=5//Range(1,20)这是一个定义范围--float
        _2D("Texture",2D)="white"{}//"white" 的作用的当我们不指定图片会默认使用白色--sampler2D
        _Cube("Cube",Cube)="while"{}//可以指定一个图片形成的效果是一个立方体的天空盒--samplerCube
        _3D("Texure",3D)="black"{}//--sampler3D
    }
        //subshader可以有很多个
        //它会分以不同的显卡用不同的subshader
        //当发现当前显卡不能支持当前的subshader会运行下一个subshader
    SubShader
    {
        //pass块相当于方法--可以有很多个,但一般只用一个
        Pass
        {
            //在这里可以直接编写shader代码
            CGPROGRAM

            //使用cg语言编写代码
            //float  half  fixed------float4  float3  float2  float 
            //float 是32位存储 
            //half 是16位 -6万到6万
            //fixed 是11位 -2到2

            float4 _Color;
            float4 _Vector;
            float _Int;
            float _Range;
            sampler2D _2D;
            samplerCube _Cube;
            sampler3D _3D;

            ENDCG
            
        }
    }
    //后备方案,当上面的subshader都不能执行的时候执行此
    Fallback "VertexLit"
}

在这里插入图片描述
上面对shader的一些基本数据有了一个了解之后我们再了解一下必须要有的两个函数(#pragma vertex vert)、(#pragma fragment frag)这两个是必须要定义的,它们是进行一些shader功能的必要函数,在vertex 中会进行定点函数的处理,就是对于买一个定点数据的处理,fragment 是对于片元的处理,可以参考渲染流水线的几何阶段。
在函数定义的方法里面,有人会想玩什么会加一个:还有后面的参数名是个什么意思,首先我们第一个函数(float4 vert(float4 v:POSITION) :SV_POSITION)POSITION他是一个宏,相当于将物体的数据传入函数中变成float4 v的参数,然后括号后面的SV_POSITION是类似以返回值,在前面将参数获取到之后得返回回去,不然我们获取、计算值就没有什么意义,所以在函数定义前面会加一个float4,这个相当于c#中定义函数会写一个返回值类型意义下面这个函数。
下面这个函数中SV_Target 也是一样的,将片元的参数返回到物体中,让物体显示出来。在下面我们返回了一个float4的值,物体就会将这个值进行转换成颜色,然后显示出来,这个参数会显示出来下面这个物体的颜色。

Shader "MyShaderTwo"
{
    SubShader
    {
        //pass块相当于方法--可以有很多个,但一般只用一个
        Pass
        {
            CGPROGRAM
            //基本作用 完成顶点坐标从模型看见到裁剪空间的转换(从游戏环境转到视野相机屏幕)
            //定点函数 这里只是声明了,定点函数的函数名
#pragma vertex vert
            //基本作用 返回模型对应的屏幕上的每一个像素的颜色值
            //片元函数 这里只是声明了,片元函数的函数名
#pragma fragment frag
        //position是一种语义好让函数知道数据的来源括号后面的语义是给数据来源做语义通过语义告诉系统我这个参数是什么的
            float4 vert(float4 v:POSITION) :SV_POSITION {
                //通过这个宏就可以将模型空间转到剪裁空间(float4类型)
                return UnityObjectToClipPos(v);
            }
            float4 frag() : SV_Target {
                return float4(0.5,0.5,1,1);
            }
            ENDCG
            
        }
    }
    Fallback "VertexLit"
}

在这里插入图片描述
然后会有人想之前说的Properties为什么一直没有用,因为上面只是对shader让你有一个基本的了解,得有金刚钻才能揽瓷器活。所以在写shader之前,要先将框架有一个基本的了解,以及知道每一个步骤是干什么的,为什么要这么定义,以及一些必要的宏的使用方法。
当了解了框架之后我们来了解一下基本的逻辑处理。

Shader "MyShaderFour"
{
    Properties{
        _Diffuse("Diffuse Color",Color) = (1,1,1,1)
    }
        SubShader{
            Pass{
                Tags{"LightMode" = "ForwardBase"}
                CGPROGRAM
        //获取第一个直射光的颜色 _LightColor0 第一个直射光的位置_WorldSpaceLightPos0
        #include "Lighting.cginc"

        #pragma vertex vert
        #pragma fragment frag
            fixed4 _Diffuse;
            //application to vertex从应用传递到顶点
            struct a2v {
                float4 vertex:POSITION;//告诉unity把模型空间下的顶点坐标填充给vertex
                float3 normal:NORMAL;
            };
            //SV_POSITION是必须有的没有的话就不会显示出物体的模型
            struct v2f {
                float4 position:SV_POSITION;
                fixed3 color : COLOR;
            };
            //用结构体返回值可以返回多个值,对后面的一些操作有帮助
            //系统自动调用,会给屏幕上的每一个顶点调用
            v2f vert(a2v v){
                v2f f;
                f.position = UnityObjectToClipPos(v.vertex);
                fixed3 normalDir = normalize( mul(v.normal,(float3x3) unity_WorldToObject));//3x3是shader的一个表示方式,可以将数据转换成3x3
                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//获取到场景中灯光的位置
                fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0)*_Diffuse.rgb;//获取漫反射颜色--_Diffuse.rgb是之前定义的_Diffuse的值
                f.color = diffuse; 
                return f;
            }

            //系统自动调用,会模型所对应在屏幕上的像素点对应--调用的多
            fixed4 frag(v2f f): SV_Target {
                return float4(f.color,1);
            }
            ENDCG
            
        }
    }
    Fallback "VertexLit"
}

上面我所写的这个函数就是对shader的一个基础的编写,首先Properties中定义的是一个对于颜色的修改,在我们的Inspector里面会出现下面这个图片中红框所标记的。在这里插入图片描述
然后下面(Tags{“LightMode” = “ForwardBase”})与(#include “Lighting.cginc”)是获取场景中直射光的数据在后面的函数中科院使用。在Properties中定义的_Diffuse需要在Pass里面定义一个(fixed4 _Diffuse;)才可能在线面的函数中使用,不然会报错。然后定义了(a2v)函数和(v2f)函数是通过这两个函数进行传值的一些操作,用函数会比直接传值增加效率。
对于定点函数(vert)中的一些方法具体是干什么的,我在函数里面也做了相对应的注释,在最后(f.color = diffuse; )就是将值进行一个赋值可以使这个值在下面的片元函数(frag)中使用。
在片元函数中会有人想一个float4的值为什么float3的值也可以用,还有(f.color)后面的,1是干什么的,其实在上面我们定义的(f.color)是一个现对于unity中(Vector3)的一个参数,但我们在Properties中定义的(_Diffuse)是一个float4的值相当于unity中(Quaternion)是有四个参数的,所以我们在(f.color)后面加了一个(,1)是补全他们所相差的一个参数值。
上述所说三个基本案例只是对shader的一个基本了解,仅限于入门,shader更重要的对于数学的一个逻辑思维能力,以及算法的研究,对于定点函数以及片元函数而言,片元函数所执行的次数会更多。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:17:32  更:2022-01-01 14:18:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 0:51:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码