c – Ogre3d /延迟渲染/点光源
发布时间:2020-12-16 07:02:53 所属栏目:百科 来源:网络整理
导读:我试图使用ogre compositor框架设置延迟渲染器.我尝试在下面的代码中实现一个点光着色器(作为全屏四边形效果,没有衰减或镜面反射计算): 将延迟数据输出到GBuffer的材料: void ToGBufferVP ( float4 iPosition : POSITION,float3 iNormal : NORMAL,float2 i
我试图使用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 } } 轻材料脚本: 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.7f)); light->setVisible(true); light->setDiffuseColour(Ogre::ColourValue::White); light->setSpecularColour(Ogre::ColourValue::White); lLightSceneNodeHolder->attachObject(light); 我得到输出,一切正常 – 除了我不能让灯光正常工作. G Buffer包含有效数据 – 视图空间法线,线性z深度,纹理.我也将视图空间中的光位置作为参数 – 但是在矢量计算期间存在一些问题 – 并且输出与点光源不同.我在这做错了什么? 谢谢! 附:我也尝试通过合成器监听器手动传递lightPos参数,但随后灯光看起来更像是定向灯…… 解决方法
问题在于:
float3 ray = float3(projPos.x,1); 它必须乘以farCorner值,这是相机视锥的远角: float3 ray = float3(projPos.x,1)* farCorner; 你可以通过使用获得它 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]); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |