zoukankan      html  css  js  c++  java
  • Shader预处理宏、内置状态变量、多版本编译等

    预定义shader预处理宏:
      Target platform:

      SHADER_API_OPENGL - desktop OpenGL
      SHADER_API_D3D9 - Direct3D 9
      SHADER_API_XBOX360 - Xbox 360
      SHADER_API_PS3 - PlayStation 3
      SHADER_API_D3D11 - desktop Direct3D 11
      SHADER_API_GLES - OpenGL ES 2.0 (desktop or mobile), use presence of SHADER_API_MOBILE to determine.
      SHADER_API_FLASH - Flash Stage3D
      SHADER_API_D3D11_9X - Direct3D 11 target for Windows RT

      Surface shader pass indicators:

      UNITY_PASS_FORWARDBASE - 前向渲染的base pass(主方向光、lightmaps、SH)
      UNITY_PASS_FORWARDADD - 前向渲染的add pass(没盏灯一个pass)
      UNITY_PASS_PREPASSBASE - 延迟渲染base pass(renders normals & specular exponent).
      UNITY_PASS_PREPASSFINAL - 延迟渲染final pass (applies lighting & textures).
      UNITY_PASS_SHADOWCASTER - 阴影投射渲染pass.
      UNITY_PASS_SHADOWCOLLECTOR - 阴影手机pass for directional light shadows.

    内置全局状态变量:

      内置的矩阵:

    UNITY_MATRIX_MVP                                   float4x4    Current model * view * projection matrix.
    UNITY_MATRIX_MV                                    float4x4    Current model * view matrix.
    UNITY_MATRIX_V                                     float4x4    Current view matrix.
    UNITY_MATRIX_P                      float4x4    Current projection matrix.
    UNITY_MATRIX_VP                       float4x4    Current view * projection matrix.
    UNITY_MATRIX_T_MV                                  float4x4    Transpose of model * view matrix.
    UNITY_MATRIX_IT_MV                     float4x4    Inverse transpose of model * view matrix.
    UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3     float4x4    Texture transformation matrices.
    _Object2World                                      float4x4    Current model matrix.
    _World2Object                                      float4x4    Inverse of current world matrix.
    _WorldSpaceCameraPos                               float3    World space position of the camera.
    unity_Scale                                        float4    xyz components unused; w contains scale for uniformly scaled objects.

      内置的向量:

      UNITY_LIGHTMODEL_AMBIENT: Current ambient color.

      光照相关的:

    _ModelLightColor                                   float4    Material’s Main * Light color
    _SpecularLightColor                                float4    Material’s Specular * Light color
    _ObjectSpaceLightPos                               float4    Light’s position in object space. w component is 0 for directional lights, 1 for other lights
    _Light2World                                       float4x4    Light to World space matrix
    _World2Light                                       float4x4    World to Light space matrix
    _Object2Light                                      float4x4    Object to Light space matrix

      变量:

    _Time                                              float4    Time (t/20, t, t*2, t*3), use to animate things inside the shaders.
    _SinTime                                           float4    Sine of time: (t/8, t/4, t/2, t).
    _CosTime                                           float4    Cosine of time: (t/8, t/4, t/2, t).
    unity_DeltaTime                                    float4    Delta time: (dt, 1/dt, smoothDt, 1/smoothDt).
    _ProjectionParams                                  float4    x is 1.0 (or –1.0 if currently rendering with a flipped projection matrix), y is the camera’s near plane, z is the camera’s far plane and w is 1/FarPlane.
    _ScreenParams                                      float4    x is the current render target width in pixels, y is the current render target height in pixels, z is 1.0 + 1.0/width and w is 1.0 + 1.0/height.

      内置光照参数:
      对于不同的Rendering Path和Pass Tag,可以使用的光照参数是不一样的。(当然所有参数你都可以在shader中使用,但并不能保证其一定会存储有效的值)。
      Forward rendering(ForwardBase和PorwardAdd标记的pass)支持的变量:

    LightColor0 (declared in Lighting.cginc) | fixed4 |Light color. | |WorldSpaceLightPos0  float4    Directional lights: (world space direction, 0). Other lights: (world space position, 1).
    _LightMatrix0 (declared in AutoLight.cginc)                           float4x4    World-to-light matrix. Used to sample cookie & attenuation textures.
    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0                    float4    (ForwardBase pass only) world space positions of first four non-important point lights.
    unity_4LightAtten0                                          float4    (ForwardBase pass only) attenuation factors of first four non-important point lights.
    unity_LightColor                                            half4[4]   (ForwardBase pass only) colors of of first four non-important point lights.

      说明:

      (1)_LightColor0在ForwardBass里面表示:主光,一定是Pixel(Important)、Directional光源,没有的话则改值不可用;

      (2)_LightColor0在ForwardAdd里面表示:当前执行的ForwardAdd的pixel光;

      _WorldSpaceLightPos0的意义和_LightColor类似,也是在Base里表示主光,Add里表示像素光。

      (3)unity_LightColor是距离物体最近的4个point光,也就是说同一个场景中每个物体的这4个光不一样,注意这4个point光的选择非常有意思;

        (a)当shader中没有ForwardAdd Pass的时候,unity_LightColor记录了4盏vertex point光源,无视pixel光;

        (b)当shader中包含ForwardAdd Pass的时候,unity_LightColor记录了4盏point光源,pixel比vertex优先。

      (4)如果场景中有多个pixel光,则对每一个物体,所有的非主光的pixel光都会执行一遍ForwardAdd Pass,按照强度大小、平行光优先的顺序来执行;

      (5)不要在ForwardAdd Pass里面使用unity4LightPosX/Y/Z等数据,因为它们就是给ForwardBase Pass使用的,而且如果其中有pixel光,它们本身就会对ForwardAdd执行一遍;

      (6)可以使用Shade4PointLights函数在ForwardBase中计算Vertex光源的照明。

      Deferred shading:

    LightColor | float4 | Light color. | |LightMatrix0                        float4x4  World-to-light matrix. Used to sample cookie & attenuation textures.

      Vertex-lit rendering(Vertex标记的pass):
      顶点光照可以使用最多8盏光源,这些光源按照亮度排序,按顺序存储在一下这些数据结构中,如果光源数量少于8,那么多出来的都将黑色:

    unity_LightColor            half4[8]    Light colors.
    unity_LightPosition          float4[8]    View-space light positions. (-direction,0) for directional lights; (position,1) for point/spot lights.
    unity_LightAtten            half4[8]    Light attenuation factors. x is cos(spotAngle/2) or –1 for non-spot lights; y is 1/cos(spotAngle/4) or 1 for non-spot lights; z is quadratic attenuation; w is squared light range.
    unity_SpotDirection          float4[8]    View-space spot light positions; (0,0,1,0) for non-spot lights.

      说明:

      (1)_LightColor0表示unity_LightColor[0]

      (2)unity_LightPosition是MV空间中的位置

      (3)逐顶点光照函数float4 ShadeVertexLights(float4 vertex, float3 normal)

      注意:

      (1)_LightColor0变量不代表某个具体含义,它在不同的Render Path和Pass里面是有不同的意义的

      (2)ShaderLab里面的内置变量是不会及时清理的,这是Unity处于性能方面的考虑,因为在CPU和GPU之间频繁传递数据是很耗资源的

      Fog和Ambient环境光信息:

    UNITY_LIGHTMODEL_AMBIENT      fixed4    Ambient lighting color (Equator ambient in three-color lighting case).
    unity_AmbientSky           fixed4    Sky ambient lighting color in three-color lighting case.
    unity_AmbientGround         fixed4    Ground ambient lighting color in three-color lighting case.
    unity_FogColor            fixed4    Fog color.
    unity_FogParams            float4    Parameters for fog calculation: (density / sqrt(ln(2)), density / ln(2), –1/(end-start), end/(end-start)). x is useful for Exp2 fog mode, y for Exp mode, z and w for Linear mode.

    使用multi_compile编译Shader的多个版本:

      有时候我们希望保留一个shader的大多数实现,而只是做一些细节的修改,此时我们就可以通过该方式来生成shader的多个版本,然后在代码中控制使用哪个版本。
      命令:
      #pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
      控制:
      Material.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
      Shader.EnableKeyword(keyword: string)/DisableKeyword(keyword: string)
      在shader中根据定义好的关键字处理具体显示方案:

      float4 frag(vertOut i):COLOR
      {
        float4 c = float4(0, 0, 0, 0);
        #ifdef MY_multi_1
          c = float4(0, 1, 0, 0);
        #endif
        #ifdef MY_multi_2
          c = float4(0, 0, 1, 0);
        #endif
        return c;
    }

      注意不要在shader中大量使用此命令,因为关键字的个数是有上限的,而多条multi_complie会交叉匹配产生很多种结果。

    GLSL shader编程
      在Shader中,除了Cg/HLSL以外,GLSL(OpenGL Shading Languate)也可以直接使用。
      一般不建议使用GLSL,除非你确定你的目标平台只有Max OS X或兼容OpenGL ES 2.0的移动设备。
      Unity默认都会将Cg/HLSL交叉编译出优化过得GLSL,以此来支持多平台。在desktop平台下可以通过打开#pragma glsl选项来支持。

    平台特性相关的渲染差异:
      Unity封装了大多数的平台问题,但有些时候还是需要自己处理一下的。
      纹理坐标
      Direct3D里面是左上角为原点;
      OpenGL和OpenGL ES是左下角为原点。
      多数时候都ok,除了在Render To Texture时。但是在RTT时,Unity对于D3D平台会自动将渲染的贴图上下翻转一下,以此隐藏了各平台的差异。
      D3D平台下,有一种情况不需要Unity自动翻转渲染贴图,那就是使用Image Effects和Anti-Aliasing时,因为直接渲染到Screen了,
      需要手动处理的情况:但同时使用screen texture和RenderTexture时,有可能会得到不一致的坐标朝向,此时就需要在shader里面通过代码处理了:

    // On D3D when AA is used, the main texture and scene depth texture
    // will come out in different vertical orientations.
    // So flip sampling of the texture when that is the case (main texture
    // texel size will have negative Y).
    
    #if UNITY_UV_STARTS_AT_TOP
    if (_MainTex_TexelSize.y < 0)
            uv.y = 1-uv.y;
    
    #endif

      AlphaTest:
      在OpenGL ES 2.0和Direct3D 11中,没有alpha testing的固定函数。所以在编写programmable shader时,建议在pixel shader中使用CG/HLSL clip()函数来替代。
      D3D 11 shader编译器比较挑剔:
      D3D 9和OpenGL使用NVIDIA的Cg来编译shader,但D3D 11使用微软的HLSL来编译,此时就会产生一些差异化。
      OpenGL ES 2.0只支持部分GLSL原生的东西,所以Unity实现了一些内置的参数,让其以OpenGL的方式工作,但是也有一些参数是没有的。

    _WorldSpaceLightPos0:
      在UnityCG.cginc里,提供了获取世界空间下的光照方向的函数

        // Computes world space light direction
        inline float3 WorldSpaceLightDir( in float4 v )
        {
            float3 worldPos = mul(_Object2World, v).xyz;
            #ifndef USING_LIGHT_MULTI_COMPILE
            return _WorldSpaceLightPos0.xyz - worldPos * _WorldSpaceLightPos0.w;
            #else
            #ifndef USING_DIRECTIONAL_LIGHT
            return _WorldSpaceLightPos0.xyz - worldPos;
            #else
            return _WorldSpaceLightPos0.xyz;
            #endif
            #endif
        }

    其中,由于平行光的方向不随顶点位置发生变化,因此直接使用_WorldSpaceLightPos0.xyz即可,此时里面存储的其实就是平行光的方向,而非位置。同时,
    _WorldSpaceLightPos0.w可以表明该光源的类型,如果为0表示是平行光,为1表示是点光源或者聚光灯光源。

    TANGENT_SPACE_ROTATION:
      创建一个正切空间的旋转矩阵,TANGENT_SPACE_ROTATION由下面两行组成
      等同于如下两行代码:

    float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
    float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );



    CSDN博客:http://blog.csdn.net/candycat1992/article/details/47284289

  • 相关阅读:
    mac 通过SSH连接服务器aws和github
    Android开发 View与Activity的生命周期[转载]
    Android开发 APP闪退Fragment重叠泄露问题
    3月3日 一堆一堆事
    杭州.net俱乐部 新开qq群
    招聘 .net 开发工程师
    852009
    872009
    01背包和完全背包
    8142009
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/4716047.html
Copyright © 2011-2022 走看看