包含光照,可处理多个光源,有光照衰减和阴影的shader,代码如下:

转载请注明出处:http://www.cnblogs.com/jietian331/p/7199311.html

Shader "Custom/Bumped Specular"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_NormalMap("Normal Map", 2D) = "bump" {}
_Specular("Specular", Color) = (,,,)
_Gloss("Gloss", Range(, )) =
} SubShader
{
Tags
{
"Queue" = "Geometry"
"RenderType" = "Opaque"
} Pass
{
Tags
{
"LightMode" = "ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase #include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc" sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _NormalMap;
float4 _NormalMap_ST;
fixed4 _Specular;
float _Gloss; struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
fixed4 color : COLOR;
float4 tangent : TANGENT;
float3 normal : NORMAL;
}; struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
fixed4 color : COLOR;
float4 T2W1 : TEXCOORD1;
float4 T2W2 : TEXCOORD2;
float4 T2W3 : TEXCOORD3;
SHADOW_COORDS()
}; v2f vert(appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float2 uv1 = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
float2 uv2 = v.uv.zw * _NormalMap_ST.xy + _NormalMap_ST.zw;
o.uv = float4(uv1, uv2);
o.color = v.color; float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
float3 worldNormal = UnityObjectToWorldNormal(v.normal);
float3 binormal = cross(normalize(worldNormal), normalize(worldTangent)) * v.tangent.w;
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.T2W1 = float4(worldTangent.x, binormal.x, worldNormal.x, worldPos.x);
o.T2W2 = float4(worldTangent.y, binormal.y, worldNormal.y, worldPos.y);
o.T2W3 = float4(worldTangent.z, binormal.z, worldNormal.z, worldPos.z);
TRANSFER_SHADOW(o);
return o;
} fixed4 frag(v2f i) : SV_TARGET
{
float3 worldPos = float3(i.T2W1.w, i.T2W2.w, i.T2W3.w);
float3 worldLight = normalize(UnityWorldSpaceLightDir(worldPos));
float3 worldView = normalize(UnityWorldSpaceViewDir(worldPos)); fixed4 albedo = tex2D(_MainTex, i.uv.xy) * i.color;
float3 tangentNormal = UnpackNormal(tex2D(_NormalMap, i.uv.zw));
float3x3 tanToWorld = float3x3(i.T2W1.xyz, i.T2W2.xyz, i.T2W3.xyz);
float3 worldNormal = mul(tanToWorld, tangentNormal); fixed3 ambient = albedo.xyz * UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 diffuse = albedo.xyz * _LightColor0.xyz * max(, dot(worldLight, worldNormal)); float3 halfDir = normalize(worldLight + worldView);
fixed3 specular = albedo.xyz * _Specular * pow(max(, dot(worldNormal, halfDir)), _Gloss); UNITY_LIGHT_ATTENUATION(atten, i, worldPos); fixed3 col = ambient + (diffuse + specular) * atten;
return fixed4(col, );
} ENDCG
} Pass
{
Tags
{
"LightMode" = "ForwardAdd"
}
Blend One One CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd_fullshadows #include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc" sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _NormalMap;
float4 _NormalMap_ST;
fixed4 _Specular;
float _Gloss; struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
fixed4 color : COLOR;
float4 tangent : TANGENT;
float3 normal : NORMAL;
}; struct v2f
{
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
fixed4 color : COLOR;
float4 T2W1 : TEXCOORD1;
float4 T2W2 : TEXCOORD2;
float4 T2W3 : TEXCOORD3;
SHADOW_COORDS()
}; v2f vert(appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
float2 uv1 = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
float2 uv2 = v.uv.zw * _NormalMap_ST.xy + _NormalMap_ST.zw;
o.uv = float4(uv1, uv2);
o.color = v.color; float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
float3 worldNormal = UnityObjectToWorldNormal(v.normal);
float3 binormal = cross(normalize(worldNormal), normalize(worldTangent)) * v.tangent.w;
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.T2W1 = float4(worldTangent.x, binormal.x, worldNormal.x, worldPos.x);
o.T2W2 = float4(worldTangent.y, binormal.y, worldNormal.y, worldPos.y);
o.T2W3 = float4(worldTangent.z, binormal.z, worldNormal.z, worldPos.z);
TRANSFER_SHADOW(o);
return o;
} fixed4 frag(v2f i) : SV_TARGET
{
float3 worldPos = float3(i.T2W1.w, i.T2W2.w, i.T2W3.w);
float3 worldLight = normalize(UnityWorldSpaceLightDir(worldPos));
float3 worldView = normalize(UnityWorldSpaceViewDir(worldPos)); fixed4 albedo = tex2D(_MainTex, i.uv.xy) * i.color;
float3 tangentNormal = UnpackNormal(tex2D(_NormalMap, i.uv.zw));
float3x3 tanToWorld = float3x3(i.T2W1.xyz, i.T2W2.xyz, i.T2W3.xyz);
float3 worldNormal = mul(tanToWorld, tangentNormal); fixed3 diffuse = albedo.xyz * _LightColor0.xyz * max(, dot(worldLight, worldNormal)); float3 halfDir = normalize(worldLight + worldView);
fixed3 specular = albedo.xyz * _Specular * pow(max(, dot(worldNormal, halfDir)), _Gloss); UNITY_LIGHT_ATTENUATION(atten, i, worldPos); fixed3 col = (diffuse + specular) * atten;
return fixed4(col, );
} ENDCG
}
} Fallback "Specular"
}

