谈一下unity3d的光照

其实学习shader的话,搞unity开发,就是《unity 3d shaderLab开发实战详解》。unity在opengl的基础上又封装了了一个表面着色器,本id其实并不怎么喜欢写表面着色器,因为以前学习opengl的时候都没有听说过这个东西,其实表面着色器最终是要编译成顶点和片元着色器的。

今天本id突然想说起这个,是因为昨天下午被自己坑了一把,就导致了在unity编辑器上运行正常,手机上却看不到效果。就是对于点光源的光照计算,当然如果是平行光就不会出现这种情况,unity对于点光源的计算在《unity 3d shaderLab开发实战详解》这本书上也是有介绍的,这是原文:

VcHexL⒒渲染模式下,FomardBasc和
FowardAdd的 ughtM。 de都 不被支持。 另外,FwdAddX.shadcr在 3个 渲染路径下都没有输出,这
说明 FoⅢ ardAdd这个 Pass需 要和 FomardBasc— 起使用,否 则会被Unity所忽视掉。 在 Fomard
Dcfcrred渲 染路径下,Fomard的 Pass均 能被正常渲染。


下面是关于光照的shader:

Shader "Custom/LightAndOutline" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,1)
		_OutlineColor ("Outline Color", Color) = (1,1,1,1)
		_Outline ("Outline width", Range (0.0, 0.03)) = .005
		_MainTex ("Base (RGB)", 2D) = "white" { }
		_BumpMap ("Bumpmap", 2D) = "bump" {}
	}
 
	
 
	SubShader {
		//Tags { "Queue" = "Transparent" }
 
		// 描边通道
		/*Pass {
			CGINCLUDE
			#include "UnityCG.cginc"
			 
			struct appdata {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			struct v2f {
				float4 pos : POSITION;
				float4 color : COLOR;
			};
			 
			uniform float _Outline;
			uniform float4 _OutlineColor;
			ENDCG
			Name "OUTLINE"
			Tags { "LightMode" = "Always" }
			Cull Back
			ZWrite Off
			ZTest Less
			//Blend Off
			// you can choose what kind of blending mode you want for the outline
			Blend SrcAlpha OneMinusSrcAlpha // Normal
			//Blend One One // Additive
			//Blend One OneMinusDstColor // Soft Additive
			//Blend DstColor Zero // Multiplicative
			//Blend DstColor SrcColor // 2x Multiplicative

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			 v2f vert(appdata v) {
				// just make a copy of incoming vertex data but scaled according to normal direction
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
			 
				float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
				float2 offset = TransformViewToProjection(norm.xy);
			 
				o.pos.xy += offset * o.pos.z * _Outline;
				o.color = _OutlineColor;
				return o;
			}
			half4 frag(v2f i) : COLOR {
				return i.color;
			}
			ENDCG
		}*/
		
		Pass {  
			Tags{ "LightMode"="ForwardBase"}
			Cull Off
			Blend SrcAlpha OneMinusSrcAlpha 
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			struct appdata_t {
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
			};
			struct v2f_t {
				float4 vertex : SV_POSITION;
				half2 texcoord : TEXCOORD0;
			};
			sampler2D _MainTex;
			float4 _MainTex_ST;
			v2f_t vert (appdata_t v)
			{
				v2f_t o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				return o;
			}
			fixed4 frag (v2f_t i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.texcoord);
				return col;
			}
			ENDCG
		}
		
		
		//光亮通道
	Pass {  
			Tags{ "LightMode"="ForwardAdd"}
			Cull Off
			Blend One Zero
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			struct appdata_t {
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
				float3 normal : NORMAL;
			};
			struct v2f_t {
				float4 vertex : SV_POSITION;
				half2 texcoord : TEXCOORD0;
				float3 lightDir:TEXCOORD1;
				float color : COLOR;
			};
			sampler2D _MainTex;
			float4 _MainTex_ST;
			v2f_t vert (appdata_t v)
			{
				v2f_t o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				
				
				
				float3 lightColor = _LightColor0.xyz;
				o.lightDir = ObjSpaceLightDir(v.vertex);
				float cos_a = saturate(dot(o.lightDir, v.normal));
				cos_a = pow(lightColor*cos_a, 5);
				o.color = cos_a + 0.9;
				
				
				return o;
			}
			fixed4 frag (v2f_t i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.texcoord);
				col.r = col.r*i.color;
				col.g = col.g*i.color;
				col.b = col.b*i.color;
				return col;
			}
			ENDCG
		}
 
	}
 Fallback "Diffuse"
}

注意,这里的光照部分使用了两个通道,我们的光照计算主要在Tags{ "LightMode"="ForwardAdd"}这个通道中,书上说,要使得这个通道有效,必须有一个Tags{ "LightMode"="ForwardBase"}通道,所以在Add通道中需要使用Blend One Zero,把前一个通道隐藏起来。

这里只是简单光照模型,见笑了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章