Style: Fix code formatting in GLES3 shaders

This commit is contained in:
Rémi Verschelde 2018-08-24 13:42:18 +02:00
parent f123694b4e
commit 1b6d75a599
17 changed files with 1552 additions and 1923 deletions

View file

@ -1,6 +1,5 @@
[vertex] [vertex]
/* /*
from VisualServer: from VisualServer:
@ -23,56 +22,56 @@ ARRAY_INDEX=8,
/* INPUT ATTRIBS */ /* INPUT ATTRIBS */
layout(location=0) in highp VFORMAT vertex_attrib; layout(location = 0) in highp VFORMAT vertex_attrib;
layout(location=1) in vec3 normal_attrib; layout(location = 1) in vec3 normal_attrib;
#ifdef ENABLE_TANGENT #ifdef ENABLE_TANGENT
layout(location=2) in vec4 tangent_attrib; layout(location = 2) in vec4 tangent_attrib;
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
layout(location=3) in vec4 color_attrib; layout(location = 3) in vec4 color_attrib;
#endif #endif
#ifdef ENABLE_UV #ifdef ENABLE_UV
layout(location=4) in vec2 uv_attrib; layout(location = 4) in vec2 uv_attrib;
#endif #endif
#ifdef ENABLE_UV2 #ifdef ENABLE_UV2
layout(location=5) in vec2 uv2_attrib; layout(location = 5) in vec2 uv2_attrib;
#endif #endif
#ifdef ENABLE_SKELETON #ifdef ENABLE_SKELETON
layout(location=6) in ivec4 bone_attrib; layout(location = 6) in ivec4 bone_attrib;
layout(location=7) in vec4 weight_attrib; layout(location = 7) in vec4 weight_attrib;
#endif #endif
/* BLEND ATTRIBS */ /* BLEND ATTRIBS */
#ifdef ENABLE_BLEND #ifdef ENABLE_BLEND
layout(location=8) in highp VFORMAT vertex_attrib_blend; layout(location = 8) in highp VFORMAT vertex_attrib_blend;
layout(location=9) in vec3 normal_attrib_blend; layout(location = 9) in vec3 normal_attrib_blend;
#ifdef ENABLE_TANGENT #ifdef ENABLE_TANGENT
layout(location=10) in vec4 tangent_attrib_blend; layout(location = 10) in vec4 tangent_attrib_blend;
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
layout(location=11) in vec4 color_attrib_blend; layout(location = 11) in vec4 color_attrib_blend;
#endif #endif
#ifdef ENABLE_UV #ifdef ENABLE_UV
layout(location=12) in vec2 uv_attrib_blend; layout(location = 12) in vec2 uv_attrib_blend;
#endif #endif
#ifdef ENABLE_UV2 #ifdef ENABLE_UV2
layout(location=13) in vec2 uv2_attrib_blend; layout(location = 13) in vec2 uv2_attrib_blend;
#endif #endif
#ifdef ENABLE_SKELETON #ifdef ENABLE_SKELETON
layout(location=14) in ivec4 bone_attrib_blend; layout(location = 14) in ivec4 bone_attrib_blend;
layout(location=15) in vec4 weight_attrib_blend; layout(location = 15) in vec4 weight_attrib_blend;
#endif #endif
#endif #endif
@ -110,7 +109,6 @@ uniform float blend_amount;
void main() { void main() {
#ifdef ENABLE_BLEND #ifdef ENABLE_BLEND
vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount; vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
@ -140,7 +138,6 @@ void main() {
uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount; uv2_out = uv2_attrib_blend + uv2_attrib * blend_amount;
#endif #endif
#ifdef ENABLE_SKELETON #ifdef ENABLE_SKELETON
bone_out = bone_attrib_blend; bone_out = bone_attrib_blend;
@ -149,7 +146,6 @@ void main() {
#else //ENABLE_BLEND #else //ENABLE_BLEND
vertex_out = vertex_attrib * blend_amount; vertex_out = vertex_attrib * blend_amount;
#ifdef ENABLE_NORMAL #ifdef ENABLE_NORMAL
@ -177,7 +173,6 @@ void main() {
uv2_out = uv2_attrib * blend_amount; uv2_out = uv2_attrib * blend_amount;
#endif #endif
#ifdef ENABLE_SKELETON #ifdef ENABLE_SKELETON
bone_out = bone_attrib; bone_out = bone_attrib;
@ -190,8 +185,6 @@ void main() {
[fragment] [fragment]
void main() { void main() {
} }

View file

@ -1,12 +1,11 @@
[vertex] [vertex]
layout(location = 0) in highp vec2 vertex;
layout(location=0) in highp vec2 vertex; layout(location = 3) in vec4 color_attrib;
layout(location=3) in vec4 color_attrib;
#ifdef USE_SKELETON #ifdef USE_SKELETON
layout(location=6) in uvec4 bone_indices; // attrib:6 layout(location = 6) in uvec4 bone_indices; // attrib:6
layout(location=7) in vec4 bone_weights; // attrib:7 layout(location = 7) in vec4 bone_weights; // attrib:7
#endif #endif
#ifdef USE_TEXTURE_RECT #ifdef USE_TEXTURE_RECT
@ -18,25 +17,24 @@ uniform vec4 src_rect;
#ifdef USE_INSTANCING #ifdef USE_INSTANCING
layout(location=8) in highp vec4 instance_xform0; layout(location = 8) in highp vec4 instance_xform0;
layout(location=9) in highp vec4 instance_xform1; layout(location = 9) in highp vec4 instance_xform1;
layout(location=10) in highp vec4 instance_xform2; layout(location = 10) in highp vec4 instance_xform2;
layout(location=11) in lowp vec4 instance_color; layout(location = 11) in lowp vec4 instance_color;
#ifdef USE_INSTANCE_CUSTOM #ifdef USE_INSTANCE_CUSTOM
layout(location=12) in highp vec4 instance_custom_data; layout(location = 12) in highp vec4 instance_custom_data;
#endif #endif
#endif #endif
layout(location=4) in highp vec2 uv_attrib; layout(location = 4) in highp vec2 uv_attrib;
//skeletn // skeleton
#endif #endif
uniform highp vec2 color_texpixel_size; uniform highp vec2 color_texpixel_size;
layout(std140) uniform CanvasItemData { //ubo:0 layout(std140) uniform CanvasItemData { //ubo:0
highp mat4 projection_matrix; highp mat4 projection_matrix;
@ -46,7 +44,6 @@ layout(std140) uniform CanvasItemData { //ubo:0
uniform highp mat4 modelview_matrix; uniform highp mat4 modelview_matrix;
uniform highp mat4 extra_matrix; uniform highp mat4 extra_matrix;
out highp vec2 uv_interp; out highp vec2 uv_interp;
out mediump vec4 color_interp; out mediump vec4 color_interp;
@ -55,7 +52,6 @@ out mediump vec4 color_interp;
out highp vec2 pixel_size_interp; out highp vec2 pixel_size_interp;
#endif #endif
#ifdef USE_SKELETON #ifdef USE_SKELETON
uniform mediump sampler2D skeleton_texture; // texunit:-1 uniform mediump sampler2D skeleton_texture; // texunit:-1
uniform highp mat4 skeleton_transform; uniform highp mat4 skeleton_transform;
@ -66,7 +62,7 @@ uniform highp mat4 skeleton_transform_inverse;
layout(std140) uniform LightData { //ubo:1 layout(std140) uniform LightData { //ubo:1
//light matrices // light matrices
highp mat4 light_matrix; highp mat4 light_matrix;
highp mat4 light_local_matrix; highp mat4 light_local_matrix;
highp mat4 shadow_matrix; highp mat4 shadow_matrix;
@ -80,11 +76,9 @@ layout(std140) uniform LightData { //ubo:1
highp float shadow_distance_mult; highp float shadow_distance_mult;
}; };
out vec4 light_uv_interp; out vec4 light_uv_interp;
out vec2 transformed_light_uv; out vec2 transformed_light_uv;
out vec4 local_rot; out vec4 local_rot;
#ifdef USE_SHADOWS #ifdef USE_SHADOWS
@ -101,7 +95,6 @@ uniform int h_frames;
uniform int v_frames; uniform int v_frames;
#endif #endif
#if defined(USE_MATERIAL) #if defined(USE_MATERIAL)
layout(std140) uniform UniformData { //ubo:2 layout(std140) uniform UniformData { //ubo:2
@ -112,7 +105,6 @@ MATERIAL_UNIFORMS
#endif #endif
VERTEX_SHADER_GLOBALS VERTEX_SHADER_GLOBALS
void main() { void main() {
@ -120,8 +112,8 @@ void main() {
vec4 color = color_attrib; vec4 color = color_attrib;
#ifdef USE_INSTANCING #ifdef USE_INSTANCING
mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0))); mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
color*=instance_color; color *= instance_color;
vec4 instance_custom = instance_custom_data; vec4 instance_custom = instance_custom_data;
#else #else
@ -136,29 +128,27 @@ void main() {
} else { } else {
uv_interp = src_rect.xy + abs(src_rect.zw) * vertex; uv_interp = src_rect.xy + abs(src_rect.zw) * vertex;
} }
highp vec4 outvec = vec4(dst_rect.xy + abs(dst_rect.zw) * mix(vertex,vec2(1.0,1.0)-vertex,lessThan(src_rect.zw,vec2(0.0,0.0))),0.0,1.0); highp vec4 outvec = vec4(dst_rect.xy + abs(dst_rect.zw) * mix(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0))), 0.0, 1.0);
#else #else
uv_interp = uv_attrib; uv_interp = uv_attrib;
highp vec4 outvec = vec4(vertex,0.0,1.0); highp vec4 outvec = vec4(vertex, 0.0, 1.0);
#endif #endif
#ifdef USE_PARTICLES #ifdef USE_PARTICLES
//scale by texture size //scale by texture size
outvec.xy/=color_texpixel_size; outvec.xy /= color_texpixel_size;
//compute h and v frames and adjust UV interp for animation //compute h and v frames and adjust UV interp for animation
int total_frames = h_frames * v_frames; int total_frames = h_frames * v_frames;
int frame = min(int(float(total_frames) *instance_custom.z),total_frames-1); int frame = min(int(float(total_frames) * instance_custom.z), total_frames - 1);
float frame_w = 1.0/float(h_frames); float frame_w = 1.0 / float(h_frames);
float frame_h = 1.0/float(v_frames); float frame_h = 1.0 / float(v_frames);
uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames); uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames);
uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames); uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames);
#endif #endif
#define extra_matrix extra_matrix2 #define extra_matrix extra_matrix2
{ {
@ -167,10 +157,9 @@ VERTEX_SHADER_CODE
} }
#ifdef USE_NINEPATCH #ifdef USE_NINEPATCH
pixel_size_interp=abs(dst_rect.zw) * vertex; pixel_size_interp = abs(dst_rect.zw) * vertex;
#endif #endif
#if !defined(SKIP_TRANSFORM_USED) #if !defined(SKIP_TRANSFORM_USED)
@ -184,47 +173,46 @@ VERTEX_SHADER_CODE
#ifdef USE_PIXEL_SNAP #ifdef USE_PIXEL_SNAP
outvec.xy=floor(outvec+0.5).xy; outvec.xy = floor(outvec + 0.5).xy;
#endif #endif
#ifdef USE_SKELETON #ifdef USE_SKELETON
if (bone_weights!=vec4(0.0)){ //must be a valid bone if (bone_weights != vec4(0.0)) { //must be a valid bone
//skeleton transform //skeleton transform
ivec4 bone_indicesi = ivec4(bone_indices); ivec4 bone_indicesi = ivec4(bone_indices);
ivec2 tex_ofs = ivec2( bone_indicesi.x%256, (bone_indicesi.x/256)*2 ); ivec2 tex_ofs = ivec2(bone_indicesi.x % 256, (bone_indicesi.x / 256) * 2);
highp mat2x4 m = mat2x4( highp mat2x4 m;
texelFetch(skeleton_texture,tex_ofs,0), m = mat2x4(
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) texelFetch(skeleton_texture, tex_ofs, 0),
) * bone_weights.x; texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0))
* bone_weights.x;
tex_ofs = ivec2( bone_indicesi.y%256, (bone_indicesi.y/256)*2 ); tex_ofs = ivec2(bone_indicesi.y % 256, (bone_indicesi.y / 256) * 2);
m+= mat2x4( m += mat2x4(
texelFetch(skeleton_texture,tex_ofs,0), texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0))
) * bone_weights.y; * bone_weights.y;
tex_ofs = ivec2( bone_indicesi.z%256, (bone_indicesi.z/256)*2 ); tex_ofs = ivec2(bone_indicesi.z % 256, (bone_indicesi.z / 256) * 2);
m+= mat2x4( m += mat2x4(
texelFetch(skeleton_texture,tex_ofs,0), texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0) texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0))
) * bone_weights.z; * bone_weights.z;
tex_ofs = ivec2(bone_indicesi.w % 256, (bone_indicesi.w / 256) * 2);
tex_ofs = ivec2( bone_indicesi.w%256, (bone_indicesi.w/256)*2 ); m += mat2x4(
texelFetch(skeleton_texture, tex_ofs, 0),
texelFetch(skeleton_texture, tex_ofs + ivec2(0, 1), 0))
* bone_weights.w;
m+= mat2x4( mat4 bone_matrix = skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_transform_inverse;
texelFetch(skeleton_texture,tex_ofs,0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0)
) * bone_weights.w;
mat4 bone_matrix = skeleton_transform * transpose(mat4(m[0],m[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))) * skeleton_transform_inverse;
outvec = bone_matrix * outvec; outvec = bone_matrix * outvec;
} }
@ -236,45 +224,37 @@ VERTEX_SHADER_CODE
#ifdef USE_LIGHTING #ifdef USE_LIGHTING
light_uv_interp.xy = (light_matrix * outvec).xy; light_uv_interp.xy = (light_matrix * outvec).xy;
light_uv_interp.zw =(light_local_matrix * outvec).xy; light_uv_interp.zw = (light_local_matrix * outvec).xy;
mat3 inverse_light_matrix = mat3(inverse(light_matrix)); mat3 inverse_light_matrix = mat3(inverse(light_matrix));
inverse_light_matrix[0] = normalize(inverse_light_matrix[0]); inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
inverse_light_matrix[1] = normalize(inverse_light_matrix[1]); inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
inverse_light_matrix[2] = normalize(inverse_light_matrix[2]); inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
transformed_light_uv = (inverse_light_matrix * vec3(light_uv_interp.zw,0.0)).xy; //for normal mapping transformed_light_uv = (inverse_light_matrix * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping
#ifdef USE_SHADOWS #ifdef USE_SHADOWS
pos=outvec.xy; pos = outvec.xy;
#endif #endif
local_rot.xy = normalize((modelview_matrix * (extra_matrix * vec4(1.0, 0.0, 0.0, 0.0))).xy);
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy ); local_rot.zw = normalize((modelview_matrix * (extra_matrix * vec4(0.0, 1.0, 0.0, 0.0))).xy);
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy );
#ifdef USE_TEXTURE_RECT #ifdef USE_TEXTURE_RECT
local_rot.xy*=sign(src_rect.z); local_rot.xy *= sign(src_rect.z);
local_rot.zw*=sign(src_rect.w); local_rot.zw *= sign(src_rect.w);
#endif #endif
#endif #endif
} }
[fragment] [fragment]
uniform mediump sampler2D color_texture; // texunit:0 uniform mediump sampler2D color_texture; // texunit:0
uniform highp vec2 color_texpixel_size; uniform highp vec2 color_texpixel_size;
uniform mediump sampler2D normal_texture; // texunit:1 uniform mediump sampler2D normal_texture; // texunit:1
in highp vec2 uv_interp; in highp vec2 uv_interp;
in mediump vec4 color_interp; in mediump vec4 color_interp;
#if defined(SCREEN_TEXTURE_USED) #if defined(SCREEN_TEXTURE_USED)
uniform sampler2D screen_texture; // texunit:-3 uniform sampler2D screen_texture; // texunit:-3
@ -292,7 +272,6 @@ layout(std140) uniform CanvasItemData {
highp float time; highp float time;
}; };
#ifdef USE_LIGHTING #ifdef USE_LIGHTING
layout(std140) uniform LightData { layout(std140) uniform LightData {
@ -314,10 +293,8 @@ uniform lowp sampler2D light_texture; // texunit:-1
in vec4 light_uv_interp; in vec4 light_uv_interp;
in vec2 transformed_light_uv; in vec2 transformed_light_uv;
in vec4 local_rot; in vec4 local_rot;
#ifdef USE_SHADOWS #ifdef USE_SHADOWS
uniform highp sampler2D shadow_texture; // texunit:-2 uniform highp sampler2D shadow_texture; // texunit:-2
@ -332,11 +309,7 @@ const bool at_light_pass = false;
uniform mediump vec4 final_modulate; uniform mediump vec4 final_modulate;
layout(location = 0) out mediump vec4 frag_color;
layout(location=0) out mediump vec4 frag_color;
#if defined(USE_MATERIAL) #if defined(USE_MATERIAL)
@ -351,25 +324,24 @@ MATERIAL_UNIFORMS
FRAGMENT_SHADER_GLOBALS FRAGMENT_SHADER_GLOBALS
void light_compute( void light_compute(
inout vec4 light, inout vec4 light,
inout vec2 light_vec, inout vec2 light_vec,
inout float light_height, inout float light_height,
inout vec4 light_color, inout vec4 light_color,
vec2 light_uv, vec2 light_uv,
inout vec4 shadow_color, inout vec4 shadow_color,
vec3 normal, vec3 normal,
vec2 uv, vec2 uv,
#if defined(SCREEN_UV_USED) #if defined(SCREEN_UV_USED)
vec2 screen_uv, vec2 screen_uv,
#endif #endif
vec4 color) { vec4 color) {
#if defined(USE_LIGHT_SHADER_CODE) #if defined(USE_LIGHT_SHADER_CODE)
LIGHT_SHADER_CODE LIGHT_SHADER_CODE
#endif #endif
} }
#ifdef USE_TEXTURE_RECT #ifdef USE_TEXTURE_RECT
@ -385,48 +357,44 @@ in highp vec2 pixel_size_interp;
uniform int np_repeat_v; uniform int np_repeat_v;
uniform int np_repeat_h; uniform int np_repeat_h;
uniform bool np_draw_center; uniform bool np_draw_center;
//left top right bottom in pixel coordinates // left top right bottom in pixel coordinates
uniform vec4 np_margins; uniform vec4 np_margins;
float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) {
float tex_size = 1.0 / tex_pixel_size;
float map_ninepatch_axis(float pixel, float draw_size,float tex_pixel_size,float margin_begin,float margin_end,int np_repeat,inout int draw_center) {
float tex_size = 1.0/tex_pixel_size;
if (pixel < margin_begin) { if (pixel < margin_begin) {
return pixel * tex_pixel_size; return pixel * tex_pixel_size;
} else if (pixel >= draw_size-margin_end) { } else if (pixel >= draw_size - margin_end) {
return (tex_size-(draw_size-pixel)) * tex_pixel_size; return (tex_size - (draw_size - pixel)) * tex_pixel_size;
} else { } else {
if (!np_draw_center){ if (!np_draw_center) {
draw_center--; draw_center--;
} }
if (np_repeat==0) { //stretch if (np_repeat == 0) { //stretch
//convert to ratio //convert to ratio
float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end); float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end);
//scale to source texture //scale to source texture
return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size; return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size;
} else if (np_repeat==1) { //tile } else if (np_repeat == 1) { //tile
//convert to ratio //convert to ratio
float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end); float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end);
//scale to source texture //scale to source texture
return (margin_begin + ofs) * tex_pixel_size; return (margin_begin + ofs) * tex_pixel_size;
} else if (np_repeat==2) { //tile fit } else if (np_repeat == 2) { //tile fit
//convert to ratio //convert to ratio
float src_area = draw_size - margin_begin - margin_end; float src_area = draw_size - margin_begin - margin_end;
float dst_area = tex_size - margin_begin - margin_end; float dst_area = tex_size - margin_begin - margin_end;
float scale = max(1.0,floor(src_area / max(dst_area,0.0000001) + 0.5)); float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5));
//convert to ratio //convert to ratio
float ratio = (pixel - margin_begin) / src_area; float ratio = (pixel - margin_begin) / src_area;
ratio = mod(ratio * scale,1.0); ratio = mod(ratio * scale, 1.0);
return (margin_begin + ratio * dst_area) * tex_pixel_size; return (margin_begin + ratio * dst_area) * tex_pixel_size;
} }
} }
} }
#endif #endif
@ -443,42 +411,39 @@ void main() {
#ifdef USE_NINEPATCH #ifdef USE_NINEPATCH
int draw_center=2; int draw_center = 2;
uv = vec2( uv = vec2(
map_ninepatch_axis(pixel_size_interp.x,abs(dst_rect.z),color_texpixel_size.x,np_margins.x,np_margins.z,np_repeat_h,draw_center), map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, np_repeat_h, draw_center),
map_ninepatch_axis(pixel_size_interp.y,abs(dst_rect.w),color_texpixel_size.y,np_margins.y,np_margins.w,np_repeat_v,draw_center) map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, np_repeat_v, draw_center));
);
if (draw_center==0) { if (draw_center == 0) {
color.a=0.0; color.a = 0.0;
} }
uv = uv*src_rect.zw+src_rect.xy; //apply region if needed uv = uv * src_rect.zw + src_rect.xy; //apply region if needed
#endif #endif
if (clip_rect_uv) { if (clip_rect_uv) {
uv = clamp(uv,src_rect.xy,src_rect.xy+abs(src_rect.zw)); uv = clamp(uv, src_rect.xy, src_rect.xy + abs(src_rect.zw));
} }
#endif #endif
#if !defined(COLOR_USED) #if !defined(COLOR_USED)
//default behavior, texture by color //default behavior, texture by color
#ifdef USE_DISTANCE_FIELD #ifdef USE_DISTANCE_FIELD
const float smoothing = 1.0/32.0; const float smoothing = 1.0 / 32.0;
float distance = textureLod(color_texture, uv,0.0).a; float distance = textureLod(color_texture, uv, 0.0).a;
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a; color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a;
#else #else
color *= texture( color_texture, uv ); color *= texture(color_texture, uv);
#endif #endif
#endif #endif
vec3 normal; vec3 normal;
#if defined(NORMAL_USED) #if defined(NORMAL_USED)
@ -489,59 +454,52 @@ void main() {
#endif #endif
if (use_default_normal) { if (use_default_normal) {
normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0; normal.xy = textureLod(normal_texture, uv, 0.0).xy * 2.0 - 1.0;
normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used=true; normal_used = true;
} else { } else {
normal = vec3(0.0,0.0,1.0); normal = vec3(0.0, 0.0, 1.0);
} }
#if defined(SCREEN_UV_USED) #if defined(SCREEN_UV_USED)
vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size; vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
#endif #endif
{
{ float normal_depth = 1.0;
float normal_depth=1.0;
#if defined(NORMALMAP_USED) #if defined(NORMALMAP_USED)
vec3 normal_map=vec3(0.0,0.0,1.0); vec3 normal_map = vec3(0.0, 0.0, 1.0);
#endif #endif
FRAGMENT_SHADER_CODE FRAGMENT_SHADER_CODE
#if defined(NORMALMAP_USED) #if defined(NORMALMAP_USED)
normal = mix(vec3(0.0,0.0,1.0), normal_map * vec3(2.0,-2.0,1.0) - vec3( 1.0, -1.0, 0.0 ), normal_depth ); normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
#endif #endif
}
}
#ifdef DEBUG_ENCODED_32 #ifdef DEBUG_ENCODED_32
highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ); highp float enc32 = dot(color, highp vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1));
color = vec4(vec3(enc32),1.0); color = vec4(vec3(enc32), 1.0);
#endif #endif
color *= final_modulate;
color*=final_modulate;
#ifdef USE_LIGHTING #ifdef USE_LIGHTING
vec2 light_vec = transformed_light_uv; vec2 light_vec = transformed_light_uv;
if (normal_used) { if (normal_used) {
normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
} }
float att=1.0; float att = 1.0;
vec2 light_uv = light_uv_interp.xy; vec2 light_uv = light_uv_interp.xy;
vec4 light = texture(light_texture,light_uv); vec4 light = texture(light_texture, light_uv);
if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) { if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) {
color.a*=light_outside_alpha; //invisible color.a *= light_outside_alpha; //invisible
} else { } else {
float real_light_height = light_height; float real_light_height = light_height;
@ -549,178 +507,176 @@ FRAGMENT_SHADER_CODE
vec4 real_light_shadow_color = light_shadow_color; vec4 real_light_shadow_color = light_shadow_color;
#if defined(USE_LIGHT_SHADER_CODE) #if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader //light is written by the light shader
light_compute( light_compute(
light, light,
light_vec, light_vec,
real_light_height, real_light_height,
real_light_color, real_light_color,
light_uv, light_uv,
real_light_shadow_color, real_light_shadow_color,
normal, normal,
uv, uv,
#if defined(SCREEN_UV_USED) #if defined(SCREEN_UV_USED)
screen_uv, screen_uv,
#endif #endif
color); color);
#endif #endif
light *= real_light_color; light *= real_light_color;
if (normal_used) { if (normal_used) {
vec3 light_normal = normalize(vec3(light_vec,-real_light_height)); vec3 light_normal = normalize(vec3(light_vec, -real_light_height));
light*=max(dot(-light_normal,normal),0.0); light *= max(dot(-light_normal, normal), 0.0);
} }
color*=light; color *= light;
#ifdef USE_SHADOWS #ifdef USE_SHADOWS
light_vec = light_uv_interp.zw; //for shadows light_vec = light_uv_interp.zw; //for shadows
float angle_to_light = -atan(light_vec.x,light_vec.y); float angle_to_light = -atan(light_vec.x, light_vec.y);
float PI = 3.14159265358979323846264; float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/ float ang*/
float su,sz; float su, sz;
float abs_angle = abs(angle_to_light); float abs_angle = abs(angle_to_light);
vec2 point; vec2 point;
float sh; float sh;
if (abs_angle<45.0*PI/180.0) { if (abs_angle < 45.0 * PI / 180.0) {
point = light_vec; point = light_vec;
sh=0.0+(1.0/8.0); sh = 0.0 + (1.0 / 8.0);
} else if (abs_angle>135.0*PI/180.0) { } else if (abs_angle > 135.0 * PI / 180.0) {
point = -light_vec; point = -light_vec;
sh = 0.5+(1.0/8.0); sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light>0.0) { } else if (angle_to_light > 0.0) {
point = vec2(light_vec.y,-light_vec.x); point = vec2(light_vec.y, -light_vec.x);
sh = 0.25+(1.0/8.0); sh = 0.25 + (1.0 / 8.0);
} else { } else {
point = vec2(-light_vec.y,light_vec.x); point = vec2(-light_vec.y, light_vec.x);
sh = 0.75+(1.0/8.0); sh = 0.75 + (1.0 / 8.0);
} }
highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0);
highp vec4 s = shadow_matrix * vec4(point,0.0,1.0); s.xyz /= s.w;
s.xyz/=s.w; su = s.x * 0.5 + 0.5;
su=s.x*0.5+0.5; sz = s.z * 0.5 + 0.5;
sz=s.z*0.5+0.5;
//sz=lightlength(light_vec); //sz=lightlength(light_vec);
highp float shadow_attenuation=0.0; highp float shadow_attenuation = 0.0;
#ifdef USE_RGBA_SHADOWS #ifdef USE_RGBA_SHADOWS
#define SHADOW_DEPTH(m_tex,m_uv) dot(texture((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) ) #define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1))
#else #else
#define SHADOW_DEPTH(m_tex,m_uv) (texture((m_tex),(m_uv)).r) #define SHADOW_DEPTH(m_tex, m_uv) (texture((m_tex), (m_uv)).r)
#endif #endif
#ifdef SHADOW_USE_GRADIENT #ifdef SHADOW_USE_GRADIENT
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=1.0-smoothstep(sd,sd+shadow_gradient,sz); } #define SHADOW_TEST(m_ofs) \
{ \
highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \
shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); \
}
#else #else
#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture,vec2(m_ofs,sh)); shadow_attenuation+=step(sz,sd); } #define SHADOW_TEST(m_ofs) \
{ \
highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \
shadow_attenuation += step(sz, sd); \
}
#endif #endif
#ifdef SHADOW_FILTER_NEAREST #ifdef SHADOW_FILTER_NEAREST
SHADOW_TEST(su); SHADOW_TEST(su);
#endif #endif
#ifdef SHADOW_FILTER_PCF3 #ifdef SHADOW_FILTER_PCF3
SHADOW_TEST(su+shadowpixel_size); SHADOW_TEST(su + shadowpixel_size);
SHADOW_TEST(su); SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size); SHADOW_TEST(su - shadowpixel_size);
shadow_attenuation/=3.0; shadow_attenuation /= 3.0;
#endif #endif
#ifdef SHADOW_FILTER_PCF5 #ifdef SHADOW_FILTER_PCF5
SHADOW_TEST(su+shadowpixel_size*2.0); SHADOW_TEST(su + shadowpixel_size * 2.0);
SHADOW_TEST(su+shadowpixel_size); SHADOW_TEST(su + shadowpixel_size);
SHADOW_TEST(su); SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size); SHADOW_TEST(su - shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0); SHADOW_TEST(su - shadowpixel_size * 2.0);
shadow_attenuation/=5.0; shadow_attenuation /= 5.0;
#endif #endif
#ifdef SHADOW_FILTER_PCF7 #ifdef SHADOW_FILTER_PCF7
SHADOW_TEST(su+shadowpixel_size*3.0); SHADOW_TEST(su + shadowpixel_size * 3.0);
SHADOW_TEST(su+shadowpixel_size*2.0); SHADOW_TEST(su + shadowpixel_size * 2.0);
SHADOW_TEST(su+shadowpixel_size); SHADOW_TEST(su + shadowpixel_size);
SHADOW_TEST(su); SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size); SHADOW_TEST(su - shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0); SHADOW_TEST(su - shadowpixel_size * 2.0);
SHADOW_TEST(su-shadowpixel_size*3.0); SHADOW_TEST(su - shadowpixel_size * 3.0);
shadow_attenuation/=7.0; shadow_attenuation /= 7.0;
#endif #endif
#ifdef SHADOW_FILTER_PCF9 #ifdef SHADOW_FILTER_PCF9
SHADOW_TEST(su+shadowpixel_size*4.0); SHADOW_TEST(su + shadowpixel_size * 4.0);
SHADOW_TEST(su+shadowpixel_size*3.0); SHADOW_TEST(su + shadowpixel_size * 3.0);
SHADOW_TEST(su+shadowpixel_size*2.0); SHADOW_TEST(su + shadowpixel_size * 2.0);
SHADOW_TEST(su+shadowpixel_size); SHADOW_TEST(su + shadowpixel_size);
SHADOW_TEST(su); SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size); SHADOW_TEST(su - shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0); SHADOW_TEST(su - shadowpixel_size * 2.0);
SHADOW_TEST(su-shadowpixel_size*3.0); SHADOW_TEST(su - shadowpixel_size * 3.0);
SHADOW_TEST(su-shadowpixel_size*4.0); SHADOW_TEST(su - shadowpixel_size * 4.0);
shadow_attenuation/=9.0; shadow_attenuation /= 9.0;
#endif #endif
#ifdef SHADOW_FILTER_PCF13 #ifdef SHADOW_FILTER_PCF13
SHADOW_TEST(su+shadowpixel_size*6.0); SHADOW_TEST(su + shadowpixel_size * 6.0);
SHADOW_TEST(su+shadowpixel_size*5.0); SHADOW_TEST(su + shadowpixel_size * 5.0);
SHADOW_TEST(su+shadowpixel_size*4.0); SHADOW_TEST(su + shadowpixel_size * 4.0);
SHADOW_TEST(su+shadowpixel_size*3.0); SHADOW_TEST(su + shadowpixel_size * 3.0);
SHADOW_TEST(su+shadowpixel_size*2.0); SHADOW_TEST(su + shadowpixel_size * 2.0);
SHADOW_TEST(su+shadowpixel_size); SHADOW_TEST(su + shadowpixel_size);
SHADOW_TEST(su); SHADOW_TEST(su);
SHADOW_TEST(su-shadowpixel_size); SHADOW_TEST(su - shadowpixel_size);
SHADOW_TEST(su-shadowpixel_size*2.0); SHADOW_TEST(su - shadowpixel_size * 2.0);
SHADOW_TEST(su-shadowpixel_size*3.0); SHADOW_TEST(su - shadowpixel_size * 3.0);
SHADOW_TEST(su-shadowpixel_size*4.0); SHADOW_TEST(su - shadowpixel_size * 4.0);
SHADOW_TEST(su-shadowpixel_size*5.0); SHADOW_TEST(su - shadowpixel_size * 5.0);
SHADOW_TEST(su-shadowpixel_size*6.0); SHADOW_TEST(su - shadowpixel_size * 6.0);
shadow_attenuation/=13.0; shadow_attenuation /= 13.0;
#endif #endif
//color*=shadow_attenuation; //color *= shadow_attenuation;
color=mix(real_light_shadow_color,color,shadow_attenuation); color = mix(real_light_shadow_color, color, shadow_attenuation);
//use shadows //use shadows
#endif #endif
} }
//use lighting //use lighting
#endif #endif
//color.rgb*=color.a; //color.rgb *= color.a;
frag_color = color; frag_color = color;
} }

