2012-12-25 119 views
4

我試圖使用食人魔合成器框架設置延遲渲染器。我試圖執行一個點的光的着色器(作爲全屏四效果,無衰減或鏡面計算)在下面的代碼:Ogre3d /延遲渲染/點光源

材料,其輸出延遲數據GBuffer:

void ToGBufferVP 
       (
        float4 iPosition : POSITION, 
        float3 iNormal : NORMAL, 
        float2 iUV0 : TEXCOORD, 

        out float4 oPosition : POSITION, 
        out float3 oViewPos : TEXCOORD0, 
        out float3 oNormal : TEXCOORD1, 
        out float2 oUV0 : TEXCOORD2, 

        uniform float4x4 cWorldViewProj, 
        uniform float4x4 cWorldView 
       ) 
{ 
    oPosition = mul(cWorldViewProj, iPosition); 
    oNormal = mul(cWorldView, float4(iNormal,0)).xyz; 
    oViewPos = mul(cWorldView, iPosition).xyz; 
    oUV0 = iUV0; 
} 

void ToGBufferFP 
       (
        float3 iViewPos : TEXCOORD0, 
        float3 iNormal : TEXCOORD1, 
        float2 iUV0 : TEXCOORD2, 

        out float4 oColor0 : COLOR0, 
        out float4 oColor1 : COLOR1, 

        uniform sampler2D sTex : register(s0), 
        uniform sampler2D sSpec : register(s1), 

        uniform float cFarDistance 
       ) 
{ 
    oColor0.rgb = tex2D(sTex, iUV0); 
    oColor0.a = tex2D(sSpec, iUV0); 
    oColor1.rgb = normalize(iNormal); 
    oColor1.a = length(iViewPos)/cFarDistance; 
} 

頂點程序描述:

vertex_program ScreenQuadDebugLight_VS cg 
{ 
    source MyDeferredPostShader.hlsl 
    profiles vs_1_1 arbvp1 
    entry_point ScreenQuadDebugLight_VS 

    default_params 
    { 
     param_named_auto worldViewProj worldviewproj_matrix 
    } 
} 

片段節目描述:

fragment_program ScreenQuadDebugLight_PS cg 
{ 
    source MyDeferredPostShader.hlsl 
    profiles ps_2_0 arbfp1 
    entry_point ScreenQuadDebugLight_PS 

    default_params 
    { 
     param_named_auto vpWidth viewport_width 
     param_named_auto vpHeight viewport_height  

     param_named_auto flip render_target_flipping 
     param_named_auto farClipDistance far_clip_distance 

     param_named_auto lightPos light_position_view_space 0 
    } 
} 

光材質腳本:

material DeferredShadingPostQuadLight 
{ 
    technique 
    { 
     pass 
     { 
      cull_hardware none 
      cull_software none 

      depth_func always_pass 

      vertex_program_ref ScreenQuadDebugLight_VS 
      { 
      } 

      fragment_program_ref ScreenQuadDebugLight_PS 
      { 
      } 

      texture_unit 
      { 
       tex_coord_set 0 
       tex_address_mode clamp 
       filtering none 
      } 

      texture_unit 
      { 
       tex_coord_set 1 
       tex_address_mode clamp 
       filtering none 
      } 
     } 
    } 
} 

光着色器:

void ScreenQuadDebugLight_VS 
    (
     float4 Pos: POSITION, 
     out float4 oPos: POSITION, 
     out float4 oTexCoord : TEXCOORD0, 
     uniform float4x4 worldViewProj 
    ) 
{ 
    float4 projPos = mul(worldViewProj, Pos); 
    oTexCoord = projPos;  
    oPos = projPos; 
} 

float4 ScreenQuadDebugLight_PS 
    (
     float4 projPos : TEXCOORD0, 
     uniform sampler Tex0: register(s0), 
     uniform sampler Tex1: register(s1), 

     uniform float vpWidth, 
     uniform float vpHeight, 

     uniform float flip, 
     uniform float farClipDistance, 

     uniform float3 lightPos 
    ) : COLOR 
{ 
    // Get homogenous coordinates 
    projPos.xy /= projPos.w; 

    // Compensate texture coordinate half pixel jitter 
    float2 texCoord = 0.5f * (float2(projPos.x, -projPos.y) + 1); 
    float2 halfPixel = float2(0.5/vpWidth, 0.5/vpHeight); 
    texCoord += halfPixel; 

    float3 ray = float3(projPos.x, projPos.y * flip, 1); 

    float4 a0 = tex2D(Tex0, texCoord); // Albedo and Specularity 
    float4 a1 = tex2D(Tex1, texCoord); // Normal and Depth 

    // Attributes 
    float3 colour = a0.rgb; 
    float specularity = a0.a; 
    float distance = a1.w; 
    float3 normal = a1.xyz; 

    float3 viewPos = normalize(ray); 
    viewPos.z = distance; 

    float3 objToLightVec = lightPos - viewPos; 
    float len_sq = dot(objToLightVec, objToLightVec); 
    float len = sqrt(len_sq); 
    float3 objToLightDir = normalize(objToLightVec); 

    float3 total_light_contrib; 
    total_light_contrib = max(0.0, dot(objToLightDir, normal)); 

    return float4(total_light_contrib, 0.0); 
} 

這是怎麼我在.cpp文件中聲明光:

lLightSceneNodeHolder = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 

Ogre::Light *light; 
light = mSceneMgr->createLight(); 
light->setType(Ogre::Light::LT_POINT); 
light->setPosition(Ogre::Vector3(0, 0, -0.7f)); 
light->setVisible(true); 
light->setDiffuseColour(Ogre::ColourValue::White); 
light->setSpecularColour(Ogre::ColourValue::White); 
lLightSceneNodeHolder->attachObject(light); 

我得到的輸出,一切工作正常 - 除非我不能讓照明正常工作。 G緩衝區包含有效數據 - 視圖空間法線,線性z深度,紋理。我也將視角空間中的光照位置作爲參數 - 但在矢量計算過程中存在一些問題 - 輸出不像點光源那樣。我在這裏做錯了什麼?

謝謝!

P.S.我也試過手動傳遞lightPos參數,通過合成器監聽,但隨後的光看起來更像是定向光...

回答

1

的問題是公式中:

float3 ray = float3(projPos.x, projPos.y * flip, 1);

它必須是乘以farCorner價值,這是相機視錐遠角:

float3 ray = float3(projPos.x, projPos.y * flip, 1) * farCorner;

你可以得到它通過使用

mCamera->getWorldSpaceCorners()[1];

,然後插上在合成器監聽器是這樣的:

void LightListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    vpParams = mat->getBestTechnique()->getPass(0)->getVertexProgramParameters(); 
    fpParams = mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); 
} 

void LightListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) 
{ 
    vpParams->setNamedConstant("lightPos", lightPos); 
    fpParams->setNamedConstant("farCorner", mCamera->getWorldSpaceCorners()[1]); 
}