Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
    Home     Help   Search   Login   Register   
Pages: 1 [2]
  ignore  |  Print  
  sRGB textures  (Read 8680 times)
0 Members and 1 Guest are viewing this topic.
Offline Roquen
« Reply #30 - Posted 2012-03-06 07:14:28 »

All of this stems from the real world problem of creating an additive color display device.  It's been know (since at least the 1930s) that RGB was a terrible way to describe color.  The only reason we use RGB is because it's possible to build such a device.  A good art package allows the artist to create images with a specific target color response...but all of that information is lost if not stored in a supporting format.
Offline theagentd
« Reply #31 - Posted 2012-03-06 09:22:55 »


I understand WHY we have/need gamma correction, I'm just questioning HOW it should be done...

Offline princec

JGO Kernel

Medals: 404
Projects: 3
Exp: 16 years

Eh? Who? What? ... Me?

« Reply #32 - Posted 2012-03-06 09:47:49 »

Well, I think the linked articles from Spas pretty much explained exactly what to do and when to do it.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Spasi
« Reply #33 - Posted 2012-03-06 12:01:50 »

I think theagentd is asking why we need to convert from gamma to linear in the shader (or sRGB sampler), instead of doing it as a preprocess or when loading the texture data. The answer lies in what I said about sRGB being a form of compression. If you perform the linear conversion ahead of time and store the result in a 8-bit-per-channel texture, you lose information. This code sample should provide enough evidence that it's true:

byte[] colors = new byte[256];
for ( int i = 0; i < colors.length; i++ )
   colors[i] = (byte)i;

for ( int i = 0; i < colors.length; i++ ) {
   // 8-bit-per-channel RGB source in gamma-space
   byte gammaSrc = colors[i];
   // The result of texture(tex, coord) in the shader.
   float gammaSample = (gammaSrc & 0xFF) / 255.0f;
   // The RGB value in linear-space, converted in the shader or through sRGB sampling.
   float gammaValue = (float)Math.pow(gammaSample, 2.2);

   // 8-bit-per-channel RGB source in linear-space
   byte linearSrc = (byte)(gammaValue * 255.0);
   // The result of texture(tex, coord) in the shader.
   float linearValue = (linearSrc & 0xFF) / 255.0f;

   System.out.println(gammaValue + " - " + linearValue);

If you run it and inspect the output, you'll see that every value is different except the two extremes, 0.0 and 1.0. More importantly, sampling the linear-space texture results in the first 20 or so values being clipped at 0.0.

And why the f*ck does monitors expect inverse gamma data? That makes just as much sense as saying that you have to add Pi to each color channel or multiply each channel by 10 or something just because "the monitor expects it". Maybe I'm just being stupid... ._.

They expect inverse gamma data because every piece of visual information ever made, whether it's photographs, textures, videos or even subpixel font antialiasing, has been designed with gamma output in mind. With good reason too. It couldn't have been Pi, or 10x, or anything else, because the gamma curve emulates the light and color response in human eyes. It makes perfect sense and helps computer systems get the most quality out of only 8 bits of information per color channel.
Offline theagentd
« Reply #34 - Posted 2012-03-06 12:07:20 »

Thanks Spasi. I think that cleared it up a bit, but I'm still skeptical. Tongue I'll just have to do as my artist says then. xd

Offline Spasi
« Reply #35 - Posted 2012-03-06 16:32:57 »

I was doing some tests and something important came up. When going from 8bit gamma to fp linear and back, the correct behavior is to round instead of truncating:

byte src = ...
double d = Math.pow((src & 0xFF) / 255.0, 2.2);
// This is wrong
byte trg = (byte)(Math.pow(d, 1.0 / 2.2) * 255.0);
// This is correct
byte trg = (byte)Math.round(Math.pow(d, 1.0 / 2.2) * 255.0);

So if you use Riven's code above, the last line should be:

return (int)Math.round(Math.pow((x+y+z+w) * 0.25f, 1.0 / gamma) * 255.0);

Without rounding, a gamma-to-linear-to-gamma conversion of a 0-255 gradient will differ in 65 places and 24 gradient steps will be lost.
Pages: 1 [2]
  ignore  |  Print  
You cannot reply to this message, because it is very, very old.


Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (37 views)
2014-10-17 03:59:02

Norakomi (28 views)
2014-10-16 15:22:06

Norakomi (24 views)
2014-10-16 15:20:20

lcass (27 views)
2014-10-15 16:18:58

TehJavaDev (52 views)
2014-10-14 00:39:48

TehJavaDev (54 views)
2014-10-14 00:35:47

TehJavaDev (42 views)
2014-10-14 00:32:37

BurntPizza (63 views)
2014-10-11 23:24:42

BurntPizza (36 views)
2014-10-11 23:10:45

BurntPizza (77 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06 is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!