View file

@ -1,20 +1,18 @@
[vertex] [vertex]
uniform highp mat4 projection_matrix; uniform highp mat4 projection_matrix;
uniform highp mat4 light_matrix; uniform highp mat4 light_matrix;
uniform highp mat4 world_matrix; uniform highp mat4 world_matrix;
uniform highp float distance_norm; uniform highp float distance_norm;
layout(location=0) in highp vec3 vertex; layout(location = 0) in highp vec3 vertex;
out highp vec4 position_interp; out highp vec4 position_interp;
void main() { void main() {
gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex,1.0))); gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex, 1.0)));
position_interp=gl_Position; position_interp = gl_Position;
} }
[fragment] [fragment]
@ -22,28 +20,22 @@ void main() {
in highp vec4 position_interp; in highp vec4 position_interp;
#ifdef USE_RGBA_SHADOWS #ifdef USE_RGBA_SHADOWS
layout(location = 0) out lowp vec4 distance_buf;
layout(location=0) out lowp vec4 distance_buf;
#else #else
layout(location = 0) out highp float distance_buf;
layout(location=0) out highp float distance_buf;
#endif #endif
void main() { void main() {
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0;//bias; highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
#ifdef USE_RGBA_SHADOWS #ifdef USE_RGBA_SHADOWS
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
distance_buf=comp; distance_buf = comp;
#else #else
distance_buf=depth; distance_buf = depth;
#endif #endif
} }

View file

@ -1,13 +1,12 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib;
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA) #if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
layout(location=4) in vec3 cube_in; layout(location = 4) in vec3 cube_in;
#else #else
layout(location=4) in vec2 uv_in; layout(location = 4) in vec2 uv_in;
#endif #endif
layout(location=5) in vec2 uv2_in; layout(location = 5) in vec2 uv2_in;
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA) #if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
out vec3 cube_interp; out vec3 cube_interp;
@ -32,7 +31,7 @@ void main() {
#else #else
uv_interp = uv_in; uv_interp = uv_in;
#ifdef V_FLIP #ifdef V_FLIP
uv_interp.y = 1.0-uv_interp.y; uv_interp.y = 1.0 - uv_interp.y;
#endif #endif
#endif #endif
@ -44,7 +43,6 @@ void main() {
uv_interp = copy_section.xy + uv_interp * copy_section.zw; uv_interp = copy_section.xy + uv_interp * copy_section.zw;
gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0; gl_Position.xy = (copy_section.xy + (gl_Position.xy * 0.5 + 0.5) * copy_section.zw) * 2.0 - 1.0;
#endif #endif
} }
[fragment] [fragment]
@ -72,38 +70,33 @@ uniform samplerCube source_cube; //texunit:0
uniform sampler2D source; //texunit:0 uniform sampler2D source; //texunit:0
#endif #endif
#ifdef USE_MULTIPLIER #ifdef USE_MULTIPLIER
uniform float multiplier; uniform float multiplier;
#endif #endif
#if defined(USE_PANORAMA) || defined(USE_ASYM_PANO) #if defined(USE_PANORAMA) || defined(USE_ASYM_PANO)
vec4 texturePanorama(vec3 normal,sampler2D pano ) { vec4 texturePanorama(vec3 normal, sampler2D pano) {
vec2 st = vec2( vec2 st = vec2(
atan(normal.x, normal.z), atan(normal.x, normal.z),
acos(normal.y) acos(normal.y));
);
if(st.x < 0.0) if (st.x < 0.0)
st.x += M_PI*2.0; st.x += M_PI * 2.0;
st/=vec2(M_PI*2.0,M_PI); st /= vec2(M_PI * 2.0, M_PI);
return textureLod(pano,st,0.0);
return textureLod(pano, st, 0.0);
} }
#endif #endif
uniform float stuff; uniform float stuff;
uniform vec2 pixel_size; uniform vec2 pixel_size;
in vec2 uv2_interp; in vec2 uv2_interp;
#ifdef USE_BCS #ifdef USE_BCS
uniform vec3 bcs; uniform vec3 bcs;
@ -118,16 +111,13 @@ uniform sampler2D color_correction; //texunit:1
layout(location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
void main() { void main() {
//vec4 color = color_interp; //vec4 color = color_interp;
#ifdef USE_PANORAMA #ifdef USE_PANORAMA
vec4 color = texturePanorama( normalize(cube_interp), source ); vec4 color = texturePanorama(normalize(cube_interp), source);
#elif defined(USE_ASYM_PANO) #elif defined(USE_ASYM_PANO)
@ -142,72 +132,68 @@ void main() {
cube_normal = mat3(pano_transform) * cube_normal; cube_normal = mat3(pano_transform) * cube_normal;
cube_normal.z = -cube_normal.z; cube_normal.z = -cube_normal.z;
vec4 color = texturePanorama( normalize(cube_normal.xyz), source ); vec4 color = texturePanorama(normalize(cube_normal.xyz), source);
#elif defined(USE_CUBEMAP) #elif defined(USE_CUBEMAP)
vec4 color = texture( source_cube, normalize(cube_interp) ); vec4 color = texture(source_cube, normalize(cube_interp));
#else #else
vec4 color = textureLod( source, uv_interp,0.0 ); vec4 color = textureLod(source, uv_interp, 0.0);
#endif #endif
#ifdef LINEAR_TO_SRGB #ifdef LINEAR_TO_SRGB
//regular Linear -> SRGB conversion //regular Linear -> SRGB conversion
vec3 a = vec3(0.055); vec3 a = vec3(0.055);
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); color.rgb = mix((vec3(1.0) + a) * pow(color.rgb, vec3(1.0 / 2.4)) - a, 12.92 * color.rgb, lessThan(color.rgb, vec3(0.0031308)));
#endif #endif
#ifdef SRGB_TO_LINEAR #ifdef SRGB_TO_LINEAR
color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),color.rgb * (1.0 / 12.92),lessThan(color.rgb,vec3(0.04045))); color.rgb = mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045)));
#endif #endif
#ifdef DEBUG_GRADIENT #ifdef DEBUG_GRADIENT
color.rg=uv_interp; color.rg = uv_interp;
color.b=0.0; color.b = 0.0;
#endif #endif
#ifdef DISABLE_ALPHA #ifdef DISABLE_ALPHA
color.a=1.0; color.a = 1.0;
#endif #endif
#ifdef GAUSSIAN_HORIZONTAL #ifdef GAUSSIAN_HORIZONTAL
color*=0.38774; color *= 0.38774;
color+=texture( source, uv_interp+vec2( 1.0, 0.0)*pixel_size )*0.24477; color += texture(source, uv_interp + vec2(1.0, 0.0) * pixel_size) * 0.24477;
color+=texture( source, uv_interp+vec2( 2.0, 0.0)*pixel_size )*0.06136; color += texture(source, uv_interp + vec2(2.0, 0.0) * pixel_size) * 0.06136;
color+=texture( source, uv_interp+vec2(-1.0, 0.0)*pixel_size )*0.24477; color += texture(source, uv_interp + vec2(-1.0, 0.0) * pixel_size) * 0.24477;
color+=texture( source, uv_interp+vec2(-2.0, 0.0)*pixel_size )*0.06136; color += texture(source, uv_interp + vec2(-2.0, 0.0) * pixel_size) * 0.06136;
#endif #endif
#ifdef GAUSSIAN_VERTICAL #ifdef GAUSSIAN_VERTICAL
color*=0.38774; color *= 0.38774;
color+=texture( source, uv_interp+vec2( 0.0, 1.0)*pixel_size )*0.24477; color += texture(source, uv_interp + vec2(0.0, 1.0) * pixel_size) * 0.24477;
color+=texture( source, uv_interp+vec2( 0.0, 2.0)*pixel_size )*0.06136; color += texture(source, uv_interp + vec2(0.0, 2.0) * pixel_size) * 0.06136;
color+=texture( source, uv_interp+vec2( 0.0,-1.0)*pixel_size )*0.24477; color += texture(source, uv_interp + vec2(0.0, -1.0) * pixel_size) * 0.24477;
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136; color += texture(source, uv_interp + vec2(0.0, -2.0) * pixel_size) * 0.06136;
#endif #endif
#ifdef USE_BCS #ifdef USE_BCS
color.rgb = mix(vec3(0.0),color.rgb,bcs.x); color.rgb = mix(vec3(0.0), color.rgb, bcs.x);
color.rgb = mix(vec3(0.5),color.rgb,bcs.y); color.rgb = mix(vec3(0.5), color.rgb, bcs.y);
color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z); color.rgb = mix(vec3(dot(vec3(1.0), color.rgb) * 0.33333), color.rgb, bcs.z);
#endif #endif
#ifdef USE_COLOR_CORRECTION #ifdef USE_COLOR_CORRECTION
color.r = texture(color_correction,vec2(color.r,0.0)).r; color.r = texture(color_correction, vec2(color.r, 0.0)).r;
color.g = texture(color_correction,vec2(color.g,0.0)).g; color.g = texture(color_correction, vec2(color.g, 0.0)).g;
color.b = texture(color_correction,vec2(color.b,0.0)).b; color.b = texture(color_correction, vec2(color.b, 0.0)).b;
#endif #endif
#ifdef USE_MULTIPLIER #ifdef USE_MULTIPLIER
color.rgb*=multiplier; color.rgb *= multiplier;
#endif #endif
frag_color = color; frag_color = color;
} }

