美文网首页
[Shader] 固定管线2 纹理混合及透明

[Shader] 固定管线2 纹理混合及透明

作者: 周末的游戏之旅 | 来源:发表于2019-08-27 14:13 被阅读0次

    纹理混合

    Shader "Sbin/ff2"
    {
        Properties{
            //变量名 在监视面板显示的名字 类型 = 默认值
            _Color("Main Color",Color) = (1,1,1,1)
            _Ambient("环境光",Color) = (0.3,0.3,0.3,0.3)
            _Specular("高光(镜面反射光)",Color)=(1,1,1,1)
            _Shininess("高光强度",Range(0,8)) = 4
            _Emission("自发光",Color)=(1,1,1,1)
            _MainTexture("主纹理",2d)=""
            _SecondTexture("次纹理",2d)=""
        }
    
        SubShader {
            //必须使用pass编写一个渲染通道
            pass{
                //小括号为固定值 中括号为参数值
                // Color(1,0,0,1)
                // Color[_Color]
    
                //材质命令块
                Material{
                    //下面是属性
    
                    //描述的是材质的漫反射颜色,可以理解为这个物体本身固有的颜色
                    DIFFUSE[_Color]
                    //设置环境光
                    AMBIENT[_Ambient]
                    //设置高光
                    SPECULAR[_Specular]
                    // 浮点值 描述Specular有多强,决定在镜面高光反射过程中被高光反射的部分的区域
                    SHININESS[_Shininess]
                    //自发光
                    emission[_Emission]
                }
                //启用顶点光照 如果不开启光照,物体的颜色不会被反射,这时不论怎么修改颜色都不会变化
                Lighting on
                //独立的高光
                SeparateSpecular on
                
                SetTexture[_MainTexture]
                {   
                    // Combine texture
                    // Combine 表示合并,texture 表示参数_MainTexture
                    // 这里只应用了贴图而没有应用之前的顶点光照,因此会失去光照效果
                    
                    // Combine texture * primary
                    // primary 是fixed function shader的关键词
                    // primary 代表前面所有计算了材质和光照以后的颜色
                    // 这两个颜色相乘就会得到一个混合的颜色
                    // 这里要注意的是 颜色rgba的每一个分量都是一个浮点数,范围是[0,1]
                    // 也就是两个浮点数相乘,这时会得到一个更小的浮点数,因此颜色会看起来更深
    
                    Combine texture * primary double
                    // double 表示对这个结果乘2,也就是对 texture * primary 乘2 ,也就是提高两倍的亮度
    
                    // Combine texture * primary quad
                    // qua 乘4
                }
                // 多个纹理混合
                // SetTexture 只能有一个参数
                SetTexture[_SecondTexture]
                {
                    Combine texture * previous double
                    // previous 表示在这个SetTexture之前的所有计算过的材质和光照的颜色
                    // 按照这个想法,可以继续编写SetTexture,但不是无限写的
                    // fixed function shader 是基本对照于显卡硬件的固定渲染部分
                    // 显示卡是有一个混合纹理最大上限的,显卡硬件越好能混合的纹理越多
                    // 两张纹理混合是现在几乎所有显卡都支持的
                }
            }
        }
    }
    

    透明

    通过上面对 fiexd function shader 的学习,可以假设如果需要透明,那么只要将各种颜色的Alpha值降低,那么经过一轮计算下来,Alpha值肯定是小数,这样就可以透明了?
    事实只有这样是不够的。

    ShaderLab:Blending

    上面是一张渲染流程图。
    当着色器渲染过后,会进入AlphaTest阶段,然后再进入Blending(混合)阶段。
    Blending可以使用SrcFactor(源的部分)和DstFactor(目标的部分)进行一种混合运算。

    SrcFactor是指当前正在渲染的。
    DstFactor是指当前处自己之外已经渲染完的(包括天空盒)。

    Blending Factor(混合因素) 解释
    SrcAlpha 此阶段的值乘以源alpha值。(当前已经渲染完的Alpha值)
    OneMinusSrcAlpha 此阶段的值乘以(1 - 源alpha)。(1-当前已经渲染完的Alpha值)

    常见的混合类型:

    Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency(传统透明度)
    Blend One OneMinusSrcAlpha // Premultiplied transparency(预乘透明度)
    Blend One One // Additive(附加)
    Blend OneMinusDstColor One // Soft Additive(软附加)
    Blend DstColor Zero // Multiplicative(乘)
    Blend DstColor SrcColor // 2x Multiplicative(2倍乘)
    

    在Pass中添加Blending指令

    Shader "Sbin/ff2"
    {
        Properties{
            _Color("Main Color",Color) = (1,1,1,1)
            _Ambient("环境光",Color) = (0.3,0.3,0.3,0.3)
            _Specular("高光(镜面反射光)",Color)=(1,1,1,1)
            _Shininess("高光强度",Range(0,8)) = 4
            _Emission("自发光",Color)=(1,1,1,1)
            _MainTexture("主纹理",2d)=""
            _SecondTexture("次纹理",2d)=""
        }
    
        SubShader {
            pass{
                Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency(传统透明度)
                // 效果是,用当前颜色中的的Alpha值与(1-当前颜色的Alpha值)的比例去混合之前已经渲染好的乘积颜色值
    
    
                Material{
                    DIFFUSE[_Color]
                    AMBIENT[_Ambient]
                    SPECULAR[_Specular]
                    SHININESS[_Shininess]
                    emission[_Emission]
                }
    
                Lighting on
                
                SeparateSpecular on
                
                SetTexture[_MainTexture]
                {   
                    Combine texture * primary double
                }
    
                SetTexture[_SecondTexture]
                {
                    Combine texture * previous double
                }
            }
        }
    }
    

    效果如下:


    小球的颜色虽然发生了变化,但是并没有达到透明效果。
    这是因为在Unity引擎中存在一种渲染顺序的东西。

    ShaderLab SubShader Tags(标签)

    子着色器使用标签来告诉他们希望如何以及何时将其渲染到渲染引擎。

    基本语法:

    Tags {"TagName1"="Value1" "TagName2"="Value2"}
    

    渲染顺序-队列标记:

    可以使用Queue标记确定的对象的绘制顺序,一个着色器决定其对象属于哪个渲染队列,这样任何透明着色器都会确保它们在所有不透明对象之后绘制,依此类推。
    有四个预定义的渲染队列:

    • Background 此渲染队列在任何其他渲染队列之前呈现。你通常会将它用于真正需要在后台运行的东西。
    • Gemetry几何 (默认)用于大多数对象。不透明几何体使用此队列。
    • AlphaTest alpha测试几何使用此队列。它是几何体的独立队列,因为在绘制完所有实体之后渲染经过alpha测试的对象会更有效。
    • Transparent 此渲染队列按照从后到前的顺序在Geometry和AlphaTest之后呈现。 任何alpha混合(即不写入深度缓冲区的着色器)都应该放在这里(玻璃,粒子效果)。

    在SubShader中添加渲染队列

    Shader "Sbin/ff2"
    {
        Properties{
            _Color("Main Color",Color) = (1,1,1,1)
            _Ambient("环境光",Color) = (0.3,0.3,0.3,0.3)
            _Specular("高光(镜面反射光)",Color)=(1,1,1,1)
            _Shininess("高光强度",Range(0,8)) = 4
            _Emission("自发光",Color)=(1,1,1,1)
            _MainTexture("主纹理",2d)=""
            _SecondTexture("次纹理",2d)=""
        }
    
        SubShader {
            
            Tags { "Queue" = "Transparent" }
            //设置渲染队列
    
            pass{
                Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency(传统透明度)
                // 效果是,用当前颜色中的的Alpha值与(1-当前颜色的Alpha值)的比例去混合之前已经渲染好的乘积颜色值
    
    
                Material{
                    DIFFUSE[_Color]
                    AMBIENT[_Ambient]
                    SPECULAR[_Specular]
                    SHININESS[_Shininess]
                    emission[_Emission]
                }
    
                Lighting on
                
                SeparateSpecular on
                
                SetTexture[_MainTexture]
                {   
                    Combine texture * primary double
                }
    
                SetTexture[_SecondTexture]
                {
                    Combine texture * previous double
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:[Shader] 固定管线2 纹理混合及透明

          本文链接:https://www.haomeiwen.com/subject/cyleectx.html