Advertisement
Guest User

Deferred Shading

a guest
May 14th, 2014
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.54 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "Shader.h"
  4.  
  5. class DeferredRenderer
  6. {
  7. private:
  8.   struct QuadVertex
  9.   {
  10.     float x, y, z;
  11.     float tx, ty;
  12.  
  13.     QuadVertex( float ax, float ay, float az, float atx, float aty )
  14.     {
  15.       x = ax;
  16.       y = ay;
  17.       z = az;
  18.  
  19.       tx = atx;
  20.       ty = aty;
  21.     }
  22.   };
  23.  
  24.   IDirect3DTexture9 * positionMap;
  25.   IDirect3DTexture9 * normalMap;
  26.   IDirect3DTexture9 * diffuseMap;
  27.  
  28.   IDirect3DSurface9 * positionSurface;
  29.   IDirect3DSurface9 * normalSurface;
  30.   IDirect3DSurface9 * diffuseSurface;
  31.   IDirect3DSurface9 * backSurface;
  32.  
  33.   VertexShader * vertexShaderPassOne;
  34.   PixelShader * pixelShaderPassOne;
  35.  
  36.   VertexShader * vertexShaderPassTwo;
  37.   PixelShader * pixelShaderPassTwo;
  38.  
  39.   IDirect3DVertexBuffer9 * screenQuad;
  40.   IDirect3DVertexDeclaration9 * vertexDeclaration;
  41.  
  42.   D3DXHANDLE v1World;
  43.   D3DXHANDLE v1Proj;
  44.   D3DXHANDLE v1View;
  45.  
  46.   D3DXHANDLE v2World;
  47.   D3DXHANDLE v2Proj;
  48.   D3DXHANDLE v2View;
  49.  
  50.   D3DXHANDLE p2LightPos;
  51.   D3DXHANDLE p2LightRange;
  52.   D3DXHANDLE p2CameraPos;
  53. public:
  54.  
  55.   void CreateScreenQuad()
  56.   {
  57.     g_device->CreateVertexBuffer( 6 * sizeof( QuadVertex ), D3DUSAGE_WRITEONLY, D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &screenQuad, 0 );
  58.  
  59.     QuadVertex vertices[ ] = { QuadVertex( -0.5, -0.5, 0, 0, 0 ), QuadVertex( g_width - 0.5, 0 - 0.5, 0, 1, 0 ), QuadVertex ( 0 - 0.5, g_height - 0.5, 0, 0, 1 ),
  60.       QuadVertex( g_width - 0.5, 0 - 0.5, 0, 1, 0 ), QuadVertex( g_width - 0.5, g_height - 0.5, 0, 1, 1 ), QuadVertex ( 0 - 0.5, g_height - 0.5, 0, 0, 1 ) };
  61.  
  62.     void * data = 0;
  63.  
  64.     screenQuad->Lock( 0, 0, &data, 0 );
  65.     memcpy( data, vertices, sizeof( QuadVertex ) * 6 );
  66.     screenQuad->Unlock( );
  67.  
  68.     D3DVERTEXELEMENT9 quadVertexDeclation[ ] =
  69.     {
  70.       { 0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  71.       { 0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
  72.       D3DDECL_END()
  73.     };
  74.  
  75.     g_device->CreateVertexDeclaration( quadVertexDeclation, &vertexDeclaration );
  76.   }
  77.  
  78.   void CreateRenderTargets()
  79.   {
  80.     D3DCAPS9 caps;  g_device->GetDeviceCaps( &caps );
  81.  
  82.     if( caps.NumSimultaneousRTs < 4 )
  83.       MessageBoxA( 0, "Your video card does not support MRT.", 0, MB_OK | MB_ICONERROR );
  84.  
  85.     D3DFORMAT format = D3DFMT_A16B16G16R16F;
  86.  
  87.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &positionMap )))
  88.       MessageBoxA( 0, "Failed to create 'PositionMap' texture.", 0, MB_OK | MB_ICONERROR );
  89.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &normalMap )))
  90.       MessageBoxA( 0, "Failed to create 'PositionMap' texture.", 0, MB_OK | MB_ICONERROR );
  91.     if( FAILED( D3DXCreateTexture( g_device, g_width, g_height, 0, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &diffuseMap )))
  92.       MessageBoxA( 0, "Failed to create 'PositionMap' texture.", 0, MB_OK | MB_ICONERROR );
  93.  
  94.     positionMap->GetSurfaceLevel( 0, &positionSurface );
  95.     normalMap->GetSurfaceLevel( 0, &normalSurface );
  96.     diffuseMap->GetSurfaceLevel( 0, &diffuseSurface );
  97.  
  98.     g_device->GetRenderTarget( 0, &backSurface );
  99.   }
  100.  
  101.   void InitPassOneShaders()
  102.   {
  103.     // PASS 1 - Filling the G-Buffer
  104.     string vertexSourcePassOne =
  105.       "float4x4 g_world;\n"
  106.       "float4x4 g_view;\n"
  107.       "float4x4 g_projection;\n"
  108.  
  109.       "struct VS_INPUT {\n"
  110.       "  float4 position : POSITION;\n"
  111.       "  float4 normal   : NORMAL;\n"
  112.       "  float2 texCoord : TEXCOORD0;\n"
  113.       "};\n"
  114.  
  115.       "struct VS_OUTPUT {\n"
  116.       "  float4 position : POSITION;\n"
  117.       "  float3 worldPos : TEXCOORD0;\n"
  118.       "  float3 normal : TEXCOORD1;\n"
  119.       "  float2 diffuseMapCoord : TEXCOORD2;\n"
  120.       "};\n"
  121.  
  122.       "VS_OUTPUT main(VS_INPUT input) {\n"
  123.       "  VS_OUTPUT output;\n"
  124.       "  float4x4 worldViewProj = mul(mul(g_world, g_view), g_projection);\n"
  125.       "  output.position = mul(input.position, worldViewProj);\n"
  126.       "  output.normal = normalize(mul(input.normal, (float3x3)g_world));\n"
  127.       "  output.worldPos = mul(input.position, g_world);\n"
  128.       "  output.diffuseMapCoord = input.texCoord;\n"
  129.       "  return output;\n"
  130.       "};\n";
  131.  
  132.     vertexShaderPassOne = new VertexShader( vertexSourcePassOne );
  133.  
  134.     v1World = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_world" );
  135.     v1Proj = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_projection" );
  136.     v1View = vertexShaderPassOne->GetConstantTable()->GetConstantByName( 0, "g_view" );
  137.  
  138.     string pixelSourcePassOne =
  139.  
  140.       "texture diffuseMap;\n"
  141.  
  142.       "sampler diffuseSampler : register(s0) = sampler_state\n"
  143.       "{\n"
  144.       "   texture = <diffuseMap>;\n"
  145.       "};\n"
  146.  
  147.       "struct PS_INPUT {\n"
  148.       "  float3 worldPos : TEXCOORD0;\n"
  149.       "  float3 normal : TEXCOORD1;\n"      
  150.       "  float2 diffuseMapCoord : TEXCOORD2;\n"
  151.       "};\n"
  152.  
  153.       "struct MRT_OUTPUT {\n"
  154.       "  float4 position : COLOR0;\n"
  155.       "  float4 normal : COLOR1;\n"
  156.       "  float4 diffuseMap : COLOR2;\n"
  157.       "};\n"
  158.  
  159.       "MRT_OUTPUT main( PS_INPUT input )\n"      
  160.       "{\n"
  161.       "   MRT_OUTPUT output;\n"
  162.       "   float3 normal = normalize( input.normal );\n"
  163.       "   output.position = float4( input.worldPos.x, input.worldPos.y, input.worldPos.z, 1.0 );\n"
  164.       "   output.normal = float4( normal.x, normal.y, normal.z, 1.0 );\n"
  165.       "   output.diffuseMap = tex2D( diffuseSampler, input.diffuseMapCoord );\n"
  166.       "   return output;"
  167.       "};\n"
  168.       ;
  169.  
  170.     pixelShaderPassOne = new PixelShader( pixelSourcePassOne );
  171.   }
  172.  
  173.   DeferredRenderer()
  174.   {
  175.     CreateScreenQuad();
  176.     CreateRenderTargets();      
  177.     InitPassOneShaders();
  178.     InitPassTwoShaders();
  179.   }
  180.  
  181.   void InitPassTwoShaders()
  182.   {
  183.     // PASS 2 - Final render
  184.     string vertexSourcePassTwo =
  185.       "float4x4 g_world;\n"
  186.       "float4x4 g_view;\n"
  187.       "float4x4 g_projection;\n"
  188.       "struct VS_INPUT {\n"
  189.       "  float4 position : POSITION;\n"
  190.       "  float3 texcoord : TEXCOORD0;\n"
  191.       "};\n"
  192.  
  193.       "struct VS_OUTPUT {\n"
  194.       "  float4 position : POSITION;\n"
  195.       "  float3 texcoord : TEXCOORD0;\n"
  196.       "};\n"
  197.  
  198.       "VS_OUTPUT main(VS_INPUT input) {\n"
  199.       "  VS_OUTPUT output;\n"
  200.       "  float4x4 worldViewProj = mul(mul(g_world, g_view), g_projection);\n"
  201.       "  output.position   = mul(input.position, worldViewProj);\n"
  202.       "  output.texcoord   = input.texcoord;\n"
  203.       "  return output;\n"
  204.       "};\n";
  205.  
  206.     vertexShaderPassTwo = new VertexShader( vertexSourcePassTwo );
  207.  
  208.     v2World = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_world" );
  209.     v2Proj = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_projection" );
  210.     v2View = vertexShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "g_view" );
  211.  
  212.     string pixelSourcePassTwo =
  213.      
  214.       "texture positionMap;\n"
  215.       "texture normalMap;\n"
  216.       "texture diffuseMap;\n"
  217.  
  218.       "sampler positionSampler : register(s0) = sampler_state\n"
  219.       "{\n"
  220.       "   texture = <positionMap>;\n"
  221.       "};\n"
  222.  
  223.       "sampler normalSampler : register(s1) = sampler_state\n"
  224.       "{\n"
  225.       "   texture = <normalMap>;\n"
  226.       "};\n"    
  227.  
  228.       "sampler diffuseSampler : register(s2) = sampler_state\n"
  229.       "{\n"
  230.       "   texture = <diffuseMap>;\n"
  231.       "};\n"
  232.  
  233.       // light props
  234.       "float3 lightPos;\n"
  235.       "float lightRange;\n"
  236.  
  237.       // camera props
  238.       "float3 cameraPosition;\n"
  239.  
  240.       "float4 main( float3 texcoord : TEXCOORD0 ) : COLOR0\n"
  241.       "{\n"
  242.       "   float4 diffuseTexel = tex2D( diffuseSampler, texcoord.xy );\n"
  243.       "   float3 p = tex2D( positionSampler, texcoord.xy ).xyz;\n"
  244.       "   float3 n = tex2D( normalSampler, texcoord.xy ).xyz;\n"
  245.  
  246.       "   float3 lightDirection = lightPos - p;"
  247.       "   float3 l = normalize( lightDirection );\n"
  248.  
  249.       // specular
  250.       "   float3 v = normalize( cameraPosition - p );\n"
  251.       "   float3 r = reflect( -v, n );\n"      
  252.       "   float spec = pow( saturate( dot( l, r ) ), 20.0 );\n"
  253.  
  254.       // diffuse
  255.       "   float diff = saturate(dot( l, n ));\n"
  256.  
  257.       "   float falloff = lightRange / dot( lightDirection, lightDirection );\n"
  258.  
  259.       "   float o = falloff * ( diff + spec );\n"
  260.  
  261.       "   return float4( diffuseTexel.x * o, diffuseTexel.y * o, diffuseTexel.z * o, diffuseTexel.w );\n"
  262.       "};\n";
  263.  
  264.     pixelShaderPassTwo = new PixelShader( pixelSourcePassTwo );
  265.  
  266.     p2LightPos = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "lightPos" );
  267.     p2LightRange = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "lightRange" );
  268.     p2CameraPos = pixelShaderPassTwo->GetConstantTable()->GetConstantByName( 0, "cameraPosition" );
  269.   }
  270.  
  271.   ~DeferredRenderer()
  272.   {
  273.     if( positionMap )
  274.       positionMap->Release();
  275.     if( normalMap )
  276.       normalMap->Release();
  277.     if( diffuseMap )
  278.       diffuseMap->Release();
  279.  
  280.     if( positionSurface )
  281.       positionSurface->Release();
  282.     if( normalSurface )
  283.       normalSurface->Release();
  284.     if( diffuseSurface )
  285.       diffuseSurface->Release();
  286.   }
  287.  
  288.   void Begin()
  289.   {
  290.     g_device->SetRenderTarget( 0, positionSurface );
  291.     g_device->SetRenderTarget( 1, normalSurface );
  292.     g_device->SetRenderTarget( 2, diffuseSurface );
  293.  
  294.     g_device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0, 0, 0 ), 1.0, 0 );
  295.     g_device->BeginScene( );
  296.  
  297.     vertexShaderPassOne->Bind();
  298.     pixelShaderPassOne->Bind();
  299.  
  300.     g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE );
  301.   }
  302.  
  303.   void RenderMesh( Mesh * mesh )
  304.   {
  305.     g_device->SetStreamSource( 0, mesh->vb, 0, sizeof( Vertex ));
  306.     g_device->SetIndices( mesh->ib );
  307.  
  308.     D3DXMATRIX view; g_device->GetTransform( D3DTS_VIEW, &view );
  309.     D3DXMATRIX proj; g_device->GetTransform( D3DTS_PROJECTION, &proj );
  310.     D3DXMATRIX world; GetD3DMatrixFromBulletTransform( mesh->parent->globalTransform, world );
  311.  
  312.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1View, &view );
  313.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1Proj, &proj );  
  314.     vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1World, &world );
  315.  
  316.     g_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, mesh->vertexCount, 0, mesh->faceCount );
  317.   }
  318.  
  319.   void End()
  320.   {
  321.     g_device->EndScene();
  322.  
  323.     g_device->SetRenderTarget( 0, backSurface );
  324.     g_device->SetRenderTarget( 1, 0 );
  325.     g_device->SetRenderTarget( 2, 0 );
  326.  
  327.     g_device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0, 0, 0 ), 1.0, 0 );
  328.     g_device->BeginScene( );
  329.  
  330.     g_device->SetVertexDeclaration( vertexDeclaration );
  331.  
  332.     vertexShaderPassTwo->Bind();
  333.     pixelShaderPassTwo->Bind();
  334.  
  335.     g_device->SetRenderState( D3DRS_LIGHTING, FALSE );
  336.     g_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  337.  
  338.     D3DXMATRIX ortho; D3DXMatrixOrthoOffCenterLH ( &ortho, 0, g_width, g_height, 0, 0, 1024 );
  339.     D3DXMATRIX identity; D3DXMatrixIdentity( &identity );
  340.  
  341.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2World, &identity );
  342.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2View, &identity );
  343.     vertexShaderPassTwo->GetConstantTable()->SetMatrix( g_device, v2Proj, &ortho );
  344.  
  345.     g_device->SetTexture( 0, positionMap );
  346.     g_device->SetTexture( 1, normalMap );
  347.     g_device->SetTexture( 2, diffuseMap );
  348.  
  349.     g_device->SetStreamSource( 0, screenQuad, 0, sizeof( QuadVertex ));
  350.  
  351.     g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  352.     g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE );
  353.     g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  354.  
  355.     float temp[ 3 ];
  356.  
  357.     btVector3 lightPos = g_camera->base->globalTransform.getOrigin();
  358.  
  359.     temp[ 0 ] = lightPos.x();
  360.     temp[ 1 ] = lightPos.y();
  361.     temp[ 2 ] = lightPos.z();
  362.  
  363.     pixelShaderPassTwo->GetConstantTable()->SetFloatArray( g_device, p2CameraPos, temp, 3 );
  364.  
  365.     for( int i = 0; i < g_lights.size(); i++ )
  366.     {
  367.       Light * light = g_lights.at( i );      
  368.  
  369.       btVector3 lightPos = light->base->globalTransform.getOrigin();
  370.  
  371.       temp[ 0 ] = lightPos.x();
  372.       temp[ 1 ] = lightPos.y();
  373.       temp[ 2 ] = lightPos.z();
  374.  
  375.       pixelShaderPassTwo->GetConstantTable()->SetFloatArray( g_device, p2LightPos, temp, 3 );
  376.       pixelShaderPassTwo->GetConstantTable()->SetFloat( g_device, p2LightRange, light->radius );
  377.  
  378.  
  379.       g_device->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
  380.     }    
  381.  
  382.     g_device->SetTexture( 0, 0 );
  383.     g_device->SetTexture( 1, 0 );
  384.     g_device->SetTexture( 2, 0 );
  385.   }
  386. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement