Unity3D游戏开发从零单排(十) - 进击的Shader续

自定义光照模型

在这之前首先来了解一下SurfaceOutput这个结构体,它是一个包含大多数描述一个物体表面渲染特征的结构,具体结构如下:

struct SurfaceOutput {
	half3 Albedo;//纹理颜色
	half3 Normal;//法线
	half3 Emission;//自发光,不受照明的影响
	half Specular;//高光指数
	half Gloss;//光泽度
	half Alpha;//Alpha通道
};

基本上所有的Shader函数要处理的就是这个结构体。

Unity自带的光照实现都定义在一些*.cginc文件中,要自定义光照模型,只要不用Unity自带的光照模型就可以了。

将下面这一行的语句的最后替换成对应的光照计算函数。

#pragma surface surf  NoLight

无光照的材质Shader

Shader "Custom/NoLight" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
		#pragma surface surf NoLight

		sampler2D _MainTex;
		inline float4 LightingNoLight(SurfaceOutput s, fixed3 lightDir, fixed3 atten)
		{
			float4 col;
			col.rgb = s.Albedo;
			col.a = s.Alpha;
			return col;
		}

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}

		ENDCG
	}
	FallBack "Diffuse"
}

自己实现一个diffuse

inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
	float difLight = max(0, dot (s.Normal, lightDir));
	float4 col;
	col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
	col.a = s.Alpha;
	return col;
}

上图中左边是NoLight,右边是SimpleDiffuse。

同理可以自定义实现各种光照模型了,Lambert,Blinning,,,,,

补充一下光照函数的几种写法

half4 LightingName (SurfaceOutput s, half3 lightDir,half atten){}

这个函数用于不需要视角方向的情况下的Forward rendering。

half4 LightingName (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten){}

这个函数用于需要视角方向的情况下的Forward rendering。

half4 LightingName_PrePass (SurfaceOutput s, half4 light){}

这个函数用于Deferred rendering。

用代码控制shader动态修改材质

对SimpleDiffuse稍微做一下修改,添加一个叠加的颜色。

Shader "Custom/SimpleDiffuse" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Color ("Main Color", Color) = (0,1,0,1)
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;
		float4 _Color;

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb * _Color.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

在模型(有MeshRenderer的)上面挂一个脚本,实现如下

MeshChanger

using UnityEngine;
using System.Collections;

public class MaterialChanger : MonoBehaviour {
	float time = 0.0f;
	float changeSpeed1 = 2.0f;
	float changeSpeed2 = 5.0f;
	Renderer render;

	// Use this for initialization
	void Start () {
		render = transform.GetComponent<Renderer>();
	}

	// Update is called once per frame
	void Update () {
		float v1 = (Mathf.Cos(time * changeSpeed1) + 1.0f) * 0.5f;
		float v2 = (Mathf.Sin(time * changeSpeed2)+ 1.0f) * 0.5f;

		render.materials[0].SetColor("_Color", new Color(v1, v2, v2));
		time += Time.deltaTime;
	}
}

根据时间动态修改0号材质的_Color选项,结果就像这样

自行脑补中间过程。

使用渐变纹理来处理光照

首先要准备一张渐变纹理,原理就是通过计算当前位置的光照与法线的点积,索引到渐变图片上的像素值,最后将其和diffuse叠加。

