mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 09:49:40 +00:00
got MRT working, some minor quirks to solve (black viewport background)
This commit is contained in:
parent
eb67afe552
commit
3f05aba76d
11 changed files with 206 additions and 14 deletions
|
@ -357,6 +357,7 @@ void OMW::Engine::go()
|
|||
|
||||
addResourcesDirectory(mResDir / "mygui");
|
||||
addResourcesDirectory(mResDir / "water");
|
||||
addResourcesDirectory(mResDir / "gbuffer");
|
||||
|
||||
// Create the window
|
||||
mOgre->createWindow("OpenMW");
|
||||
|
|
|
@ -40,9 +40,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
|||
return;
|
||||
}
|
||||
|
||||
// This means that everything up to RQG_Main can occlude the objects that are tested
|
||||
const int queue = RQG_Main+1;
|
||||
|
||||
MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
|
||||
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
|
||||
matQueryArea->setDepthWriteEnabled(false);
|
||||
|
@ -65,14 +62,14 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
|||
mBBQueryTotal->setDefaultDimensions(150, 150);
|
||||
mBBQueryTotal->createBillboard(Vector3::ZERO);
|
||||
mBBQueryTotal->setMaterialName("QueryTotalPixels");
|
||||
mBBQueryTotal->setRenderQueueGroup(queue+1);
|
||||
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||
mBBNodeReal->attachObject(mBBQueryTotal);
|
||||
|
||||
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
|
||||
mBBQueryVisible->setDefaultDimensions(150, 150);
|
||||
mBBQueryVisible->createBillboard(Vector3::ZERO);
|
||||
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
|
||||
mBBQueryVisible->setRenderQueueGroup(queue+1);
|
||||
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
|
||||
mBBNodeReal->attachObject(mBBQueryVisible);
|
||||
|
||||
mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1);
|
||||
|
@ -80,7 +77,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
|||
mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003);
|
||||
mBBQuerySingleObject->createBillboard(Vector3::ZERO);
|
||||
mBBQuerySingleObject->setMaterialName("QueryVisiblePixels");
|
||||
mBBQuerySingleObject->setRenderQueueGroup(queue);
|
||||
mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery);
|
||||
mObjectNode->attachObject(mBBQuerySingleObject);
|
||||
|
||||
mRendering->getScene()->addRenderObjectListener(this);
|
||||
|
|
|
@ -14,6 +14,8 @@ enum RenderQueueGroups
|
|||
|
||||
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
|
||||
|
||||
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_MAIN+1,
|
||||
|
||||
RQG_Alpha = Ogre::RENDER_QUEUE_7,
|
||||
|
||||
// Sky late (sun & sun flare)
|
||||
|
|
|
@ -37,6 +37,14 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
// Load resources
|
||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||
|
||||
if (Settings::Manager::getBool("multiple render targets", "Render"))
|
||||
{
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer");
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer");
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||
}
|
||||
|
||||
// Turn the entire scene (represented by the 'root' node) -90
|
||||
// degrees around the x axis. This makes Z go upwards, and Y go into
|
||||
// the screen (when x is to the right.) This is the orientation that
|
||||
|
@ -252,11 +260,22 @@ bool RenderingManager::toggleRenderMode(int mode)
|
|||
{
|
||||
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
|
||||
{
|
||||
// disable compositors
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false);
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false);
|
||||
|
||||
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// re-enable compositors
|
||||
if (Settings::Manager::getBool("multiple render targets", "Render"))
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||
}
|
||||
|
||||
mRendering.getCamera()->setPolygonMode(PM_SOLID);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,21 @@ Ogre::MaterialPtr Water::createMaterial()
|
|||
if (mReflectionTarget == 0)
|
||||
mat->removeTechnique(0);
|
||||
|
||||
if (Settings::Manager::getBool("multiple render targets", "Render"))
|
||||
{
|
||||
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer");
|
||||
|
||||
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
|
||||
TextureUnitState* tus = mat->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap");
|
||||
if (tus != 0)
|
||||
tus->setTexture(colorTexture);
|
||||
|
||||
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
|
||||
tus = mat->getTechnique(0)->getPass(0)->getTextureUnitState("depthMap");
|
||||
if (tus != 0)
|
||||
tus->setTexture(depthTexture);
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,3 +8,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.compositor "${OpenMW_BINA
|
|||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.material "${OpenMW_BINARY_DIR}/resources/water/water.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal2.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal2.tga" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.cg "${OpenMW_BINARY_DIR}/resources/water/water.cg" COPYONLY)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.cg "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.material "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.compositor "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.compositor" COPYONLY)
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// Compositor that just controls output to the MRT textures
|
||||
compositor gbuffer
|
||||
{
|
||||
technique
|
||||
{
|
||||
// MRT output. Currently this is a color texture plus a depth texture
|
||||
texture mrt_output target_width target_height PF_FLOAT16_RGBA PF_FLOAT16_RGBA chain_scope depth_pool 2
|
||||
|
||||
target mrt_output
|
||||
{
|
||||
input none
|
||||
pass clear
|
||||
{
|
||||
}
|
||||
pass render_scene
|
||||
{
|
||||
first_render_queue 0
|
||||
last_render_queue 69
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
target_output
|
||||
{
|
||||
input none
|
||||
|
||||
pass render_quad
|
||||
{
|
||||
material RenderScene
|
||||
input 0 mrt_output 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finalizer compositor to render objects that we don't want in the MRT textures (this is the case for most transparent stuff)
|
||||
compositor gbufferFinalizer
|
||||
{
|
||||
technique
|
||||
{
|
||||
texture no_mrt_output target_width target_height PF_R8G8B8A8 depth_pool 2 no_fsaa
|
||||
texture previousscene target_width target_height PF_R8G8B8A8
|
||||
|
||||
target previousscene
|
||||
{
|
||||
input previous
|
||||
}
|
||||
target no_mrt_output
|
||||
{
|
||||
input none
|
||||
shadows off
|
||||
pass clear
|
||||
{
|
||||
buffers colour
|
||||
colour_value 0 0 0 0
|
||||
}
|
||||
pass render_quad
|
||||
{
|
||||
material RenderSceneNoDepth
|
||||
input 0 previousscene
|
||||
}
|
||||
pass render_scene
|
||||
{
|
||||
first_render_queue 70
|
||||
last_render_queue 100
|
||||
}
|
||||
}
|
||||
target_output
|
||||
{
|
||||
input none
|
||||
pass clear
|
||||
{
|
||||
}
|
||||
pass render_quad
|
||||
{
|
||||
material RenderSceneNoDepth
|
||||
input 0 no_mrt_output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
vertex_program RenderGBuffer_vs cg
|
||||
{
|
||||
source gbuffer.cg
|
||||
profiles vs_4_0 vs_1_1 arbvp1
|
||||
entry_point RenderScene_vs
|
||||
default_params
|
||||
{
|
||||
param_named_auto wvp worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
fragment_program RenderGBuffer_ps cg
|
||||
{
|
||||
source gbuffer.cg
|
||||
entry_point RenderScene_ps
|
||||
profiles ps_4_0 ps_2_x arbfp1
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
material RenderScene
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program_ref RenderGBuffer_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref RenderGBuffer_ps
|
||||
{
|
||||
}
|
||||
|
||||
texture_unit tex1
|
||||
{
|
||||
//scenebuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material RenderSceneNoDepth
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
depth_write off
|
||||
vertex_program_ref RenderGBuffer_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref RenderGBuffer_ps
|
||||
{
|
||||
}
|
||||
|
||||
texture_unit tex1
|
||||
{
|
||||
//scenebuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
sampler RT : register(s0);
|
||||
sampler NormalMap : register(s1);
|
||||
sampler CausticMap : register(s2);
|
||||
|
||||
float4 main_ps(float2 iTexCoord : TEXCOORD0,
|
||||
float3 noiseCoord : TEXCOORD1,
|
||||
uniform sampler2D RT : register(s0),
|
||||
uniform sampler2D NormalMap : register(s1),
|
||||
uniform sampler2D CausticMap : register(s2),
|
||||
uniform float4 tintColour) : COLOR
|
||||
{
|
||||
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
|
||||
|
|
|
@ -34,7 +34,8 @@ void main_fp
|
|||
, uniform float renderTargetFlipping
|
||||
|
||||
, uniform sampler2D reflectionMap : register(s0)
|
||||
, uniform sampler2D normalMap : register(s1)
|
||||
, uniform sampler2D refractionMap : register(s1)
|
||||
, uniform sampler2D normalMap : register(s2)
|
||||
, uniform float time
|
||||
, uniform float4 fogParams
|
||||
, uniform float4 fogColour
|
||||
|
@ -42,7 +43,7 @@ void main_fp
|
|||
{
|
||||
|
||||
float2 screenCoords = iScreenCoords.xy / iScreenCoords.z;
|
||||
screenCoords.y = (renderTargetFlipping == -1) ? (1-screenCoords.y) : screenCoords.y;
|
||||
screenCoords.y = (1-saturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y;
|
||||
|
||||
float2 uv1 = iUv + time * float2(0.5, 0);
|
||||
float2 uv2 = iUv + time * float2(0, 0.5);
|
||||
|
@ -55,8 +56,11 @@ void main_fp
|
|||
screenCoords += normal.yx * 0.05;
|
||||
|
||||
float4 reflection = tex2D(reflectionMap, screenCoords);
|
||||
float4 refraction = tex2D(refractionMap, screenCoords);
|
||||
|
||||
oColor.xyz = lerp(reflection.xyz, refraction.xyz, 1);
|
||||
|
||||
float fogValue = saturate((iDepth - fogParams.y) * fogParams.w);
|
||||
oColor.xyz = lerp(reflection.xyz, fogColour, fogValue);
|
||||
oColor.a = 0.45;
|
||||
oColor.xyz = lerp(oColor.xyz, fogColour, fogValue);
|
||||
oColor.a = 1;
|
||||
}
|
||||
|
|
|
@ -48,13 +48,13 @@ material Water
|
|||
|
||||
vertex_program_ref Water_VP
|
||||
{
|
||||
param_named_auto renderTargetFlipping render_target_flipping
|
||||
}
|
||||
fragment_program_ref Water_FP
|
||||
{
|
||||
param_named_auto time time 0.1
|
||||
param_named_auto fogColour fog_colour
|
||||
param_named_auto fogParams fog_params
|
||||
param_named_auto renderTargetFlipping render_target_flipping
|
||||
}
|
||||
|
||||
texture_unit reflectionMap
|
||||
|
@ -62,6 +62,12 @@ material Water
|
|||
texture WaterReflection
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit refractionMap
|
||||
{
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit normalMap
|
||||
{
|
||||
texture WaterNormal2.tga
|
||||
|
|
Loading…
Reference in a new issue