1.可能是着色器预置了一定数目的光源信息,使用时只要数目在预置数目之下,都没问题
2.可能是每增加一个光源,就多加一个该光源类型的着色器
实际渲染的时候分别对应每个光源逐个执行各自的着色器,把结果放帧缓冲区内,最后再合成
N年前做了一个,你看这个如何?演示地址:http://test.pc365.net/light.htm
(如打不开,请多刷新几次)
代码如下:
===========================================================
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=gb2312">
<title>烛光效果</title>
<STYLE>
.drag
{CURSOR: hand
POSITION: relative
filter:blur(strength=12)
}
</STYLE>
<SCRIPT language=JavaScript>
var dragapproved=false
var z,x,y
function move()
{
if(event.button==1&&dragapproved)
{z.style.pixelLeft=temp1+event.clientX-x
z.style.pixelTop=temp2+event.clientY-y
movelight(z.style.pixelLeft,z.style.pixelTop)
return false
}
}
function drags()
{
if(!document.all) return
if(event.srcElement.className=="drag")
{
dragapproved=truez=event.srcElement
temp1=z.style.pixelLeft
temp2=z.style.pixelTop
x=event.clientXy=event.clientY
document.onmousemove=move
}
}
function setlight(xx,yy)
{
// main.filters.light(0).addambient(235,239,129,110)
main.filters.light(0).addpoint(xx,yy,50,235,239,169,100)
//x坐标,y坐标,扩散范围,颜色,颜色,颜色,强度
//main.filters.light(0).addcone(xx,yy,0,100,100,200,204,200,180,20)
}
//第一个参数:光源的X坐标;第二个参数:光源的Y坐标;第三个参数:光源离开页面的高度;
//第四至第六个参数:光源的颜色;第七个参数:光源光的色相;第八个参数:光源的形状;
//第九个参数:光源的光的强度 ;第十个参数:光源光散开的范围。
function movelight(xx,yy)
{
xx+=400
yy+=50
main.filters.light(0).clear()
setlight(xx,yy)
}
document.onmousedown=drags
document.onmouseup=new Function("dragapproved=false")
</SCRIPT>
</head>
<body bgcolor="#000000" topmargin="0" leftmargin="0">
<div id='Layerw' style='position: absoluteleft: 0top:50width: 100%height: 40z-index: 1' align="center">
<img src="http://test.pc365.net/lz.gif" alt="蜡烛照明 拖动使用" class=drag width="98" height="120">
</div>
<div align="center" >
<center>
<table id="main" border="0" width="780" cellpadding="0" cellspacing="0" height="580" background="images/house.gif" style="filter:light">
<tr >
<td width="100%">
<p align="center"><img id="pt" border="0" src="http://test.pc365.net/123456.jpg" ></p>
</td>
</tr>
</table>
</center>
</div>
</body>
</html>
<script>setlight(400,50)</script>
平行光本质是一个方向向量,在shader中计算时直接与模型顶点的法线方向进行dot点乘操作。
如果L(平行光)的向量与N(顶点法线方向)一样(N Dot L=1),那么表示模型的这个点正对着光源,应该最亮,相反,如果两个向量呈相反方向(N Dot L=-1),那么则表示这个点背对光源,应该最暗。
基础的兰伯特计算模型的明暗就是NdotL。
与Unity中的平行光不一样的是,Unity中平行光仅使用方向不使用位置来表示平行光方向;而Three.js中是设定一个起点和一个终点(默认为0,0,0),来确定平行光的方向。因此Three.js中通常在创建完成后设定一下光照的位置,如下:
平行光是可以产生阴影的,需要将castShadow打开,如下
也可以设置光源照射的对象target,光的照射终点会跟随着物体移动(默认为上述的0,0,0)。
无论在Unity中还是Three.js中,平行光通常是场景中的主光源,也通常是产生阴影、计算亮暗面的主要光源。