包含光照,可处理多个光源,有光照衰减和阴影的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. ionic中执行pop返回上一个页面,还需要执行操作

    <ion-navbar> </ion-navbar> 从A页面push到B页面拿到数据以后,从B页面pop到A页面,在A页面展示刚刚拿到的数据,用 ionViewDidEnte ...

  2. oplog

    参考资料:https://www.cnblogs.com/ruizhang3/p/6539730.html http://www.jb51.net/article/113432.htm :insert ...

  3. jpa持久化对象四种状态

    自己理解,不完全正确,大致如下: 例:某实体类   Person(int id,string name,int age);   id 为主键. 新建:new Person(),  并且未给 id 赋值 ...

  4. 下载JDK和Jmeter并设置系统环境变量

    一.JDK下载并设置系统环境变量 1.JDK官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 点左边的 ...

  5. LeetCode 561 Array Partition I 解题报告

    题目要求 Given an array of 2n integers, your task is to group these integers into n pairs of integer, sa ...

  6. Python开发【笔记】:PEP 8 编码规范

    PEP 8 编码规范     https://bk.tencent.com/document/bkrule/040101.pdf                                     ...

  7. 基于Gogs+Drone搭建的私有CI/CD平台

    请移步 基于Gogs+Drone搭建的私有CI/CD平台

  8. python摸爬滚打之day02----while循环,运算符,格式化输出

    1.while循环 1.1  结构:while +条件判断: while 循环体 else: 条件不成立时语句块 while...else...是一个循环整体,当循环条件成立时执行while循环体内容 ...

  9. WPF 参数在Page见传递

    void goButton_Click(object sender, RoutedEventArgs e) { this.NavigationService.Navigate(new ContentP ...

  10. jquery有几种选择器?

    ①.基本选择器:#id,class,element,*: ②.层次选择器:parent > child,prev + next,prev ~ siblings: ③.基本过滤器选择器::firs ...