bayer-dithering shader revisited

This commit is contained in:
minjaesong
2017-07-15 18:35:57 +09:00
parent 81acfecbd7
commit b9c93dd6b0
4 changed files with 54 additions and 49 deletions

View File

@@ -4,56 +4,53 @@ uniform sampler2D u_texture;
uniform mat4 Bayer;
uniform float monitorGamma;
//uniform mat4 bayer;
uniform float monitorGamma; // give 2.2f
vec4 gammaIn(vec4 col) {
return pow(col, vec4(vec3(monitorGamma), 1.0));
}
int bayer[8][8] = {
{ 0, 32, 8, 40, 2, 34, 10, 42}, // 8x8 bayer ordered dithering
{48, 16, 56, 24, 50, 18, 58, 26}, // pattern. Each input pixel
{12, 44, 4, 36, 14, 46, 6, 38}, // is scaled to the 0..63 range
{60, 28, 52, 20, 62, 30, 54, 22}, // before looking in this table
{ 3, 35, 11, 43, 1, 33, 9, 41}, // to determine the action
{51, 19, 59, 27, 49, 17, 57, 25},
{15, 47, 7, 39, 13, 45, 5, 37},
{63, 31, 55, 23, 61, 29, 53, 21} }; // fun fact: you can calculate bayer value on-the-fly but LUT is faster
float bayerSize = 8.0;
float bayerDivider = bayerSize * bayerSize;
vec4 gammaOut(vec4 col) {
return pow(col, vec4(vec3(1.0 / monitorGamma), 1.0));
vec4 nearestColour(vec4 incolor) {
vec4 rgbaCounts = vec4(16.0, 16.0, 16.0, 1.0);
vec4 color = incolor;
color.r = floor((rgbaCounts.r - 1.0) * color.r + 0.5) / (rgbaCounts.r - 1.0);
color.g = floor((rgbaCounts.g - 1.0) * color.g + 0.5) / (rgbaCounts.g - 1.0);
color.b = floor((rgbaCounts.b - 1.0) * color.b + 0.5) / (rgbaCounts.b - 1.0);
if (rgbaCounts.a >= 2.0) {
color.a = floor((rgbaCounts.a - 1.0) * color.a + 0.5) / (rgbaCounts.a - 1.0);
}
else if (rgbaCounts.a == 1.0) {
color.a = (color.a >= 0.5f) ? 1.0 : 0.0;
}
else {
color.a = 1.0;
}
return color;
}
void main(void) {
// create texture coordinates based on pixelSize //
float pixelSize = 1.0;
vec4 inColor = texture2D(u_texture, v_texCoords);
vec2 pixelSizeVec = vec2(float(pixelSize), float(pixelSize));
vec2 entry = mod(gl_FragCoord.xy, vec2(bayerSize, bayerSize));
vec2 discrete = (gl_FragCoord.xy + 0.001) / v_texCoords / pixelSizeVec;
//vec2 discrete = (gl_FragCoord.xy) / v_texCoords / pixelSizeVec;
float r = 1.0 / monitorGamma;
discrete = floor(discrete * v_texCoords) / discrete;
vec4 color = texture2D(u_texture, discrete).rgba;
// add Bayer matrix entry to current pixel //
vec2 entry = mod(gl_FragCoord.xy / pixelSizeVec, vec2(4, 4));
color.r = color.r + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
color.g = color.g + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
color.b = color.b + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
//color.a = color.a + Bayer[int(entry.x)][int(entry.y)] / 17.0 - 0.5;
// find nearest 8-bit color //
color.r = floor(15.0 * color.r + 0.5) / 15.0;
color.g = floor(15.0 * color.g + 0.5) / 15.0;
color.b = floor(15.0 * color.b + 0.5) / 15.0;
//color.a = floor(15.0 * color.a + 0.5) / 15.0;
gl_FragColor = color;
//vec4 color = texture2D(u_texture, v_texCoords);
//color = floor(15.0 * color + 0.5) / 15.0;
//
//gl_FragColor = color;
gl_FragColor = nearestColour(inColor + r * (bayer[int(entry.y)][int(entry.x)] / bayerDivider - 0.5));
//gl_FragColor = nearestColour(inColor);
}

View File

@@ -23,6 +23,13 @@ class Float16() {
bits = Float16.fromFloat(fval)
}
operator fun times(other: Float) = fromFloat(this.toFloat() * other)
operator fun times(other: Float16) = fromFloat(this.toFloat() * other.toFloat())
operator fun div(other: Float) = fromFloat(this.toFloat() / other)
operator fun div(other: Float16) = fromFloat(this.toFloat() / other.toFloat())
// operators are stripped: you don't calculate from FP16; this is only for storing values //
companion object {

View File

@@ -37,9 +37,9 @@ object ColorLimiterTest : ApplicationAdapter() {
override fun create() {
ShaderProgram.pedantic = false
shader4096 = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096.frag"))
shader4096 = ShaderProgram(Gdx.files.internal("assets/4096.vert"), Gdx.files.internal("assets/4096_bayer.frag"))
shader4096.begin()
//shader4096.setUniformMatrix("Bayer", Matrix4(floatArrayOf(0f,8f,2f,10f,12f,4f,14f,6f,3f,11f,1f,9f,15f,7f,13f,5f)))
shader4096.setUniformf("monitorGamma", 2.2f)
shader4096.end()
@@ -57,13 +57,14 @@ object ColorLimiterTest : ApplicationAdapter() {
batch.inUse {
batch.shader = shader4096
//batch.shader.setUniformf("monitorGamma", 2.2f)
shader4096.setUniformf("rgbaCounts", 16f, 16f, 16f, 16f)
batch.color = Color.WHITE
batch.draw(img, 0f, 0f)
batch.shader = null
batch.color = Color.WHITE
batch.draw(img, img.width.toFloat(), 0f)
}
}

View File

@@ -21,6 +21,8 @@ import java.util.*
//typealias RGB10 = Int
// NOTE: no Float16 on this thing: 67 kB of memory footage is totally acceptable
object LightmapRenderer {
private val world: GameWorld = Terrarum.ingame!!.world
@@ -41,8 +43,6 @@ object LightmapRenderer {
val LIGHTMAP_HEIGHT = Terrarum.ingame!!.ZOOM_MINIMUM.inv().times(Terrarum.HEIGHT)
.div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3
//data class Lux(var r: Float16, var g: Float16, var b: Float16, var uv: Float16)
/**
* Float value, 1.0 for 1023
*/