There is not much documentation out there but from what I've found I have derived the following code for creating a cube map texture and rendering to it around a point light position. Just wondering if its close to being right.
creating the cubemap
device->CreateCubeTexture( 1024, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F,
D3DPOOL_DEFAULT, &cubeTexture, 0 );
rendering the depth environment around the light position to a cubemap
LPDIRECT3DSURFACE9 BackBuffer, ZBuffer;
LPDIRECT3DSURFACE9 cubeFace;
D3DMATRIX matProj;
D3DMATRIX matView;
D3DXVECTOR3 lightPos( light.x, light.y, light.z );
D3DXVECTOR3 up ( 0.0f, 1.0f, 0.0f );
D3DXVECTOR3 upForTop( 0.0f, 0.0f, 1.0f );
D3DXVECTOR3 upForBot( 0.0f, 0.0f, -1.0f );
D3DXVECTOR3 negX ( light.x-1.0f, light.y, light.z );
D3DXVECTOR3 posX ( light.x+1.0f, light.y, light.z );
D3DXVECTOR3 negY ( light.x, light.y-1.0f, light.z);
D3DXVECTOR3 posY ( light.x, light.y+1.0f, light.z );
D3DXVECTOR3 negZ ( light.x, light.y, light.z-1.0f );
D3DXVECTOR3 posZ ( light.x, light.y, light.z+1.0f );
//saving old back and depth buffers
device->GetRenderTarget(&BackBuffer);
device->GetDepthStencilSurface(&ZBuffer);
//setup 90 degree field of view projection
D3DXMatrixPerspectiveFovRH(&matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f);
device->SetTransform(D3DTS_PROJECTION, &matProj);
//render to all sides of cubemap
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_NEGATIVE_X, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, negX, up);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_POSITIVE_X, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, posX, up);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, negY, upForBot);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_POSITIVE_Y, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, posY, upForTop);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, negZ, up);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
cubeTexture->GetCubeMapSurface( D3DCUBEMAP_FACE_POSITIVE_Z, 0, &cubeFace);
device->SetRenderTarget ( 0, cubeFace );
D3DXMatrixLookAtRH(&matView, lightPos, posZ, up);
device->SetTransform( D3DTS_VIEW, &matView );
device->Clear(0,NULL,D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
drawScene();
//restore old buffers
device->SetRenderTarget ( 0, BackBuffer );
shaders for filling the distance cubemap
////////VERTEX SHADER
float4x4 ModelViewProj : WORLDVIEWPROJ;
float4x4 ModelWorld : WORLD;
float4 lightPos;
struct VS_INPUT
{
float4 position : POSITION;
};
struct VS_OUTPUT
{
float4 hposition : POSITION;
float3 lightVec : TEXCOORD0;
};
VS_OUTPUT main( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.hposition = mul( IN.position, ModelViewProj );
//getting the position of the vertex in the world
float4 posWorld = mul(IN.position, ModelWorld);
//getting vertex -> light vector
OUT.lightVec = lightPos - posWorld;
return OUT;
}
////////PIXEL SHADER
struct VS_OUTPUT
{
float4 hposition : POSITION;
float3 lightVec : TEXCOORD0;
};
struct PS_OUTPUT
{
float4 color : COLOR;
};
PS_OUTPUT main( VS_OUTPUT IN )
{
PS_OUTPUT OUT;
OUT.color = length(lightVec);
return OUT;
}
For the scene shaders I will simply do something like
lookedupDistance = texCube( cubemap, worldPosition );
if( lookedupDistance < actualDistanceFromVertexToLight )
{
////shadowed
color = black;
}
else
{
color = diffuse + specular;
}
scene shaders
/////PIXEL SHADER
float4 diffuseColor;
float4 specularColor;
struct VS_OUTPUT
{
float4 hposition : POSITION;
float2 texcoord0 : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float3 lightVec : TEXCOORD2;
float att : TEXCOORD3;
float3 View : TEXCOORD4;
float3 distanceVec : TEXCOORD5;
};
struct PS_OUTPUT
{
float4 color : COLOR;
};
sampler colorTexture;
sampler normalTexture;
samplerCUBE distanceCubemap;
PS_OUTPUT main( VS_OUTPUT IN )
{
PS_OUTPUT OUT;
float shadowTerm = 1.0f;
float len = length( IN.distanceVec );
if( texCUBE( distanceCubemap, IN.worldPos ).r < len )
shadowTerm = 0.0f;
//calculate the color and the normal
float4 color = tex2D(colorTexture, IN.texcoord0);
//uncompress normal map
float3 normal = 2.0f * tex2D(normalTexture, IN.texcoord0).rgb - 1.0f;
float3 ViewDir = normalize(IN.View);
//normalize the light
float3 light = normalize(IN.lightVec);
//set the output color
float diffuse = saturate(dot(normal, light));
//calculate specular component
float3 Reflect = normalize(2 * diffuse * normal - light);
float4 specular = pow(diffuse*saturate(dot(Reflect, ViewDir)), 8);
//multiply the attenuation with the color
OUT.color = IN.att*shadowTerm*(color*diffuse*diffuseColor + specular);
return OUT;
}
[Edited by - Khaos Dragon on July 24, 2005 11:21:55 PM]