home *** CD-ROM | disk | FTP | other *** search
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License Version
- # 1.1 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS" basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # The Original Code is the Python Computer Graphics Kit.
- #
- # The Initial Developer of the Original Code is Matthias Baas.
- # Portions created by the Initial Developer are Copyright (C) 2004
- # the Initial Developer. All Rights Reserved.
- #
- # Contributor(s):
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the GPL or the LGPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK *****
- # $Id$
-
- import os.path
- import protocols
- from Interfaces import *
- from slots import *
- import lookat
- from lightsource import LightSource
- import ribexport
- from math import *
-
- # MayaSpotLight
- class MayaSpotLight(LightSource):
- """This class represents a spotlight that approximates a Maya spot light.
-
- The direction of the light is the local negative Z axis.
- """
-
- protocols.advise(instancesProvide=[ISceneItem, ribexport.ILightSource])
-
- def __init__(self,
- name="MayaSpotLight",
- enabled = True,
- color = (1,1,1),
- intensity = 1.0,
- decayRate = 0,
- coneAngle = 40,
- penumbraAngle = 0,
- dropoff = 0,
-
- useDepthMapShadows = False,
- dmapResolution = 512,
- useMidDistDmap = True,
- useDmapAutoFocus = True,
- dmapFocus = 90.0,
- dmapFilterSize = 1,
- dmapBias = 0.001,
-
- target=vec3(0,0,0), # spot
- **params
- ):
-
- LightSource.__init__(self, name=name, **params)
-
- # target = vec3(target)
-
- # Target
- # self.target_slot = Vec3Slot(target)
- # self.addSlot("target", self.target_slot)
-
- self.enabled = enabled
- self.color = vec3(color)
- self.intensity = float(intensity)
- self.decayRate = int(decayRate)
- self.coneAngle = float(coneAngle)
- self.penumbraAngle = float(penumbraAngle)
- self.dropoff = float(dropoff)
-
- self.useDepthMapShadows = bool(useDepthMapShadows)
- self.dmapResolution = int(dmapResolution)
- self.useMidDistDmap = bool(useMidDistDmap)
- self.useDmapAutoFocus = bool(useDmapAutoFocus)
- self.dmapFocus = float(dmapFocus)
- self.dmapFilterSize = float(dmapFilterSize)
- self.dmapBias = float(dmapBias)
-
- def protocols(self):
- return [ISceneItem]
-
-
- def createPasses(self):
- """Returns a list of RenderPass objects."""
-
- if self.useDepthMapShadows:
- if self.useDmapAutoFocus:
- fov = max(self.coneAngle, self.coneAngle+2*self.penumbraAngle)
- else:
- fov = self.dmapFocus
- shadpass = ribexport.ShadowPass(
- output = [("shadow.z", "zfile", "z", {})],
- light = self,
- fov = fov,
- resolution = self.dmapResolution,
- orientoffset = mat4(1).rotation(pi, vec3(0,1,0))
- )
- return [shadpass]
-
- return []
-
- def shaderName(self):
- """Returns the name of the corresponding light shader or None.
- """
- return "mayaspotlight"
-
- def shaderSource(self):
- """Returns surface shader source code as a string or None.
- """
- return """// MayaSpotLight shader
-
- light $SHADERNAME(
- uniform color lightcolor = color "rgb" (1, 1, 1);
- uniform float intensity = 1.0;
- uniform float decayRate = 0;
- uniform float coneAngle = 40.0;
- uniform float penumbraAngle = 0.0;
- uniform float dropoff = 0.0;
-
- uniform string dmapName = "";
- uniform float dmapFilterSize = 1;
- uniform float dmapBias = 0.001;
- )
- {
- uniform vector axis = normalize(vector "shader" (0,0,-1));
- uniform float coneAngle2 = radians(0.5*coneAngle);
- uniform float penumbra_start = coneAngle2;
- uniform float penumbra_end = coneAngle2;
- if (penumbraAngle<0)
- penumbra_start += radians(penumbraAngle);
- else
- penumbra_end += radians(penumbraAngle);
- uniform float penumbra_range = penumbra_end-penumbra_start;
-
- illuminate(point "shader" (0,0,0), axis, penumbra_end)
- {
- vector L0 = normalize(L);
- float dist = length(vtransform("world", L));
- float att = 1.0;
-
- // Penumbra
- float angle = acos(L0.axis);
- // Linear decay inside the penumbra
- // att *= clamp(1.0-(angle-penumbra_start)/penumbra_range, 0.0, 1.0);
- // Smooth decay inside the penumbra
- att *= 1.0-smoothstep(penumbra_start, penumbra_end, angle);
-
- // Dropoff
- // att *= clamp(2.0-pow(exp(angle),dropoff/255), 0.0, 1.0);
-
- // Decay
- if (dist>1.0)
- att /= pow(dist, decayRate);
-
- Cl = att * intensity * lightcolor;
-
- if (dmapName!="")
- Cl *= 1.0 - shadow(dmapName, Ps, "width", dmapFilterSize, "bias", dmapBias, "samples", 32);
-
- }
- }
- """
-
- def shaderParams(self, passes):
- """Return a dictionary with shader parameters and their values."""
- params = {"intensity":self.intensity,
- "uniform color lightcolor":self.color,
- "uniform float decayRate":self.decayRate,
- "uniform float coneAngle":self.coneAngle,
- "uniform float penumbraAngle":self.penumbraAngle,
- "uniform float dropoff":self.dropoff,
- }
- if self.useDepthMapShadows and passes[0].done():
- zfile = passes[0].realFilename(passes[0].output[0][0])
- mapname = os.path.splitext(zfile)[0]+".map"
- params["uniform string dmapName"] = mapname
- params["uniform float dmapFilterSize"] = self.dmapFilterSize
- params["uniform float dmapBias"] = self.dmapBias
- return params
-
-
-
-