zoukankan      html  css  js  c++  java
  • ForwardPath渲染路径-基础

    根据之前的学习,ForwardPath有两个Pass可以处理光照:

    • ForwardBase通道会立即渲染环境光、光照贴图、主方向光和不重要的顶点光。
    • ForwardAdd通道被用于增强逐像素光照,每个物体都被这样的光照亮。

    Basepass用逐像素渲染的方向光以及所有SH和逐顶点光,可以实现效果:注意:需要开启multi_compile_fwbase计算光照衰减;

    • 光照贴图,但不会接受SH光
    • 环境光
    • 自发光
    • 可以有方向光阴影

    Additional passes 计算其他影响物体的逐像素光照渲染物体,开启multi_compile_fwdadd 计算光照衰减。默认不支持绘制阴影,除非开启multi_compile_fwdadd _fullshadows指令。

    简单实现的代码如下:

    //ForwardBase-pass
    struct a2v {
         float4 vertex : POSITION;
         float3 normal : NORMAL;
     };
    
    struct v2f {
         float4 pos : SV_POSITION;
         float3 worldNormal : TEXCOORD0;
         float3 worldPos : TEXCOORD1;
         SHADOW_COORDS(2)//内置宏,2是TEXCOORD下标
     };
    
    v2f vert(a2v v) {
         v2f o;
         o.pos = UnityObjectToClipPos(v.vertex);
         o.worldNormal = UnityObjectToWorldNormal(v.normal);
         o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
         TRANSFER_SHADOW(o);//内置宏计算阴影
         return o;
     }
    
    fixed4 frag(v2f i) : SV_Target {
         fixed3 worldNormal = normalize(i.worldNormal);
         fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
         fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
         fixed3 diffuse = _Kd * _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));
         fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
         //使用了纯反射计算公式2*N平方*L-L
         fixed3 ref_dir = normalize(2*dot(worldNormal,worldLightDir)*worldNormal - worldLightDir);
         fixed3 specular = _Ks *_LightColor0.rgb * _Specular.rgb * pow(max(0, dot(ref_dir, viewDir)), _n);
         UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
         return fixed4(ambient + (diffuse + specular) * atten, 1.0);
    }
    
    
    //ForwardAdd-pass
    //如果开启了#pragma multi_compile_fwdadd_fullshadows,就可以计算点光源和聚光源产生的阴影
    struct a2v {
            float4 vertex : POSITION;
             float3 normal : NORMAL;
     };
    
    struct v2f {
        float4 pos : SV_POSITION;
        float3 worldNormal : TEXCOORD0;
        float3 worldPos : TEXCOORD1;
        SHADOW_COORDS(2)
    };
    
    v2f vert(a2v v) {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.worldNormal = UnityObjectToWorldNormal(v.normal);
        o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
        TRANSFER_SHADOW(o);
        return o;
    }
    
    fixed4 frag(v2f i) : SV_Target {
        ffixed3 worldNormal = normalize(i.worldNormal);
        fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
        //内置函数UnityWorldSpaceLightDir
        /*#ifdef USING_DIRECTIONAL_LIGHT
            fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
        #else
            fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
        endif*/
        
        fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));
        fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));//normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
        fixed3 ref_dir = normalize(2 * dot(worldNormal, worldLightDir) * worldNormal - worldLightDir); 
        fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(ref_dir,viewDir)), _n);
        //光照衰减
        /*#ifdef USING_DIRECTIONAL_LIGHT
            fixed atten = 1.0;
        #else
            #if defined (POINT)
                float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz;//把顶点所在世界坐标转换到光照空间
                fixed atten = tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;//dot模拟平方取结果两次组成采样uv坐标
            #elif defined (SPOT)
                float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));
                fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;
            #else
                fixed atten = 1.0;
            #endif
        #endif*/
        //内置函数UNITY_LIGHT_ATTENUATION计算了光照衰减和阴影
        UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
        return fixed4((diffuse + specular) * atten, 1.0);
    }
  • 相关阅读:
    Python 的编码格式
    Python import其他层级的模块
    自己写ORM框架 DBUtils_DG Java(C#的写在链接里)
    C#对象深度克隆
    SpringMVC文件上传下载
    HttpRuntime.Cache .Net自带的缓存类
    Winform跨窗体操作控件(使用委托)
    Winform调用WebKitBrowser,基于chrome内核WebKit的浏览器控件
    ORM框架 EF code first 的封装 优化一
    Go Language 开发环境搭建
  • 原文地址:https://www.cnblogs.com/baolong-chen/p/11708796.html
Copyright © 2011-2022 走看看