效果如下:

Unity shader学习之标准的Unity shader的更多相关文章

  1. unity shader学习笔记(1) shader基础结构以及Properties面板

    首先是shader的基础结构: Shader "Custom/Example { Properties//变量属性面板 { } SubShader { Tags { "Render ...

  2. Unity Shader 学习之旅之SurfaceShader

    Unity Shader 学习之旅之SurfaceShader unity shader 图形图像  如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...

  3. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

  4. Unity Shader 学习之旅

    Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...

  5. [转]Unity Shader 学习总结

    1.先来一段单张纹理贴图的shader示例代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClip ...

  6. 第四章 开始Unity Shader学习之旅(3)

    1. 程序员的烦恼:Debug 调试(debug),大概是所有程序员的噩梦.而不幸的是,对一个Shader进行调试更是噩梦中的噩梦.这也是造成Shader难写的原因之一--如果发现得到的效果不对,我们 ...

  7. 第四章 开始Unity Shader学习之旅(2)

    目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...

  8. Unity Shader学习笔记-1

    本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...

  9. Unity的shader学习2

    下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. Shade ...

随机推荐

  1. 结构体指针 Pointers to Structures struct Books Book1; struct Books *struct_pointer;

    小结: 1.To access the members of a structure using a pointer to that structure, you must use the → ope ...

  2. 1 byte 8 bit 1 sh 1 bit 2. 字符与编码在程序中的实现

    https://en.wikipedia.org/wiki/Shannon_(unit) 1字节(英语:Byte)=8比特(英语:bit) The shannon (symbol Sh), also ...

  3. Flash and Scalform CLIK

    Flash shift + f7 打开组件检查面板 Scaleform As bit define bool                Unrolling       :1;    // indi ...

  4. Java基础知识之锁

    Java中实现锁的方式有多种,并且锁的分类也有很多,这篇文章会从锁分类方面简单介绍各分类的锁的特点. 悲观锁和乐观锁 悲观锁:先假设别人也会对数据就行修改,所以先获得锁再进行操作.一个县城在获得锁之后 ...

  5. sshd_config配置详解

    sshd_config配置详解 名称 sshd_config - OpenSSH SSH 服务器守护进程配置文件 大纲 /etc/ssh/sshd_config 描述 sshd(8) 默认从 /etc ...

  6. Java+Selenium 如何处理Try/Catch

    场景:为了检查数据是否存在,如果存在就把数据删除,不存在则新增保存.因为我们需要做下数据初始化准备工作. 一.:Feature 示例: Scenario: E-251:维护薪资帐套明细 When I ...

  7. ES6面试题总结

    1.说出至少5个ES6的新特性,并简述它们的作用.(简答题) 1.let关键字,用于声明只在块级作用域起作用的变量: 2.const关键字,用于声明一个常量: 3.结构赋值,一种新的变量赋值方式.常用 ...

  8. es组合多个条件进行查询

    GET /test_index/_search{ "query": { "bool": { "must": { "match&qu ...

  9. Ubuntu上Xilinx ARM交叉编译器安装

    1,Windows中下载交叉编译器 2,在ubuntu中创建zedboard目录,并将交叉编译器复制进来 3,将该交叉编译器设置成可执行程序 chmod  a+x  xilinx-2011.09-50 ...

  10. explain之key_len计算

    通常在优化SQL查询的时候,我们都会使用explain分析SQL执行计划,通常来说当用到组合索引的时候我们如何判断索引完全用上呢?当然高手看看表结构及SQL语句就知道到底用到了几个字段,对于不熟悉的同 ...