View file

@ -1,8 +1,7 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib; layout(location = 4) in vec2 uv_in;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
@ -14,7 +13,6 @@ void main() {
[fragment] [fragment]
uniform highp samplerCube source_cube; //texunit:0 uniform highp samplerCube source_cube; //texunit:0
in vec2 uv_interp; in vec2 uv_interp;
@ -25,55 +23,53 @@ uniform highp float bias;
void main() { void main() {
highp vec3 normal = vec3( uv_interp * 2.0 - 1.0, 0.0 ); highp vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
/* /*
if(z_flip) { if (z_flip) {
normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
} else { } else {
normal.z = -0.5 + 0.5*((normal.x * normal.x) + (normal.y * normal.y)); normal.z = -0.5 + 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
} }
*/ */
//normal.z = sqrt(1.0-dot(normal.xy,normal.xy)); //normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
//normal.xy*=1.0+normal.z; //normal.xy *= 1.0 + normal.z;
normal.z = 0.5 - 0.5*((normal.x * normal.x) + (normal.y * normal.y)); normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
normal = normalize(normal); normal = normalize(normal);
/*
normal.z = 0.5;
normal = normalize(normal);
*/
/*
normal.z=0.5;
normal=normalize(normal);
*/
if (!z_flip) { if (!z_flip) {
normal.z=-normal.z; normal.z = -normal.z;
} }
//normal = normalize(vec3( uv_interp * 2.0 - 1.0, 1.0 )); //normal = normalize(vec3(uv_interp * 2.0 - 1.0, 1.0));
float depth = texture(source_cube,normal).r; float depth = texture(source_cube, normal).r;
// absolute values for direction cosines, bigger value equals closer to basis axis // absolute values for direction cosines, bigger value equals closer to basis axis
vec3 unorm = abs(normal); vec3 unorm = abs(normal);
if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) { if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
// x code // x code
unorm = normal.x > 0.0 ? vec3( 1.0, 0.0, 0.0 ) : vec3( -1.0, 0.0, 0.0 ) ; unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
} else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) { } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
// y code // y code
unorm = normal.y > 0.0 ? vec3( 0.0, 1.0, 0.0 ) : vec3( 0.0, -1.0, 0.0 ) ; unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
} else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) { } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
// z code // z code
unorm = normal.z > 0.0 ? vec3( 0.0, 0.0, 1.0 ) : vec3( 0.0, 0.0, -1.0 ) ; unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
} else { } else {
// oh-no we messed up code // oh-no we messed up code
// has to be // has to be
unorm = vec3( 1.0, 0.0, 0.0 ); unorm = vec3(1.0, 0.0, 0.0);
} }
float depth_fix = 1.0 / dot(normal,unorm); float depth_fix = 1.0 / dot(normal, unorm);
depth = 2.0 * depth - 1.0; depth = 2.0 * depth - 1.0;
float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near)); float linear_depth = 2.0 * z_near * z_far / (z_far + z_near - depth * (z_far - z_near));
gl_FragDepth = (linear_depth*depth_fix+bias) / z_far; gl_FragDepth = (linear_depth * depth_fix + bias) / z_far;
} }

View file

@ -1,21 +1,19 @@
[vertex] [vertex]
layout(location = 0) in highp vec2 vertex;
layout(location=0) in highp vec2 vertex; layout(location = 4) in highp vec2 uv;
layout(location=4) in highp vec2 uv;
out highp vec2 uv_interp; out highp vec2 uv_interp;
void main() { void main() {
uv_interp=uv; uv_interp = uv;
gl_Position=vec4(vertex,0,1); gl_Position = vec4(vertex, 0, 1);
} }
[fragment] [fragment]
precision highp float; precision highp float;
precision highp int; precision highp int;
@ -36,90 +34,85 @@ uniform int face_id;
uniform float roughness; uniform float roughness;
in highp vec2 uv_interp; in highp vec2 uv_interp;
layout(location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
#define M_PI 3.14159265359 #define M_PI 3.14159265359
vec3 texelCoordToVec(vec2 uv, int faceID) {
mat3 faceUvVectors[6];
/*
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
vec3 texelCoordToVec(vec2 uv, int faceID) // +x
{ faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z
mat3 faceUvVectors[6]; faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
/* faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face
// -x
faceUvVectors[1][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[1][2] = vec3(-1.0, 0.0, 0.0); // -x face
// +x // -y
faceUvVectors[0][0] = vec3(0.0, 0.0, -1.0); // u -> -z faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[0][2] = vec3(1.0, 0.0, 0.0); // +x face faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face
// -y // +y
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[3][1] = vec3(0.0, 0.0, -1.0); // v -> -z faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[3][2] = vec3(0.0, -1.0, 0.0); // -y face faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face
// +y // -z
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[2][1] = vec3(0.0, 0.0, 1.0); // v -> +z faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[2][2] = vec3(0.0, 1.0, 0.0); // +y face faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face
// -z // +z
faceUvVectors[5][0] = vec3(-1.0, 0.0, 0.0); // u -> -x faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[5][2] = vec3(0.0, 0.0, -1.0); // -z face faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face
*/
// +z // -x
faceUvVectors[4][0] = vec3(1.0, 0.0, 0.0); // u -> +x faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, 1.0); // +z face faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face
*/
// -x // +x
faceUvVectors[0][0] = vec3(0.0, 0.0, 1.0); // u -> +z faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z
faceUvVectors[0][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[0][2] = vec3(-1.0, 0.0, 0.0); // -x face faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face
// +x // -y
faceUvVectors[1][0] = vec3(0.0, 0.0, -1.0); // u -> -z faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[1][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z
faceUvVectors[1][2] = vec3(1.0, 0.0, 0.0); // +x face faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face
// -y // +y
faceUvVectors[2][0] = vec3(1.0, 0.0, 0.0); // u -> +x faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[2][1] = vec3(0.0, 0.0, -1.0); // v -> -z faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z
faceUvVectors[2][2] = vec3(0.0, -1.0, 0.0); // -y face faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face
// +y // -z
faceUvVectors[3][0] = vec3(1.0, 0.0, 0.0); // u -> +x faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x
faceUvVectors[3][1] = vec3(0.0, 0.0, 1.0); // v -> +z faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[3][2] = vec3(0.0, 1.0, 0.0); // +y face faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face
// -z // +z
faceUvVectors[4][0] = vec3(-1.0, 0.0, 0.0); // u -> -x faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x
faceUvVectors[4][1] = vec3(0.0, -1.0, 0.0); // v -> -y faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y
faceUvVectors[4][2] = vec3(0.0, 0.0, -1.0); // -z face faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
// +z // out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
faceUvVectors[5][0] = vec3(1.0, 0.0, 0.0); // u -> +x vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
faceUvVectors[5][1] = vec3(0.0, -1.0, 0.0); // v -> -y return normalize(result);
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
return normalize(result);
} }
vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
{
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
// Compute distribution direction // Compute distribution direction
float Phi = 2.0 * M_PI * Xi.x; float Phi = 2.0 * M_PI * Xi.x;
float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y));
float SinTheta = sqrt(1.0 - CosTheta * CosTheta); float SinTheta = sqrt(1.0 - CosTheta * CosTheta);
// Convert to spherical direction // Convert to spherical direction
@ -137,33 +130,29 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
} }
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html // http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float GGX(float NdotV, float a) float GGX(float NdotV, float a) {
{
float k = a / 2.0; float k = a / 2.0;
return NdotV / (NdotV * (1.0 - k) + k); return NdotV / (NdotV * (1.0 - k) + k);
} }
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html // http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float G_Smith(float a, float nDotV, float nDotL) float G_Smith(float a, float nDotV, float nDotL) {
{
return GGX(nDotL, a * a) * GGX(nDotV, a * a); return GGX(nDotL, a * a) * GGX(nDotV, a * a);
} }
float radicalInverse_VdC(uint bits) { float radicalInverse_VdC(uint bits) {
bits = (bits << 16u) | (bits >> 16u); bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000 return float(bits) * 2.3283064365386963e-10; // / 0x100000000
} }
vec2 Hammersley(uint i, uint N) { vec2 Hammersley(uint i, uint N) {
return vec2(float(i)/float(N), radicalInverse_VdC(i)); return vec2(float(i) / float(N), radicalInverse_VdC(i));
} }
#ifdef LOW_QUALITY #ifdef LOW_QUALITY
#define SAMPLE_COUNT 64u #define SAMPLE_COUNT 64u
@ -178,37 +167,33 @@ uniform bool z_flip;
#ifdef USE_SOURCE_PANORAMA #ifdef USE_SOURCE_PANORAMA
vec4 texturePanorama(vec3 normal,sampler2D pano ) { vec4 texturePanorama(vec3 normal, sampler2D pano) {
vec2 st = vec2( vec2 st = vec2(
atan(normal.x, normal.z), atan(normal.x, normal.z),
acos(normal.y) acos(normal.y));
);
if(st.x < 0.0) if (st.x < 0.0)
st.x += M_PI*2.0; st.x += M_PI * 2.0;
st/=vec2(M_PI*2.0,M_PI); st /= vec2(M_PI * 2.0, M_PI);
return textureLod(pano,st,0.0);
return textureLod(pano, st, 0.0);
} }
#endif #endif
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY #ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
vec4 textureDualParaboloidArray(vec3 normal) { vec4 textureDualParaboloidArray(vec3 normal) {
vec3 norm = normalize(normal); vec3 norm = normalize(normal);
norm.xy/=1.0+abs(norm.z); norm.xy /= 1.0 + abs(norm.z);
norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); norm.xy = norm.xy * vec2(0.5, 0.25) + vec2(0.5, 0.25);
if (norm.z<0.0) { if (norm.z < 0.0) {
norm.y=0.5-norm.y+0.5; norm.y = 0.5 - norm.y + 0.5;
} }
return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0); return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index)), 0.0);
} }
#endif #endif
@ -217,19 +202,18 @@ void main() {
#ifdef USE_DUAL_PARABOLOID #ifdef USE_DUAL_PARABOLOID
vec3 N = vec3( uv_interp * 2.0 - 1.0, 0.0 ); vec3 N = vec3(uv_interp * 2.0 - 1.0, 0.0);
N.z = 0.5 - 0.5*((N.x * N.x) + (N.y * N.y)); N.z = 0.5 - 0.5 * ((N.x * N.x) + (N.y * N.y));
N = normalize(N); N = normalize(N);
if (z_flip) { if (z_flip) {
N.y=-N.y; //y is flipped to improve blending between both sides N.y = -N.y; //y is flipped to improve blending between both sides
N.z=-N.z; N.z = -N.z;
} }
#else #else
vec2 uv = (uv_interp * 2.0) - 1.0; vec2 uv = (uv_interp * 2.0) - 1.0;
vec3 N = texelCoordToVec(uv, face_id); vec3 N = texelCoordToVec(uv, face_id);
#endif #endif
//vec4 color = color_interp; //vec4 color = color_interp;
@ -237,49 +221,46 @@ void main() {
#ifdef USE_SOURCE_PANORAMA #ifdef USE_SOURCE_PANORAMA
frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0); frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0);
#endif #endif
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY #ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
frag_color=vec4(textureDualParaboloidArray(N).rgb,1.0); frag_color = vec4(textureDualParaboloidArray(N).rgb, 1.0);
#endif #endif
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) #if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
N.y=-N.y; N.y = -N.y;
frag_color=vec4(texture(N,source_cube).rgb,1.0); frag_color = vec4(texture(N, source_cube).rgb, 1.0);
#endif #endif
#else #else
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
for(uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) { for (uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) {
vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT); vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX( xi, roughness, N ); vec3 H = ImportanceSampleGGX(xi, roughness, N);
vec3 V = N; vec3 V = N;
vec3 L = normalize(2.0 * dot( V, H ) * H - V); vec3 L = normalize(2.0 * dot(V, H) * H - V);
float ndotl = clamp(dot(N, L),0.0,1.0); float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl>0.0) { if (ndotl > 0.0) {
#ifdef USE_SOURCE_PANORAMA #ifdef USE_SOURCE_PANORAMA
sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl; sum.rgb += texturePanorama(H, source_panorama).rgb * ndotl;
#endif #endif
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY #ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
sum.rgb += textureDualParaboloidArray(H).rgb *ndotl; sum.rgb += textureDualParaboloidArray(H).rgb * ndotl;
#endif #endif
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) #if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
H.y=-H.y; H.y = -H.y;
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl; sum.rgb += textureLod(source_cube, H, 0.0).rgb * ndotl;
#endif #endif
sum.a += ndotl; sum.a += ndotl;
} }
@ -289,6 +270,4 @@ void main() {
frag_color = vec4(sum.rgb, 1.0); frag_color = vec4(sum.rgb, 1.0);
#endif #endif
} }

View file

@ -1,8 +1,7 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib; layout(location = 4) in vec2 uv_in;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
@ -39,7 +38,6 @@ uniform sampler2D source_ssao; //texunit:1
uniform float lod; uniform float lod;
uniform vec2 pixel_size; uniform vec2 pixel_size;
layout(location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
#ifdef SSAO_MERGE #ifdef SSAO_MERGE
@ -48,31 +46,31 @@ uniform vec4 ssao_color;
#endif #endif
#if defined (GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL) #if defined(GLOW_GAUSSIAN_HORIZONTAL) || defined(GLOW_GAUSSIAN_VERTICAL)
uniform float glow_strength; uniform float glow_strength;
#endif #endif
#if defined(DOF_FAR_BLUR) || defined (DOF_NEAR_BLUR) #if defined(DOF_FAR_BLUR) || defined(DOF_NEAR_BLUR)
#ifdef DOF_QUALITY_LOW #ifdef DOF_QUALITY_LOW
const int dof_kernel_size=5; const int dof_kernel_size = 5;
const int dof_kernel_from=2; const int dof_kernel_from = 2;
const float dof_kernel[5] = float[] (0.153388,0.221461,0.250301,0.221461,0.153388); const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388);
#endif #endif
#ifdef DOF_QUALITY_MEDIUM #ifdef DOF_QUALITY_MEDIUM
const int dof_kernel_size=11; const int dof_kernel_size = 11;
const int dof_kernel_from=5; const int dof_kernel_from = 5;
const float dof_kernel[11] = float[] (0.055037,0.072806,0.090506,0.105726,0.116061,0.119726,0.116061,0.105726,0.090506,0.072806,0.055037); const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037);
#endif #endif
#ifdef DOF_QUALITY_HIGH #ifdef DOF_QUALITY_HIGH
const int dof_kernel_size=21; const int dof_kernel_size = 21;
const int dof_kernel_from=10; const int dof_kernel_from = 10;
const float dof_kernel[21] = float[] (0.028174,0.032676,0.037311,0.041944,0.046421,0.050582,0.054261,0.057307,0.059587,0.060998,0.061476,0.060998,0.059587,0.057307,0.054261,0.050582,0.046421,0.041944,0.037311,0.032676,0.028174); const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174);
#endif #endif
uniform sampler2D dof_source_depth; //texunit:1 uniform sampler2D dof_source_depth; //texunit:1
@ -88,7 +86,6 @@ uniform sampler2D source_dof_original; //texunit:2
#endif #endif
#ifdef GLOW_FIRST_PASS #ifdef GLOW_FIRST_PASS
uniform float exposure; uniform float exposure;
@ -112,53 +109,51 @@ uniform float camera_z_near;
void main() { void main() {
#ifdef GAUSSIAN_HORIZONTAL #ifdef GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size; vec2 pix_size = pixel_size;
pix_size*=0.5; //reading from larger buffer, so use more samples pix_size *= 0.5; //reading from larger buffer, so use more samples
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.214607; vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.214607;
color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.189879; color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.189879;
color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.157305; color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.157305;
color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.071303; color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.071303;
color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.189879; color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.189879;
color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.157305; color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.157305;
color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.071303; color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.071303;
frag_color = color; frag_color = color;
#endif #endif
#ifdef GAUSSIAN_VERTICAL #ifdef GAUSSIAN_VERTICAL
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pixel_size,lod )*0.38774; vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.38774;
color+=textureLod( source_color, uv_interp+vec2( 0.0, 1.0)*pixel_size,lod )*0.24477; color += textureLod(source_color, uv_interp + vec2(0.0, 1.0) * pixel_size, lod) * 0.24477;
color+=textureLod( source_color, uv_interp+vec2( 0.0, 2.0)*pixel_size,lod )*0.06136; color += textureLod(source_color, uv_interp + vec2(0.0, 2.0) * pixel_size, lod) * 0.06136;
color+=textureLod( source_color, uv_interp+vec2( 0.0,-1.0)*pixel_size,lod )*0.24477; color += textureLod(source_color, uv_interp + vec2(0.0, -1.0) * pixel_size, lod) * 0.24477;
color+=textureLod( source_color, uv_interp+vec2( 0.0,-2.0)*pixel_size,lod )*0.06136; color += textureLod(source_color, uv_interp + vec2(0.0, -2.0) * pixel_size, lod) * 0.06136;
frag_color = color; frag_color = color;
#endif #endif
//glow uses larger sigma for a more rounded blur effect //glow uses larger sigma for a more rounded blur effect
#ifdef GLOW_GAUSSIAN_HORIZONTAL #ifdef GLOW_GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size; vec2 pix_size = pixel_size;
pix_size*=0.5; //reading from larger buffer, so use more samples pix_size *= 0.5; //reading from larger buffer, so use more samples
vec4 color =textureLod( source_color, uv_interp+vec2( 0.0, 0.0)*pix_size,lod )*0.174938; vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pix_size, lod) * 0.174938;
color+=textureLod( source_color, uv_interp+vec2( 1.0, 0.0)*pix_size,lod )*0.165569; color += textureLod(source_color, uv_interp + vec2(1.0, 0.0) * pix_size, lod) * 0.165569;
color+=textureLod( source_color, uv_interp+vec2( 2.0, 0.0)*pix_size,lod )*0.140367; color += textureLod(source_color, uv_interp + vec2(2.0, 0.0) * pix_size, lod) * 0.140367;
color+=textureLod( source_color, uv_interp+vec2( 3.0, 0.0)*pix_size,lod )*0.106595; color += textureLod(source_color, uv_interp + vec2(3.0, 0.0) * pix_size, lod) * 0.106595;
color+=textureLod( source_color, uv_interp+vec2(-1.0, 0.0)*pix_size,lod )*0.165569; color += textureLod(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size, lod) * 0.165569;
color+=textureLod( source_color, uv_interp+vec2(-2.0, 0.0)*pix_size,lod )*0.140367; color += textureLod(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size, lod) * 0.140367;
color+=textureLod( source_color, uv_interp+vec2(-3.0, 0.0)*pix_size,lod )*0.106595; color += textureLod(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size, lod) * 0.106595;
color*=glow_strength; color *= glow_strength;
frag_color = color; frag_color = color;
#endif #endif
#ifdef GLOW_GAUSSIAN_VERTICAL #ifdef GLOW_GAUSSIAN_VERTICAL
vec4 color =textureLod( source_color, uv_interp+vec2(0.0, 0.0)*pixel_size,lod )*0.288713; vec4 color = textureLod(source_color, uv_interp + vec2(0.0, 0.0) * pixel_size, lod) * 0.288713;
color+=textureLod( source_color, uv_interp+vec2(0.0, 1.0)*pixel_size,lod )*0.233062; color += textureLod(source_color, uv_interp + vec2(0.0, 1.0) * pixel_size, lod) * 0.233062;
color+=textureLod( source_color, uv_interp+vec2(0.0, 2.0)*pixel_size,lod )*0.122581; color += textureLod(source_color, uv_interp + vec2(0.0, 2.0) * pixel_size, lod) * 0.122581;
color+=textureLod( source_color, uv_interp+vec2(0.0,-1.0)*pixel_size,lod )*0.233062; color += textureLod(source_color, uv_interp + vec2(0.0, -1.0) * pixel_size, lod) * 0.233062;
color+=textureLod( source_color, uv_interp+vec2(0.0,-2.0)*pixel_size,lod )*0.122581; color += textureLod(source_color, uv_interp + vec2(0.0, -2.0) * pixel_size, lod) * 0.122581;
color*=glow_strength; color *= glow_strength;
frag_color = color; frag_color = color;
#endif #endif
@ -166,47 +161,45 @@ void main() {
vec4 color_accum = vec4(0.0); vec4 color_accum = vec4(0.0);
float depth = textureLod( dof_source_depth, uv_interp, 0.0).r; float depth = textureLod(dof_source_depth, uv_interp, 0.0).r;
depth = depth * 2.0 - 1.0; depth = depth * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
#endif #endif
float amount = smoothstep(dof_begin,dof_end,depth); float amount = smoothstep(dof_begin, dof_end, depth);
float k_accum=0.0; float k_accum = 0.0;
for(int i=0;i<dof_kernel_size;i++) { for (int i = 0; i < dof_kernel_size; i++) {
int int_ofs = i-dof_kernel_from; int int_ofs = i - dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius; vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius;
float tap_k = dof_kernel[i]; float tap_k = dof_kernel[i];
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
tap_depth = tap_depth * 2.0 - 1.0; tap_depth = tap_depth * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
#endif #endif
float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0); float tap_amount = mix(smoothstep(dof_begin, dof_end, tap_depth), 1.0, int_ofs == 0);
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
vec4 tap_color = textureLod( source_color, tap_uv, 0.0) * tap_k;
k_accum+=tap_k*tap_amount;
color_accum+=tap_color*tap_amount;
vec4 tap_color = textureLod(source_color, tap_uv, 0.0) * tap_k;
k_accum += tap_k * tap_amount;
color_accum += tap_color * tap_amount;
} }
if (k_accum>0.0) { if (k_accum > 0.0) {
color_accum/=k_accum; color_accum /= k_accum;
} }
frag_color = color_accum;///k_accum; frag_color = color_accum; ///k_accum;
#endif #endif
@ -214,47 +207,45 @@ void main() {
vec4 color_accum = vec4(0.0); vec4 color_accum = vec4(0.0);
float max_accum=0.0; float max_accum = 0.0;
for(int i=0;i<dof_kernel_size;i++) { for (int i = 0; i < dof_kernel_size; i++) {
int int_ofs = i-dof_kernel_from; int int_ofs = i - dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius; vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius;
float ofs_influence = max(0.0,1.0-float(abs(int_ofs))/float(dof_kernel_from)); float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from));
float tap_k = dof_kernel[i]; float tap_k = dof_kernel[i];
vec4 tap_color = textureLod( source_color, tap_uv, 0.0); vec4 tap_color = textureLod(source_color, tap_uv, 0.0);
float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
tap_depth = tap_depth * 2.0 - 1.0; tap_depth = tap_depth * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; tap_depth = ((tap_depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near));
#endif #endif
float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth); float tap_amount = 1.0 - smoothstep(dof_end, dof_begin, tap_depth);
tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
#ifdef DOF_NEAR_FIRST_TAP #ifdef DOF_NEAR_FIRST_TAP
tap_color.a= 1.0-smoothstep(dof_end,dof_begin,tap_depth); tap_color.a = 1.0 - smoothstep(dof_end, dof_begin, tap_depth);
#endif #endif
max_accum=max(max_accum,tap_amount*ofs_influence); max_accum = max(max_accum, tap_amount * ofs_influence);
color_accum+=tap_color*tap_k;
color_accum += tap_color * tap_k;
} }
color_accum.a=max(color_accum.a,sqrt(max_accum)); color_accum.a = max(color_accum.a, sqrt(max_accum));
#ifdef DOF_NEAR_BLUR_MERGE #ifdef DOF_NEAR_BLUR_MERGE
vec4 original = textureLod( source_dof_original, uv_interp, 0.0); vec4 original = textureLod(source_dof_original, uv_interp, 0.0);
color_accum = mix(original,color_accum,color_accum.a); color_accum = mix(original, color_accum, color_accum.a);
#endif #endif
@ -265,37 +256,32 @@ void main() {
#endif #endif
#ifdef GLOW_FIRST_PASS #ifdef GLOW_FIRST_PASS
#ifdef GLOW_USE_AUTO_EXPOSURE #ifdef GLOW_USE_AUTO_EXPOSURE
frag_color/=texelFetch(source_auto_exposure,ivec2(0,0),0).r/auto_exposure_grey; frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey;
#endif #endif
frag_color*=exposure; frag_color *= exposure;
float luminance = max(frag_color.r,max(frag_color.g,frag_color.b)); float luminance = max(frag_color.r, max(frag_color.g, frag_color.b));
float feedback = max( smoothstep(glow_hdr_threshold,glow_hdr_threshold+glow_hdr_scale,luminance), glow_bloom ); float feedback = max(smoothstep(glow_hdr_threshold, glow_hdr_threshold + glow_hdr_scale, luminance), glow_bloom);
frag_color *= feedback; frag_color *= feedback;
#endif #endif
#ifdef SIMPLE_COPY #ifdef SIMPLE_COPY
vec4 color =textureLod( source_color, uv_interp,0.0); vec4 color = textureLod(source_color, uv_interp, 0.0);
frag_color = color; frag_color = color;
#endif #endif
#ifdef SSAO_MERGE #ifdef SSAO_MERGE
vec4 color =textureLod( source_color, uv_interp,0.0); vec4 color = textureLod(source_color, uv_interp, 0.0);
float ssao =textureLod( source_ssao, uv_interp,0.0).r; float ssao = textureLod(source_ssao, uv_interp, 0.0).r;
frag_color = vec4( mix(color.rgb,color.rgb*mix(ssao_color.rgb,vec3(1.0),ssao),color.a), 1.0 ); frag_color = vec4(mix(color.rgb, color.rgb * mix(ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0);
#endif #endif
} }

View file

@ -1,18 +1,14 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib;
void main() { void main() {
gl_Position = vertex_attrib; gl_Position = vertex_attrib;
} }
[fragment] [fragment]
uniform highp sampler2D source_exposure; //texunit:0 uniform highp sampler2D source_exposure; //texunit:0
#ifdef EXPOSURE_BEGIN #ifdef EXPOSURE_BEGIN
@ -33,66 +29,56 @@ uniform highp float max_luminance;
layout(location = 0) out highp float exposure; layout(location = 0) out highp float exposure;
void main() { void main() {
#ifdef EXPOSURE_BEGIN #ifdef EXPOSURE_BEGIN
ivec2 src_pos = ivec2(gl_FragCoord.xy) * source_render_size / target_size;
ivec2 src_pos = ivec2(gl_FragCoord.xy)*source_render_size/target_size;
#if 1 #if 1
//more precise and expensive, but less jittery //more precise and expensive, but less jittery
ivec2 next_pos = ivec2(gl_FragCoord.xy+ivec2(1))*source_render_size/target_size; ivec2 next_pos = ivec2(gl_FragCoord.xy + ivec2(1)) * source_render_size / target_size;
next_pos = max(next_pos,src_pos+ivec2(1)); //so it at least reads one pixel next_pos = max(next_pos, src_pos + ivec2(1)); //so it at least reads one pixel
highp vec3 source_color=vec3(0.0); highp vec3 source_color = vec3(0.0);
for(int i=src_pos.x;i<next_pos.x;i++) { for (int i = src_pos.x; i < next_pos.x; i++) {
for(int j=src_pos.y;j<next_pos.y;j++) { for (int j = src_pos.y; j < next_pos.y; j++) {
source_color += texelFetch(source_exposure,ivec2(i,j),0).rgb; source_color += texelFetch(source_exposure, ivec2(i, j), 0).rgb;
} }
} }
source_color/=float( (next_pos.x-src_pos.x)*(next_pos.y-src_pos.y) ); source_color /= float((next_pos.x - src_pos.x) * (next_pos.y - src_pos.y));
#else #else
highp vec3 source_color = texelFetch(source_exposure,src_pos,0).rgb; highp vec3 source_color = texelFetch(source_exposure, src_pos, 0).rgb;
#endif #endif
exposure = max(source_color.r,max(source_color.g,source_color.b)); exposure = max(source_color.r, max(source_color.g, source_color.b));
#else #else
ivec2 coord = ivec2(gl_FragCoord.xy); ivec2 coord = ivec2(gl_FragCoord.xy);
exposure = texelFetch(source_exposure,coord*3+ivec2(0,0),0).r; exposure = texelFetch(source_exposure, coord * 3 + ivec2(0, 0), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,0),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 0), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,0),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 0), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(0,1),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 1), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,1),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 1), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,1),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 1), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(0,2),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(0, 2), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(1,2),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(1, 2), 0).r;
exposure += texelFetch(source_exposure,coord*3+ivec2(2,2),0).r; exposure += texelFetch(source_exposure, coord * 3 + ivec2(2, 2), 0).r;
exposure *= (1.0/9.0); exposure *= (1.0 / 9.0);
#ifdef EXPOSURE_END #ifdef EXPOSURE_END
#ifdef EXPOSURE_FORCE_SET #ifdef EXPOSURE_FORCE_SET
//will stay as is //will stay as is
#else #else
highp float prev_lum = texelFetch(prev_exposure,ivec2(0,0),0).r; //1 pixel previous exposure highp float prev_lum = texelFetch(prev_exposure, ivec2(0, 0), 0).r; //1 pixel previous exposure
exposure = clamp( prev_lum + (exposure-prev_lum)*exposure_adjust,min_luminance,max_luminance); exposure = clamp(prev_lum + (exposure - prev_lum) * exposure_adjust, min_luminance, max_luminance);
#endif //EXPOSURE_FORCE_SET #endif //EXPOSURE_FORCE_SET
#endif //EXPOSURE_END #endif //EXPOSURE_END
#endif //EXPOSURE_BEGIN #endif //EXPOSURE_BEGIN
} }

