zoukankan      html  css  js  c++  java
  • Unity Shaders 第一个默认程序分析

     Unity Shaders 第一个默认程序

     1 Shader "Custom/Shader" {
     2     Properties {
     3         _MainTex ("Base (RGB)", 2D) = "white" {}
     4     }
     5     SubShader {
     6         Tags { "RenderType"="Opaque" }
     7         LOD 200
     8         
     9         CGPROGRAM
    10         #pragma surface surf Lambert
    11 
    12         sampler2D _MainTex;
    13 
    14         struct Input {
    15             float2 uv_MainTex;
    16         };
    17 
    18         void surf (Input IN, inout SurfaceOutput o) {
    19             half4 c = tex2D (_MainTex, IN.uv_MainTex);
    20             o.Albedo = c.rgb;
    21             o.Alpha = c.a;
    22         }
    23         ENDCG
    24     } 
    25     FallBack "Diffuse"
    26 }
    1,Tags  硬件童工这些标签来决定什么时候调用该着色器。
    Tags{“RenderType”=“Opaque"}告诉系统应该在渲染非透明物体的时候调用我们。
    “RenderType”=“Transparent"表示渲染含有透明效果的物体时候调用。
    在这里暗示你得shader输出的是什么。
    “IgnoreProjector”=“True” 不被Projectors影响。
    “ForceNoShadowCasting”=“True”从不产生阴影。
    “Queue”=“xxx"指定渲染顺序队列。
    注意:不透明物体可能无法呈现在透明物体之后的情况。可能由于shader渲染顺序不正确导致的。
    预定义的Queue有:
    Background: 最早被调用的渲染,用来渲染太空盒或背景
    Geomery:这是默认值,用来渲染非透明物体。
    AlphaTest:用来渲染经过AlphaTest的像素,单独AlphaTest设定一个Queue是出于对效率的考虑。
    Transparent:以从后往前的顺序渲染透明物体。
    Overlay:用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等效果)。
    我们也可以这么写 “Queue”=“Transparent+100”,表示一个在Transparent之后100的Queue上进行调用。通过调用Queue值,我们可以确保某些物体一定在另一些物体之前或之后渲染。
    2,LOD 是Level of Detail的缩写。这个值决定我们用什么样的Shader。
    当Quality Settings中我们设定的LOD小于subShader中得LOD时,这个SubShader将不可用。
    根据设备图形性能来调整画质的时候,可以比较准确的控制。
    VertextLit =100
    Decal,Reflective VertexLit=150
    Diffuse=200
    Diffuse Detail,Reflective Bumped Unit,Reflective Bumped VertexLit=250
    Bumped,Specular=300
    Bumped Specular=400
    Parallax=500
    Parallax Specular=600
    3,编译指令:
    #progma surface Func Lambert 声明我们要写的一个表面Shader Func 指定了光照模型。
    surface 声明一个表面着色器
    Func 着色器方法的名字
    Lambert 使用的光照模型。 Lambert 就是普通的diffuse 漫反射 
    4,sampler2D 和texture   texture 加载后 储存在 sampler2D类型的对象中。 简单说就是sampler2D就是GLSL中得2D贴图类型。 相应还有sampler1D,sampler3D,samplerCube 
    我们每个shader 由两个独立的块组成,外面属性声明,回滚是使用Unity可以直接使用和编译的ShaderLab;而 里面的是 CGPROGRAM…. ENDCG 块,是CG程序。CG程序想访问Properties中所定义的变量的话,必须使用和之前变量名相同的名字的进行声明。 那么CG程序就可以访问这个变量了。
    5,CG已经规定好了声明表面着色器方法的参数的类型和名字。就是:
    第一个参数是一个Input结构。第二个参数是一个inout的SurfaceOutput 结构。
    Input结构是需要我们去定义的结构,可以把所需要的参与计算的数据都放到这个Input结构中,传入surf 函数使用;
    第二个SurfaceOutput 是已经定义好了的输出结构,但是一开始的时候内容是空白的,我们需要向里面填写输出,
    这样就可以完成着色了。
    6,unity中每个贴图变量之前都会加上uv_代表提取它的值是uv值,其实就是代表贴图上点的二维坐标。之后可以在surf程序中访问uv_MainText来获取这张贴图当前需要的点得坐标值了。
    7,在计算输出的时候Shader会多次调用surf函数,每次给入一个贴图上的点坐标,来计算输出。第二个参数是一个可写的SurfaceOutput,SurfaceOutput是预设定的输出结构,我们的surf函数的目标就是根据输入把这个结构填上。
    SurfaceOutput结构如下:
    struct SurfaceOutput{
         half3 Albedo;    //像素的颜色
         half3 Normal;    //像素的法向量
         half3  Emission;//像素的发散颜色
         half     Specular;// 像素的镜面高光 
         half    Gloss;     //像素的发光强度
         half    Alpha;     //像素的透明值
    }
    8,half4 c = tex2D (_MainTex, IN.uv_MainTex);
    text2D函数:用来在一张贴图中对一个点进行采样的方法,返回float4,这里对_MainText上的点进行采样,并将其颜色的rgb值赋予了输出的像素颜色,将a值赋予了透明度。这样着色器 就可以,找到贴图上对应的uv点,直接使用颜色信息进行着色。
  • 相关阅读:
    debug error 错误日志的调试模式
    fork(2)
    Fundamental theorem of arithmetic 为什么1不是质数
    Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入
    LevelDB
    MySQL Bugs: #34354: Feature request: EXPLAIN ALTER TABLE https://bugs.mysql.com/bug.php?id=34354
    explain 分析 聚合统计语句的性能
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--005
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--004
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--003
  • 原文地址:https://www.cnblogs.com/lvyongbo/p/4199574.html
Copyright © 2011-2022 走看看