Environment mapping Szécsi László
Új osztály: Lab3EnvMap copy&paste: Lab2Trafo.h -> Lab3EnvMap.h copy&paste: Lab2Trafo.cpp -> Lab3EnvMap.cpp copy&paste: trafo.fx -> envmap.fx search&replace ebben a két fileban: Lab2Trafo -> Lab3EnvMap Effect betöltésnél: envmap.fx
Lab2 példány helyett Lab3 példányt hozzunk létre #include “Lab3EnvMap.h” HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { engine = new Lab2Transform(pd3dDevice); engine = new Lab3EnvMap(pd3dDevice); Globális példány kicserélése FILEGraphGame.cppOPdel/add codeFUNCOnD3D9CreateDevice
Első laborból copy&paste, nevezzük át quad~-ra: class Lab3Envmap : public EngineInterface { LPDIRECT3DVERTEXBUFFER9 quadVertexBuffer; struct QuadVertex{ D3DXVECTOR3 pos; D3DXVECTOR3 tex; }; Full viewport quad FILELab3EnvMap.hOPnew memberCLASSLab3EnvMap
HRESULT Lab3EnvMap::createDefaultResources() { device->CreateVertexBuffer( 4 * sizeof(QuadVertex), D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0), D3DPOOL_DEFAULT, &quadVertexBuffer, NULL);... Vertex buffer létrehozása FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODcreateDefaultResources
QuadVertex* vertexData; quadVertexBuffer->Lock(0, 0, (void**)&vertexData, D3DLOCK_DISCARD); vertexData[0].pos = D3DXVECTOR3(-1.0f, 1.0f, 0.0f); vertexData[1].pos = D3DXVECTOR3(1.0f, 1.0f, 0.0f); vertexData[2].pos = D3DXVECTOR3(-1.0f, -1.0f, 0.0f); vertexData[3].pos = D3DXVECTOR3(1.0f, -1.0f, 0.0f); vertexData[0].tex = D3DXVECTOR3(0.0f, 0.0f, 0.0f); vertexData[1].tex = D3DXVECTOR3(1.0f, 0.0f, 0.0f); vertexData[2].tex = D3DXVECTOR3(0.0f, 1.0f, 0.0f); vertexData[3].tex = D3DXVECTOR3(1.0f, 1.0f, 0.0f); quadVertexBuffer->Unlock(); Vertex buffer feltöltése FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODcreateDefaultResources
HRESULT Lab3EnvMap:: releaseDefaultResources() { quadVertexBuffer->Release(); return S_OK; } Vertex buffer felszabadítása FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODreleaseDefaultResources
... device->BeginScene(); device->SetStreamSource(0, quadVertexBuffer, 0, sizeof(QuadVertex)); device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0)); device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); device->EndScene(); } Full viewport quad rajzolás FILELab3EnvMap.cppOPedit codeCLASSLab3EnvMap METHODrender
próba téglalap, lefedi a viewportot
Effect Először: rajzoljuk ki a hátteret Cube map textúra: doboz 6 oldallal cloudyNoon.dds letöltése Régen: NAGY doboz vagy gömb skybox, skydome Most már van shader amiben kiszámíthatjuk mi látszik a pixelben: full viewport quad
struct QuadInput { float4 pos: POSITION; float2 tex: TEXCOORD0; }; struct QuadOutput { float4 pos: POSITION; float2 tex: TEXCOORD0; float3 worldPosMinusEye: TEXCOORD1; }; Input-output szemantika FILEenvmap.fxOPnew structFUNC::
float4x4 rotProjMatrixInverse; QuadOutput vsQuad(QuadInput input) { QuadOutput output = (QuadOutput)0; output.pos = input.pos; float4 hWorldPosMinusEye = mul(input.pos, rotProjMatrixInverse); hWorldPosMinusEye /= hWorldPosMinusEye.w; output.worldPosMinusEye = hWorldPosMinusEye.xyz; output.pos.z = 1; // minden mögé output.tex = input.tex; return output; }; Vertex shader FILEenvmap.fxOPnew funcFUNCvsQuad
textureCUBE environmentCubeTexture; samplerCUBE environmentCubeSampler = sampler_state { texture = ; MipFilter = Linear; MagFilter = Linear; MinFilter = Linear; }; Textúra és sampler FILEenvmap.fxOPnew varFUNC::
float4 psEnvironment(QuadOutput input) : COLOR0 { return texCUBE(environmentCubeSampler, input.worldPosMinusEye); }; Pixel shader FILEenvmap.fxOPnew funcFUNCpsEnvironment
technique environment { pass P0 { VertexShader = compile vs_3_0 vsQuad(); PixelShader = compile ps_3_0 psEnvironment(); } }; Környezet háttér technique FILEenvmap.fxOPnew techniqueFUNC::
const D3DXVECTOR3& eyePos = *camera.GetEyePt(); D3DXMATRIX eyePosTranslationMatrix; D3DXMatrixTranslation(&eyePosTranslationMatrix, eyePos.x, eyePos.y, eyePos.z); D3DXMATRIX rpmi; D3DXMatrixInverse(&rpmi, NULL, &(eyePosTranslationMatrix * *camera.GetViewMatrix() * *camera.GetProjMatrix())); effect->SetMatrix("rotProjMatrixInverse", &rpmi); Mátrix beállítása FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODrender
class Lab3EnvMap { LPDIRECT3DCUBETEXTURE9 environmentCube; Textúra változó FILELab3EnvMap.hOPnew memberCLASSLab3EnvMap
HRESULT Lab3EnvMap::createManagedResources() { D3DXCreateCubeTextureFromFile(device, L"media\\cloudyNoon.dds", &environmentCube); Textúra betöltés FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODcreateManagedResources
HRESULT Lab3EnvMap::releaseManagedResources() { environmentCube->Release(); Textúra felszabadítás FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODreleaseManagedResources
effect-> SetTexture("environmentCubeTexture", environmentCube); Textúra bekötése az effecnek FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODrender
effect->SetTechnique("environment"); effect->Begin(&a, 0); effect->BeginPass(0); device->SetStreamSource(0, quadVertexBuffer, 0, sizeof(QuadVertex)); device->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0)); device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); effect->EndPass(); effect->End(); Rajzolás (pl. buggy rajzolása után) FILELab3EnvMap.cppOPadd codeCLASSLab3EnvMap METHODrender
Próba égbolt
float3 eyePosition; effect->SetFloatArray("eyePosition", (float*)camera.GetEyePt(), 3); Szempozíció: Uniform paraméter FILEenvmap.fxOPverify varFUNC:: Bekötése FILELab3EnvMap.cppOPverify codeCLASSLab3EnvMap METHODrender
float4 psEnvMapped(TrafoOutput input) : COLOR0 { float3 viewDir = normalize(eyePosition - input.worldPos); float3 reflectionDir = reflect(-viewDir, input.normal); return texCUBE(environmentCubeSampler, reflectionDir); } Tükröződés a modellen FILEenvmap.fxOPnew funcFUNCpsEnvMapped
technique envmapped { pass P0 { VertexShader = compile vs_3_0 vsTrafo(); PixelShader = compile ps_3_0 psEnvMapped(); } }; Environment mapping technique FILEenvmap.fxOPnew techniqueFUNC::
effect->SetTechnique("envmapped"); Buggy rajzolása envmapped techniqueval FILELab3EnvMap.cppOPedit codeCLASSLab3EnvMap METHODrender
float4 psEnvMapped(TrafoOutput input) : COLOR0 { float3 viewDir = normalize(eyePosition - input.worldPos); float3 reflectionDir = reflect(-viewDir, input.normal); return tex2D(kdMapSampler, input.tex) * texCUBE(environmentCubeSampler, reflectionDir); } Kd textúra FILEenvmap.fxOPadd codeFUNCpsEnvMapped