View file

@ -1,14 +1,11 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 color;
layout(location = 1) in highp vec4 velocity_active;
layout(location=0) in highp vec4 color; layout(location = 2) in highp vec4 custom;
layout(location=1) in highp vec4 velocity_active; layout(location = 3) in highp vec4 xform_1;
layout(location=2) in highp vec4 custom; layout(location = 4) in highp vec4 xform_2;
layout(location=3) in highp vec4 xform_1; layout(location = 5) in highp vec4 xform_3;
layout(location=4) in highp vec4 xform_2;
layout(location=5) in highp vec4 xform_3;
struct Attractor { struct Attractor {
@ -39,7 +36,6 @@ uniform float lifetime;
uniform mat4 emission_transform; uniform mat4 emission_transform;
uniform uint random_seed; uniform uint random_seed;
out highp vec4 out_color; //tfb: out highp vec4 out_color; //tfb:
out highp vec4 out_velocity_active; //tfb: out highp vec4 out_velocity_active; //tfb:
out highp vec4 out_custom; //tfb: out highp vec4 out_custom; //tfb:
@ -47,7 +43,6 @@ out highp vec4 out_xform_1; //tfb:
out highp vec4 out_xform_2; //tfb: out highp vec4 out_xform_2; //tfb:
out highp vec4 out_xform_3; //tfb: out highp vec4 out_xform_3; //tfb:
#if defined(USE_MATERIAL) #if defined(USE_MATERIAL)
layout(std140) uniform UniformData { //ubo:0 layout(std140) uniform UniformData { //ubo:0
@ -58,7 +53,6 @@ MATERIAL_UNIFORMS
#endif #endif
VERTEX_SHADER_GLOBALS VERTEX_SHADER_GLOBALS
uint hash(uint x) { uint hash(uint x) {
@ -69,13 +63,12 @@ uint hash(uint x) {
return x; return x;
} }
void main() { void main() {
#ifdef PARTICLES_COPY #ifdef PARTICLES_COPY
out_color=color; out_color = color;
out_velocity_active=velocity_active; out_velocity_active = velocity_active;
out_custom = custom; out_custom = custom;
out_xform_1 = xform_1; out_xform_1 = xform_1;
out_xform_2 = xform_2; out_xform_2 = xform_2;
@ -83,47 +76,47 @@ void main() {
#else #else
bool apply_forces=true; bool apply_forces = true;
bool apply_velocity=true; bool apply_velocity = true;
float local_delta=delta; float local_delta = delta;
float mass = 1.0; float mass = 1.0;
float restart_phase = float(gl_VertexID)/float(total_particles); float restart_phase = float(gl_VertexID) / float(total_particles);
if (randomness>0.0) { if (randomness > 0.0) {
uint seed = cycle; uint seed = cycle;
if (restart_phase >= system_phase) { if (restart_phase >= system_phase) {
seed-=uint(1); seed -= uint(1);
} }
seed*=uint(total_particles); seed *= uint(total_particles);
seed+=uint(gl_VertexID); seed += uint(gl_VertexID);
float random = float(hash(seed) % uint(65536)) / 65536.0; float random = float(hash(seed) % uint(65536)) / 65536.0;
restart_phase+=randomness * random * 1.0 / float(total_particles); restart_phase += randomness * random * 1.0 / float(total_particles);
} }
restart_phase*= (1.0-explosiveness); restart_phase *= (1.0 - explosiveness);
bool restart=false; bool restart = false;
bool shader_active = velocity_active.a > 0.5; bool shader_active = velocity_active.a > 0.5;
if (system_phase > prev_system_phase) { if (system_phase > prev_system_phase) {
// restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed // restart_phase >= prev_system_phase is used so particles emit in the first frame they are processed
if (restart_phase >= prev_system_phase && restart_phase < system_phase ) { if (restart_phase >= prev_system_phase && restart_phase < system_phase) {
restart=true; restart = true;
#ifdef USE_FRACTIONAL_DELTA #ifdef USE_FRACTIONAL_DELTA
local_delta = (system_phase - restart_phase) * lifetime; local_delta = (system_phase - restart_phase) * lifetime;
#endif #endif
} }
} else if(delta > 0.0) { } else if (delta > 0.0) {
if (restart_phase >= prev_system_phase) { if (restart_phase >= prev_system_phase) {
restart=true; restart = true;
#ifdef USE_FRACTIONAL_DELTA #ifdef USE_FRACTIONAL_DELTA
local_delta = (1.0 - restart_phase + system_phase) * lifetime; local_delta = (1.0 - restart_phase + system_phase) * lifetime;
#endif #endif
} else if (restart_phase < system_phase ) { } else if (restart_phase < system_phase) {
restart=true; restart = true;
#ifdef USE_FRACTIONAL_DELTA #ifdef USE_FRACTIONAL_DELTA
local_delta = (system_phase - restart_phase) * lifetime; local_delta = (system_phase - restart_phase) * lifetime;
#endif #endif
@ -133,14 +126,14 @@ void main() {
uint current_cycle = cycle; uint current_cycle = cycle;
if (system_phase < restart_phase) { if (system_phase < restart_phase) {
current_cycle-=uint(1); current_cycle -= uint(1);
} }
uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID); uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID);
int index = int(gl_VertexID); int index = int(gl_VertexID);
if (restart) { if (restart) {
shader_active=emitting; shader_active = emitting;
} }
mat4 xform; mat4 xform;
@ -150,23 +143,22 @@ void main() {
#else #else
if (clear || restart) { if (clear || restart) {
#endif #endif
out_color=vec4(1.0); out_color = vec4(1.0);
out_velocity_active=vec4(0.0); out_velocity_active = vec4(0.0);
out_custom=vec4(0.0); out_custom = vec4(0.0);
if (!restart) if (!restart)
shader_active=false; shader_active = false;
xform = mat4( xform = mat4(
vec4(1.0,0.0,0.0,0.0), vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0,1.0,0.0,0.0), vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0,0.0,1.0,0.0), vec4(0.0, 0.0, 1.0, 0.0),
vec4(0.0,0.0,0.0,1.0) vec4(0.0, 0.0, 0.0, 1.0));
);
} else { } else {
out_color=color; out_color = color;
out_velocity_active=velocity_active; out_velocity_active = velocity_active;
out_custom=custom; out_custom = custom;
xform = transpose(mat4(xform_1,xform_2,xform_3,vec4(vec3(0.0),1.0))); xform = transpose(mat4(xform_1, xform_2, xform_3, vec4(vec3(0.0), 1.0)));
} }
if (shader_active) { if (shader_active) {
@ -181,26 +173,25 @@ VERTEX_SHADER_CODE
if (false) { if (false) {
vec3 force = vec3(0.0); vec3 force = vec3(0.0);
for(int i=0;i<attractor_count;i++) { for (int i = 0; i < attractor_count; i++) {
vec3 rel_vec = xform[3].xyz - attractors[i].pos; vec3 rel_vec = xform[3].xyz - attractors[i].pos;
float dist = length(rel_vec); float dist = length(rel_vec);
if (attractors[i].radius < dist) if (attractors[i].radius < dist)
continue; continue;
if (attractors[i].eat_radius>0.0 && attractors[i].eat_radius > dist) { if (attractors[i].eat_radius > 0.0 && attractors[i].eat_radius > dist) {
out_velocity_active.a=0.0; out_velocity_active.a = 0.0;
} }
rel_vec = normalize(rel_vec); rel_vec = normalize(rel_vec);
float attenuation = pow(dist / attractors[i].radius,attractors[i].attenuation); float attenuation = pow(dist / attractors[i].radius, attractors[i].attenuation);
if (attractors[i].dir==vec3(0.0)) { if (attractors[i].dir == vec3(0.0)) {
//towards center //towards center
force+=attractors[i].strength * rel_vec * attenuation * mass; force += attractors[i].strength * rel_vec * attenuation * mass;
} else { } else {
force+=attractors[i].strength * attractors[i].dir * attenuation *mass; force += attractors[i].strength * attractors[i].dir * attenuation * mass;
} }
} }
@ -216,25 +207,23 @@ VERTEX_SHADER_CODE
} }
#endif #endif
} else { } else {
xform=mat4(0.0); xform = mat4(0.0);
} }
xform = transpose(xform); xform = transpose(xform);
out_velocity_active.a = mix(0.0,1.0,shader_active); out_velocity_active.a = mix(0.0, 1.0, shader_active);
out_xform_1 = xform[0]; out_xform_1 = xform[0];
out_xform_2 = xform[1]; out_xform_2 = xform[1];
out_xform_3 = xform[2]; out_xform_3 = xform[2];
#endif //PARTICLES_COPY #endif //PARTICLES_COPY
} }
[fragment] [fragment]
//any code here is never executed, stuff is filled just so it works // any code here is never executed, stuff is filled just so it works
#if defined(USE_MATERIAL) #if defined(USE_MATERIAL)

View file

@ -1,12 +1,10 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib; layout(location = 4) in vec2 uv_in;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
void main() { void main() {
uv_interp = uv_in; uv_interp = uv_in;
@ -20,8 +18,8 @@ precision mediump float;
#endif #endif
in vec2 uv_interp; in vec2 uv_interp;
uniform sampler2D source_specular; //texunit:0 uniform sampler2D source_specular; // texunit:0
uniform sampler2D source_ssr; //texunit:1 uniform sampler2D source_ssr; // texunit:1
uniform vec2 pixel_size; uniform vec2 pixel_size;
@ -31,14 +29,12 @@ layout(location = 0) out vec4 frag_color;
void main() { void main() {
vec4 specular = texture( source_specular, uv_interp ); vec4 specular = texture(source_specular, uv_interp);
#ifdef USE_SSR #ifdef USE_SSR
vec4 ssr = textureLod(source_ssr, uv_interp, 0.0);
vec4 ssr = textureLod(source_ssr,uv_interp,0.0); specular.rgb = mix(specular.rgb, ssr.rgb * specular.a, ssr.a);
specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a);
#endif #endif
frag_color = vec4(specular.rgb,1.0); frag_color = vec4(specular.rgb, 1.0);
} }

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,7 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib; layout(location = 4) in vec2 uv_in;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
out vec2 pos_interp; out vec2 pos_interp;
@ -11,12 +10,11 @@ void main() {
uv_interp = uv_in; uv_interp = uv_in;
gl_Position = vertex_attrib; gl_Position = vertex_attrib;
pos_interp.xy=gl_Position.xy; pos_interp.xy = gl_Position.xy;
} }
[fragment] [fragment]
in vec2 uv_interp; in vec2 uv_interp;
in vec2 pos_interp; in vec2 pos_interp;
@ -40,81 +38,67 @@ uniform float depth_tolerance;
uniform float distance_fade; uniform float distance_fade;
uniform float curve_fade_in; uniform float curve_fade_in;
layout(location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
vec2 view_to_screen(vec3 view_pos, out float w) {
vec2 view_to_screen(vec3 view_pos,out float w) { vec4 projected = projection * vec4(view_pos, 1.0);
vec4 projected = projection * vec4(view_pos, 1.0); projected.xyz /= projected.w;
projected.xyz /= projected.w; projected.xy = projected.xy * 0.5 + 0.5;
projected.xy = projected.xy * 0.5 + 0.5; w = projected.w;
w=projected.w; return projected.xy;
return projected.xy;
} }
#define M_PI 3.14159265359 #define M_PI 3.14159265359
void main() { void main() {
vec4 diffuse = texture(source_diffuse, uv_interp);
//// vec4 normal_roughness = texture(source_normal_roughness, uv_interp);
vec4 diffuse = texture( source_diffuse, uv_interp );
vec4 normal_roughness = texture( source_normal_roughness, uv_interp);
vec3 normal; vec3 normal;
normal = normal_roughness.xyz * 2.0 - 1.0;
normal = normal_roughness.xyz*2.0-1.0;
float roughness = normal_roughness.w; float roughness = normal_roughness.w;
float depth_tex = texture(source_depth,uv_interp).r; float depth_tex = texture(source_depth, uv_interp).r;
vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 ); vec4 world_pos = inverse_projection * vec4(uv_interp * 2.0 - 1.0, depth_tex * 2.0 - 1.0, 1.0);
vec3 vertex = world_pos.xyz/world_pos.w; vec3 vertex = world_pos.xyz / world_pos.w;
vec3 view_dir = normalize(vertex); vec3 view_dir = normalize(vertex);
vec3 ray_dir = normalize(reflect(view_dir, normal)); vec3 ray_dir = normalize(reflect(view_dir, normal));
if (dot(ray_dir,normal)<0.001) { if (dot(ray_dir, normal) < 0.001) {
frag_color=vec4(0.0); frag_color = vec4(0.0);
return; return;
} }
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
//ray_dir = normalize(vec3(1, 1, -1));
//ray_dir = normalize(vec3(1,1,-1));
//////////////// ////////////////
// make ray length and clip it against the near plane (don't want to trace beyond visible)
//make ray length and clip it against the near plane (don't want to trace beyond visible)
float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far; float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far;
vec3 ray_end = vertex + ray_dir*ray_len; vec3 ray_end = vertex + ray_dir * ray_len;
float w_begin; float w_begin;
vec2 vp_line_begin = view_to_screen(vertex,w_begin); vec2 vp_line_begin = view_to_screen(vertex, w_begin);
float w_end; float w_end;
vec2 vp_line_end = view_to_screen( ray_end, w_end); vec2 vp_line_end = view_to_screen(ray_end, w_end);
vec2 vp_line_dir = vp_line_end-vp_line_begin; vec2 vp_line_dir = vp_line_end - vp_line_begin;
//we need to interpolate w along the ray, to generate perspective correct reflections // we need to interpolate w along the ray, to generate perspective correct reflections
w_begin = 1.0 / w_begin;
w_end = 1.0 / w_end;
w_begin = 1.0/w_begin; float z_begin = vertex.z * w_begin;
w_end = 1.0/w_end; float z_end = ray_end.z * w_end;
vec2 line_begin = vp_line_begin / pixel_size;
float z_begin = vertex.z*w_begin; vec2 line_dir = vp_line_dir / pixel_size;
float z_end = ray_end.z*w_end;
vec2 line_begin = vp_line_begin/pixel_size;
vec2 line_dir = vp_line_dir/pixel_size;
float z_dir = z_end - z_begin; float z_dir = z_end - z_begin;
float w_dir = w_end - w_begin; float w_dir = w_end - w_begin;
// clip the line to the viewport edges // clip the line to the viewport edges
float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x)); float scale_max_x = min(1.0, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
@ -124,126 +108,114 @@ void main() {
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y); float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
line_dir *= line_clip; line_dir *= line_clip;
z_dir *= line_clip; z_dir *= line_clip;
w_dir *=line_clip; w_dir *= line_clip;
//clip z and w advance to line advance // clip z and w advance to line advance
vec2 line_advance = normalize(line_dir); //down to pixel vec2 line_advance = normalize(line_dir); // down to pixel
float step_size = length(line_advance)/length(line_dir); float step_size = length(line_advance) / length(line_dir);
float z_advance = z_dir*step_size; // adapt z advance to line advance float z_advance = z_dir * step_size; // adapt z advance to line advance
float w_advance = w_dir*step_size; // adapt w advance to line advance float w_advance = w_dir * step_size; // adapt w advance to line advance
//make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice) // make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y)); float advance_angle_adj = 1.0 / max(abs(line_advance.x), abs(line_advance.y));
line_advance*=advance_angle_adj; // adapt z advance to line advance line_advance *= advance_angle_adj; // adapt z advance to line advance
z_advance*=advance_angle_adj; z_advance *= advance_angle_adj;
w_advance*=advance_angle_adj; w_advance *= advance_angle_adj;
vec2 pos = line_begin; vec2 pos = line_begin;
float z = z_begin; float z = z_begin;
float w = w_begin; float w = w_begin;
float z_from=z/w; float z_from = z / w;
float z_to=z_from; float z_to = z_from;
float depth; float depth;
vec2 prev_pos=pos; vec2 prev_pos = pos;
bool found=false; bool found = false;
float steps_taken=0.0; float steps_taken = 0.0;
for(int i=0;i<num_steps;i++) { for (int i = 0; i < num_steps; i++) {
pos+=line_advance; pos += line_advance;
z+=z_advance; z += z_advance;
w+=w_advance; w += w_advance;
//convert to linear depth // convert to linear depth
depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0; depth = texture(source_depth, pos * pixel_size).r * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
#endif #endif
depth=-depth; depth = -depth;
z_from = z_to; z_from = z_to;
z_to = z/w; z_to = z / w;
if (depth>z_to) { if (depth > z_to) {
//if depth was surpassed // if depth was surpassed
if (depth<=max(z_to,z_from)+depth_tolerance) { if (depth <= max(z_to, z_from) + depth_tolerance) {
//check the depth tolerance // check the depth tolerance
found=true; found = true;
} }
break; break;
} }
steps_taken+=1.0; steps_taken += 1.0;
prev_pos=pos; prev_pos = pos;
} }
if (found) { if (found) {
float margin_blend=1.0; float margin_blend = 1.0;
vec2 margin = vec2((viewport_size.x + viewport_size.y) * 0.5 * 0.05); // make a uniform margin
vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin if (any(bvec4(lessThan(pos, -margin), greaterThan(pos, viewport_size + margin)))) {
if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) { // clip outside screen + margin
//clip outside screen + margin frag_color = vec4(0.0);
frag_color=vec4(0.0);
return; return;
} }
{ {
//blend fading out towards external margin //blend fading out towards external margin
vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0))); vec2 margin_grad = mix(pos - viewport_size, -pos, lessThan(pos, vec2(0.0)));
margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y)); margin_blend = 1.0 - smoothstep(0.0, margin.x, max(margin_grad.x, margin_grad.y));
//margin_blend=1.0; //margin_blend = 1.0;
} }
vec2 final_pos; vec2 final_pos;
float grad; float grad;
grad=steps_taken/float(num_steps); grad = steps_taken / float(num_steps);
float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in); float initial_fade = curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), curve_fade_in);
float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade; float fade = pow(clamp(1.0 - grad, 0.0, 1.0), distance_fade) * initial_fade;
final_pos=pos; final_pos = pos;
#ifdef REFLECT_ROUGHNESS #ifdef REFLECT_ROUGHNESS
vec4 final_color; vec4 final_color;
//if roughness is enabled, do screen space cone tracing // if roughness is enabled, do screen space cone tracing
if (roughness > 0.001) { if (roughness > 0.001) {
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////
//use a blurred version (in consecutive mipmaps) of the screen to simulate roughness // use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
float gloss = 1.0-roughness; float gloss = 1.0 - roughness;
float cone_angle = roughness * M_PI * 0.5; float cone_angle = roughness * M_PI * 0.5;
vec2 cone_dir = final_pos - line_begin; vec2 cone_dir = final_pos - line_begin;
float cone_len = length(cone_dir); float cone_len = length(cone_dir);
cone_dir = normalize(cone_dir); //will be used normalized from now on cone_dir = normalize(cone_dir); // will be used normalized from now on
float max_mipmap = filter_mipmap_levels - 1.0; float max_mipmap = filter_mipmap_levels - 1.0;
float gloss_mult=gloss; float gloss_mult = gloss;
float rem_alpha=1.0; float rem_alpha = 1.0;
final_color = vec4(0.0); final_color = vec4(0.0);
for(int i=0;i<7;i++) { for (int i = 0; i < 7; i++) {
float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle
float radius; float radius;
{ {
//fit to sphere inside cone (sphere ends at end of cone), something like this: // fit to sphere inside cone (sphere ends at end of cone), something like this:
// ___ // ___
// \O/ // \O/
// V // V
@ -257,31 +229,31 @@ void main() {
radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
} }
//find the place where screen must be sampled // find the place where screen must be sampled
vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size; vec2 sample_pos = (line_begin + cone_dir * (cone_len - radius)) * pixel_size;
//radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels // radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
float mipmap = clamp( log2( radius ), 0.0, max_mipmap ); float mipmap = clamp(log2(radius), 0.0, max_mipmap);
//mipmap = max(mipmap - 1.0, 0.0);
//mipmap = max(mipmap-1.0,0.0); // do sampling
//do sampling
vec4 sample_color; vec4 sample_color;
{ {
sample_color = textureLod(source_diffuse,sample_pos,mipmap); sample_color = textureLod(source_diffuse, sample_pos, mipmap);
} }
//multiply by gloss // multiply by gloss
sample_color.rgb*=gloss_mult; sample_color.rgb *= gloss_mult;
sample_color.a=gloss_mult; sample_color.a = gloss_mult;
rem_alpha -= sample_color.a; rem_alpha -= sample_color.a;
if(rem_alpha < 0.0) { if (rem_alpha < 0.0) {
sample_color.rgb *= (1.0 - abs(rem_alpha)); sample_color.rgb *= (1.0 - abs(rem_alpha));
} }
final_color+=sample_color; final_color += sample_color;
if (final_color.a>=0.95) { if (final_color.a >= 0.95) {
// This code of accumulating gloss and aborting on near one // This code of accumulating gloss and aborting on near one
// makes sense when you think of cone tracing. // makes sense when you think of cone tracing.
// Think of it as if roughness was 0, then we could abort on the first // Think of it as if roughness was 0, then we could abort on the first
@ -290,29 +262,21 @@ void main() {
break; break;
} }
cone_len-=radius*2.0; //go to next (smaller) circle. cone_len -= radius * 2.0; // go to next (smaller) circle.
gloss_mult*=gloss;
gloss_mult *= gloss;
} }
} else { } else {
final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0); final_color = textureLod(source_diffuse, final_pos * pixel_size, 0.0);
} }
frag_color = vec4(final_color.rgb,fade*margin_blend); frag_color = vec4(final_color.rgb, fade * margin_blend);
#else #else
frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend); frag_color = vec4(textureLod(source_diffuse, final_pos * pixel_size, 0.0).rgb, fade * margin_blend);
#endif #endif
} else { } else {
frag_color = vec4(0.0,0.0,0.0,0.0); frag_color = vec4(0.0, 0.0, 0.0, 0.0);
} }
} }

