Files
OpenSpace/shaders/abuffer/abufferfragment.glsl
Alexander Bock 906470f28e Untabify the rest of the source files
Update Ghoul repository
2016-04-18 20:14:29 +02:00

197 lines
6.0 KiB
GLSL

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 - 2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef _ABUFFERFRAGMENT_GLSL_
#define _ABUFFERFRAGMENT_GLSL_
struct ABufferFragment {
uint channel0;
uint channel1;
uint channel2;
uint channel3;
};
// An abuffer frame
// Values stored in abuffer:
// -----CHANNEL 0-----
// type 8 bits (signed char) 0: geometry, >0: volume entry, <0: volume exit
// msaa 8 bits
// --- if geometry --- | ---- if volume ----
// reserved 16 bits | x 16 bits
// -----CHANNEL 1-----
// r 8 bits | y 16 bits
// g 8 bits |
// b 8 bits | z 16 bits
// a 8 bits |
// -----CHANNEL 2-----
// depth 32 bits
// -----CHANNEL 3-----
// blend 4 bits (0 = normal, 1 = additive, 2-7 reserved)
// next 28 bits
// -------------------
const uint mask_1 = uint(1);
const uint mask_8 = uint(255);
const uint mask_16 = uint(65535);
const uint mask_24 = uint(16777215);
const uint mask_28 = uint(268435455);
const uint mask_31 = uint(2147483647);
const uint mask_32 = uint(4294967295);
const uint mask_red = mask_16;
const uint shift_red = 0;
const uint mask_type = mask_32 - mask_24;
const uint shift_type = 24;
const uint mask_msaa = mask_24 - mask_16;
const uint shift_msaa = 16;
const uint mask_blend = mask_32 - mask_28;
const uint shift_blend = 28;
const uint mask_next = mask_28;
const uint shift_next = 0;
void bitinsert(inout uint pack, uint val, uint mask, uint shift) {
pack &= ~mask;
pack |= (val << shift) & mask;
}
uint bitextract(in uint pack, uint mask, uint shift) {
return (pack >> shift) & (mask >> shift);
}
/**
* Color
*/
void _color_(inout ABufferFragment frag, vec4 color) {
frag.channel1 = packUnorm4x8(color);
}
vec4 _color_(ABufferFragment frag) {
return unpackUnorm4x8(frag.channel1);
}
/**
* Position
*/
void _position_(inout ABufferFragment frag, vec3 pos) {
uint red = uint(round(clamp(pos.x, 0.0, 1.0) * 65535.0));
bitinsert(frag.channel0, red, mask_red, shift_red);
frag.channel1 = packUnorm2x16(pos.yz);
}
vec3 _position_(ABufferFragment frag) {
float x = float(bitextract(frag.channel0, mask_red, shift_red)) / 65535.0;
vec2 yz = unpackUnorm2x16(frag.channel1);
return vec3(x, yz);
}
/**
* Depth
*/
void _depth_(inout ABufferFragment frag, float depth) {
frag.channel2 = floatBitsToUint(depth);
}
float _depth_(ABufferFragment frag) {
return uintBitsToFloat(frag.channel2);
}
/**
* Type
*/
void _type_(inout ABufferFragment frag, int type) {
uint val;
if (type < 0) {
val = uint(-type) + 128;
} else {
val = type;
}
bitinsert(frag.channel0, val, mask_type, shift_type);
}
int _type_(ABufferFragment frag) {
uint val = bitextract(frag.channel0, mask_type, shift_type);
if (val > 127) {
return 128 - int(val);
} else {
return int(val);
}
}
/**
* Msaa
*/
void _msaa_(inout ABufferFragment frag, int type) {
uint val = uint(type);
bitinsert(frag.channel0, val, mask_msaa, shift_msaa);
}
int _msaa_(ABufferFragment frag) {
uint val = bitextract(frag.channel0, mask_msaa, shift_msaa);
return int(val);
}
/**
* Next
*/
void _next_(inout ABufferFragment frag, uint val) {
bitinsert(frag.channel3, val, mask_next, shift_next);
}
uint _next_(ABufferFragment frag) {
uint val = bitextract(frag.channel3, mask_next, shift_next);
return val;
}
/**
* Blend
*/
void _blend_(inout ABufferFragment frag, uint val) {
bitinsert(frag.channel3, val, mask_blend, shift_blend);
}
uint _blend_(ABufferFragment frag) {
uint val = bitextract(frag.channel3, mask_blend, shift_blend);
return val;
}
/**
* Raw data
*/
void _raw_(inout ABufferFragment frag, uvec4 raw) {
frag.channel0 = raw.x;
frag.channel1 = raw.y;
frag.channel2 = raw.z;
frag.channel3 = raw.w;
}
uvec4 _raw_(inout ABufferFragment frag) {
return uvec4(frag.channel0, frag.channel1, frag.channel2, frag.channel3);
}
#endif