123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /******************************************************************************/
- /* */
- /* Copyright (c)The 3Delight Team. */
- /* All Rights Reserved. */
- /* */
- /******************************************************************************/
- /*
- A light source for image based lighting.
-
- PARAMETERS
- light_color
- : a multiplier on the light from the envmap.
- Kenv : intensity multiplier
- Kocc : if >0, trace transmission rays to take into account occlusion
- by other objects
- envmap : the environment map to use
- envspace : the coordinate system where to place the environment map
- samples : number of samples to use to compute lighting. Setting samples
- to 0 will use the SH-based indirectdiffuse approximation
- without ray-tracing.
- bias : ray-tracing bias.
- */
- light lm_envlight2(
- color light_color = 1;
- float Kenv = 1.0;
- float Kocc = 0.0;
- string envmap = "", envspace = "world";
- float samples = 64;
- float maxdist = 1e10;
- float bias = -1;
- string __category = "env";
- float __nonspecular = 1;
- )
- {
- uniform string raytype="";
- rayinfo( "type", raytype );
- uniform string gather_cat = concat("environment:", envmap);
- vector envdir = 0;
- color envcolor = 0;
- float solidangle = 0;
- if( raytype == "light" )
- {
- /* This light is called to cast some photons. Use gather() to give us
- the most intersting directions and use a solar() construct to cast
- a photon coming from that direction. (The photon casting process
- is dealt with automagically inside 3Delight) */
- gather(
- gather_cat, 0, 0, 0, samples,
- "environment:color", envcolor,
- "environment:direction", envdir,
- "environment:solidangle", solidangle )
- {
- envdir = vtransform( envspace, "current", envdir );
- /* Convert from solid angle to angle */
- solar( -envdir, acos( 1-solidangle/(2*PI) ))
- {
- Cl = envcolor * light_color / (4*PI);
- }
- }
- }
- else
- {
- normal shading_normal = normalize(Ns);
- if( samples == 0 )
- {
- /* Use the SH-based approximation. */
- normal tN = ntransform( envspace, shading_normal );
- illuminate( Ps + shading_normal ) /* shade all surface points */
- {
- Cl = Kenv * light_color * indirectdiffuse( envmap, tN ) / (4*PI);
- }
- }
- else
- {
- uniform float t1 = 0.025 * sqrt(samples);
- uniform float t2 = 0.05 * sqrt(samples);
- illuminate( Ps + shading_normal ) /* shade all surface points */
- {
- Cl = 0;
- if( Kenv > 0 )
- {
- vector raydir = 0;
- gather(
- gather_cat, 0, 0, 0, samples,
- "environment:color", envcolor,
- "ray:direction", raydir,
- "environment:direction", envdir,
- "environment:solidangle", solidangle )
- {
- raydir = vtransform( envspace, "current", raydir );
- envdir = vtransform( envspace, "current", envdir );
- float atten = max( shading_normal . normalize(envdir), 0 );
- float kocc = 1 - smoothstep( t1, t2, solidangle );
- kocc *= Kocc;
- uniform float diffusedepth = 0;
- attribute( "diffusedepth", diffusedepth );
- color trs = 1;
- if( kocc > 0 && atten > 0 && diffusedepth==0 )
- {
- trs = transmission(
- Ps, Ps + raydir * maxdist, "bias", bias );
- trs = 1 - kocc * (1 - trs);
- }
- Cl += envcolor * trs * atten * light_color / (4*PI);
- }
- Cl *= Kenv;
- }
- }
- }
- }
- }
|