void DXDirectionalLight::BlurShadowMap(LPDIRECT3DDEVICE9 device, LPD3DXEFFECT effect) { if( !shadowmap || !blur || !blurdeclforpointfordirectional || !needsblur ) return; float blurvertices[36] = { -0.5f, -0.5f, 0, 1, 0, 0, (float)shadowsize - 0.5f, -0.5f, 0, 1, 1, 0, -0.5f, (float)shadowsize - 0.5f, 0, 1, 0, 1, -0.5f, (float)shadowsize - 0.5f, 0, 1, 0, 1, (float)shadowsize - 0.5f, -0.5f, 0, 1, 1, 0, (float)shadowsize - 0.5f, (float)shadowsize - 0.5f, 0, 1, 1, 1 }; LPDIRECT3DSURFACE9 surface = NULL; D3DXVECTOR4 texelsize(1.0f / shadowsize, 0, 0, 0); UINT stride = 6 * sizeof(float); device->SetVertexDeclaration(blurdeclforpointfordirectional); // x blur->GetSurfaceLevel(0, &surface); effect->SetVector("texelSize", &texelsize); effect->CommitChanges(); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); device->SetTexture(0, shadowmap); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, blurvertices, stride); surface->Release(); std::swap(texelsize.x, texelsize.y); // y shadowmap->GetSurfaceLevel(0, &surface); effect->SetVector("texelSize", &texelsize); effect->CommitChanges(); device->SetRenderTarget(0, surface); device->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0); device->SetTexture(0, blur); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, blurvertices, stride); surface->Release(); if( shadowtype == Static ) needsblur = false; }
//************************************************************************************************************* void BlurTexture(LPDIRECT3DTEXTURE9 tex) { LPDIRECT3DSURFACE9 surface = NULL; LPDIRECT3DSURFACE9 blursurface = NULL; LPDIRECT3DTEXTURE9 blurtex = NULL; D3DXVECTOR4 texelsize(1.0f / SHADOWMAP_SIZE, 0, 0, 0); D3DSURFACE_DESC desc; tex->GetLevelDesc(0, &desc); if( desc.Format == D3DFMT_A8R8G8B8 ) blurtex = blurARGB8; // for convolution else blurtex = blurRGBA32F; // for others blurtex->GetSurfaceLevel(0, &blursurface); tex->GetSurfaceLevel(0, &surface); device->SetRenderTarget(0, blursurface); device->SetTexture(0, tex); device->SetVertexDeclaration(vertexdecl); boxblur5x5->SetVector("texelSize", &texelsize); boxblur5x5->Begin(NULL, 0); boxblur5x5->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float)); std::swap(texelsize.x, texelsize.y); boxblur5x5->SetVector("texelSize", &texelsize); boxblur5x5->CommitChanges(); device->SetRenderTarget(0, surface); device->SetTexture(0, blurtex); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float)); } boxblur5x5->EndPass(); boxblur5x5->End(); surface->Release(); blursurface->Release(); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { static float time = 0; D3DXMATRIX inv; D3DXVECTOR3 axis(0, 1, 0); D3DXVECTOR4 texelsize(1.0f / (float)screenwidth, 1.0f / (float)screenheight, 0, 1); LPDIRECT3DSURFACE9 oldtarget = NULL; time += elapsedtime; D3DXMatrixRotationAxis(&inv, &axis, time); D3DXMatrixScaling(&world, 0.3f, 0.3f, 0.3f); //D3DXMatrixScaling(&world, 0.6f, 0.6f, 0.6f); D3DXMatrixMultiply(&world, &world, &inv); D3DXMatrixInverse(&inv, NULL, &world); device->SetTexture(0, texture); device->SetTexture(1, intensity); effect->SetMatrix("matWorld", &world); effect->SetMatrix("matWorldInv", &inv); effect->SetMatrix("matView", &view); effect->SetMatrix("matProj", &proj); if( useedgedetect ) { device->GetRenderTarget(0, &oldtarget); device->SetRenderTarget(0, colorsurface); device->SetRenderTarget(1, normalsurface); } device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0xff6694ed, 1.0f, 0); if( SUCCEEDED(device->BeginScene()) ) { // draw scene + normals/depth effect->SetTechnique("celshading"); effect->Begin(NULL, 0); effect->BeginPass(0); { mesh->DrawSubset(0); } effect->EndPass(); effect->End(); if( useedgedetect ) { // edge detection device->SetVertexDeclaration(vertexdecl); device->SetRenderTarget(0, edgesurface); device->SetRenderTarget(1, NULL); device->SetTexture(0, normaltarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); effect->SetTechnique("edgedetect"); effect->SetVector("texelSize", &texelsize); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); // put together device->SetRenderTarget(0, oldtarget); device->SetTexture(0, colortarget); device->SetTexture(2, edgetarget); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); oldtarget->Release(); effect->SetTechnique("final"); effect->Begin(NULL, 0); effect->BeginPass(0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } effect->EndPass(); effect->End(); } else { D3DXMATRIX offproj; // use the stencil buffer device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, TRUE); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); device->SetRenderState(D3DRS_STENCILREF, 1); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); float thickness = 3.5f; // render object 4 times with offseted frustum for( float i = -thickness; i < thickness + 1; i += 2 * thickness ) { for( float j = -thickness; j < thickness + 1; j += 2 * thickness ) { D3DXMatrixTranslation(&offproj, i / (float)screenwidth, j / (float)screenheight, 0); D3DXMatrixMultiply(&offproj, &proj, &offproj); device->SetTransform(D3DTS_PROJECTION, &offproj); mesh->DrawSubset(0); } } // erase area in the center device->SetRenderState(D3DRS_STENCILREF, 0); device->SetTransform(D3DTS_PROJECTION, &proj); mesh->DrawSubset(0); // now render outlines device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_ALPHA); device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL); device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT); device->SetTextureStageState(0, D3DTSS_CONSTANT, 0); { device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(D3DXVECTOR4) + sizeof(D3DXVECTOR2)); } device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); device->SetRenderState(D3DRS_STENCILENABLE, FALSE); } device->SetTexture(2, NULL); // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->SetTexture(0, NULL); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
//************************************************************************************************************* void Render(float alpha, float elapsedtime) { D3DXMATRIX view, proj; D3DXMATRIX inv, vp, tmp; D3DXMATRIX lightview, lightproj, lightvp; D3DXVECTOR2 orient = cameraangle.smooth(alpha); D3DXVECTOR4 lightpos(0, 0, -5, 0); D3DXVECTOR3 look(0, 0.5f, 0), up(0, 1, 0); D3DXVECTOR3 eye(0, 0, -5.2f); D3DXVECTOR4 clipplanes(0, 0, 0, 0); D3DXVECTOR4 texelsize(1.0f / SHADOWMAP_SIZE, 1.0f / SHADOWMAP_SIZE, 0, 0); // setup camera D3DXMatrixRotationYawPitchRoll(&tmp, orient.x, orient.y, 0); D3DXVec3TransformCoord(&eye, &eye, &tmp); D3DXMatrixLookAtLH(&view, &eye, &look, &up); D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, (float)screenwidth / (float)screenheight, 0.1f, 20); D3DXMatrixMultiply(&vp, &view, &proj); // setup light orient = lightangle.smooth(alpha); look = D3DXVECTOR3(0, 0, 0); D3DXMatrixRotationYawPitchRoll(&tmp, orient.x, orient.y, 0); D3DXVec4Transform(&lightpos, &lightpos, &tmp); D3DXMatrixLookAtLH(&lightview, (D3DXVECTOR3*)&lightpos, &look, &up); DXFitToBox(lightproj, clipplanes, lightview, scenebb); D3DXMatrixMultiply(&lightvp, &lightview, &lightproj); if( SUCCEEDED(device->BeginScene()) ) { switch( shadowtech ) { case 0: RenderWithPCF(vp, eye, lightview, lightproj, lightpos, clipplanes, D3DXVECTOR4(0, 0, 0, 0)); break; case 1: RenderWithPCF(vp, eye, lightview, lightproj, lightpos, clipplanes, texelsize); break; case 2: RenderWithIrregularPCF(vp, eye, lightview, lightproj, lightpos, clipplanes, texelsize); break; case 3: RenderWithVariance(vp, eye, lightview, lightproj, lightpos, clipplanes); break; case 4: RenderWithConvolution(vp, eye, lightview, lightproj, lightpos, clipplanes); break; case 5: RenderWithExponential(vp, eye, lightview, lightproj, lightpos, clipplanes); break; case 6: RenderWithExponentialVariance(vp, eye, lightview, lightproj, lightpos, clipplanes); break; case 7: RenderWithPCSS(vp, eye, lightview, lightproj, lightpos, clipplanes, texelsize); break; default: device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0); break; } // render text device->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX1); device->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetTexture(0, text); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, textvertices, 6 * sizeof(float)); device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, TRUE); device->EndScene(); } device->Present(NULL, NULL, NULL, NULL); }
void RenderLightShafts(const D3DXMATRIX& view, const D3DXMATRIX& proj, const D3DXVECTOR3& eye, const D3DXVECTOR4& lightpos) { D3DXMATRIX world; D3DXVECTOR3 viewdir(view._13, view._23, view._33); D3DXVECTOR3 lightdir; D3DXVECTOR4 lightss; D3DXVECTOR4 texelsize(1.0f / screenwidth, 1.0f / screenheight, 0, 1); D3DXVec3Normalize(&lightdir, (D3DXVECTOR3*)&lightpos); float exposure = min(max(D3DXVec3Dot(&viewdir, &lightdir), 0), 1); lightss.x = eye.x + lightpos.x; lightss.y = eye.y + lightpos.y; lightss.z = eye.z + lightpos.z; lightss.w = 1; D3DXVec4Transform(&lightss, &lightss, &view); D3DXVec4Transform(&lightss, &lightss, &proj); lightss.x = (1.0f + lightss.x / lightss.w) * 0.5f; lightss.y = (1.0f - lightss.y / lightss.w) * 0.5f; device->SetRenderTarget(0, occludersurf); device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x68686868, 1.0f, 0); D3DXMatrixScaling(&world, 6, 6, 6); world._42 = -2; device->SetTransform(D3DTS_WORLD, &world); device->SetTransform(D3DTS_VIEW, &view); device->SetTransform(D3DTS_PROJECTION, &proj); palm->DrawSubset(0, DXObject::Opaque); palm->DrawSubset(1, DXObject::Opaque); device->SetVertexDeclaration(quaddecl); device->SetRenderState(D3DRS_ZENABLE, FALSE); // first blur godray->SetTechnique("godray"); godray->SetVector("lightPos", (D3DXVECTOR4*)&lightss); godray->SetFloat("exposure", exposure); device->SetRenderTarget(0, blursurf); godray->Begin(0, 0); godray->BeginPass(0); { device->SetTexture(0, occluders); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } godray->EndPass(); godray->End(); // second blur godray->SetTechnique("blur"); godray->SetVector("texelSize", &texelsize); godray->SetVector("lightPos", (D3DXVECTOR4*)&lightss); device->SetRenderTarget(0, occludersurf); godray->Begin(0, 0); godray->BeginPass(0); { device->SetTexture(0, blurtex); device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, quadvertices, 6 * sizeof(float)); } godray->EndPass(); godray->End(); device->SetRenderState(D3DRS_ZENABLE, TRUE); }