Cg入门17:Fragment shader - 片段级光照(添加阴影)

投射阴影

方法一:添加一个单独的pass通道

pass

{

Tags{"LightMode" = "ShadowCaster"}

}

ShadowCaster:阴影投射器,可以投射阴影

方法二:添加物体默认阴影投射

FallBack "Diffuse"

然后给光线开启阴影:

效果如下:(效果图为添加平行光)

如果要让我们的shader支持点光源阴影投射,就添加 FallBack "Diffuse"

添加点光源后效果:

接收阴影:让我们的球平面接受阴影

源代码:

Shader "Sbin/MyDiffuse_Shadow" {
	SubShader {

//		pass{
//			tags{"lightmode" = "shadowcaster"}
//		}

		pass{
			tags{"lightmode" = "ForwardBase"}   //现实一个平行光按像素计算		

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			#pragma multi_compile_fwdbase		//多版本编译
			#include "autolight.cginc"

			struct v2f{
				float4 pos : POSITION;
				float4 color : COLOR;
				LIGHTING_COORDS(0,1)
			};

			v2f vert(appdata_base v){
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP,v.vertex);

				float3 N = normalize(v.normal);
				float3 L = normalize(_WorldSpaceLightPos0);

				N = mul(float4(N,0),_World2Object).xyz;
				N = normalize(N);

				float ndot = saturate(dot(N,L));
				o.color = _LightColor0 * ndot;

				//点光源
				float3 wpos = mul(_Object2World,v.vertex).xyz;
				o.color.rgb += 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,wpos,N);

				TRANSFER_VERTEX_TO_FRAGMENT(o);	//传送阴影

				return o;
			}

			fixed4 frag(v2f v):COLOR
			{
				float atten = LIGHT_ATTENUATION(v);//光照衰减

				fixed4 col = (v.color + UNITY_LIGHTMODEL_AMBIENT);
				col.rgb *= atten;

				return col;
			}

			ENDCG
		}

		//--------------------------------------------------------------------------

		pass{
			tags{"lightmode" = "ForwardAdd"}	//平行光和顶点光全部按像素计算,是像素光就调用一次这个pass

			blend one one 	//叠加上一个pass的颜色值

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "Lighting.cginc"
			#pragma multi_compile_fwdadd_fullshadows
			#include "autolight.cginc"

			struct v2f{
				float4 pos : POSITION;
				float4 color : COLOR;
				LIGHTING_COORDS(0,1)
			};

			float4 _MainColor;
			float4 _SpecalarColor;
			float _Shininess; 

			v2f vert(appdata_base v){
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP,v.vertex);

				float3 N = normalize(v.normal);
				float3 L = normalize(_WorldSpaceLightPos0);

				N = mul(float4(N,0),_World2Object).xyz;
				N = normalize(N);

				float ndot = saturate(dot(N,L));
				o.color = _LightColor0 * ndot;

				//点光源
				float3 wpos = mul(_Object2World,v.vertex).xyz;
				o.color.rgb += 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,wpos,N);

				TRANSFER_VERTEX_TO_FRAGMENT(o);

				return o;
			}

			fixed4 frag(v2f v):COLOR
			{
				float atten = LIGHT_ATTENUATION(v);

				fixed4 col = v.color;
				col.rgb *= atten;

				return col;
			}

			ENDCG
		}
	} 

	fallback "Diffuse"
}

总结:

1.设置支持多版本编译:

#pragma multi_compile_fwdbase        //多版本编译

2.pass 与pass 叠加

blend one one     //叠加上一个pass的颜色值

3.添加tags

tags{"lightmode" = "ForwardBase"} //现实一个平行光按像素计算    