View file

@ -1,12 +1,11 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib;
void main() { void main() {
gl_Position = vertex_attrib; gl_Position = vertex_attrib;
gl_Position.z=1.0; gl_Position.z = 1.0;
} }
[fragment] [fragment]
@ -14,21 +13,15 @@ void main() {
#define TWO_PI 6.283185307179586476925286766559 #define TWO_PI 6.283185307179586476925286766559
#ifdef SSAO_QUALITY_HIGH #ifdef SSAO_QUALITY_HIGH
#define NUM_SAMPLES (80) #define NUM_SAMPLES (80)
#endif #endif
#ifdef SSAO_QUALITY_LOW #ifdef SSAO_QUALITY_LOW
#define NUM_SAMPLES (15) #define NUM_SAMPLES (15)
#endif #endif
#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH) #if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH)
#define NUM_SAMPLES (40) #define NUM_SAMPLES (40)
#endif #endif
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower // If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
@ -43,19 +36,21 @@ void main() {
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent // This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9 // taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
const int ROTATIONS[] = int[]( 1, 1, 2, 3, 2, 5, 2, 3, 2, const int ROTATIONS[] = int[](
3, 3, 5, 5, 3, 4, 7, 5, 5, 7, 1, 1, 2, 3, 2, 5, 2, 3, 2,
9, 8, 5, 5, 7, 7, 7, 8, 5, 8, 3, 3, 5, 5, 3, 4, 7, 5, 5, 7,
11, 12, 7, 10, 13, 8, 11, 8, 7, 14, 9, 8, 5, 5, 7, 7, 7, 8, 5, 8,
11, 11, 13, 12, 13, 19, 17, 13, 11, 18, 11, 12, 7, 10, 13, 8, 11, 8, 7, 14,
19, 11, 11, 14, 17, 21, 15, 16, 17, 18, 11, 11, 13, 12, 13, 19, 17, 13, 11, 18,
13, 17, 11, 17, 19, 18, 25, 18, 19, 19, 19, 11, 11, 14, 17, 21, 15, 16, 17, 18,
29, 21, 19, 27, 31, 29, 21, 18, 17, 29, 13, 17, 11, 17, 19, 18, 25, 18, 19, 19,
31, 31, 23, 18, 25, 26, 25, 23, 19, 34, 29, 21, 19, 27, 31, 29, 21, 18, 17, 29,
19, 27, 21, 25, 39, 29, 17, 21, 27 ); 31, 31, 23, 18, 25, 26, 25, 23, 19, 34,
19, 27, 21, 25, 39, 29, 17, 21, 27
);
//#define NUM_SPIRAL_TURNS (7) //#define NUM_SPIRAL_TURNS (7)
const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES-1]; const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1];
uniform sampler2D source_depth; //texunit:0 uniform sampler2D source_depth; //texunit:0
uniform highp usampler2D source_depth_mipmaps; //texunit:1 uniform highp usampler2D source_depth_mipmaps; //texunit:1
@ -90,44 +85,41 @@ vec3 reconstructCSPosition(vec2 S, float z) {
} }
vec3 getPosition(ivec2 ssP) { vec3 getPosition(ivec2 ssP) {
vec3 P; vec3 P;
P.z = texelFetch(source_depth, ssP, 0).r; P.z = texelFetch(source_depth, ssP, 0).r;
P.z = P.z * 2.0 - 1.0; P.z = P.z * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
#endif #endif
P.z = -P.z; P.z = -P.z;
// Offset to pixel center // Offset to pixel center
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
return P; return P;
} }
/** Reconstructs screen-space unit normal from screen-space position */ /** Reconstructs screen-space unit normal from screen-space position */
vec3 reconstructCSFaceNormal(vec3 C) { vec3 reconstructCSFaceNormal(vec3 C) {
return normalize(cross(dFdy(C), dFdx(C))); return normalize(cross(dFdy(C), dFdx(C)));
} }
/** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */ /** Returns a unit vector and a screen-space radius for the tap on a unit disk (the caller should scale by the actual disk radius) */
vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR){ vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR) {
// Radius relative to ssR // Radius relative to ssR
float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES)); float alpha = (float(sampleNumber) + 0.5) * (1.0 / float(NUM_SAMPLES));
float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle; float angle = alpha * (float(NUM_SPIRAL_TURNS) * 6.28) + spinAngle;
ssR = alpha; ssR = alpha;
return vec2(cos(angle), sin(angle)); return vec2(cos(angle), sin(angle));
} }
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */ /** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) {
// Derivation: // Derivation:
// mipLevel = floor(log(ssR / MAX_OFFSET)); // mipLevel = floor(log(ssR / MAX_OFFSET));
int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL); int mipLevel = clamp(int(floor(log2(ssR))) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
ivec2 ssP = ivec2(ssR * unitOffset) + ssC; ivec2 ssP = ivec2(ssR * unitOffset) + ssC;
@ -138,98 +130,91 @@ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) {
// Manually clamp to the texture size because texelFetch bypasses the texture unit // Manually clamp to the texture size because texelFetch bypasses the texture unit
ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1)); ivec2 mipP = clamp(ssP >> mipLevel, ivec2(0), (screen_size >> mipLevel) - ivec2(1));
if (mipLevel < 1) { if (mipLevel < 1) {
//read from depth buffer //read from depth buffer
P.z = texelFetch(source_depth, mipP, 0).r; P.z = texelFetch(source_depth, mipP, 0).r;
P.z = P.z * 2.0 - 1.0; P.z = P.z * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; P.z = ((P.z + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near));
#endif #endif
P.z = -P.z; P.z = -P.z;
} else { } else {
//read from mipmaps //read from mipmaps
uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel-1).r; uint d = texelFetch(source_depth_mipmaps, mipP, mipLevel - 1).r;
P.z = -(float(d)/65535.0)*camera_z_far; P.z = -(float(d) / 65535.0) * camera_z_far;
} }
// Offset to pixel center // Offset to pixel center
P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z);
return P; return P;
} }
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds /** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling radius \a ssDiskRadius
Note that units of H() in the HPG12 paper are meters, not Note that units of H() in the HPG12 paper are meters, not
unitless. The whole falloff/sampling function is therefore unitless. The whole falloff/sampling function is therefore
unitless. In this implementation, we factor out (9 / radius). unitless. In this implementation, we factor out (9 / radius).
Four versions of the falloff function are implemented below Four versions of the falloff function are implemented below
*/ */
float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius,in float p_radius, in int tapIndex, in float randomPatternRotationAngle) { float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in float p_radius, in int tapIndex, in float randomPatternRotationAngle) {
// Offset on the unit disk, spun for this pixel // Offset on the unit disk, spun for this pixel
float ssR; float ssR;
vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR); vec2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR);
ssR *= ssDiskRadius; ssR *= ssDiskRadius;
// The occluding point in camera space // The occluding point in camera space
vec3 Q = getOffsetPosition(ssC, unitOffset, ssR); vec3 Q = getOffsetPosition(ssC, unitOffset, ssR);
vec3 v = Q - C; vec3 v = Q - C;
float vv = dot(v, v); float vv = dot(v, v);
float vn = dot(v, n_C); float vn = dot(v, n_C);
const float epsilon = 0.01; const float epsilon = 0.01;
float radius2 = p_radius*p_radius; float radius2 = p_radius * p_radius;
// A: From the HPG12 paper // A: From the HPG12 paper
// Note large epsilon to avoid overdarkening within cracks // Note large epsilon to avoid overdarkening within cracks
//return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6; //return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended] // B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
float f=max(radius2 - vv, 0.0); float f = max(radius2 - vv, 0.0);
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0); return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
// C: Medium contrast (which looks better at high radii), no division. Note that the // C: Medium contrast (which looks better at high radii), no division. Note that the
// contribution still falls off with radius^2, but we've adjusted the rate in a way that is // contribution still falls off with radius^2, but we've adjusted the rate in a way that is
// more computationally efficient and happens to be aesthetically pleasing. // more computationally efficient and happens to be aesthetically pleasing.
// return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0); // return 4.0 * max(1.0 - vv * invRadius2, 0.0) * max(vn - bias, 0.0);
// D: Low contrast, no division operation // D: Low contrast, no division operation
// return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0); // return 2.0 * float(vv < radius * radius) * max(vn - bias, 0.0);
} }
void main() { void main() {
// Pixel being shaded // Pixel being shaded
ivec2 ssC = ivec2(gl_FragCoord.xy); ivec2 ssC = ivec2(gl_FragCoord.xy);
// World space point being shaded // World space point being shaded
vec3 C = getPosition(ssC); vec3 C = getPosition(ssC);
/* if (C.z <= -camera_z_far*0.999) { /*
// We're on the skybox if (C.z <= -camera_z_far * 0.999) {
visibility=1.0; // We're on the skybox
return; visibility=1.0;
}*/ return;
}
*/
//visibility=-C.z/camera_z_far; //visibility = -C.z / camera_z_far;
//return; //return;
#if 0 #if 0
vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; vec3 n_C = texelFetch(source_normal, ssC, 0).rgb * 2.0 - 1.0;
#else #else
vec3 n_C = reconstructCSFaceNormal(C); vec3 n_C = reconstructCSFaceNormal(C);
n_C = -n_C; n_C = -n_C;
@ -251,7 +236,7 @@ void main() {
#endif #endif
float sum = 0.0; float sum = 0.0;
for (int i = 0; i < NUM_SAMPLES; ++i) { for (int i = 0; i < NUM_SAMPLES; ++i) {
sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle); sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius, i, randomPatternRotationAngle);
} }
float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / float(NUM_SAMPLES))); float A = max(0.0, 1.0 - sum * intensity_div_r6 * (5.0 / float(NUM_SAMPLES)));
@ -271,10 +256,10 @@ void main() {
sum = 0.0; sum = 0.0;
for (int i = 0; i < NUM_SAMPLES; ++i) { for (int i = 0; i < NUM_SAMPLES; ++i) {
sum += sampleAO(ssC, C, n_C, ssDiskRadius,radius2, i, randomPatternRotationAngle); sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius2, i, randomPatternRotationAngle);
} }
A= min(A,max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES)))); A = min(A, max(0.0, 1.0 - sum * intensity_div_r62 * (5.0 / float(NUM_SAMPLES))));
#endif #endif
// Bilateral box-filter over a quad for free, respecting depth edges // Bilateral box-filter over a quad for free, respecting depth edges
// (the difference that this makes is subtle) // (the difference that this makes is subtle)
@ -286,8 +271,4 @@ void main() {
} }
visibility = A; visibility = A;
} }

