博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity Shader 入门精要(03) -- Unity的基础光照
阅读量:1871 次
发布时间:2019-04-26

本文共 6037 字,大约阅读时间需要 20 分钟。

一、什么是光照模型

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

二、标准光照模型

在标准光照模型里面,我们把进入摄像机的光分为下面四个部分

自发光:光源散发的光。
高光反射 :光源照射到模型表面时,该表面会在完全镜面反射方向散射。
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"}

转载地址:http://sghff.baihongyu.com/

你可能感兴趣的文章
Java 读写锁
查看>>
JVM Minor GC、Full GC和Major GC
查看>>
SpringBoot @Scheduled 执行两次的问题
查看>>
tomcat配置JVM
查看>>
Ubuntu软件安装&卸载
查看>>
面试笔试易错知识点Java篇八
查看>>
弹性事务框架ETF4J——面向Java微服务的交易最终一致性解决方案
查看>>
【Scala 教程】Scala 条件与循环语句
查看>>
【Scala 教程】Scala 集合类型
查看>>
使用 jsDelivr CDN 对 Github 图床进行加速,带给你如丝滑般的图片体验!
查看>>
JAVA 线程同步机制 synchronized
查看>>
MySQL 安装教程(无脑版)
查看>>
IDEA 怎么删除一个Module
查看>>
中科院刘康:低资源环境下的事件知识抽取
查看>>
走进数据科学:最好是通过比网课更好的方法
查看>>
AI革命第一步:最容易被忽略但必不可少的物联网
查看>>
2020年开发运维工具清单:选择开发运维工具堆栈吧
查看>>
效率提升法则:高效人士不会去做的4件事
查看>>
8.PostgreSQL约束
查看>>
【技术分享】使用AES加密技术保障数据安全
查看>>