tags{"lightmode" = "ForwardAdd”}  //平行光和顶点光全部按像素计算,是像素光就调用一次这个pass

时间: 2024-10-13 01:43:52

Cg入门17:Fragment shader - 片段级光照(添加阴影)的相关文章

Cg入门16:Fragment shader - 片段级光照

将顶点程序实现漫反射放至片段程序后处理效果如下: 看到和左边内建实现的漫反射一样了 片段程序特点: 1.采用三角面的形式渲染,而顶点程序是按顶点形式渲染 注意事项:直接将计算好的顶点法线向量和光向量 直接传给片段程序使用 效果如下:为啥不一样呢? 顶点程序: 1.按顶点计算,一个顶点一个顶点处理程序 片段程序: 1.先进行光栅化,把面片分割成三角形, 2.一个片段程序,可以看成一个一个像素处理 原因: 1.由于面片程序,分割成很多个小三角形处理,但是一下三角形上的法线和光向量相同,就导致了这种现

Cg入门19:Fragment shader - 片段级模型动态变色

y值要表示范围为[-0.5,0.5],所以语义要注意不要用Color(注意:Color 语义值范围为[0,1] ) (特别注意:内建的cube范围才是[-0.5,0.5],其它模型就不一定是这个值了噢) 发现顶部没有融合掉.为了所有融合掉.我们将_Center范围+R的大小,就所有融合了 效果例如以下: 优化:去掉if else,由于if else 可能在其它硬件上不能运行. 代码: Shader "Sbin/vf55" { Properties { _UpColor("Up

Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)

Unity 一个面片的最大顶点数为65524,所以大于这个数,请拆分成多个面片 1.获取汽车x轴的最大值和最小值[-2.5,2.5]+R surfaceShader 语法 surf :surface shader的方法名 vert :使用顶点程序方法名 surface shader 方法不能有返回值 源代码: Shader "Sbin/SurfaceShader" { Properties { _Glossiness ("Smoothness", Range(0,1

UnityShader之顶点片段着色器Vertex and Fragment Shader【Shader资料】

顶点片段着色器 V&F Shader:英文全称Vertex and Fragment Shader,最强大的Shader类型,也是我们在使用ShaderLab中的重点部分,属于可编程管线,使用的是CG/HLSL语法.分为vertex顶点部分和Fragment像素部分. 本篇的末尾讲述顶点函数传入的结构体类型的参数appdata_base. Shader "Custom/Exam1" { Properties { _MainTex ("Texture", 2D

Android官方入门文档[16]创建一个Fragment代码片段

Android官方入门文档[16]创建一个Fragment代码片段 Creating a Fragment创建一个Fragment代码片段 This lesson teaches you to1.Create a Fragment Class2.Add a Fragment to an Activity using XML You should also read?Fragments 这节课教你1.创建一个Fragment代码片段类2.使用XML来添加一个Fragment代码片段给一个活动 你也

【Unity Shaders】Vertex & Fragment Shader入门

写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判断的,因此,对于那些平整的表面,它们的法线通常是一个常量或者会发生突变(例如立方体的每个面),这样就会导致最后的效果并非如我们所愿.如下图所示: 因此,我们有一个更好的方法来实现描边效果,也就是通过两个pass进行渲染--首先渲染对象的背面,用黑色略微向外扩展一点,就是我们的描边效果:然后正常渲染正

【Unity Shaders】Shader中的光照

写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已.当然,我相信这是因为我们写得少...不过这也是由于官方文档对这方面介绍很少的缘故,导致我们无法自如地处理很多常见的光照变量.这篇我们就来讨论下Unity内置的一些光照变量和函数到底怎么用. 以下内容均建立在Forward Rendering Path的基础上. 自己总结的,如果有硬伤一定要告诉我啊!感激不尽~ 主要参考: http://en.wikibooks.org/wiki/Cg_P

Unity3D教程宝典之Shader篇:第三讲Vertex&Fragment Shader

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院 Vertex and Fragment Shader:最强大的Shader类型,也是本系列的重点,下文中简称V&F Shader,属于可编程渲染管线. 使用的是CG/HLSL语法.分为2个部分vertex顶点部分和Fragment像素部分.下面依然通过写几个简单的Shader来学习. 例一:显示一张贴图 新建Unity工程,新建一个Cube立方体,新建一个名为Exam1的Shader(Project视图->Create->Sh

3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader

上节的最后我们实现了两个绿色的三角形,而绿色是直接在Fragment Shader中指定的. 这节我们将为这两个三角形进行更加自由的着色--五个顶点各自使用不同的颜色. 要实现这个目的,我们分两步进行,首先 在顶点数组里增加数据用来表示颜色 修改sendDataToOpenGL()函数中的verts数组: 1 GLfloat verts[] = 2 { 3 +0.0f, +0.0f, //Vertex 0 4 +1.0, +0.0, +0.0f, //Color 0 5 +1.0f, +1.0f