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点,直接使用颜色信息进行着色。
  • 相关阅读:
    年轻人的第一个 Spring Boot 应用,太爽了!
    面试问我 Java 逃逸分析,瞬间被秒杀了。。
    Spring Boot 配置文件 bootstrap vs application 到底有什么区别?
    坑爹的 Java 可变参数,把我整得够惨。。
    6月来了,Java还是第一!
    Eclipse 最常用的 10 组快捷键,个个牛逼!
    Spring Cloud Eureka 自我保护机制实战分析
    今天是 Java 诞生日,Java 24 岁了!
    厉害了,Dubbo 正式毕业!
    Spring Boot 2.1.5 正式发布,1.5.x 即将结束使命!
  • 原文地址:https://www.cnblogs.com/lvyongbo/p/4199574.html
Copyright © 2011-2022 走看看