mirror of https://github.com/OpenMW/openmw.git
support postprocess distortion
parent
51cb3b08cb
commit
187f63d3d3
@ -0,0 +1,28 @@
|
||||
#include "distortion.hpp"
|
||||
|
||||
#include <osg/FrameBufferObject>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
void DistortionCallback::drawImplementation(
|
||||
osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous)
|
||||
{
|
||||
osg::State* state = renderInfo.getState();
|
||||
size_t frameId = state->getFrameStamp()->getFrameNumber() % 2;
|
||||
|
||||
mFBO[frameId]->apply(*state);
|
||||
|
||||
const osg::Texture* tex
|
||||
= mFBO[frameId]->getAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0).getTexture();
|
||||
|
||||
glViewport(0, 0, tex->getTextureWidth(), tex->getTextureHeight());
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
bin->drawImplementation(renderInfo, previous);
|
||||
|
||||
tex = mOriginalFBO[frameId]->getAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0).getTexture();
|
||||
glViewport(0, 0, tex->getTextureWidth(), tex->getTextureHeight());
|
||||
mOriginalFBO[frameId]->apply(*state);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
#include <array>
|
||||
|
||||
#include <osgUtil/RenderBin>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class FrameBufferObject;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class DistortionCallback : public osgUtil::RenderBin::DrawCallback
|
||||
{
|
||||
public:
|
||||
void drawImplementation(
|
||||
osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override;
|
||||
|
||||
void setFBO(const osg::ref_ptr<osg::FrameBufferObject>& fbo, size_t frameId) { mFBO[frameId] = fbo; }
|
||||
void setOriginalFBO(const osg::ref_ptr<osg::FrameBufferObject>& fbo, size_t frameId)
|
||||
{
|
||||
mOriginalFBO[frameId] = fbo;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mFBO;
|
||||
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mOriginalFBO;
|
||||
};
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
fragment main {
|
||||
|
||||
omw_In vec2 omw_TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float multiplier = 0.14;
|
||||
|
||||
vec2 offset = omw_Texture2D(omw_SamplerDistortion, omw_TexCoord).rg;
|
||||
offset *= multiplier;
|
||||
offset = clamp(offset, vec2(-1.0), vec2(1.0));
|
||||
|
||||
float occlusionFactor = omw_Texture2D(omw_SamplerDistortion, omw_TexCoord+offset).b;
|
||||
|
||||
omw_FragColor = mix(omw_GetLastShader(omw_TexCoord + offset), omw_GetLastShader(omw_TexCoord), occlusionFactor);
|
||||
}
|
||||
}
|
||||
|
||||
technique {
|
||||
description = "Internal refraction shader for OpenMW";
|
||||
version = "1.0";
|
||||
author = "OpenMW";
|
||||
passes = main;
|
||||
flags = hidden;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#ifndef LIB_UTIL_DISTORTION
|
||||
#define LIB_UTIL_DISTORTION
|
||||
|
||||
vec4 applyDistortion(in vec4 color, in float strength, in float pixelDepth, in float sceneDepth)
|
||||
{
|
||||
vec4 distortion = color;
|
||||
float invOcclusion = 1.0;
|
||||
|
||||
// TODO: Investigate me. Alpha-clipping is enabled for refraction for what seems an arbitrary threshold, even when
|
||||
// there are no associated NIF properties.
|
||||
if (distortion.a < 0.1)
|
||||
discard;
|
||||
|
||||
distortion.b = 0.0;
|
||||
|
||||
#if @reverseZ
|
||||
if (pixelDepth < sceneDepth)
|
||||
#else
|
||||
if (pixelDepth > sceneDepth)
|
||||
#endif
|
||||
{
|
||||
invOcclusion = 0.0;
|
||||
distortion.b = 1.0;
|
||||
}
|
||||
distortion.rg = color.rg * 2.0 - 1.0;
|
||||
|
||||
distortion.rg *= invOcclusion * strength;
|
||||
|
||||
return distortion;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue