shadow map. Árnyékok kell: minden fényforrásra egy render target (spotlight) egy közös depth...
TRANSCRIPT
Shadow map
Árnyékok
kell:
minden fényforrásra egy render target (Spotlight)
egy közös depth buffer, aminek stimmel a mérete (EngineDeferred)
EngineDeferred.h
LPDIRECT3DTEXTURE9 shadowMapDepthBufferTexture;
LPDIRECT3DSURFACE9 shadowMapDepthBufferSurface;
unsigned int shadowMapSize;
void renderShadowMaps();
EngineDeferred::EngineDeferred
shadowMapSize = 512;
EngineDeferred::createDefaultResources
device->CreateTexture(
shadowMapSize, shadowMapSize, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D24S8, D3DPOOL_DEFAULT,
&shadowMapDepthBufferTexture, NULL);
shadowMapDepthBufferTexture->GetSurfaceLevel(0, &shadowMapDepthBufferSurface);
SpotlightDirectory::iterator i = spotlightDirectory.begin();
while(i != spotlightDirectory.end())
{
i->second->createShadowMap(device);
i++;
}
EngineDeferred::releaseDefaultResources
shadowMapDepthBufferTexture->Release();
shadowMapDepthBufferSurface->Release();
SpotlightDirectory::iterator i = spotlightDirectory.begin();
while(i != spotlightDirectory.end())
{
i->second->releaseShadowMap();
i++;
}
Spotlight.hLPDIRECT3DTEXTURE9 shadowMap;LPDIRECT3DSURFACE9 shadowSurface;unsigned int shadowMapSize;D3DXMATRIX lightViewProjMatrix;EntityCamera lightCamera;
public:void createShadowMap(LPDIRECT3DDEVICE9 device);void releaseShadowMap();
void updateShadowMap(const RenderContext& context, NodeGroup* sceneRoot);
LPDIRECT3DTEXTURE9 getShadowMap();const D3DXMATRIX& getLightViewProjMatrix();
#include "EntityCamera.h"
Spotlight::Spotlight
this->shadowMapSize = 512;
D3DXMatrixIdentity(
&lightViewProjMatrix);
Spotlight::createShadowMap
void Spotlight::createShadowMap(
LPDIRECT3DDEVICE9 device)
{
device->CreateTexture(
shadowMapSize, shadowMapSize, 1,
D3DUSAGE_RENDERTARGET, D3DFMT_R32F,
D3DPOOL_DEFAULT, &shadowMap, NULL);
shadowMap->GetSurfaceLevel(
0, &shadowSurface);
}
Spotlight::releaseShadowMap
void Spotlight::releaseShadowMap()
{
shadowMap->Release();
shadowSurface->Release();
}
Spotlight::updateShadowMap
D3DXVECTOR3 worldPosition = getPosition();
D3DXVECTOR3 worldDirection = getDirection();
lightCamera = EntityCamera(
NULL,
worldPosition, worldPosition + worldDirection, D3DXVECTOR3(0, 0, 1),
1.55f, 1.0f, 0.1f, 1000.0f);
RenderContext lightContext(
context.device,
context.effect,
&lightCamera,
context.roleName);
folyt.
context.device->SetRenderTarget(0, shadowSurface);
context.device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0);
context.effect->
SetFloatArray("spotlight.position", (float*)&worldPosition, 3);
// Spotlight többi tagja most nem kell
sceneRoot->render(lightContext);
Spotlightconst D3DXMATRIX& Spotlight::getLightViewProjMatrix(){
lightViewProjMatrix = lightCamera.getViewMatrix() * lightCamera.getProjMatrix();
return lightViewProjMatrix;}
LPDIRECT3DTEXTURE9 Spotlight::getShadowMap(){
return shadowMap;
}
EngineDeferred::renderShadowMaps
void EngineDeferred::renderShadowMaps(){
device->SetDepthStencilSurface(
shadowMapDepthBufferSurface);
SpotlightDirectory::iterator i =
spotlightDirectory.begin();
while(i != spotlightDirectory.end()) {
i->second->updateShadowMap(
RenderContext(device, effect, NULL,
L"shadow"), worldRoot);
i++;
}
device->SetRenderTarget(0, displayColorBuffer);
device->SetDepthStencilSurface(
displayDepthStencilBuffer);
}
kell egy shadow Role
EngineDeferred::createAutoShadedMesh
shadedMesh->addRole( L"defer", new Role(materialBuffer, nSubmeshes, textureDirectory, device, "defer"));
shadedMesh->addRole( L"shadow", new Role(materialBuffer, nSubmeshes, textureDirectory, device, "shadow"));
shadow map építő shaderfloat4 psShadow(TrafoOutput input) : COLOR0 {
return
length(spotlight.position - input.worldPos);
}
technique shadow {
pass P0 {
VertexShader = compile vs_3_0 vsTrafo();
PixelShader = compile ps_3_0 psShadow();
}
};
EngineDeferred::renderblur dolgokat szedjük ki
//device->SetRenderTarget(0, postProcSurface);//device->SetRenderTarget(1, NULL);
//device->SetRenderTarget(0, deferredGeometrySurface);//effect->SetTexture("deferredGeometryMap", postProcTexture);//effect->SetTechnique("blurHorizontal");//effect->Begin(&np, 0);//effect->BeginPass(0);// meshDirectory[L"quad"]->DrawSubset(0);//effect->EndPass();//effect->End();////device->SetRenderTarget(0, displayColorBuffer);//effect->SetTexture("deferredGeometryMap", deferredGeometryTexture);//effect->SetTechnique("blurVertical");//effect->Begin(&np, 0);//effect->BeginPass(0);// meshDirectory[L"quad"]->DrawSubset(0);//effect->EndPass();//effect->End();
EngineDeferred::renderdevice->BeginScene();
renderShadowMaps();
… // deferred buffer gyártás, setTexture
effect->SetTechnique("deferredShadowed");SpotlightDirectory::iterator i =
spotlightDirectory.begin();
while(i != spotlightDirectory.end()) {
Spotlight* spotlight = i->second;
effect->SetFloatArray("spotlight.peakRadiance", (float*)&spotlight->getPeakRadiance(), 3);
... // Spotlight többi tagja ugyanígy
effect->SetTexture("shadowMap",
spotlight->getShadowMap());
effect->SetMatrix("lightViewProjMatrix",
&spotlight->getLightViewProjMatrix());
mezei deferred helyett
folyt.
UINT np;
effect->Begin(&np, 0);
effect->BeginPass(0);
meshDirectory[L"quad"]
->DrawSubset(0);effect->EndPass();
effect->End();
i++;
}
.fxtexture shadowMap;sampler2D shadowMapSampler =sampler_state{
texture = < shadowMap >;MinFilter = LINEAR;MagFilter = LINEAR;MipFilter = LINEAR;AddressU = Wrap;AddressV = Wrap;};
Spotlight spotlight;float4x4 lightViewProjMatrix;
.fx deferredShadowedtechnique deferredShadowed {
pass P0 {
ZEnable = false;
ZWriteEnable = false;
CullMode = None;
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = One;
BlendOp = Add;
VertexShader = compile vs_3_0 vsQuad();
PixelShader = compile ps_3_0
psDeferredShadowed();
} };
psDeferredShadowedfloat4 psDeferredShadowed(QuadOutput input) : COLOR0 {
float4 geometry = tex2D( deferredGeometrySampler, input.tex);
float4 brdf = tex2D( deferredBrdfSampler, input.tex);
float3 viewDir = normalize(input.worldPosMinusEye);
float3 worldPos = eyePosition + viewDir * geometry.w;
float4 shadowMapPos =
mul(float4(worldPos, 1), lightViewProjMatrix);
shadowMapPos /= shadowMapPos.w;
float3 lightDiff = spotlight.position - worldPos;
float lightDist = length(lightDiff);
float2 lextex = shadowMapPos.xy
* float2(0.5, -0.5) + float2(0.5, 0.5);
float shadowDist = tex2D(shadowMapSampler, lextex);
float visibility = lightDist < shadowDist + 0.5;
return visibility * 0.5;
};
lightingfloat4 psDeferredShadowed(QuadOutput input) : COLOR0 {
float4 geometry = tex2D( deferredGeometrySampler, input.tex);
float4 brdf = tex2D( deferredBrdfSampler, input.tex);
float3 viewDir = normalize(input.worldPosMinusEye);
float3 worldPos = eyePosition + viewDir * geometry.w;
float4 shadowMapPos = mul(float4(worldPos, 1), lightViewProjMatrix);
shadowMapPos /= shadowMapPos.w;
float3 lightDiff = spotlight.position - worldPos;
float lightDist = length(lightDiff);
float3 lightDir = lightDiff / lightDist;
float3 lighting = spotlight.peakRadiance * max(0, dot(geometry.xyz, lightDir)) * pow(max(0,dot(-lightDir, spotlight.direction)), spotlight.focus) / dot(lightDiff, lightDiff);
float2 lextex = shadowMapPos.xy * float2(0.5, -0.5) + float2(0.5, 0.5);
float shadowDist = tex2D(shadowMapSampler, lextex);
float visibility = lightDist < shadowDist;
return brdf * float4(lighting * visibility + float3(0.5, 0.5, 0.5), 1);
};