Unity Shader 入门精要(03) -- Unity的基础光照

一、什么是光照模型

光照模型就是一个公式,使用这个公式来计算在某个点的光照效果

二、标准光照模型

在标准光照模型里面,我们把进入摄像机的光分为下面四个部分
自发光:光源散发的光。
高光反射 :光源照射到模型表面时,该表面会在完全镜面反射方向散射。
Blinn光照模型:Specular=直射光 * pow( max(cosθ,0),10) θ:是反射光方向和视野方向的夹角
Blinn-Phong光照模型:Specular=直射光 * pow( max(cosθ,0),10) θ:是法线和x的夹角 x 是平行光和视野方向的平分线
漫反射:光源照射到模型表面时,该表面会想买个防线散射。
Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) )
环境光:其他所有间接光照。

三、光照模型的实现

兰伯特光照模型:在光照无法到达的区域,模型外观通常是全黑的。如背面没有明暗的变化,失去模型细节变化。
Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) ) cosθ = 光方向· 法线方向
半兰伯特光照模型
Diffuse = 直射光颜色 *( cosθ *0.5 +0.5 )

//兰伯特逐片元光照
Shader "Custom/Chapter 5/03_Diffuse1" {
    Properties {
        _Diffuse("Diffuse", Color) = (1.0, 1.0, 1.0, 1.0) //材质的漫反射颜色
    }

    SubShader{
        Pass{

            //只有定义了正确的LightMode才能得到一些Unity的内置光照变量
            Tags{ "LightMode"="ForwardBase" }

            CGPROGRAM

            #include "Lighting.cginc" //包含unity的内置的文件,才可以使用unity内置的一些变量
            #pragma vertex vert   //顶点着色器
            #pragma fragment frag //片元着色器

            //在Cg代码中,与属性名称和类型都匹配
            fixed4 _Diffuse;

            //application to vertex
            struct a2v{
                float4 vertex:POSITION; //模型顶点坐标 
                float3 normal:NORMAL; //法线 计算光照
            };

            //
            struct v2f{
                float4 pos:SV_POSITION;
                float3 color:COLOR0;
            };

            v2f vert(a2v v){
                v2f f; //声明输出结构
                f.pos = UnityObjectToClipPos (v.vertex);//把顶点坐标从模型空间转换到剪裁空间

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 normalDir = normalize( mul(v.normal, (float3x3)unity_WorldToObject)); //法线转换到世界空间
                fixed3 lightDir = normalize( _WorldSpaceLightPos0.xyz); //对于每个顶点,取得平行光世界空间下的位置(方向).
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot( normalDir, lightDir)); //得到漫反射的颜色
                f.color = ambient + diffuse;
                return f; //传递给片元着色器
            }

            float4 frag(v2f f) : SV_Target{ 
                return fixed4(f.color, 1);
            }

            ENDCG
        }
    }

    FallBack "Diffuse"
}
//兰伯特逐像素光照
Shader "Custom/Chapter 5/03_Diffuse2" {
    Properties {
        _Diffuse("Diffuse", Color) = (1.0, 1.0, 1.0, 1.0)
    }

    SubShader{
        Pass{

            Tags{ "LightMode"="ForwardBase" }

            CGPROGRAM

            #include "Lighting.cginc"
            #pragma vertex vert   //顶点着色器
            #pragma fragment frag //片元着色器

            //在Cg代码中,与属性名称和类型都匹配
            fixed4 _Diffuse;

            //application to vertex
            struct a2v{
                float4 vertex:POSITION; //模型顶点坐标 
                float3 normal:NORMAL; //法线 计算光照
            };

            //
            struct v2f{
                float4 pos:SV_POSITION;
                float3 worldNormal:TEXCOORD0;
            };

            v2f vert(a2v v){
                v2f f; //声明输出结构
                f.pos = UnityObjectToClipPos (v.vertex);//把顶点坐标从模型空间转换到剪裁空间
                f.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject); //法线转换到世界空间

                return f; //传递给片元着色器
            }

            float4 frag(v2f f) : SV_Target{ 

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 normalDir = normalize(f.worldNormal); //法线转换到世界空间
                fixed3 lightDir = normalize( _WorldSpaceLightPos0.xyz); //对于每个顶点,取得平行光世界空间下的位置(方向).
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot( normalDir, lightDir)); //得到漫反射的颜色
                fixed3 color = ambient + diffuse;

                return fixed4(color, 1);
            }

            ENDCG
        }
    }

    FallBack "Diffuse"
}
//半兰伯特光照模型 + BlinnPhong光照模型
Shader "Custom/Chapter 6/06_Specular Fragment BlinnPhong" {
    Properties {
        _Diffuse("Diffuse", Color) = (1.0, 1.0, 1.0, 1.0)   //材质的漫反射颜色
        _Specular("Specular", Color) = (1.0, 1.0, 1.0, 1.0) //材质的高光反射颜色
        _Gloss("Gloss", Range(2, 256)) = 20 //控制高光区域的大小
    }

    SubShader{
        Pass{

            //只有定义了正确的LightMode才能得到一些Unity的内置光照变量 _LightColor0
            Tags{ "LightMode"="ForwardBase" }

            CGPROGRAM

            #include "Lighting.cginc" //包含unity的内置的文件,才可以使用unity内置的一些变量 _LightColor0
            #pragma vertex vert   //顶点着色器
            #pragma fragment frag //片元着色器

            //在Cg代码中,与属性名称和类型都匹配 (0-1)使用 fixed精度的变量存储   _Gloss的变化范围大,使用float精度存储
            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            //application to vertex
            struct a2v{
                float4 vertex:POSITION; //模型顶点坐标 
                float3 normal:NORMAL; //法线 计算光照
            };

            //
            struct v2f{
                float4 pos:SV_POSITION;
                float3 worldNormal:TEXCOORD0;
                float3 worldPos:TEXCOORD1;
            };

            v2f vert(a2v v){
                v2f f; //声明输出结构
                f.pos = UnityObjectToClipPos (v.vertex);//把顶点坐标从模型空间转换到剪裁空间
                f.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject); //法线转换到世界空间
                f.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; //世界空间下的顶点坐标
                return f; //传递给片元着色器
            }

            float4 frag(v2f f) : SV_Target{ 

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 normalDir = normalize(f.worldNormal); //法线转换到世界空间
                fixed3 lightDir = normalize( _WorldSpaceLightPos0.xyz); //对于每个顶点,取得平行光世界空间下的位置(方向).
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot( normalDir, lightDir)); //得到漫反射的颜色

                //fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
                fixed3 viewDir = normalize(_WorldSpaceLightPos0.xyz - f.worldPos.xyz);
                fixed3 halfDir = normalize(normalDir + viewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot( normalDir, halfDir)), _Gloss);//得到高光反射的颜色

                fixed3 color = ambient + diffuse + specular;

                return fixed4(color, 1);
            }

            ENDCG
        }
    }

    FallBack "Diffuse"
}
所支持的Unity版本 5.2.0 及以上版本 WebGL Showcase | WebGL压力测试|文档|论坛 这个插件允许您通过生成真正容积的程序光束来大大改善场景的照明。 这是模拟聚光灯和手电筒的密度,深度和音量的完美,简单而便宜的方法。 简单高效的体积照明解决方案兼容各种平台(Windows PC,Mac OS X,Linux,WebGL,iOS,Android,VR)! 即使在移动设备上,也能为您的聚光灯和手电筒模拟密度,深度和体积的完美,简单且便宜的方式! 它通过自动高效地生成真正的体积程序光束来渲染高质量的光轴光线效果,从而极大地改善了场景的照明。 特征: - 真正的体积效果:即使你在光束中也能工作。 - 非常容易使用和集成/需要零设置。 - 程序生成:一切都是在引擎盖下动态计算的。 - 在任何地方添加无限光束:替代解决方案通常只需要实时灯光:此插件不需要。您可以制作烘烤的光量,甚至可以在没有任何光线的情况下添加光束。 - 动态3D噪声功能,用于模拟动画体积雾/雾/烟雾效果。 - 体积粉尘颗粒功能可模拟高度详细的防尘灯和微尘效果。 - 动态遮挡:可以通过移动几何体来阻挡光束。 - 您可以实时移动和旋转光束。 - 触发区域功能:您可以跟踪通过光束的对象。 - 完全动态:在游戏时间内从脚本,动画师或时间轴更改或动画每个属性。 - Super FAST:不需要任何后处理,命令缓冲区和计算着色器:即使在移动设备和WebGL等低性能平台上也能很好地工作。 - VR Ready:支持Normal和VR Single pass立体声。 - 平滑交叉并与几何和相机混合。 - 自定义截头圆锥几何体。 - 支持许多图形变体:延迟和前向渲染路径,Gamma和线性颜色空间,HDR颜色,多种混合模式。 - 调整分层图层和图层顺序,以使用2D精灵调整光束渲染。 - 开箱即用的透视和正交相机。 - 支持Unity内置雾。 - WYSIWYG:在场景视图中立即可以看到每个修改:无需在编辑器和播放模式之间切换以查看您的更改。 - 完整源代码可用/无DLL。光束设置和处理通过功能强大的API完全暴露。 - 详细的文件。 - 支持从Unity 5.2到最新的2017.X和2018.X版本。 - 示例场景包括:展示演示。 请注意,此资产不是全屏后期处理/图像效果。这与Unity内置的Sun Shafts图像效果不相似。 相反,体积光束将产生优化的几何形状和材料光谱。这种技术有几个优点: - 更精细:独立精确定制每个光束。 - 您可以在任何地方添加光束,即使在没有光线的地方也是如此。 - 当连接到聚光灯时,它支持实时,烘焙和混合模式。 - 您可以渲染的光束数量没有限制。 - 更容易与您自己的管道集成:无需与您自己的图像效果或后处理堆栈混合,没有命令缓冲区,不需要计算着色器功能。 - 运行得更快。没有后期处理添加到您的相机。 - 支持移动等低端平台。 如何使用它? 体积光束设计非常易于使用。无需设置。您不必将多个对象链接在一起。您只需要使用一个简单的新组件。你可以通过2次点击添加一个新的光束! 您可以通过调整一组用户友好的属性来精确定制每个光束的渲染。为了获得更好看的效果,一些属性会自动绑定到附加的聚光灯。 限制: 目前,此资产的当前版本有一些小的限制: - 此资产仅支持“聚光灯”(形状像锥形的光束)。不支持点光源(光线向各个方向平等)。 - “3D噪声”功能要求着色器功能等于或高于Shader Model 3.5 / OpenGL ES 3.0。 2012年之后发布的任何移动设备都应该支持它。 - 仅在Unity 5.5或更高版本上支持“体积粉尘颗粒”。 - “动态遮挡”功能计算遮挡的近似值,但尚不支持“部分遮挡”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值