View file

@ -1,26 +1,21 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib;
void main() { void main() {
gl_Position = vertex_attrib; gl_Position = vertex_attrib;
gl_Position.z=1.0; gl_Position.z = 1.0;
} }
[fragment] [fragment]
uniform sampler2D source_ssao; //texunit:0 uniform sampler2D source_ssao; //texunit:0
uniform sampler2D source_depth; //texunit:1 uniform sampler2D source_depth; //texunit:1
uniform sampler2D source_normal; //texunit:3 uniform sampler2D source_normal; //texunit:3
layout(location = 0) out float visibility; layout(location = 0) out float visibility;
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// Tunable Parameters: // Tunable Parameters:
@ -28,18 +23,18 @@ layout(location = 0) out float visibility;
uniform float edge_sharpness; uniform float edge_sharpness;
/** Step in 2-pixel intervals since we already blurred against neighbors in the /** Step in 2-pixel intervals since we already blurred against neighbors in the
first AO pass. This constant can be increased while R decreases to improve first AO pass. This constant can be increased while R decreases to improve
performance at the expense of some dithering artifacts. performance at the expense of some dithering artifacts.
Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was
unobjectionable after shading was applied but eliminated most temporal incoherence unobjectionable after shading was applied but eliminated most temporal incoherence
from using small numbers of sample taps. from using small numbers of sample taps.
*/ */
uniform int filter_scale; uniform int filter_scale;
/** Filter radius in pixels. This will be multiplied by SCALE. */ /** Filter radius in pixels. This will be multiplied by SCALE. */
#define R (4) #define R (4)
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
@ -47,13 +42,13 @@ uniform int filter_scale;
// Gaussian coefficients // Gaussian coefficients
const float gaussian[R + 1] = const float gaussian[R + 1] =
// float[](0.356642, 0.239400, 0.072410, 0.009869); // float[](0.356642, 0.239400, 0.072410, 0.009869);
// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0 // float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0 float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0 // float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
/** (1, 0) or (0, 1)*/ /** (1, 0) or (0, 1) */
uniform ivec2 axis; uniform ivec2 axis;
uniform float camera_z_far; uniform float camera_z_far;
uniform float camera_z_near; uniform float camera_z_near;
@ -65,18 +60,18 @@ void main() {
ivec2 ssC = ivec2(gl_FragCoord.xy); ivec2 ssC = ivec2(gl_FragCoord.xy);
float depth = texelFetch(source_depth, ssC, 0).r; float depth = texelFetch(source_depth, ssC, 0).r;
//vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0; //vec3 normal = texelFetch(source_normal, ssC, 0).rgb * 2.0 - 1.0;
depth = depth * 2.0 - 1.0; depth = depth * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float depth_divide = 1.0 / camera_z_far; float depth_divide = 1.0 / camera_z_far;
// depth*=depth_divide; //depth *= depth_divide;
/* /*
if (depth > camera_z_far*0.999) { if (depth > camera_z_far * 0.999) {
discard;//skybox discard; //skybox
} }
*/ */
@ -96,23 +91,21 @@ void main() {
if (r != 0) { if (r != 0) {
ivec2 ppos = ssC + axis * (r * filter_scale); ivec2 ppos = ssC + axis * (r * filter_scale);
float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r; float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit); ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
float temp_depth = texelFetch(source_depth, rpos, 0).r; float temp_depth = texelFetch(source_depth, rpos, 0).r;
//vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0; //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0;
temp_depth = temp_depth * 2.0 - 1.0; temp_depth = temp_depth * 2.0 - 1.0;
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near)); temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
// temp_depth *= depth_divide; //temp_depth *= depth_divide;
// spatial domain: offset gaussian tap // spatial domain: offset gaussian tap
float weight = 0.3 + gaussian[abs(r)]; float weight = 0.3 + gaussian[abs(r)];
//weight *= max(0.0,dot(temp_normal,normal)); //weight *= max(0.0, dot(temp_normal, normal));
// range domain (the "bilateral" weight). As depth difference increases, decrease weight. // range domain (the "bilateral" weight). As depth difference increases, decrease weight.
weight *= max(0.0, 1.0 weight *= max(0.0, 1.0 - edge_sharpness * abs(temp_depth - depth));
- edge_sharpness * abs(temp_depth - depth)
);
sum += value * weight; sum += value * weight;
totalWeight += weight; totalWeight += weight;

View file

@ -1,7 +1,6 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib;
void main() { void main() {
@ -10,7 +9,6 @@ void main() {
[fragment] [fragment]
#ifdef MINIFY_START #ifdef MINIFY_START
#define SDEPTH_TYPE highp sampler2D #define SDEPTH_TYPE highp sampler2D
@ -32,28 +30,23 @@ layout(location = 0) out mediump uint depth;
void main() { void main() {
ivec2 ssP = ivec2(gl_FragCoord.xy); ivec2 ssP = ivec2(gl_FragCoord.xy);
// Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling. // Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling.
// On DX9, the bit-and can be implemented with floating-point modulo // On DX9, the bit-and can be implemented with floating-point modulo
#ifdef MINIFY_START #ifdef MINIFY_START
float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
fdepth = fdepth * 2.0 - 1.0; fdepth = fdepth * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
fdepth = ((fdepth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; fdepth = ((fdepth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near)); fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near));
#endif #endif
fdepth /= camera_z_far; fdepth /= camera_z_far;
depth = uint(clamp(fdepth*65535.0,0.0,65535.0)); depth = uint(clamp(fdepth * 65535.0, 0.0, 65535.0));
#else #else
depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; depth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r;
#endif #endif
} }

View file

@ -1,12 +1,10 @@
[vertex] [vertex]
layout(location = 0) in highp vec4 vertex_attrib;
layout(location=0) in highp vec4 vertex_attrib; layout(location = 4) in vec2 uv_in;
layout(location=4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
void main() { void main() {
uv_interp = uv_in; uv_interp = uv_in;
@ -19,87 +17,77 @@ void main() {
#define QUALIFIER const #define QUALIFIER const
#ifdef USE_25_SAMPLES #ifdef USE_25_SAMPLES
const int kernel_size = 25;
const int kernel_size=25;
QUALIFIER vec2 kernel[25] = vec2[] ( QUALIFIER vec2 kernel[25] = vec2[] (
vec2(0.530605, 0.0), vec2(0.530605, 0.0),
vec2(0.000973794, -3.0), vec2(0.000973794, -3.0),
vec2(0.00333804, -2.52083), vec2(0.00333804, -2.52083),
vec2(0.00500364, -2.08333), vec2(0.00500364, -2.08333),
vec2(0.00700976, -1.6875), vec2(0.00700976, -1.6875),
vec2(0.0094389, -1.33333), vec2(0.0094389, -1.33333),
vec2(0.0128496, -1.02083), vec2(0.0128496, -1.02083),
vec2(0.017924, -0.75), vec2(0.017924, -0.75),
vec2(0.0263642, -0.520833), vec2(0.0263642, -0.520833),
vec2(0.0410172, -0.333333), vec2(0.0410172, -0.333333),
vec2(0.0493588, -0.1875), vec2(0.0493588, -0.1875),
vec2(0.0402784, -0.0833333), vec2(0.0402784, -0.0833333),
vec2(0.0211412, -0.0208333), vec2(0.0211412, -0.0208333),
vec2(0.0211412, 0.0208333), vec2(0.0211412, 0.0208333),
vec2(0.0402784, 0.0833333), vec2(0.0402784, 0.0833333),
vec2(0.0493588, 0.1875), vec2(0.0493588, 0.1875),
vec2(0.0410172, 0.333333), vec2(0.0410172, 0.333333),
vec2(0.0263642, 0.520833), vec2(0.0263642, 0.520833),
vec2(0.017924, 0.75), vec2(0.017924, 0.75),
vec2(0.0128496, 1.02083), vec2(0.0128496, 1.02083),
vec2(0.0094389, 1.33333), vec2(0.0094389, 1.33333),
vec2(0.00700976, 1.6875), vec2(0.00700976, 1.6875),
vec2(0.00500364, 2.08333), vec2(0.00500364, 2.08333),
vec2(0.00333804, 2.52083), vec2(0.00333804, 2.52083),
vec2(0.000973794, 3.0) vec2(0.000973794, 3.0)
); );
#endif //USE_25_SAMPLES #endif //USE_25_SAMPLES
#ifdef USE_17_SAMPLES #ifdef USE_17_SAMPLES
const int kernel_size = 17;
const int kernel_size=17;
QUALIFIER vec2 kernel[17] = vec2[]( QUALIFIER vec2 kernel[17] = vec2[](
vec2(0.536343, 0.0), vec2(0.536343, 0.0),
vec2(0.00317394, -2.0), vec2(0.00317394, -2.0),
vec2(0.0100386, -1.53125), vec2(0.0100386, -1.53125),
vec2(0.0144609, -1.125), vec2(0.0144609, -1.125),
vec2(0.0216301, -0.78125), vec2(0.0216301, -0.78125),
vec2(0.0347317, -0.5), vec2(0.0347317, -0.5),
vec2(0.0571056, -0.28125), vec2(0.0571056, -0.28125),
vec2(0.0582416, -0.125), vec2(0.0582416, -0.125),
vec2(0.0324462, -0.03125), vec2(0.0324462, -0.03125),
vec2(0.0324462, 0.03125), vec2(0.0324462, 0.03125),
vec2(0.0582416, 0.125), vec2(0.0582416, 0.125),
vec2(0.0571056, 0.28125), vec2(0.0571056, 0.28125),
vec2(0.0347317, 0.5), vec2(0.0347317, 0.5),
vec2(0.0216301, 0.78125), vec2(0.0216301, 0.78125),
vec2(0.0144609, 1.125), vec2(0.0144609, 1.125),
vec2(0.0100386, 1.53125), vec2(0.0100386, 1.53125),
vec2(0.00317394,2.0) vec2(0.00317394, 2.0)
); );
#endif //USE_17_SAMPLES #endif //USE_17_SAMPLES
#ifdef USE_11_SAMPLES #ifdef USE_11_SAMPLES
const int kernel_size = 11;
const int kernel_size=11;
QUALIFIER vec2 kernel[11] = vec2[]( QUALIFIER vec2 kernel[11] = vec2[](
vec2(0.560479, 0.0), vec2(0.560479, 0.0),
vec2(0.00471691, -2.0), vec2(0.00471691, -2.0),
vec2(0.0192831, -1.28), vec2(0.0192831, -1.28),
vec2(0.03639, -0.72), vec2(0.03639, -0.72),
vec2(0.0821904, -0.32), vec2(0.0821904, -0.32),
vec2(0.0771802, -0.08), vec2(0.0771802, -0.08),
vec2(0.0771802, 0.08), vec2(0.0771802, 0.08),
vec2(0.0821904, 0.32), vec2(0.0821904, 0.32),
vec2(0.03639, 0.72), vec2(0.03639, 0.72),
vec2(0.0192831, 1.28), vec2(0.0192831, 1.28),
vec2(0.00471691,2.0) vec2(0.00471691, 2.0)
); );
#endif //USE_11_SAMPLES #endif //USE_11_SAMPLES
uniform float max_radius; uniform float max_radius;
uniform float camera_z_far; uniform float camera_z_far;
uniform float camera_z_near; uniform float camera_z_near;
@ -115,28 +103,24 @@ layout(location = 0) out vec4 frag_color;
void main() { void main() {
float strength = texture(source_sss,uv_interp).r; float strength = texture(source_sss, uv_interp).r;
strength*=strength; //stored as sqrt strength *= strength; //stored as sqrt
// Fetch color of current pixel: // Fetch color of current pixel:
vec4 base_color = texture(source_diffuse, uv_interp); vec4 base_color = texture(source_diffuse, uv_interp);
if (strength > 0.0) {
if (strength>0.0) {
// Fetch linear depth of current pixel: // Fetch linear depth of current pixel:
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0; float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; depth = ((depth + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
float scale = unit_size; //remember depth is negative by default in OpenGL float scale = unit_size; //remember depth is negative by default in OpenGL
#else #else
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float scale = unit_size / depth; //remember depth is negative by default in OpenGL float scale = unit_size / depth; //remember depth is negative by default in OpenGL
#endif #endif
// Calculate the final step to fetch the surrounding pixels: // Calculate the final step to fetch the surrounding pixels:
vec2 step = max_radius * scale * dir; vec2 step = max_radius * scale * dir;
step *= strength; // Modulate it using the alpha channel. step *= strength; // Modulate it using the alpha channel.
@ -157,35 +141,33 @@ void main() {
#ifdef ENABLE_FOLLOW_SURFACE #ifdef ENABLE_FOLLOW_SURFACE
// If the difference in depth is huge, we lerp color back to "colorM": // If the difference in depth is huge, we lerp color back to "colorM":
float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0; float depth_cmp = texture(source_depth, offset).r * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION #ifdef USE_ORTHOGONAL_PROJECTION
depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near) / (camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near)) / 2.0;
#else #else
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near)); depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
#endif #endif
float s = clamp(300.0f * scale * float s = clamp(300.0f * scale * max_radius * abs(depth - depth_cmp), 0.0, 1.0);
max_radius * abs(depth - depth_cmp),0.0,1.0);
color = mix(color, base_color.rgb, s); color = mix(color, base_color.rgb, s);
#endif #endif
// Accumulate: // Accumulate:
color*=kernel[i].x; color *= kernel[i].x;
#ifdef ENABLE_STRENGTH_WEIGHTING #ifdef ENABLE_STRENGTH_WEIGHTING
float color_s = texture(source_sss, offset).r; float color_s = texture(source_sss, offset).r;
color_weight+=color_s * kernel[i].x; color_weight += color_s * kernel[i].x;
color*=color_s; color *= color_s;
#endif #endif
color_accum += color; color_accum += color;
} }
#ifdef ENABLE_STRENGTH_WEIGHTING #ifdef ENABLE_STRENGTH_WEIGHTING
color_accum/=color_weight; color_accum /= color_weight;
#endif #endif
frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO) frag_color = vec4(color_accum, base_color.a); //keep alpha (used for SSAO)
} else { } else {
frag_color = base_color; frag_color = base_color;
} }

View file

@ -1,25 +1,24 @@
[vertex] [vertex]
layout (location = 0) in highp vec4 vertex_attrib; layout(location = 0) in highp vec4 vertex_attrib;
layout (location = 4) in vec2 uv_in; layout(location = 4) in vec2 uv_in;
out vec2 uv_interp; out vec2 uv_interp;
void main() void main() {
{
gl_Position = vertex_attrib; gl_Position = vertex_attrib;
uv_interp = uv_in; uv_interp = uv_in;
#ifdef V_FLIP #ifdef V_FLIP
uv_interp.y = 1.0f - uv_interp.y; uv_interp.y = 1.0f - uv_interp.y;
#endif #endif
} }
[fragment] [fragment]
#if !defined(GLES_OVER_GL) #if !defined(GLES_OVER_GL)
precision mediump float; precision mediump float;
#endif #endif
in vec2 uv_interp; in vec2 uv_interp;
@ -30,109 +29,99 @@ uniform float exposure;
uniform float white; uniform float white;
#ifdef USE_AUTO_EXPOSURE #ifdef USE_AUTO_EXPOSURE
uniform highp sampler2D source_auto_exposure; //texunit:1 uniform highp sampler2D source_auto_exposure; //texunit:1
uniform highp float auto_exposure_grey; uniform highp float auto_exposure_grey;
#endif #endif
#if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7) #if defined(USE_GLOW_LEVEL1) || defined(USE_GLOW_LEVEL2) || defined(USE_GLOW_LEVEL3) || defined(USE_GLOW_LEVEL4) || defined(USE_GLOW_LEVEL5) || defined(USE_GLOW_LEVEL6) || defined(USE_GLOW_LEVEL7)
#define USING_GLOW // only use glow when at least one glow level is selected #define USING_GLOW // only use glow when at least one glow level is selected
uniform highp sampler2D source_glow; //texunit:2 uniform highp sampler2D source_glow; //texunit:2
uniform highp float glow_intensity; uniform highp float glow_intensity;
#endif #endif
#ifdef USE_BCS #ifdef USE_BCS
uniform vec3 bcs; uniform vec3 bcs;
#endif #endif
#ifdef USE_COLOR_CORRECTION #ifdef USE_COLOR_CORRECTION
uniform sampler2D color_correction; //texunit:3 uniform sampler2D color_correction; //texunit:3
#endif #endif
layout (location = 0) out vec4 frag_color; layout(location = 0) out vec4 frag_color;
#ifdef USE_GLOW_FILTER_BICUBIC #ifdef USE_GLOW_FILTER_BICUBIC
// w0, w1, w2, and w3 are the four cubic B-spline basis functions // w0, w1, w2, and w3 are the four cubic B-spline basis functions
float w0(float a) float w0(float a) {
{ return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f); }
}
float w1(float a) float w1(float a) {
{ return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f);
return (1.0f / 6.0f) * (a * a * (3.0f * a - 6.0f) + 4.0f); }
}
float w2(float a) float w2(float a) {
{ return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f);
return (1.0f / 6.0f) * (a * (a * (-3.0f * a + 3.0f) + 3.0f) + 1.0f); }
}
float w3(float a) float w3(float a) {
{ return (1.0f / 6.0f) * (a * a * a);
return (1.0f / 6.0f) * (a * a * a); }
}
// g0 and g1 are the two amplitude functions // g0 and g1 are the two amplitude functions
float g0(float a) float g0(float a) {
{ return w0(a) + w1(a);
return w0(a) + w1(a); }
}
float g1(float a) float g1(float a) {
{ return w2(a) + w3(a);
return w2(a) + w3(a); }
}
// h0 and h1 are the two offset functions // h0 and h1 are the two offset functions
float h0(float a) float h0(float a) {
{ return -1.0f + w1(a) / (w0(a) + w1(a));
return -1.0f + w1(a) / (w0(a) + w1(a)); }
}
float h1(float a) float h1(float a) {
{ return 1.0f + w3(a) / (w2(a) + w3(a));
return 1.0f + w3(a) / (w2(a) + w3(a)); }
}
uniform ivec2 glow_texture_size; uniform ivec2 glow_texture_size;
vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) {
{ float lod = float(p_lod);
float lod = float(p_lod); vec2 tex_size = vec2(glow_texture_size >> p_lod);
vec2 tex_size = vec2(glow_texture_size >> p_lod); vec2 pixel_size = vec2(1.0f) / tex_size;
vec2 pixel_size = vec2(1.0f) / tex_size;
uv = uv * tex_size + vec2(0.5f); uv = uv * tex_size + vec2(0.5f);
vec2 iuv = floor(uv); vec2 iuv = floor(uv);
vec2 fuv = fract(uv); vec2 fuv = fract(uv);
float g0x = g0(fuv.x); float g0x = g0(fuv.x);
float g1x = g1(fuv.x); float g1x = g1(fuv.x);
float h0x = h0(fuv.x); float h0x = h0(fuv.x);
float h1x = h1(fuv.x); float h1x = h1(fuv.x);
float h0y = h0(fuv.y); float h0y = h0(fuv.y);
float h1y = h1(fuv.y); float h1y = h1(fuv.y);
vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size; vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size;
vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size; vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size;
return g0(fuv.y) * (g0x * textureLod(tex, p0,lod) + return g0(fuv.y) * (g0x * textureLod(tex, p0, lod) +
g1x * textureLod(tex, p1,lod)) + g1x * textureLod(tex, p1, lod)) +
g1(fuv.y) * (g0x * textureLod(tex, p2,lod) + g1(fuv.y) * (g0x * textureLod(tex, p2, lod) +
g1x * textureLod(tex, p3,lod)); g1x * textureLod(tex, p3, lod));
} }
#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod)
#else #else
#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod)) #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod))
#endif #endif
vec3 tonemap_filmic(vec3 color, float white) vec3 tonemap_filmic(vec3 color, float white) {
{
const float A = 0.15f; const float A = 0.15f;
const float B = 0.50f; const float B = 0.50f;
const float C = 0.10f; const float C = 0.10f;
@ -147,8 +136,7 @@ vec3 tonemap_filmic(vec3 color, float white)
return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
} }
vec3 tonemap_aces(vec3 color, float white) vec3 tonemap_aces(vec3 color, float white) {
{
const float A = 2.51f; const float A = 2.51f;
const float B = 0.03f; const float B = 0.03f;
const float C = 2.43f; const float C = 2.43f;
@ -161,96 +149,90 @@ vec3 tonemap_aces(vec3 color, float white)
return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f));
} }
vec3 tonemap_reindhart(vec3 color, float white) vec3 tonemap_reindhart(vec3 color, float white) {
{
return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here!
} }
vec3 linear_to_srgb(vec3 color) // convert linear rgb to srgb, assumes clamped input in range [0;1] vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1]
{
const vec3 a = vec3(0.055f); const vec3 a = vec3(0.055f);
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
} }
vec3 apply_tonemapping(vec3 color, float white) // inputs are LINEAR, always outputs clamped [0;1] color vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color
{ #ifdef USE_REINDHART_TONEMAPPER
#ifdef USE_REINDHART_TONEMAPPER return tonemap_reindhart(color, white);
return tonemap_reindhart(color, white); #endif
#endif
#ifdef USE_FILMIC_TONEMAPPER #ifdef USE_FILMIC_TONEMAPPER
return tonemap_filmic(color, white); return tonemap_filmic(color, white);
#endif #endif
#ifdef USE_ACES_TONEMAPPER #ifdef USE_ACES_TONEMAPPER
return tonemap_aces(color, white); return tonemap_aces(color, white);
#endif #endif
return clamp(color, vec3(0.0f), vec3(1.0f)); // no other seleced -> linear return clamp(color, vec3(0.0f), vec3(1.0f)); // no other seleced -> linear
} }
vec3 gather_glow(sampler2D tex, vec2 uv) // sample all selected glow levels vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels
{
vec3 glow = vec3(0.0f); vec3 glow = vec3(0.0f);
#ifdef USE_GLOW_LEVEL1 #ifdef USE_GLOW_LEVEL1
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL2 #ifdef USE_GLOW_LEVEL2
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL3 #ifdef USE_GLOW_LEVEL3
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL4 #ifdef USE_GLOW_LEVEL4
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL5 #ifdef USE_GLOW_LEVEL5
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL6 #ifdef USE_GLOW_LEVEL6
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb;
#endif #endif
#ifdef USE_GLOW_LEVEL7 #ifdef USE_GLOW_LEVEL7
glow += GLOW_TEXTURE_SAMPLE(tex, uv, 7).rgb; glow += GLOW_TEXTURE_SAMPLE(tex, uv, 7).rgb;
#endif #endif
return glow; return glow;
} }
vec3 apply_glow(vec3 color, vec3 glow) // apply glow using the selected blending mode vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blending mode
{ #ifdef USE_GLOW_REPLACE
#ifdef USE_GLOW_REPLACE color = glow;
color = glow; #endif
#endif
#ifdef USE_GLOW_SCREEN #ifdef USE_GLOW_SCREEN
color = max((color + glow) - (color * glow), vec3(0.0)); color = max((color + glow) - (color * glow), vec3(0.0));
#endif #endif
#ifdef USE_GLOW_SOFTLIGHT #ifdef USE_GLOW_SOFTLIGHT
glow = glow * vec3(0.5f) + vec3(0.5f); glow = glow * vec3(0.5f) + vec3(0.5f);
color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r))); color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g))); color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g)));
color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b))); color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b)));
#endif #endif
#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive #if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) && !defined(USE_GLOW_REPLACE) // no other selected -> additive
color += glow; color += glow;
#endif #endif
return color; return color;
} }
vec3 apply_bcs(vec3 color, vec3 bcs) vec3 apply_bcs(vec3 color, vec3 bcs) {
{
color = mix(vec3(0.0f), color, bcs.x); color = mix(vec3(0.0f), color, bcs.x);
color = mix(vec3(0.5f), color, bcs.y); color = mix(vec3(0.5f), color, bcs.y);
color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z); color = mix(vec3(dot(vec3(1.0f), color) * 0.33333f), color, bcs.z);
@ -258,8 +240,7 @@ vec3 apply_bcs(vec3 color, vec3 bcs)
return color; return color;
} }
vec3 apply_color_correction(vec3 color, sampler2D correction_tex) vec3 apply_color_correction(vec3 color, sampler2D correction_tex) {
{
color.r = texture(correction_tex, vec2(color.r, 0.0f)).r; color.r = texture(correction_tex, vec2(color.r, 0.0f)).r;
color.g = texture(correction_tex, vec2(color.g, 0.0f)).g; color.g = texture(correction_tex, vec2(color.g, 0.0f)).g;
color.b = texture(correction_tex, vec2(color.b, 0.0f)).b; color.b = texture(correction_tex, vec2(color.b, 0.0f)).b;
@ -267,15 +248,14 @@ vec3 apply_color_correction(vec3 color, sampler2D correction_tex)
return color; return color;
} }
void main() void main() {
{
vec3 color = textureLod(source, uv_interp, 0.0f).rgb; vec3 color = textureLod(source, uv_interp, 0.0f).rgb;
// Exposure // Exposure
#ifdef USE_AUTO_EXPOSURE #ifdef USE_AUTO_EXPOSURE
color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey; color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / auto_exposure_grey;
#endif #endif
color *= exposure; color *= exposure;
@ -283,33 +263,33 @@ void main()
color = apply_tonemapping(color, white); color = apply_tonemapping(color, white);
#ifdef KEEP_3D_LINEAR #ifdef KEEP_3D_LINEAR
// leave color as is (-> don't convert to SRGB) // leave color as is (-> don't convert to SRGB)
#else #else
color = linear_to_srgb(color); // regular linear -> SRGB conversion color = linear_to_srgb(color); // regular linear -> SRGB conversion
#endif #endif
// Glow // Glow
#ifdef USING_GLOW #ifdef USING_GLOW
vec3 glow = gather_glow(source_glow, uv_interp) * glow_intensity; vec3 glow = gather_glow(source_glow, uv_interp) * glow_intensity;
// high dynamic range -> SRGB // high dynamic range -> SRGB
glow = apply_tonemapping(glow, white); glow = apply_tonemapping(glow, white);
glow = linear_to_srgb(glow); glow = linear_to_srgb(glow);
color = apply_glow(color, glow); color = apply_glow(color, glow);
#endif #endif
// Additional effects // Additional effects
#ifdef USE_BCS #ifdef USE_BCS
color = apply_bcs(color, bcs); color = apply_bcs(color, bcs);
#endif #endif
#ifdef USE_COLOR_CORRECTION #ifdef USE_COLOR_CORRECTION
color = apply_color_correction(color, color_correction); color = apply_color_correction(color, color_correction);
#endif #endif
frag_color = vec4(color, 1.0f); frag_color = vec4(color, 1.0f);
} }