C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – Ogre3d /延迟渲染/点光源大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图使用ogre compositor框架设置延迟渲染器.我尝试在下面的代码中实现一个点光着色器(作为全屏四边形效果,没有衰减或镜面反射计算):

将延迟数据输出到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
    }
}

轻材料脚本:

@H_891_9@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 @R_948_10586@l_light_contrib;
    @R_948_10586@l_light_contrib = max(0.0,dot(objToLightDir,normal));

    return float4(@R_948_10586@l_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.7f));
light->setVisible(true);
light->setDiffuseColour(Ogre::ColourValue::WhitE);
light->setSpecularColour(Ogre::ColourValue::WhitE);
lLightSceneNodeHolder->attachObject(light);

我得到输出,一切正常 – 除了我不能让灯光正常工作. G Buffer包含有效数据 – 视图空间法线,线性z深度,纹理.我也将视图空间中的光位置作为参数 – 但是在矢量计算期间存在一些问题 – 并且输出与点光源不同.我在这做错了什么?

谢谢!

附:我也尝试通过合成器监听器手动传递lightPos参数,但随后灯光看起来更像是定向灯……

解决方法@H_502_53@
问题在于:

float3 ray = float3(projpos.x,1);

它必须乘以farCorner值,这是相机视锥的远角:

float3 ray = float3(projpos.x,1)* farCorner;

你可以通过使用获得它

@H_828_5@mCamera-> getWorldspaceCorners()[1];

然后将它插入到compositor侦听器中,如下所示:

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]);
}

大佬总结

以上是大佬教程为你收集整理的c – Ogre3d /延迟渲染/点光源全部内容,希望文章能够帮你解决c – Ogre3d /延迟渲染/点光源所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。