The real way to do an environment map for diffuse lighting is horrifically expensive.

Essentially every pixel in your cube map can be treated as a small area light (for simplicity a point light with direction vector towards the center of the texel).

It works for specular reflection because your materials are super shiny and have tight (narrow) specular lobes which have high values only in a few discrete directions so you can point sample the cube map.

If you want something either more rough, or worse Lambertian (diffuse) youd need to blur/average/integrate over large portions of the cube map (hence the need for mip maps resulting from gaussian blur).

These two will explain it

http://http.developer.nvidia.com/GPUGem ... _ch19.htmlhttp://http.developer.nvidia.com/GPUGem ... ter10.htmlContrary to what REDDemon says, generating SH from a cubemap is piss easy every band coefficient is simply a sum of all texels weighted by their solid angle and the band's basis function value in the texel's direction (basic integration of a piece-wise constant function on a sphere). Obviously if you start taking into account the linear, cubic or sinc interpolation between individual texels this might become more complicated but with large enough resolution this doesn't make a difference, just make sure you use RGB 32bit float textures for the SH band calculation.

Best part is that SH dont need filtering down for rougher materials, they already have the mip-map data inside themselves.

To evaluate lighting you need to simply calculate the SH coefficients of you lighting distribution (diffuse plus specular lobe oriented in the right direction), these can be precalculated fairly easily and because they are rotationally symmetrical they are a zonal harmonic which can be rotated out to match the lobe direction.

Since the lighting function should be an integration (convolution) of the lighting distribution against the enviornment incoming light distribution, in the frequency space its merely a dot product of the SH band coefficients.

The problem stems from the fact that most applications limit themselves to 3 band (9 coeff) or 4 band (16 coeff) spherical harmonics, while the diffuse material lobe's SH band expansion decays very quickly past the 3rd band and futher bands contribute less than 1% towards the final value, the specular doesn't behave anywhere near as nicely. Cutting off frequencies (assuming the farther bands are 0, and hence not using them) can introduce ringing, that's where the research comes in on either filtering your lighting function distribution or filtering the environment map to obtain nicer SH coefficients.

P.S. Best part is, if you're projecting the lightmap of a level into a spherical harmonic at point X, you only need to consider the parts of the lightmap which:

A) Have light value higher than 0 (since SH is a sum of weighted values)

B) Are visible from point X (rendering into a cubemap first solves this problem in a naive way, but visibility can be precalculated)

C) Are large enough when viewed from point X (you can combine this with (A) to cull certain contributions)

We chose to stream mesh data from Multiple OpenGL Contexts in many threads and do the other things, not because they are easy, but because they are hard! - JFK