shader学习笔记(一)

OpenGL DirectX

OpenGL 使用GLSL编写shader
DirectX 使用HLSL编写shader
英伟达 使用CG编写shder

shader分类

1.表面着色器 surface shader
2.顶点/片元着色器 Vertex/Fragment shader
3.固定函数着色器 Fixed Function shader

shader基本代码

Shader "ym/ymshader01"{//此处是指定shader的名字,不要求跟文件名一致,且在选择shader时会按照这个路径选择
    Properties{
        //属性
        // _Color是在接下来的subshader里面用到
        //color是在unity里面的名字
        //Color则是属性类型名
        //其他属性都是这种命名格式
        _Color("color",Color)=(1,1,1,1)
        _Vector("vector",vector)=(1,2,3,4)
    }

    //子Shader,可以有很多个
    //显卡运行效果的时候,会从第一个SubShader进行判断,如果第一个效果都可以实现,那么就使用第一个
    //如果显卡对于当前SubShader一些效果实现不了,会自动去判断下一个子Shader
    SubShader{
        //必须要有一个pass
        pass{
            //要在CGPROGRAM和ENDCG之间用CG语言编写shader代码
            CGPROGRAM

            ENDCG
        }
    }

    //如果所有的SubShader都无法实现,便实现此Shader
    Fallback "VertexLit"

}

在这里插入图片描述

常见属性类型

Properties{
        //属性
        // _Color是在接下来的subshader里面用到
        //color是在unity里面的名字
        //Color则是属性类型名
        //其他属性都是这种命名格式
        _Color("color",Color)=(1,1,1,1)
        _Vector("vector",vector)=(1,2,3,4)
        //常见的属性类型
        //int类型
        _int("int",int)=123
        //float类型
        _float("float",float)=2.3
        //范围类型 限定好了范围
        _range("range",Range(1,11))=3
        //2D图片类型   前面的"red"是默认颜色
        _2d("texture",2D)="red"{}
        //cube类型  ??
        _cube("cube",Cube)="white"{}
        //3D类型
        _3d("3d",3D)="black"{}
    }

在这里插入图片描述

属性的使用

属性在用之前,要再定义一遍

 //子Shader,可以有很多个
    //显卡运行效果的时候,会从第一个SubShader进行判断,如果第一个效果都可以实现,那么就使用第一个
    //如果显卡对于当前SubShader一些效果实现不了,会自动去判断下一个子Shader
    SubShader{
        //必须要有一个pass
        pass{
            //要在CGPROGRAM和ENDCG之间用CG语言编写shader代码
            CGPROGRAM
            //属性在用之前,要再定义一遍
            float4 _Color;
            float4 _Vector;
            float _int;
            float _float;
            float _range;
            sampler2D _2d;
            sampler3D _3d;
            samplerCUBE _cube;
            ENDCG
        }
    }

小tips

fixed half float 基本可以互换,只不过float范围大于half大于fixed

顶点函数与片元函数

Shader "ym/shader02"{
    SubShader{
        pass{
            CGPROGRAM
            //声明顶点函数的函数名
            //顶点函数作用:完成顶点坐标从模型空间到剪裁空间的转换(即从游戏环境转换到视野相机屏幕上)
            #pragma vertex vert
            //声明片元函数的函数名
            //片元函数作用:返回模型对应的屏幕上的每一个像素的颜色值
            #pragma fragment frag

            //可以暂时用xxx表示返回值与参数
            xxx vert(xxx){

            }

            xxx frag(xxx){

            }

            ENDCG
        }
    }

    Fallback "VertexLit"
}

完善顶点函数

            //:表示语义
            // float4 v : POSITION 表示参数需要的是POSITION
            //: SV_POSITION 表示返回值是剪裁空间下的顶点坐标
            float4 vert(float4 v : POSITION) : SV_POSITION{
                //此功能需要使用unity写好的一个矩阵来实现
                return mul(Unity_Matrix_MVP,v);
            }

完善片元函数

此处可以有能看得到的效果了

            fixed4 frag() :SV_TARGET{
                return fixed4(0.5,1,0.5,1);
            }

在这里插入图片描述

法线方向和纹理坐标

            //结构体,传参时便可以传入多个参数
            struct a2v{
                float4 vertex:POSITION;//语义是将顶点坐标给vertex变量
                float3 normal:NORMAL;//法线方向
                float4 texcoord0:TEXCOORD0;//第一套纹理坐标

            }

            //:表示语义
            // a2v a2v 使用结构体传参
            //: SV_POSITION 表示返回值是剪裁空间下的顶点坐标
            float4 vert(a2v a2v) : SV_POSITION{
                //此功能需要使用unity写好的一个矩阵来实现
                return mul(Unity_Matrix_MVP,a2v.vertex);
            }

此处踩了一个坑,该加分号的地方不要忘记

片元函数与顶点函数之间数据传递

此处采取将顶点函数获得的法线方向传给片元函数并展示成颜色的形式

Shader "ym/shader01"{
    SubShader{
        pass{
            CGPROGRAM
            //声明顶点函数的函数名
            //顶点函数作用:完成顶点坐标从模型空间到剪裁空间的转换(即从游戏环境转换到视野相机屏幕上)
            #pragma vertex vert
            //声明片元函数的函数名
            //片元函数作用:返回模型对应的屏幕上的每一个像素的颜色值
            #pragma fragment frag

            //结构体,传参时便可以传入多个参数
            struct a2v{
                float4 vertex:POSITION;//语义是将顶点坐标给vertex变量
                float3 normal:NORMAL;//法线方向
                float4 texcoord0:TEXCOORD0;//第一套纹理坐标

            };

            struct v2f{
                float4 position:SV_POSITION;//顶点坐标
                float3 temp:COLOR0;//法线的方向
            };

            //:表示语义
            // a2v a2v 使用结构体传参
            //: SV_POSITION 表示返回值是剪裁空间下的顶点坐标
            v2f vert(a2v v){
                v2f f;
                //此功能需要使用unity写好的一个矩阵来实现
                //f.position =  mul(Unity_Matrix_MVP,a2v.vertex);
                f.position= UnityObjectToClipPos(v.vertex);
                f.temp = v.normal;
                return f;
            }

            fixed4 frag(v2f f) :SV_TARGET{
                return fixed4(f.temp,1);
            }

            ENDCG
        }
    }

    Fallback "VertexLit"
}

在这里插入图片描述
此处有个坑:mul(Unity_Matrix_MVP,a2v.vertex);不能用了,要改成UnityObjectToClipPos(v.vertex);

标准光照模型

光照模型是一个公式,使用这个公式来计算在某个点的光照效果
光分为四部分:
自发光
高光反射
漫反射
环境光

漫反射公式

Diffuse = 直射光颜色 * max(0,cos(光和法线的夹角))
其中,夹角的计算是使用点乘来得到的,即
在这里插入图片描述
同时还需要定义正确的LightMode来得到Unity的内置光照变量

 Tags{"LightMode" = "ForwardBase"}
            CGPROGRAM
            #include "Lighting.cginc"

Tags{“LightMode” = “ForwardBase”}在pass内部,CGPROGRAM外部
#include "Lighting.cginc"在CGPROGRAM内部

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值