Better bloom effect
This commit is contained in:
parent
2358f30ce2
commit
2db1a22f81
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -29,13 +29,13 @@ varying vec4 texCoord1;
|
||||
varying vec4 texCoord2;
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
vec2 pos = positionAttribute;
|
||||
|
||||
|
||||
vec2 scrPos = pos * 2. - 1.;
|
||||
|
||||
|
||||
gl_Position = vec4(scrPos, 0.5, 1.);
|
||||
|
||||
|
||||
// generated by ./1dgaussGen.rb
|
||||
// pixelShift is texture coord shift / texture pixel
|
||||
const float pixelShift = 1.;
|
||||
@ -47,9 +47,9 @@ void main() {
|
||||
const float scale3 = 0.321295592929097;
|
||||
const float shift4 = pixelShift * 2.30654399138844;
|
||||
const float scale4 = 0.178704407070903;
|
||||
|
||||
|
||||
texCoord1 = pos.xyxy + unitShift.xyxy * vec4(vec2(shift1), vec2(shift2));
|
||||
texCoord2 = pos.xyxy + unitShift.xyxy * vec4(vec2(shift3), vec2(shift4));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2013 yvt
|
||||
|
||||
|
||||
This file is part of OpenSpades.
|
||||
|
||||
|
||||
OpenSpades is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenSpades is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -38,45 +38,45 @@ void main() {
|
||||
vec3 dust2 = texture2D(dustTexture, dustTexCoord1.zw).xyz;
|
||||
vec3 dust3 = texture2D(dustTexture, dustTexCoord2.xy).xyz;
|
||||
vec3 dust4 = texture2D(dustTexture, dustTexCoord2.zw).xyz;
|
||||
|
||||
|
||||
// linearize
|
||||
dust1 *= dust1;
|
||||
dust2 *= dust2;
|
||||
dust3 *= dust3;
|
||||
dust4 *= dust4;
|
||||
|
||||
|
||||
// blurred texture (already linearized?)
|
||||
vec3 blur1 = texture2D(blurTexture1, texCoord).xyz;
|
||||
vec3 blur2 = texture2D(blurTexture2, texCoord).xyz;
|
||||
vec3 blur3 = texture2D(blurTexture3, texCoord).xyz;
|
||||
vec3 blur4 = texture2D(blurTexture4, texCoord).xyz;
|
||||
|
||||
|
||||
vec3 sum = dust1 * blur1;
|
||||
sum += dust2 * blur2;
|
||||
sum += dust3 * blur3;
|
||||
sum += dust4 * blur4;
|
||||
|
||||
|
||||
vec3 final = texture2D(inputTexture, texCoord).xyz;
|
||||
#if !LINEAR_FRAMEBUFFER
|
||||
final *= final;
|
||||
#endif
|
||||
|
||||
|
||||
final *= 0.95;
|
||||
final += sum * 0.4;
|
||||
|
||||
final += sum * 0.8;
|
||||
|
||||
// add grain
|
||||
float grain = texture2D(noiseTexture, noiseTexCoord.xy).x;
|
||||
grain += texture2D(noiseTexture, noiseTexCoord.zw).x;
|
||||
grain = fract(grain) - 0.5;
|
||||
final += grain * 0.003;
|
||||
|
||||
|
||||
// non-linearize
|
||||
#if !LINEAR_FRAMEBUFFER
|
||||
final = sqrt(max(final, 0.));
|
||||
#else
|
||||
final = max(final, 0.);
|
||||
#endif
|
||||
|
||||
|
||||
gl_FragColor = vec4(final, 1.);
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,9 @@ SPADES_SETTING(r_hdr, "");
|
||||
namespace spades {
|
||||
namespace draw {
|
||||
GLLensDustFilter::GLLensDustFilter(GLRenderer *renderer):
|
||||
renderer(renderer){
|
||||
thru = renderer->RegisterProgram("Shaders/PostFilters/PassThroughConstAlpha.program");
|
||||
renderer(renderer){
|
||||
thru = renderer->RegisterProgram("Shaders/PostFilters/PassThroughConstAlpha.program");
|
||||
gauss1d = renderer->RegisterProgram("Shaders/PostFilters/Gauss1D.program");
|
||||
dust = renderer->RegisterProgram("Shaders/PostFilters/LensDust.program");
|
||||
dustImg = (GLImage *)renderer->RegisterImage("Textures/RealLens.jpg");
|
||||
|
||||
@ -81,8 +82,9 @@ namespace spades {
|
||||
|
||||
static GLProgramAttribute blur_positionAttribute("positionAttribute");
|
||||
static GLProgramUniform blur_textureUniform("texture");
|
||||
static GLProgramUniform blur_colorUniform("colorUniform");
|
||||
static GLProgramUniform blur_texCoordRangeUniform("texCoordRange");
|
||||
static GLProgramUniform blur_colorUniform("colorUniform");
|
||||
static GLProgramUniform blur_texCoordRangeUniform("texCoordRange");
|
||||
static GLProgramUniform blur_texCoordOffsetUniform("texCoordOffset");
|
||||
program->Use();
|
||||
blur_positionAttribute(program);
|
||||
|
||||
@ -90,12 +92,17 @@ namespace spades {
|
||||
blur_textureUniform.SetValue(0);
|
||||
dev->ActiveTexture(0);
|
||||
dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
|
||||
|
||||
blur_texCoordOffsetUniform(program);
|
||||
blur_texCoordOffsetUniform.SetValue(1.f / w, 1.f / h, -1.f / w, -1.f / h);
|
||||
|
||||
blur_colorUniform(program);
|
||||
blur_colorUniform.SetValue(1.f,1.f,1.f,1.f);
|
||||
|
||||
blur_texCoordRangeUniform(program);
|
||||
blur_texCoordRangeUniform.SetValue(0.f, 0.f, 1.f, 1.f);
|
||||
blur_texCoordRangeUniform.SetValue(0.f, 0.f,
|
||||
(float)((w + 1) & ~1) / w,
|
||||
(float)((h + 1) & ~1) / h);
|
||||
|
||||
qr.SetCoordAttributeIndex(blur_positionAttribute());
|
||||
if(linearize){
|
||||
@ -112,6 +119,39 @@ namespace spades {
|
||||
qr.Draw();
|
||||
return buf2;
|
||||
}
|
||||
|
||||
GLColorBuffer GLLensDustFilter::GaussianBlur(GLColorBuffer tex, bool vertical) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
GLProgram *program = gauss1d;
|
||||
IGLDevice *dev = renderer->GetGLDevice();
|
||||
GLQuadRenderer qr(dev);
|
||||
int w = tex.GetWidth();
|
||||
int h = tex.GetHeight();
|
||||
|
||||
static GLProgramAttribute blur_positionAttribute("positionAttribute");
|
||||
static GLProgramUniform blur_textureUniform("texture");
|
||||
static GLProgramUniform blur_unitShift("unitShift");
|
||||
program->Use();
|
||||
blur_positionAttribute(program);
|
||||
|
||||
blur_textureUniform(program);
|
||||
blur_textureUniform.SetValue(0);
|
||||
dev->ActiveTexture(0);
|
||||
dev->BindTexture(IGLDevice::Texture2D, tex.GetTexture());
|
||||
|
||||
blur_unitShift(program);
|
||||
blur_unitShift.SetValue(vertical ? 0.f : 1.f / w,
|
||||
vertical ? 1.f / h : 0.f);
|
||||
|
||||
qr.SetCoordAttributeIndex(blur_positionAttribute());
|
||||
dev->Enable(IGLDevice::Blend, false);
|
||||
|
||||
GLColorBuffer buf2 = renderer->GetFramebufferManager()->CreateBufferHandle(w, h, false);
|
||||
dev->Viewport(0, 0, buf2.GetWidth(), buf2.GetHeight());
|
||||
dev->BindFramebuffer(IGLDevice::Framebuffer, buf2.GetFramebuffer());
|
||||
qr.Draw();
|
||||
return buf2;
|
||||
}
|
||||
|
||||
void GLLensDustFilter::UpdateNoise() {
|
||||
SPADES_MARK_FUNCTION();
|
||||
@ -162,18 +202,18 @@ namespace spades {
|
||||
thruTexCoordRange(thru);
|
||||
|
||||
GLColorBuffer downSampled = DownSample(input, r_hdr ? false : true);
|
||||
downSampled = DownSample(downSampled);
|
||||
downSampled = DownSample(downSampled);
|
||||
downSampled = GaussianBlur(downSampled, false);
|
||||
downSampled = GaussianBlur(downSampled, true);
|
||||
|
||||
thru->Use();
|
||||
thruColor.SetValue(1.f, 1.f, 1.f, 1.f);
|
||||
thruTexture.SetValue(0);
|
||||
dev->Enable(IGLDevice::Blend, false);
|
||||
|
||||
levels.reserve(8);
|
||||
levels.reserve(10);
|
||||
|
||||
// create downsample levels
|
||||
for(int i = 0; i < 8; i++){
|
||||
for(int i = 0; i < 10; i++){
|
||||
GLColorBuffer prevLevel;
|
||||
if(i == 0){
|
||||
prevLevel = downSampled;
|
||||
@ -187,7 +227,9 @@ namespace spades {
|
||||
int newH = (prevH + 1) / 2;
|
||||
if(newW <= 1 || newH <= 1)
|
||||
break;
|
||||
GLColorBuffer newLevel = DownSample(prevLevel);
|
||||
GLColorBuffer newLevel = DownSample(prevLevel);
|
||||
newLevel = GaussianBlur(newLevel, false);
|
||||
newLevel = GaussianBlur(newLevel, true);
|
||||
|
||||
Level lv;
|
||||
lv.w = newW; lv.h = newH;
|
||||
@ -205,12 +247,12 @@ namespace spades {
|
||||
for(int i = (int)levels.size() - 1; i >= 1; i--){
|
||||
int cnt = (int)levels.size() - i;
|
||||
float alpha = (float)cnt / (float)(cnt + 1);
|
||||
alpha = sqrtf(alpha);
|
||||
alpha = alpha;
|
||||
|
||||
GLColorBuffer curLevel = levels[i].buffer;
|
||||
|
||||
float sx = .7f / curLevel.GetWidth();
|
||||
float sy = .7f / curLevel.GetHeight();
|
||||
float sx = .25f / curLevel.GetWidth();
|
||||
float sy = .25f / curLevel.GetHeight();
|
||||
|
||||
for(int j = 0; j < 4; j++) {
|
||||
if(i < (int)levels.size() - 1) {
|
||||
|
@ -32,13 +32,15 @@ namespace spades {
|
||||
class GLProgram;
|
||||
class GLImage;
|
||||
class GLLensDustFilter {
|
||||
GLProgram *thru;
|
||||
GLProgram *dust;
|
||||
GLProgram *thru;
|
||||
GLProgram *dust;
|
||||
GLProgram *gauss1d;
|
||||
GLImage *dustImg;
|
||||
GLRenderer *renderer;
|
||||
IGLDevice::UInteger noiseTex;
|
||||
std::vector<uint32_t> noise;
|
||||
GLColorBuffer DownSample(GLColorBuffer, bool linearize = false);
|
||||
std::vector<uint32_t> noise;
|
||||
GLColorBuffer DownSample(GLColorBuffer, bool linearize = false);
|
||||
GLColorBuffer GaussianBlur(GLColorBuffer, bool vertical);
|
||||
void UpdateNoise();
|
||||
public:
|
||||
GLLensDustFilter(GLRenderer *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user