使用2个Pass增加光照效果;

第一个Pass是基础光源,一般是第一个平行光;Tags{"LightMode" = "ForwardBase"}

第二个光源是增加的光源,一般是点光源;Tags{"LightMode" = "ForwardAdd"} Blend One One

混合:Blend

 
这里例如我们给一个模型贴一个材质,那么在某个点计算出来颜色值称为源,而该点之前累积的颜色值,叫目标。
 
语法
Blend SrcFactor DstFactor  SrcFactor是源系数,DstFactor是目标系数
最终颜色 = (Shader计算出的点颜色值 * 源系数)+(点累积颜色 * 目标系数)
 
属性(往SrcFactor,DstFactor 上填的值)
one                          1
zero                         0
SrcColor                         源的RGB值,例如(0.5,0.4,1)
SrcAlpha                         源的A值, 例如0.6
DstColor                   混合目标的RGB值例如(0.5,0.4,1)
DstAlpha                         混合目标的A值例如0.6
OneMinusSrcColor          (1,1,1) - SrcColor
OneMinusSrcAlpha          1- SrcAlpha
OneMinusDstColor          (1,1,1) - DstColor
OneMinusDstAlpha          1- DstAlpha

我们在Pass中计算光源时,需要注意,是平行光还是点光源:

                 float3 lightDirection;
float atten; if(_WorldSpaceLightPos0.w==0.0)//平行光
{
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else
{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1.0/distance;
lightDirection = normalize(fragmentToLightSource);
}

源代码:

 Shader "JQM/MultipleLight"
{
Properties
{
_Color("Color", color) = (1.0,1.0,1.0,1.0)
_SpecColor("Specular Color", color) = (1.0,1.0,1.0,1.0)
_Shininess("Shininess",float) =
_RimColor("Rim Coloe Color", color) = (1.0,1.0,1.0,1.0)
_RimPower("Rim Power",Range(0.1,10.0)) = 3.0 }
SubShader{
Pass{ Tags { "LightMode" = "ForwardBase"} CGPROGRAM
#pragma vertex vert
#pragma fragment frag //使用自定义变量
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float4 _RimColor;
uniform float _Shininess;
uniform float _RimPower; //使用Unity定义的变量
uniform float4 _LightColor0; struct vertexInput{
float4 vertex:POSITION;
float3 normal:NORMAL;
}; struct vertexOutput{
float4 pos:SV_POSITION;
float4 posWorld:TEXCOORD0;
float3 normalDir:TEXCOORD1;
}; //顶点程序
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.posWorld = mul(_Object2World, v.vertex);
o.normalDir = normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
} //片段程序
float4 frag(vertexOutput i):COLOR
{ float3 normalDirection = i.normalDir;
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
float3 lightDirection;
float atten; if(_WorldSpaceLightPos0.w==0.0)//平行光
{
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else
{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1.0/distance;
lightDirection = normalize(fragmentToLightSource);
} //灯光
float3 diffuseReflection = atten * _LightColor0.xyz * saturate( dot(normalDirection,lightDirection));
float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess); //Rim Light
float rim= -dot(normalize(viewDirection),normalDirection);
float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
return float4(lightFinal*_Color.xyz,1.0);
} ENDCG
} Pass{ Tags { "LightMode" = "ForwardAdd"}
Blend One One CGPROGRAM
#pragma vertex vert
#pragma fragment frag //使用自定义变量
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float4 _RimColor;
uniform float _Shininess;
uniform float _RimPower; //使用Unity定义的变量
uniform float4 _LightColor0; struct vertexInput{
float4 vertex:POSITION;
float3 normal:NORMAL;
}; struct vertexOutput{
float4 pos:SV_POSITION;
float4 posWorld:TEXCOORD0;
float3 normalDir:TEXCOORD1;
}; //顶点程序
vertexOutput vert(vertexInput v)
{
vertexOutput o;
o.posWorld = mul(_Object2World, v.vertex);
o.normalDir = normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
} //片段程序
float4 frag(vertexOutput i):COLOR
{ float3 normalDirection = i.normalDir;
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
float3 lightDirection;
float atten; if(_WorldSpaceLightPos0.w==0.0)//平行光
{
atten = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else
{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
float distance = length(fragmentToLightSource);
atten = 1.0/distance;
lightDirection = normalize(fragmentToLightSource);
} //灯光
float3 diffuseReflection = atten * _LightColor0.xyz * saturate( dot(normalDirection,lightDirection));
float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess); //Rim Light
float rim= -dot(normalize(viewDirection),normalDirection);
float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
return float4(lightFinal*_Color.xyz,1.0);
} ENDCG
}
} }

多光源 MultipleLight的更多相关文章

  1. CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果

    CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果 开始 一图抵千言.首先来看鼠标拖动太阳(光源)的情形. 然后是鼠标拖拽旋转模型的情形. 然后我们移动摄像 ...

  2. Three.js的光源投影

    Three.js的光源默认不会导致物体间的投影,打开投影需要执行以下几步: 打开渲染器的地图阴影: renderer.shadowMapEnabled = true; 启用光线的投影:light.ca ...

  3. 解读Unity中的CG编写Shader系列八(多光源漫反射)

    转自http://www.itnose.net/detail/6117338.html 前文中完成最简单的漫反射shader只是单个光源下的漫反射,而往往场景中不仅仅只有一个光源,那么多个光源的情况下 ...

  4. three.js光源

    在Threejs中,光源用Light表示,它是所有光源的基类.它的构造函数是: THREE.Light ( hex ) 它有一个参数hex,接受一个16进制的颜色值.例如要定义一种红色的光源,我们可以 ...

  5. SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

    这是根据徐明亮<OpenGL游戏编程>书上光灯一节的一个例子改编的. 从这个例子可以学习到二次曲面的参数设置,程序中提供了两个画球的函数,一个是用三角形画出来的,一个是二次曲面构成的. 你 ...

  6. SharpGL学习笔记(十二) 光源例子:解决光源场景中的常见问题

    笔者学到光源这一节,遇到的问题就比较多了,收集了一些如下所述: (1) 导入的3ds模型,如果没有材质光照效果很奇怪.如下图 (2) 导入的3ds模型,有材质,灯光效果发暗,材质偏色,效果也很奇怪. ...

  7. 离线渲染中的不规则光源(Meshlight)

    之前一直在考虑这样一个问题,在实际生活中的光源都是有体积的,但是图形学中,很多时候我们用简单的点光源,面光源,或者方向光来模拟实际生活中这些光源,势必会产生一些误差,同时导致很多效果不好做.那么在离线 ...

  8. [原]Unity3D深入浅出 - 光源组件(Light)

    Unity中提供了四种光源: Directional light: 方向光,类似太阳的日照效果. Point light: 点光源,类似蜡烛. Spotlight: 聚光灯,类似手电筒. Area L ...

  9. OpenGL光源位置

    一.OpenGL光源简介 OpenGL提供了多种形式的光源,如点光源.平行光源和聚光灯光源等.所有光源都使用 glLight*接口来设置光源属性,其中包括 glLight{if} 和 glLight{ ...

随机推荐

  1. iOS NSDictionary <--> NSString(JSON) in Objc

    NSDictionary --> NSString + (NSString*)stringINJSONFormatForObject:(id)obj { NSData *jsonData = [ ...

  2. IP地址简单入门

    ------------------------针对网络地址相关的小白,最快速接触网络知识------------------------- 可以使用python自带的模块IPy,进行处理IP地址或I ...

  3. Median Value

    Problem A: Median Value Time Limit: 1 Sec Memory Limit: 128 MB Submit: 874 Solved: 307 [Submit][Stat ...

  4. 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)

    (另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...

  5. 找规律 UVALive 6506 Padovan Sequence

    题目传送门 /* 找规律:看看前10项就能看出规律,打个表就行了.被lld坑了一次:( */ #include <cstdio> #include <algorithm> #i ...

  6. VS2010的一个错误,无法加载类型

    一个解决方案中的一个项目X,启动时总是报错,无法加载一个同一个解决方案中另一个项目A生成EXE中的数据类型. 做了如下的步骤解决问题. 1:检查项目A,未发现错误,调试启动A,一切正常. 2:检查项目 ...

  7. 基于Windows7下snort+apache+php 7 + acid(或者base) + adodb + jpgraph的入侵检测系统的搭建(图文详解)(博主推荐)

    为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习.人工智能.区域链研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物理机 ...

  8. AJPFX总结Socket的低层次Java网络编程

    Socket的低层次Java网络编程 1 Socket通讯 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接. ...

  9. 5 月编程语言排行榜:Java第一,R跌出Top20

    我们都知道,最近,TIOBE 发布了 5 月份编程语言排行榜.其中,前三名依然健稳不变,他们分别是 Java.C.C++,第四则为: Python ,第五则为 VB .NET. 下面两张图,我们可以看 ...

  10. 内置函数isinstance和issubclass

    1. isinstance(obj,class) 判断对象obj是不是由class生成的对象. class Foo: pass obj=Foo() print(isinstance(obj,Foo)) ...