Shader山下(十四)顶点片段着色器处理光照
来源:互联网 发布:重生之娱乐网络帝国 编辑:程序博客网 时间:2024/05/20 20:58
Shader山下(二)光照模型——漫反射里介绍了如何为表面着色器添加光照模型,但是在顶点片段(vertex-fragment)着色器里如何处理光照呢?
本文就实现一个与内置Lambert光照模型相同效果的VF着色器。
Shader "Custom/Frag/Light" {Properties {_MainTex ("Base (RGB)", 2D) = "white" {}}SubShader {Tags { "RenderType"="Opaque" }LOD 200Pass {Tags { "LightMode" = "ForwardBase" }CGPROGRAM#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"#include "AutoLight.cginc"sampler2D _MainTex;float4 _MainTex_ST;struct a2v {float4 vertex : POSITION; fixed3 normal : NORMAL; fixed4 texcoord : TEXCOORD0;fixed4 color : COLOR;};struct v2f {float4 pos : POSITION;float2 uv : TEXCOORD0;float3 worldNormal : TEXCOORD1;float3 lightDir : TEXCOORD2;float3 viewDir : TEXCOORD3;LIGHTING_COORDS(4,5)//1};v2f vert(a2v v) {v2f o;//Transform the vertex to projection spaceo.pos = mul(UNITY_MATRIX_MVP, v.vertex);//Get the UV coordinateso.uv = TRANSFORM_TEX (v.texcoord, _MainTex); //Normalo.worldNormal = mul(SCALED_NORMAL, (float3x3)_World2Object);//2//Light Directiono.lightDir = mul((float3x3)_Object2World, ObjSpaceLightDir(v.vertex));//3//View Directiono.viewDir = mul((float3x3)_Object2World, ObjSpaceViewDir(v.vertex));//4//Shadow TRANSFER_VERTEX_TO_FRAGMENT(o);//5return o;}inline fixed4 LightingFragLambert(fixed4 fcol, fixed3 lightDir, fixed atten, half3 worldNormal){fixed difLight = max(0, dot (normalize(worldNormal), normalize(lightDir)));fixed4 col;col.rgb = fcol.rgb * _LightColor0.rgb * (difLight * atten);col.a = fcol.a;return col;}half3 calDiffuse(half3 pos, half3 worldNormal){half3 ambient = Shade4PointLights (unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,unity_4LightAtten0, pos, worldNormal);ambient = ShadeSHPerVertex (worldNormal, ambient);return ShadeSHPerPixel (worldNormal, ambient);}float4 frag(v2f i) : COLOR {fixed4 texColor = tex2D(_MainTex, i.uv);fixed4 fragColor = LightingFragLambert(texColor, i.lightDir, LIGHT_ATTENUATION(i), i.worldNormal);//6half3 diffuse = calDiffuse(i.pos, i.worldNormal);//7fragColor.rgb += texColor.rgb * diffuse;//8return fragColor;}ENDCG}} FallBack "Diffuse"
比较关键或者需要解释的几个点我都用注释加了序号。
第1处,这个宏对应了第5处,LIGHTING_COORDS声明了两个变量,一个是_LightCoord,一个是_ShadowCoord,而第5处计算了这两个值(用兴趣的可以研究一下AutoLight.cginc,这里不多赘述)。在第6处的LIGHT_ATTENUATION(也在AutoLight.cginc里面)计算光衰减值(也就是我们熟悉的atten)时使用了这两个值。
第2处,计算法线向量。
第3处,计算光照向量。
第4处,计算视图向量。
第6处,为了对应表面着色器,我们特意定义了一个LightingFragLambert方法。简单讲一下,就是根据像素点与光照方向的角度,将像素色彩值与光照色彩值相乘。
第7处,这里定义了一个vertDiffuse的方法,用于计算顶点漫反射的色彩值,它在第8处使用到。
第8处,第7处得到的diffuse值与贴图色彩值相乘,加到上面的结果中去(似乎是为了取代atten * 2)。
效果:
使用Lambert光照模型的表面着色器的效果:
(大家来找茬)
1 0
- Shader山下(十四)顶点片段着色器处理光照
- Shader(顶点片段着色器)
- unity shader 可编程管线(二) 顶点和片段着色器(Vertex Shader and Fragmet Shader)
- Shader山下(八)片段着色器
- 顶点、片段着色器
- 顶点,片段着色器
- 【Unity Shader学习笔记】(二)最基本的顶点片段着色器
- Shader山下(十)表面着色器的顶点函数
- shader入门 《顶点着色器 与 片段(像素)着色器》概念
- shader 入门 《顶点着色器 的输出 和 片段着色器的 输入》
- 顶点和片段着色器
- 顶点和片段着色器
- Unity Shader 顶点和片段着色器(Vertex and Fragment Shader)
- 顶点着色器(vertex shader)
- Unity Shader:细分着色器(Tessellation Shader)在顶点与片段着色器中的写法以及各参数变量解释。
- 增加顶点和片段着色器
- [UnityShader2]顶点片段着色器实例(一)
- [UnityShader2]顶点片段着色器实例(二)
- The following packages have been kept back:
- MATLAB卷积
- 抽象工厂模式
- 【纯干货】中国的支付清算体系是怎么玩的?
- Android中使用SharedPreferences封装的本地读取类
- Shader山下(十四)顶点片段着色器处理光照
- 马云的五新其实没有哪一个是新的
- 表达式(一)
- 学习笔记-java实现复制、移动、删除文件夹
- 后缀数组
- Tair简介
- 解决无法删除表,提示被外键约束引用
- 文献阅读(6)
- 亲测详解ubuntu14.04+cuda8.0+gtx1080+caffe