Phil 2.24.12

8:30 – FP

  • I think I found GLSL documentation! http://www.opengl.org/sdk/docs/manglsl/
  • A working convolution filter that blurs anything above a certain luminance:
  • #version 150
    // glow.fs
    // outputs the color negative of a texture
    //
    
    in vec2 vTexCoord;
    
    uniform int screenWidth;
    uniform int screenHeight;
    
    uniform sampler2D textureUnit0;
    
    vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){
    	vec2 offset = texCoord + vec2(dx, dy);
    	return texture(textureUnit0, offset);
    }
    
    void main(void)
    {
    	float dx = 1.0 / float(screenWidth);
    	float dy = 1.0 / float (screenHeight);
    
    	float x;
    	float y;
    	vec4 blurSum = vec4(0, 0, 0, 0);
    	float patchSize = 4.0;
    	float xmin = -patchSize*dx;
    	float xmax = patchSize*dx+dx*0.5;
    	float ymin = -patchSize*dy;
    	float ymax = patchSize*dy+dx*0.5;
    	float count = 0;
    
    	for(x = xmin; x < xmax; x += dx){
    		for(y = ymin; y < ymax; y += dy){
     			blurSum += getTexOffset(textureUnit1, vTexCoord, x, y);
     			if(count > 1000){
    				discard;
    			}
    			count += 1.0;
    		}
    	}
    	float weight = 1.0/count;
    	vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, 1.0);
    	vec4 sharp = texture(textureUnit0, vTexCoord);
    
    	float luminance = blured.r + blured.g + blured.b;
    	if(luminance > 1.0){
    		gl_FragColor = blured;
    	}else{
    		gl_FragColor = sharp;
    	}
    }
  • And here’s the picture it produces. Note the sharp moon and gridlines with the blurry sun 🙂
  • Next on the hit parade, add a test to see if the corners of the convolution filter touch anything above the luminance threshold and discard if it doesn’t. My guess is that should speed up things a lot. Done. Discovered that there are some odd problems that crop up as the screen gets made quite large. This could have something to do with the fact that I’m not checking to see that the convolution patch’s coordinates can run off the texture (i.e not clamped between 0.0 and 1.0)?
  • Migrate the screen drawing to a DrawableObject class. I’m pretty sure it should work there, as long as it’s called after postDraw3D(). In fact, it should be possible to have multiple screen drawing classes, though I’m not sure why.
  • Add shader directory to svn repo – done
  • And it appears that after a while, something is clogging the graphics pipeline, because the drawing slows way done. This does look like it’s due to the shader, as the neg.fs doesn’t seem to be slowing things down. Yep,  adding clamping to the glow.fs shader fixed that problem. Still have the problem where the screen texture gets messed up if the window gets too big…
  • So here’s the better version of the fragment shader
  • #version 150
    // glow.fs
    // outputs the color negative of a texture
    //
    
    in vec2 vTexCoord;
    
    uniform int screenWidth;
    uniform int screenHeight;
    
    uniform sampler2D textureUnit0;
    
    void luminanceTest(const sampler2D texUnit, const vec2 texCoord, const float xmin, const float xmax, const float ymin, const float ymax, const float luminance){
    	vec2 ll = clamp(texCoord + vec2(xmin, ymin), 0.0, 1.0);
    	vec2 lr = clamp(texCoord + vec2(xmax, ymin), 0.0, 1.0);
    	vec2 ur = clamp(texCoord + vec2(xmax, ymax), 0.0, 1.0);
    	vec2 ul = clamp(texCoord + vec2(xmin, ymax), 0.0, 1.0);
    
    	vec4 total = texture(texUnit, ll);
    	total += texture(texUnit, lr);
    	total += texture(texUnit, ur);
    	total += texture(texUnit, ul);
    
    	float weight = 1.0/4.0;
    	float val = (total.r + total.g + total.b)*weight;
    	if(val < luminance){
    		discard;
    	}
    }
    
    vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){
    	vec2 offset = texCoord + vec2(dx, dy);
    	clamp(offset, 0.0, 1.0);
    	return texture(texUnit, offset);
    }
    
    void main(void)
    {
    	float dx = 1.0 / float(screenWidth);
    	float dy = 1.0 / float (screenHeight);
    
    	float x;
    	float y;
    	vec4 blurSum = vec4(0, 0, 0, 0);
    	float patchSize = 4.0;
    	float xmin = -patchSize*dx;
    	float xmax = patchSize*dx+dx*0.5;
    	float ymin = -patchSize*dy;
    	float ymax = patchSize*dy+dx*0.5;
    	float count = 0;
    
    	luminanceTest(textureUnit0, vTexCoord, xmin, xmax, ymin, ymax, 1.0);
    
    	for(x = xmin; x < xmax; x += dx){
    		for(y = ymin; y < ymax; y += dy){
     			blurSum += getTexOffset(textureUnit0, vTexCoord, x, y);
     			if(count > 1000){
    				discard;
    			}
    			count += 1.0;
    		}
    	}
    	vec4 sharp = texture(textureUnit0, vTexCoord);
    	float weight = 1.0/count;
    	vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, sharp.a);
    
    	float luminance = blured.r + blured.g + blured.b;
    	if(luminance > 1.0){
    		gl_FragColor = blured;
    	}else{
    		gl_FragColor = sharp;
    	}
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.