mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 18:59:57 +00:00
Merge branch 'render_targets' into 'master'
Bind custom render targets per pass See merge request OpenMW/openmw!1884
This commit is contained in:
commit
d4e2000d5b
6 changed files with 56 additions and 8 deletions
|
@ -79,7 +79,7 @@ namespace MWLua
|
|||
shader.mQueuedAction = true;
|
||||
|
||||
context.mLuaManager->addAction(
|
||||
[&] { MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos); },
|
||||
[=] { MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos); },
|
||||
"Enable shader " + (shader.mShader ? shader.mShader->getName() : "nil")
|
||||
);
|
||||
};
|
||||
|
|
|
@ -574,10 +574,11 @@ namespace MWRender
|
|||
uniform->setUniform(node.mRootStateSet->getOrCreateUniform(uniform->mName, type.value()));
|
||||
}
|
||||
|
||||
int subTexUnit = texUnit;
|
||||
std::unordered_map<osg::Texture2D*, osg::Texture2D*> renderTargetCache;
|
||||
|
||||
for (const auto& pass : technique->getPasses())
|
||||
{
|
||||
int subTexUnit = texUnit;
|
||||
fx::DispatchNode::SubPass subPass;
|
||||
|
||||
pass->prepareStateSet(subPass.mStateSet, technique->getName());
|
||||
|
@ -591,6 +592,7 @@ namespace MWRender
|
|||
const auto [w, h] = rt.mSize.get(mWidth, mHeight);
|
||||
|
||||
subPass.mRenderTexture = new osg::Texture2D(*rt.mTarget);
|
||||
renderTargetCache[rt.mTarget] = subPass.mRenderTexture;
|
||||
subPass.mRenderTexture->setTextureSize(w, h);
|
||||
subPass.mRenderTexture->setName(std::string(pass->getTarget()));
|
||||
|
||||
|
@ -600,10 +602,18 @@ namespace MWRender
|
|||
subPass.mRenderTarget = new osg::FrameBufferObject;
|
||||
subPass.mRenderTarget->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(subPass.mRenderTexture));
|
||||
subPass.mStateSet->setAttributeAndModes(new osg::Viewport(0, 0, w, h));
|
||||
|
||||
node.mRootStateSet->setTextureAttributeAndModes(subTexUnit, subPass.mRenderTexture);
|
||||
node.mRootStateSet->addUniform(new osg::Uniform(subPass.mRenderTexture->getName().c_str(), subTexUnit++));
|
||||
}
|
||||
|
||||
for (const auto& whitelist : pass->getRenderTargets())
|
||||
{
|
||||
auto it = technique->getRenderTargetsMap().find(whitelist);
|
||||
if (it != technique->getRenderTargetsMap().end() && renderTargetCache[it->second.mTarget])
|
||||
{
|
||||
subPass.mStateSet->setTextureAttributeAndModes(subTexUnit, renderTargetCache[it->second.mTarget]);
|
||||
subPass.mStateSet->addUniform(new osg::Uniform(std::string(it->first).c_str(), subTexUnit++));
|
||||
}
|
||||
}
|
||||
|
||||
node.mPasses.emplace_back(std::move(subPass));
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,9 @@ float omw_GetPointLightRadius(int index)
|
|||
for (size_t pos = header.find(define); pos != std::string::npos; pos = header.find(define))
|
||||
header.replace(pos, define.size(), value);
|
||||
|
||||
for (const auto& target : mRenderTargets)
|
||||
header.append("uniform sampler2D " + std::string(target) + ";");
|
||||
|
||||
for (auto& uniform : technique.getUniformMap())
|
||||
if (auto glsl = uniform->getGLSL())
|
||||
header.append(glsl.value());
|
||||
|
|
|
@ -43,7 +43,9 @@ namespace fx
|
|||
|
||||
void compile(Technique& technique, std::string_view preamble);
|
||||
|
||||
std::string_view getTarget() const { return mTarget; }
|
||||
std::string getTarget() const { return mTarget; }
|
||||
|
||||
const std::array<std::string, 3>& getRenderTargets() const { return mRenderTargets; }
|
||||
|
||||
void prepareStateSet(osg::StateSet* stateSet, const std::string& name) const;
|
||||
|
||||
|
@ -67,7 +69,9 @@ namespace fx
|
|||
bool mUBO;
|
||||
bool mSupportsNormals;
|
||||
|
||||
std::string_view mTarget;
|
||||
std::array<std::string, 3> mRenderTargets;
|
||||
|
||||
std::string mTarget;
|
||||
std::optional<osg::Vec4f> mClearColor;
|
||||
|
||||
std::optional<osg::BlendFunc::BlendFuncMode> mBlendSource;
|
||||
|
|
|
@ -822,6 +822,21 @@ namespace fx
|
|||
expect<Lexer::Literal>();
|
||||
pass->mTarget = std::get<Lexer::Literal>(mToken).value;
|
||||
}
|
||||
else if (key == "rt1")
|
||||
{
|
||||
expect<Lexer::Literal>();
|
||||
pass->mRenderTargets[0] = std::get<Lexer::Literal>(mToken).value;
|
||||
}
|
||||
else if (key == "rt2")
|
||||
{
|
||||
expect<Lexer::Literal>();
|
||||
pass->mRenderTargets[1] = std::get<Lexer::Literal>(mToken).value;
|
||||
}
|
||||
else if (key == "rt3")
|
||||
{
|
||||
expect<Lexer::Literal>();
|
||||
pass->mRenderTargets[2] =std::get<Lexer::Literal>(mToken).value;
|
||||
}
|
||||
else if (key == "blend")
|
||||
{
|
||||
expect<Lexer::Open_Parenthesis>();
|
||||
|
|
|
@ -500,7 +500,8 @@ is not wanted and you want a custom render target.
|
|||
|
||||
To use the render target you must assign passes to it, along with any optional clear modes or custom blend modes.
|
||||
|
||||
In the code snippet below a rendertarget is used to draw the red cannel of a scene at half resolution.
|
||||
In the code snippet below a rendertarget is used to draw the red cannel of a scene at half resolution, then a quarter. As a restriction,
|
||||
only three render targets can be bound per pass with ``rt1``, ``rt2``, ``rt3``, respectively.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
|
@ -512,6 +513,11 @@ In the code snippet below a rendertarget is used to draw the red cannel of a sce
|
|||
source_format = red;
|
||||
}
|
||||
|
||||
render_target RT_Downsample4 {
|
||||
width_ratio = 0.25;
|
||||
height_ratio = 0.25;
|
||||
}
|
||||
|
||||
fragment downsample2x(target=RT_Downsample) {
|
||||
|
||||
omw_In vec2 omw_TexCoord;
|
||||
|
@ -522,6 +528,16 @@ In the code snippet below a rendertarget is used to draw the red cannel of a sce
|
|||
}
|
||||
}
|
||||
|
||||
fragment downsample4x(target=RT_Downsample4, rt1=RT_Downsample) {
|
||||
|
||||
omw_In vec2 omw_TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
omw_FragColor = omw_Texture2D(RT_Downsample, omw_TexCoord);
|
||||
}
|
||||
}
|
||||
|
||||
Now, if we ever run the `downsample2x` pass it will write to the target buffer instead of the default
|
||||
one assigned by the engine.
|
||||
|
||||
|
|
Loading…
Reference in a new issue