kensonuken Posted January 4, 2009 Share Posted January 4, 2009 (edited) http://img218.imageshack.us/img218/4839/at...edshadowqx5.png Inspired by this http://www.studioinverse.com/3db-site/html...ow.php#occluder but want to get a very simple approach... I tried to decaying the shadow with distance with the following code... it works fine but its getting transparent in the beginning stage of shadow start... len = lenght(L); float start_shadow = 5; float end_shadow = 40; if( len > end_shadow ) shadowatten = 0; /* no more shadow after 40 */ else if( len < start_shadow ) shadowatten = 1; /* full shadowing before 5 */ else { /* simple linear interpolation. You can add the decay here too. */ shadowatten = 1 - (len - start_shadow) / (end_shadow-start_shadow); } Edited January 4, 2009 by Jason please use [code] [/code] tags Quote Link to comment Share on other sites More sharing options...
Jason Posted January 4, 2009 Share Posted January 4, 2009 You might want to just use a clamp( lerp(), 0, 1 ) function to make it more legible and reliable. I haven't tried it, btw:) Quote Link to comment Share on other sites More sharing options...
kensonuken Posted January 8, 2009 Author Share Posted January 8, 2009 (edited) lerp of shadowatten ? is it this? len = lenght(L); float start_shadow = 5; float end_shadow = 40; if( len > end_shadow ) shadowatten = 0; /* no more shadow after 40 */ else if( len < start_shadow ) shadowatten = 1; /* full shadowing before 5 */ else { /* simple linear interpolation. You can add the decay here too. */ shadowatten = 1 - (len - start_shadow) / (end_shadow-start_shadow); shadowat = clamp ( shadowatten, 0, 1); } Edited January 8, 2009 by kensonuken Added [code][/code] tags Quote Link to comment Share on other sites More sharing options...
kensonuken Posted January 11, 2009 Author Share Posted January 11, 2009 (edited) hi jason is there anyway that I can use this shader? // light shader that explores a strategy for soft shadows // Bertrand Bry-Marfaing // www.3db-site.com // Mai 2008 light softShadowSpot( float intensity = 1; color lightColor = 1; float coneAngle = 35; // in degrees float penumbraAngle = 5; // outside the coneAngle string shadowMap = ""; float samples = 64; float shadowBias = 0.01; float minRadius = 0.001; float maxRadius = 0.1; float biasConeSlope = 2; float shadowDecay = 0; // shadow decreases with occluder distance float shadDecayDistMin = 10; float shadDecayDistMax = 25;) { uniform float illumAngle = radians( coneAngle/2 + penumbraAngle ); uniform float cosoutside = cos( illumAngle ); uniform float cosinside = cos( radians( coneAngle/2 ) ); uniform vector lightDir = vector "shader" ( 0,0,1 ); /* _______ generate a series of random coordinates ______ (implementation of Hammersley point set) */ uniform float sampleCoordX[ samples ]; uniform float sampleCoordY[ samples ]; // note: init of variable size array (although uniform variable in this case) does not compile with prman. uniform float iter = 0; // find the num of decimals uniform float numOfDigits = ceil( log( samples, 2 ) ); uniform float revBinValues[ numOfDigits ]; for( iter = 0; iter < samples; iter += 1 ) { // generate binary fractions and their reversed uniform float digit = 0; uniform float remainder = iter; for( digit = (numOfDigits - 1); digit >= 0; digit -= 1 ) { uniform float power = pow( 2, digit ); if ( remainder >= power ) { revBinValues[ digit ] = 1; remainder -= power; } else revBinValues[ digit ] = 0; } // convert back to floats uniform float x = 0; uniform float y = 0; uniform float index = 0; for( index = 1; index <= numOfDigits; index += 1 ) { x += ( pow( 2, -index ) * revBinValues[ numOfDigits-index ] ); y += ( pow( 2, -index ) * revBinValues[ index-1 ] ); } // scale x to compensate for the non-power-of-two sample numbers x *= pow( 2, numOfDigits ) / samples ; // store coordinates sampleCoordX[ iter ] = x; sampleCoordY[ iter ] = y; } // ___________________________________ /* Function that interprets the previously generated x,y coordinates as angle and radius, and retruns the new coordinates. Output samples may be denser around 0,0 (for averaging occluder depth) or evenly spread (for shadowing sampling ) */ float randomNumber = float random(); void HammersleyToRadial( float shadowSampling; output float sampleCoordX; output float sampleCoordY ) { ; // if these samples are for light shadowing sampling if ( shadowSampling == 1 ){ // samples should be evenly distributed sampleCoordY = sqrt( sampleCoordY ); // vary the samples positions per shaded point extern float randomNumber; sampleCoordX = mod( sampleCoordX + randomNumber, 1 ); } float angleOfSample = sampleCoordX * 2 * PI; sampleCoordX = cos( angleOfSample ) * sampleCoordY; // cos = adj / hypot sampleCoordY = sqrt( pow( sampleCoordY, 2 ) - pow( sampleCoordX, 2 ) ); // a2 + b2 = c2 if( angleOfSample > PI ) sampleCoordY *= -1; } // ___________________________________ /* Function that samples the shadow map, returns sampled depth and normalised raster distance of sample */ float sampleShadowMap( float pShadS; float pShadT; float sampleX; float sampleY; float radius; float uniformSampling; output float distFromPs ) { extern string shadowMap; // sample coord float ss = sampleX; float tt = sampleY; HammersleyToRadial( uniformSampling, ss, tt ); ss *= radius; tt *= radius; ss += pShadS; tt += pShadT; // find distance from Ps coord distFromPs = distance( point( pShadS, pShadT, 0), point( ss, tt, 0 ) ); // sample map without filtering return texture( shadowMap, ss, tt, "width", 0.00001 , "samples", 1 ); // this will generate warnings at compilation time with 3Delight } // ___________________________________ illuminate( point "shader" ( 0,0,0 ), lightDir, illumAngle ) { Cl = 0; float cosangle = normalize( L ).lightDir; float atten = smoothstep( cosoutside, cosinside, cosangle ); float shadowValue = 0; if ( shadowMap != "" ) { /* _____ Compute soft shadow _____ */ // get the s and t coord of Ps on shadowmap float pShadS, pShadT; uniform matrix shadProjSpace; textureinfo( shadowMap, "projectionmatrix", shadProjSpace ); point shadProjP = transform( shadProjSpace, Ps ); pShadS = ( 1 + xcomp( shadProjP ) ) * 0.5; pShadT = ( 1 - ycomp( shadProjP ) ) * 0.5; // get Ps distance from shadow plane uniform matrix shadCamSpace; textureinfo( shadowMap, "viewingmatrix", shadCamSpace ); point shadCamP = transform( shadCamSpace, Ps ); float PsDepth = zcomp( shadCamP ); // get the average occluder depth in shadowmap around Ps float avrgedDepth = 0; float totalWeight = 0; float iterator = 0; for ( iterator = 0; iterator < samples; iterator += 1 ) { float sampleDepth, distFromPs; sampleDepth = sampleShadowMap( pShadS, pShadT, sampleCoordX[ iterator ], sampleCoordY[ iterator ], maxRadius, 0, distFromPs ); // weight according to raster distance from Ps coord if ( (sampleDepth+shadowBias) < PsDepth ) { float sampleWeight = 1 - 0.9 * ( distFromPs / maxRadius ); totalWeight += sampleWeight; avrgedDepth += ( sampleDepth * sampleWeight ); } } if ( totalWeight > 0 ) avrgedDepth /= totalWeight; // _________________________________________ if( avrgedDepth > 0 ) // there is an occluder { // compute the radius of the filter float filterRadius = minRadius + (( maxRadius-minRadius ) * ( 1 - ( avrgedDepth / PsDepth ))); // sample the shadow map with varying filter width avrgedDepth = 0; totalWeight = 0; // get the shadow occlusion of Ps for ( iterator = 0; iterator < samples; iterator += 1 ) { float sampleDepth, distFromPs; sampleDepth = sampleShadowMap( pShadS, pShadT, sampleCoordX[ iterator ], sampleCoordY[ iterator ], filterRadius, 1, distFromPs ); // add bias cone sampleDepth += shadowBias + ( distFromPs * biasConeSlope ); if ( sampleDepth < PsDepth ) { shadowValue += 1; // if shadow decay if( shadowDecay > 0 ) { // store the occluder depth of the new sampling disc float sampleWeight = 1 - 0.9 * ( distFromPs / filterRadius ); totalWeight += sampleWeight; avrgedDepth += ( sampleDepth * sampleWeight ); } } } shadowValue /= samples; // __________________________________________ // decrease light attenuation as Ps moves further from occluder if ( shadowDecay > 0 ) { if ( totalWeight > 0 ) avrgedDepth /= totalWeight; float distFromOccluder = PsDepth - avrgedDepth; shadowValue *= 1 - ( smoothstep( shadDecayDistMin, shadDecayDistMax, distFromOccluder ) * shadowDecay ); } // __________________________________________ } atten *= ( 1 - shadowValue ); } Cl = intensity * lightColor * atten; } } Edited January 11, 2009 by kensonuken Quote Link to comment Share on other sites More sharing options...
Jason Posted January 11, 2009 Share Posted January 11, 2009 hi jason is there anyway that I can use this shader? I assume you mean to use this in Mantra, correct? Sure, I don't see why this shader couldn't be converted to VEX. It's worth a shot... why not try to do that? Quote Link to comment Share on other sites More sharing options...
kensonuken Posted January 12, 2009 Author Share Posted January 12, 2009 yeah we will do that.. Quote Link to comment Share on other sites More sharing options...
Jason Posted January 12, 2009 Share Posted January 12, 2009 yeah we will do that.. Cool, let us know how that turns out! Quote Link to comment Share on other sites More sharing options...
deecue Posted June 11, 2009 Share Posted June 11, 2009 hey kensonuken, have you had much progress on this? I'd be interested in seeing something like this if you've had a chance to develop it some more. hopefully it becomes efficient enough and lacking in artifacts.. i suppose those are the challenges.. just curious as it'd be cool to see some alternatives to area lights.. cheers, dave Quote Link to comment Share on other sites More sharing options...
kensonuken Posted June 14, 2009 Author Share Posted June 14, 2009 as of now busy in production but this is in highest prio so will lay my hands on as soon as i get free..... in the mean time if anybody want to take up a move then pls... will try to work on this... Quote Link to comment Share on other sites More sharing options...
deecue Posted June 15, 2009 Share Posted June 15, 2009 cool.. thanks for the update.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.