Shader "Custom/RampTexture" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_RampTex ("Ramp Tex (RGB)", 2D) = "white" {}

	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
		#pragma surface surf RampLight

		sampler2D _MainTex;
		sampler2D _RampTex;

		half4 LightingRampLight (SurfaceOutput s, half3 lightDir, half atten)
		{
			half NdotL = dot(s.Normal, lightDir);
			float diff = NdotL * 0.5 + 0.5;
			half3 ramp = tex2D(_RampTex, float2(diff, diff)).rgb;
			half4 c;
			c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
			c.a = s.Alpha;
			return c;
		}

		struct Input {
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

渲染结果

没有纹理的情况(是大象不是小猪)

换一下索引贴图

得到结果如下(Toon Shading)

参考

Unity Shaders and Effects CookBook

时间: 2024-10-22 08:08:56

Unity3D游戏开发从零单排(十) - 进击的Shader续的相关文章

Unity3D游戏开发从零单排(九) - 进击的Shader

提要 今天要学习的是一些Shader 的例子,从简单到难.Let's go. 一大波例子来袭 还是用上一篇用到的工程.点我下载 红色的螃蟹 Test1.shader Shader "Custom/Test1" { SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float4 color : COLO

Unity3D游戏开发从零单排(六) - 人物运动及攻击连击

提要 今天要实现的是一个简单人物控制器.包括用w,a,s,d来控制人物上下左右跑动,鼠标左击发出连招,都是基于老的lagacy的动画.虽然unity3d自带有charactorcontroller,但是并不是很好用,所以人物控制相关的全部自己来实现.先上效果图: 场景搭建 首先下载这个package,里面包含了人物的动作还有地面的模型.将人物和地面都拖进场景中.这里的模型默认的动画模式是lagacy,不用修改.模型有点偏小,改变模型的scale值为10.最好不要改源文件的scale的scale

Unity3D游戏开发从零单排(五) - 导入CS模型到Unity3D

游戏动画基础 Animation组件 Animation组件是对于老的动画系统来说的. 老的动画形同对应的动画就是clip,每个运动都是一段单独的动画,使用Play()或CrossFade(),直接播放动画 或淡入淡出播放动画. animation.Play("name"); animation.CrossFade("name"); 下面的是它的几个属性 Animation:默认的动画片段: Aniamtions:包含的动画片段: Play Automaticall

Unity3D游戏开发从零单排(七) - NetworkView的Demo

提要 今天做了一个移动设备的网络通信demo,分两个部分,一个是网络连接,一个是数据通信. 需要两台Android设备A,B.A作客户端,B作服务端. 最终的效果是玩家控制设备A中的方块,B中的方块也一起动,同时在A的加速度传感器的信息在B中也实时更新. 网络连接 首先两台设备要联网,且IP在同一个网段,比如连接在同一个路由上,或者通过笔记本发出wifi信号,然后把设备连在上面. 在Unity3d中创建一个新工程,在场景中创建两个空物体,一个Client,一个Server. 在client创建一

Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

提要 此篇是一个国外教程的翻译,虽然有点老,但是适合新手入门.自己去写代码,debug,布置场景,可以收获到很多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一篇中,我们学会了怎么在Unity中搭建游戏的场景,并且设置模型的物理属性. 在第二篇中,我们学会了怎么在unity中使用脚本,并且创建了大部分的游戏逻辑,包括投球和得分! 在这最后一节中,我们将会为用户创建一个菜单系统,并且和GameController进行交互,我们开始吧. 在设备上测试 到目前为止,

Unity3D游戏开发从零单排(三) - 极速创建狂拽酷炫的游戏地形

提要 在Unity工作流程内,地形是一个必不可少的重要元素.不论是游戏或虚拟现实都会使用到各种类型的地形效果,在这个教学中我们须要了解到地形的制作基本概念与,当中对于Unity的地形操作部分须要大量的操作练习.熟悉这些功能操作之后,相信对于游戏地形的制作与运用将会更得心应手. 先看终于效果: 环境:windows7 64bit Unity3d4.2.1 所需资源:terrain.raw 创建project File  ->  New project 选择project存放的位置,同一时候导入 S

Unity3D游戏开发从零单排(八) - Shader基础

提要 今天要说的是Unity3D中shader相关的一些知识.不会做非常细致的讲解(东西实在太多!- -),但是看完之后会知道shader是怎么用的. 一些术语 在shader编程中,有一些术语,有时候不明白的话容易被整懵圈,所以这里就简单提一下. Shading Shading最开始指的在素描中给物体画明暗调子,在图形学中,其实就是给Mesh上色(Mesh就是一堆三角面片,包含顶点左边,法线坐标,uv坐标之类的),wiki中说的是根据物体相对于光线的角度及其距离光源距离改变物体颜色生成phot

零基础unity3d游戏开发系列目录

零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(一) 零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(二) 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)界面... 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目I 零基础unity3d游戏开发系列 第二章:unity3d概览(一)创建与打开项目II 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目III 零基础Unity3D游戏开发

unity3D游戏开发实战原创视频讲座系列10之《保卫战:异形入侵》游戏开发第一季

讲解目录 <保卫战:异形入侵>游戏开发    1 第一讲   游戏演示和资源的介绍    1 第二讲  "异形"怪物的实现    1 第三讲  "异形"怪物生命值的体现    9 第四讲  "异形"怪物死后处理    12 第五讲  玩家的制作    15 第六讲  玩家的行走控制(键盘)    16 第七讲  武器的切换(鼠标)     16 第八讲  摄像头的变化(鼠标)    19 第九讲  子弹预制体和特效的制作    20