Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
461 views
in Technique[技术] by (71.8m points)

three.js - Calculating the position on spotlight cone in Phong shader

I'm trying to implement light cookies (or gobos, or light textures, or light masks) for THREE.SpotLight in PhongMaterial in WebGLRenderer. The aim is to be able to attach a texture for a light, something like this: http://www.idjnow.com/ProductImagesLarge/GOBO-GLASS1C.jpg The texture would lower the intensity of the light, producing a shadow-like projection.

I think I have the "attaching a texture to light and passing it as a uniform for lookup in shader" covered, although haven't been able to test it, because I'm having problems calculating my position in the spotlight cone / spot.

I see the light contribution of spotlights is calculated here (I'm modifying the Three.js source directly, instead of creating my own material):

https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLShaders.js#L1013

The spot of spotlight is a circle, right? Or ellipse if its on an angle. So I would need to add some code here, that would tell me where in the spotlight spot I am (xy coordinates). I could map these coordinates on a texture lookup, lower the spotDiffuse accordingly, and hopefully have working gobo projection.

How could I calculate these coordinates in relation to each light?

Or is there better way to implement light cookies / gobos / light textures / light masks in Three.js? I see it's a popular feature in game engines, would be nice to have something like that built-in. http://docs.unity3d.com/Documentation/Components/class-Light.html describes pretty well what I'm looking for (the cookie parts).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Have a look here: http://www.evpopov.com/threejstest/test_spot_projtexture.html

I think it is doing what you want.

It is in fact standard projective texturing, except the texture is not used "as is" but instead attenuate the lighting calculation.

For this sample, I have used the alpha channel of the projective texture as the attenuation factor.

To create the vertex/fragment shaders I use, I have taken the vertex/fragment shaders from the phong material and kept only the relevant part for spot light rendering. I have also setup a constant ambient color to avoid having black areas (outside of the spot range).

The specific code for projective texturing has comments starting by // in the vertex/fragment shaders, if you want to reuse that in your own shaders.

You also have to generate the projection matrix corresponding to your light: the makeProjectiveMatrixForLight function does it for you => it's nearly the same code you can find in three JS source code for shadow mapping.

When launching the example, the wall rotates and the spot light stays fixed. You can make the target of the spot light moves by changing moveLightTarget to true, in which case you would want to set rotateCube to false to better see what is going on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...