Environment map (cube texture) is designed for global illumination of single object.
Suitable for
- static objects: YES
- dynamic objects: YES
- realtime calculated illumination: YES
- precalculated illumination: YES
Advantages
- offers global illumination with both specular and diffuse reflections
- object doesn't have to be part of static scene, no RRObject adapter is required
- calculation is independent to object complexity, quick even for extremely complex objects
Disadvantages
- precision decreases with size of object, suitable for characters and items, not for buildings
- complexity of objects doesn't matter, but count of environment map updates does, so if you need large clouds/crowds of dynamic objects visible all at once, share one environment map for several close objects and update it only once to save time
Interface, implementations
Instances
Rendering
- Many rendering techniques are based on faked precomputed environment maps. Here you get realtime computed environment maps, and you are free to use them for any purpose.
- Request environment (cube) map to be generated in center of your object. Environment map may be later used by GPU to add global illumination to diffuse and specular surfaces close to given point in space.
- We propose you several techniques:
For rough surface with mostly diffuse reflection, read value from environment map's small mip level, using 'surface normal' as a coordinate. This single texture lookup gives you global illumination of pixel. Multiply it by material diffuse color to get final color.
For smooth surface with specular reflection, read value from environment map, using 'eye direction reflected by surface' as a coordinate. Use smaller or larger mip level based on material shininess. This single texture lookup gives you global illumination of pixel. Don't modulate it by material color unless you want to render exotic materials, you already have final color. Size 16 of environment map is often good compromise between environment update speed and reflection sharpness.
You can use normal map or height map to modulate surface normal. Both diffuse and specular surfaces respond well to bump maps.
LightsprintGL implements all of these techniques.
- Global illumination can be further improved if you use ambient occlusion map for your dynamic object. Multiply global illumination read from environment map by ambient occlusion read from ambient occlusion map to get more precise result. Ambient occlusion maps are computed for example by BuildLightmaps sample.
Examples
- OpenGL example:
Rendering with environment maps.
GLuint program;
...
solver->updateEnvironmentMap(illumination);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(program,"diffuseEnvironmentMap"),0);
glActiveTexture(GL_TEXTURE1);
glUniform1i(glGetUniformLocation(program,"specularEnvironmentMap"),1);
glDrawElements...
Data structure with object's illumination and more.
Definition RRIllumination.h:40
Global illumination solver for interactive applications.
Definition RRSolver.h:58
void bindTexture() const
Binds texture.
RR_GL_API Texture * getTexture(const rr::RRBuffer *buffer, bool buildMipMaps=true, bool compress=true, int magn=GL_LINEAR, int mini=GL_LINEAR, int wrapS=GL_REPEAT, int wrapT=GL_REPEAT)
Converts rr::RRBuffer to Texture so it can be immediately used as a texture in OpenGL.
Applying environment maps in GLSL fragment shader: uniform samplerCube specularEnvironmentMap;
uniform samplerCube diffuseEnvironmentMap;
void fragmentShader()
{
vec3 worldNormal = ...;
vec3 worldView = ...;
vec3 worldViewReflected = reflect(worldView,worldNormal);
...
gl_FragColor = ...
+ materialDiffuseReflectance *
textureCube(diffuseEnvironmentMap, worldNormal)
+ materialSpecularReflectance *
textureCube(specularEnvironmentMap, worldViewReflected);
}
- Direct3D 9 example:
Rendering with environment maps. IDirect3DDevice9* device;
IDirect3DPixelShader9* pixelShader;
...
solver->updateEnvironmentMap(illumination);
device->SetPixelShader(pixelShader);
...
device->DrawPrimitive...
Applying environment maps in HLSL pixel shader: samplerCUBE specularEnvironmentMap;
samplerCUBE diffuseEnvironmentMap;
void pixelShader(..., out float4 oColor: COLOR)
{
float3 worldNormal = ...;
float3 worldView = ...;
float3 worldViewReflected = reflect(worldView,worldNormal);
...
oColor = ...
+ materialDiffuseReflectance *
texCUBE(diffuseEnvironmentMap, worldNormal)
+ materialSpecularReflectance *
texCUBE(specularEnvironmentMap, worldViewReflected);
}
- See Direct3D, OpenGL or your engine documentation for more details on texturemapping and applying environment maps.