34编写自己的Shader(着色器)

一、Shader 程序的基本结构##

Shader程序的基本结构

首先是一些属性定义,用来指定这段代码将有哪些输入。接下来是一个或者多个的子着色器,在实际运行中,哪一个子着色器被使用是由运行的平台所决定的。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果。最后指定一个回滚,用来处理所有Subshader都不能运行的情况(比如目标设备实在太老,所有Subshader中都有其不支持的特性)。
需要提前说明的是,在实际进行表面着色器的开发时,我们将直接在Subshader这个层次上写代码,系统将把我们的代码编译成若干个合适的Pass。废话到此为止,下面让我们真正实际进入Shader的世界吧。

二、进入Shader内部代码结构熟悉##

创建Shader
内部展示
属性定义
属性的对应
SuberShader(子着色器)
SuberShader

三、简单Shader展示##

Shader "Custom/ShaderTest" {
    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



        _MainColor("Main Color",Color)=(0,0,0,1)
        _Testure("Texture",2D)="White"{}
    }
    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+200" }//通过调用Queue值,确保渲染的先后顺序

        //Unity的内建Diffuse着色器的设定值,这个数值决定了我们能用什么样的Shader
        //这个数值可以在unity中的质量设定中设定




        LOD 200//着色器的设定值
        
        //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; // 用来获取MainTex的UV信息

            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"
}

结构体展示

四、参考##

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语言

五、CG语音学习资料##

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容