SuperTuxKart 1.5 upstream source (from official release tarball)
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D dtex;
|
||||
uniform sampler2DShadow stex;
|
||||
uniform sampler2D albedo;
|
||||
uniform sampler2D ssao;
|
||||
uniform sampler2D ctex;
|
||||
|
||||
uniform int ssr;
|
||||
|
||||
#ifdef GL_ES
|
||||
layout (location = 0) out vec4 Diff;
|
||||
layout (location = 1) out vec4 Spec;
|
||||
#else
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#endif
|
||||
|
||||
#stk_include "utils/decodeNormal.frag"
|
||||
#stk_include "utils/encode_normal.frag"
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
#stk_include "utils/DiffuseIBL.frag"
|
||||
#stk_include "utils/SpecularIBL.frag"
|
||||
#stk_include "utils/screen_space_reflection.frag"
|
||||
|
||||
vec3 gtaoMultiBounce(float visibility, vec3 albedo)
|
||||
{
|
||||
// Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"
|
||||
vec3 a = 2.0404 * albedo - 0.3324;
|
||||
vec3 b = -4.7951 * albedo + 0.6417;
|
||||
vec3 c = 2.7552 * albedo + 0.6903;
|
||||
|
||||
return max(vec3(visibility), ((visibility * a + b) * visibility + c) * visibility);
|
||||
}
|
||||
|
||||
|
||||
// Main ===================================================================
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec3 normal = (u_view_matrix * vec4(DecodeNormal(texture(ntex, uv).xy), 0)).xyz;
|
||||
|
||||
float z = texture(dtex, uv).x;
|
||||
|
||||
vec4 xpos = getPosFromUVDepth(vec3(uv, z), u_inverse_projection_matrix);
|
||||
vec3 eyedir = -normalize(xpos.xyz);
|
||||
// Extract roughness
|
||||
float specval = texture(ntex, uv).z;
|
||||
|
||||
float ao = texture(ssao, uv).x;
|
||||
// Lagarde and de Rousiers 2014, "Moving Frostbite to PBR"
|
||||
float ao_spec = clamp(pow(max(dot(normal, eyedir), 0.) + ao, exp2(-16.0 * (1.0 - specval) - 1.0)) - 1.0 + ao, 0.0, 1.0);
|
||||
|
||||
if (ssr == 0)
|
||||
{
|
||||
Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.);
|
||||
Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval) * ao_spec, 1.);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 surface_color = texture(ctex, uv).xyz;
|
||||
vec3 ao_multi = gtaoMultiBounce(ao, surface_color);
|
||||
vec3 ao_spec_multi = gtaoMultiBounce(ao_spec, surface_color);
|
||||
|
||||
// :::::::: Compute Space Screen Reflection ::::::::::::::::::::::::::::::::::::
|
||||
|
||||
// Output color
|
||||
vec3 outColor;
|
||||
|
||||
// Fallback (if the ray can't find an intersection we display the sky)
|
||||
vec3 fallback = .25 * SpecularIBL(normal, eyedir, specval);
|
||||
|
||||
// Reflection vector
|
||||
vec3 reflected = reflect(-eyedir, normal);
|
||||
// Disable raycasts towards camera
|
||||
float cosine = dot(reflected, eyedir);
|
||||
|
||||
// Only calculate reflections if the reflectivity value is high enough,
|
||||
// otherwise just use specular IBL
|
||||
if (specval < 0.5 || cosine > 0.2) {
|
||||
outColor = fallback;
|
||||
} else {
|
||||
vec2 viewport_scale = vec2(1.0);
|
||||
vec2 viewport_offset = vec2(0.0);
|
||||
vec2 coords = RayCast(reflected, xpos.xyz, u_projection_matrix,
|
||||
viewport_scale, viewport_offset, stex);
|
||||
|
||||
if (coords.x < 0. || coords.x > 1. || coords.y < 0. || coords.y > 1.) {
|
||||
outColor = fallback;
|
||||
} else {
|
||||
// Disable raycasts onto another reflective surface
|
||||
float mirror = texture(ntex, coords).z;
|
||||
|
||||
outColor = textureLod(albedo, coords, 0.f).rgb;
|
||||
outColor = mix(fallback, outColor, GetEdgeFade(coords,
|
||||
viewport_scale, viewport_offset));
|
||||
outColor = mix(fallback, outColor, 1. - max(cosine * 5., 0.));
|
||||
outColor = mix(fallback, outColor, 4. - max(mirror * 4., 3.));
|
||||
// TODO temporary measure the lack of mipmapping for RTT albedo
|
||||
// Implement it in proper way
|
||||
// Use (specval - 0.5) * 2.0 to bring specval from 0.5-1.0 range to 0.0-1.0 range
|
||||
outColor = mix(fallback, outColor, (specval - 0.5) * 2.0);
|
||||
}
|
||||
}
|
||||
|
||||
Diff = vec4(0.25 * DiffuseIBL(normal) * ao_multi, 1.);
|
||||
Spec = vec4(outColor.rgb * ao_spec_multi, 1.0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Jorge Jimenez (jorge@iryoku.com)
|
||||
* Copyright (C) 2010 Belen Masia (bmasia@unizar.es)
|
||||
* Copyright (C) 2010 Jose I. Echevarria (joseignacioechevarria@gmail.com)
|
||||
* Copyright (C) 2010 Fernando Navarro (fernandn@microsoft.com)
|
||||
* Copyright (C) 2010 Diego Gutierrez (diegog@unizar.es)
|
||||
* Copyright (C) 2011 Lauri Kasanen (cand@gmx.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the following statement:
|
||||
*
|
||||
* "Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,
|
||||
* Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."
|
||||
*
|
||||
* Only for use in the Mesa project, this point 2 is filled by naming the
|
||||
* technique Jimenez's MLAA in the Mesa config options.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are
|
||||
* those of the authors and should not be interpreted as representing official
|
||||
* policies, either expressed or implied, of the copyright holders.
|
||||
*/
|
||||
@@ -0,0 +1,15 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 tc;
|
||||
in vec4 pc;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = texture(tex, tc) * pc;
|
||||
if (color.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
uniform int flips;
|
||||
uniform int sky;
|
||||
uniform vec3 view_position;
|
||||
uniform float billboard;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec4 color_lifetime;
|
||||
layout(location = 2) in vec2 size;
|
||||
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 4) in vec2 quadcorner;
|
||||
|
||||
layout(location = 6) in float anglespeed;
|
||||
#else
|
||||
|
||||
in vec3 Position;
|
||||
in vec4 color_lifetime;
|
||||
in vec2 size;
|
||||
|
||||
in vec2 Texcoord;
|
||||
in vec2 quadcorner;
|
||||
|
||||
in float anglespeed;
|
||||
#endif
|
||||
|
||||
out vec2 tc;
|
||||
out vec4 pc;
|
||||
|
||||
vec4 getQuat(float half_sin, float half_cos)
|
||||
{
|
||||
return normalize(vec4(vec3(0.0, 1.0, 0.0) * half_sin, half_cos));
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if (size.x == 0.0 && size.y == 0.0)
|
||||
{
|
||||
gl_Position = vec4(0.);
|
||||
pc = vec4(0.0);
|
||||
tc = vec2(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float lifetime = size.y;
|
||||
vec2 particle_size = mix(size.xx, size, billboard);
|
||||
tc = Texcoord;
|
||||
pc = color_lifetime.zyxw;
|
||||
|
||||
vec4 viewpos = vec4(0.);
|
||||
if (flips == 1 || sky == 1)
|
||||
{
|
||||
vec4 quat = vec4(0.0);
|
||||
if (flips == 1)
|
||||
{
|
||||
float angle = lifetime * anglespeed;
|
||||
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
||||
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
||||
quat = getQuat(sin_a, cos_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 diff = Position - view_position;
|
||||
float angle = atan(diff.x, diff.z);
|
||||
quat = getQuat(sin(angle / -2.0), cos(angle / -2.0));
|
||||
}
|
||||
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
|
||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewpos = u_view_matrix * vec4(Position, 1.0);
|
||||
viewpos += vec4(particle_size * quadcorner, 0.0, 0.0);
|
||||
}
|
||||
gl_Position = u_projection_matrix * viewpos;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D source;
|
||||
uniform sampler2D depth;
|
||||
uniform vec2 pixel;
|
||||
layout(r16f) volatile restrict writeonly uniform image2D dest;
|
||||
uniform float sigma = 2.;
|
||||
|
||||
layout (local_size_x = 4, local_size_y = 4) in;
|
||||
|
||||
shared float local_src[4 + 2 * 4][4];
|
||||
shared float local_depth[4 + 2 * 4][4];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(4, 0)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(4, 0)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m).x;
|
||||
local_depth[x][y] = texture(depth, uv_m).x;
|
||||
local_src[x + 4][y] = texture(source, uv).x;
|
||||
local_depth[x + 4][y] = texture(depth, uv).x;
|
||||
local_src[x + 8][y] = texture(source, uv_p).x;
|
||||
local_depth[x + 8][y] = texture(depth, uv_p).x;
|
||||
|
||||
barrier();
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
float sum = local_src[x + 4][y] * g0;
|
||||
float pixel_depth = local_depth[x + 4][y];
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
float tmp_weight, total_weight = g0;
|
||||
for (int j = 1; j < 5; j++) {
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(local_depth[4 + x - j][y] - pixel_depth));
|
||||
total_weight += g0 * tmp_weight;
|
||||
sum += local_src[4 + x - j][y] * g0 * tmp_weight;
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(local_depth[4 + x + j][y] - pixel_depth));
|
||||
total_weight += g0 * tmp_weight;
|
||||
sum += local_src[4 + x + j][y] * g0 * tmp_weight;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
imageStore(dest, iuv, vec4(sum / total_weight));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D depth;
|
||||
uniform vec2 pixel;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float sigma = 2.;
|
||||
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
float pixel_depth = texture(depth, vec2(X, Y)).x;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
float tmp_weight, total_weight = g0;
|
||||
for (int i = 1; i < 5; i++) {
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X - float(i) * pixel.x, Y)).x - pixel_depth));
|
||||
sum += texture(tex, vec2(X - float(i) * pixel.x, Y)) * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X + float(i) * pixel.x, Y)).x - pixel_depth));
|
||||
sum += texture(tex, vec2(X + float(i) * pixel.x, Y)) * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum / total_weight;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D source;
|
||||
uniform sampler2D depth;
|
||||
uniform vec2 pixel;
|
||||
layout(r16f) volatile restrict writeonly uniform image2D dest;
|
||||
uniform float sigma = 2.;
|
||||
|
||||
layout (local_size_x = 4, local_size_y = 4) in;
|
||||
|
||||
shared float local_src[4][4 + 2 * 4];
|
||||
shared float local_depth[4][4 + 2 * 4];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(0, 4)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(0, 4)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m).x;
|
||||
local_depth[x][y] = texture(depth, uv_m).x;
|
||||
local_src[x][y + 4] = texture(source, uv).x;
|
||||
local_depth[x][y + 4] = texture(depth, uv).x;
|
||||
local_src[x][y + 8] = texture(source, uv_p).x;
|
||||
local_depth[x][y + 8] = texture(depth, uv_p).x;
|
||||
|
||||
barrier();
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
float sum = local_src[x][y + 4] * g0;
|
||||
float pixel_depth = local_depth[x][y + 4];
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
float tmp_weight, total_weight = g0;
|
||||
for (int j = 1; j < 5; j++) {
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(local_depth[x][y + 4 + j] - pixel_depth));
|
||||
sum += local_src[x][y + 4 + j] * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(local_depth[x][y + 4 - j] - pixel_depth));
|
||||
sum += local_src[x][y + 4 - j] * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
|
||||
}
|
||||
imageStore(dest, iuv, vec4(sum / total_weight));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D depth;
|
||||
uniform vec2 pixel;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float sigma = 2.;
|
||||
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
float pixel_depth = texture(depth, vec2(X, Y)).x;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
float tmp_weight, total_weight = g0;
|
||||
for (int i = 1; i < 5; i++) {
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X, Y - float(i) * pixel.y)).x - pixel_depth));
|
||||
sum += texture(tex, vec2(X, Y - float(i) * pixel.y)) * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X, Y + float(i) * pixel.y)).x - pixel_depth));
|
||||
sum += texture(tex, vec2(X, Y + float(i) * pixel.y)) * g0 * tmp_weight;
|
||||
total_weight += g0 * tmp_weight;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum / total_weight;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float scale;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
#stk_include "utils/getCIEXYZ.frag"
|
||||
#stk_include "utils/getRGBfromCIEXxy.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / (512. * scale);
|
||||
vec3 col = texture(tex, uv).xyz;
|
||||
vec3 Yxy = getCIEYxy(col);
|
||||
vec3 WhiteYxy = getCIEYxy(vec3(1.));
|
||||
|
||||
Yxy.x = smoothstep(WhiteYxy.x, WhiteYxy.x * 4., Yxy.x);
|
||||
|
||||
FragColor = vec4(max(vec3(0.), getRGBFromCIEXxy(Yxy)), 1.0);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
uniform sampler2D tex_128;
|
||||
uniform sampler2D tex_256;
|
||||
uniform sampler2D tex_512;
|
||||
|
||||
uniform sampler2D tex_dust;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec4 col = .125 * texture(tex_128, uv);
|
||||
col += .25 * texture(tex_256, uv);
|
||||
col += .5 * texture(tex_512, uv);
|
||||
|
||||
/* Lens dust effect ---- */
|
||||
vec4 col2 = texture(tex_128, uv);
|
||||
col2 += col2;
|
||||
col2 += col2;
|
||||
//float dustMask = max(col2.r,max(col2.g,col2.b));
|
||||
col += texture(tex_dust, uv) * col2;
|
||||
|
||||
FragColor = vec4(col.xyz, 1.);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
uniform sampler2D source;
|
||||
layout(r32f) restrict writeonly uniform image2D dest;
|
||||
uniform vec2 pixel;
|
||||
uniform float weights[7];
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
shared float local_src[8 + 2 * 6][8];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(6, 0)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(6, 0)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m).x;
|
||||
local_src[x + 6][y] = texture(source, uv).x;
|
||||
local_src[x + 12][y] = texture(source, uv_p).x;
|
||||
|
||||
barrier();
|
||||
|
||||
float sum = local_src[x + 6][y] * weights[0];
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += local_src[6 + x - i][y] * weights[i];
|
||||
sum += local_src[6 + x + i][y] * weights[i];
|
||||
}
|
||||
|
||||
imageStore(dest, iuv, vec4(sum));
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
uniform sampler2D source;
|
||||
layout(r32f) restrict writeonly uniform image2D dest;
|
||||
uniform vec2 pixel;
|
||||
uniform float weights[7];
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
shared float local_src[8][8 + 2 * 6];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(0, 6)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(0, 6)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m).x;
|
||||
local_src[x][y + 6] = texture(source, uv).x;
|
||||
local_src[x][y + 12] = texture(source, uv_p).x;
|
||||
|
||||
barrier();
|
||||
|
||||
float sum = local_src[x][y + 6] * weights[0];
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += local_src[x][6 + y - i] * weights[i];
|
||||
sum += local_src[x][6 + y + i] * weights[i];
|
||||
}
|
||||
|
||||
imageStore(dest, iuv, vec4(sum));
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
uniform ivec4 color;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(color) / 255.;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec2 Position;
|
||||
#else
|
||||
in vec2 Position;
|
||||
#endif
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
uniform vec3 col;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(col, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture(tex, uv);
|
||||
FragColor = res * color;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
uniform vec2 texcenter;
|
||||
uniform vec2 texsize;
|
||||
uniform float rotation;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location=0) in vec2 Position;
|
||||
layout(location=3) in vec2 Texcoord;
|
||||
layout(location=2) in vec4 Color;
|
||||
#else
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec4 Color;
|
||||
#endif
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
color = Color.zyxw;
|
||||
uv = Texcoord * texsize + texcenter;
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
uniform sampler2D diffuse_map;
|
||||
uniform sampler2D specular_map;
|
||||
uniform sampler2D normal_color;
|
||||
uniform sampler2D diffuse_color;
|
||||
#if defined(GL_ES) && defined(GL_FRAGMENT_PRECISION_HIGH)
|
||||
uniform highp sampler2D depth_stencil;
|
||||
#else
|
||||
uniform sampler2D depth_stencil;
|
||||
#endif
|
||||
uniform sampler2D light_scatter;
|
||||
|
||||
uniform vec4 bg_color;
|
||||
|
||||
out vec4 o_final_color;
|
||||
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = gl_FragCoord.xy / u_screen;
|
||||
vec4 diffuseMatColor = texture(diffuse_color, tc);
|
||||
|
||||
// Polish map is stored in normal color framebuffer .z
|
||||
// Metallic map is stored in normal color framebuffer .w
|
||||
// Emit map is stored in diffuse color framebuffer.w
|
||||
float metallicMapValue = texture(normal_color, tc).w;
|
||||
float specMapValue = texture(normal_color, tc).z;
|
||||
float emitMapValue = diffuseMatColor.w;
|
||||
|
||||
vec3 DiffuseComponent = texture(diffuse_map, tc).xyz;
|
||||
vec3 SpecularComponent = texture(specular_map, tc).xyz;
|
||||
|
||||
vec3 diffuse_color_for_mix = diffuseMatColor.xyz * 4.0;
|
||||
|
||||
// FIXME enable this once the fallback shader is properly done!!!
|
||||
//vec3 metallicMatColor = mix(vec3(specMapValue), diffuse_color_for_mix, metallicMapValue);
|
||||
vec3 metallicMatColor = mix(vec3(0.04), diffuse_color_for_mix, metallicMapValue);
|
||||
// END FIXME
|
||||
|
||||
vec3 tmp = DiffuseComponent * mix(diffuseMatColor.xyz, vec3(0.0), metallicMapValue) + (metallicMatColor * SpecularComponent);
|
||||
|
||||
vec3 emitCol = diffuseMatColor.xyz + (diffuseMatColor.xyz * diffuseMatColor.xyz * emitMapValue * emitMapValue * 10.0);
|
||||
vec4 color_1 = vec4(tmp + (emitMapValue * emitCol), 1.0);
|
||||
|
||||
// Fog
|
||||
float depth = texture(depth_stencil, tc).x;
|
||||
vec4 xpos = getPosFromUVDepth(vec3(tc, depth), u_inverse_projection_matrix);
|
||||
float dist = length(xpos.xyz);
|
||||
// fog density
|
||||
float factor = (1.0 - exp(u_fog_data.w * dist));
|
||||
vec3 fog = u_fog_color.xyz * factor;
|
||||
|
||||
// Additively blend the color by fog
|
||||
color_1 = color_1 + vec4(fog, factor);
|
||||
|
||||
// For skybox blending later
|
||||
if (depth == 1.0)
|
||||
{
|
||||
color_1 = bg_color;
|
||||
}
|
||||
|
||||
// Light scatter (alpha blend function: (GL_ONE, GL_ONE_MINUS_SRC_ALPHA))
|
||||
vec4 ls = texture(light_scatter, tc);
|
||||
vec4 color_2;
|
||||
color_2.r = ls.r + color_1.r * (1.0 - ls.a);
|
||||
color_2.g = ls.g + color_1.g * (1.0 - ls.a);
|
||||
color_2.b = ls.b + color_1.b * (1.0 - ls.a);
|
||||
color_2.a = ls.a + color_1.a * (1.0 - ls.a);
|
||||
o_final_color = color_2;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
uniform sampler2D ntex;
|
||||
uniform sampler2D ssao;
|
||||
|
||||
#ifdef GL_ES
|
||||
layout (location = 0) out vec4 Diff;
|
||||
layout (location = 1) out vec4 Spec;
|
||||
#else
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#endif
|
||||
|
||||
#stk_include "utils/decodeNormal.frag"
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
#stk_include "utils/DiffuseIBL.frag"
|
||||
#stk_include "utils/SpecularIBL.frag"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec3 normal = DecodeNormal(texture(ntex, uv).xy);
|
||||
vec3 spec_color = vec3(0.031, 0.106, 0.173);
|
||||
float ao = texture(ssao, uv).x;
|
||||
|
||||
Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.);
|
||||
Spec = vec4(spec_color * ao, 1.);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
float focalDepth = 10.;
|
||||
float maxblur = 1.;
|
||||
float range = 100.;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
float curdepth = texture(dtex, uv).x;
|
||||
vec4 FragPos = u_inverse_projection_matrix * (2.0 * vec4(uv, curdepth, 1.0) - 1.0);
|
||||
FragPos /= FragPos.w;
|
||||
|
||||
float depth = FragPos.z;
|
||||
float blur = clamp(abs(depth - focalDepth) / range, -maxblur, maxblur);
|
||||
|
||||
vec2 offset = 10. / u_screen;
|
||||
|
||||
vec4 col = texture(tex, uv);
|
||||
vec4 colOriginal = col;
|
||||
// Weight from here http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html
|
||||
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.29,0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.37,0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur);
|
||||
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur);
|
||||
|
||||
col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9);
|
||||
col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9);
|
||||
|
||||
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7);
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7);
|
||||
|
||||
col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4);
|
||||
col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4);
|
||||
|
||||
col = vec4(col.rgb / 41.0, col.a);
|
||||
depth = clamp(max(1.1666 - (FragPos.z/240.0), FragPos.z - 2000.0), 0., 1.);
|
||||
|
||||
vec3 final = colOriginal.rgb * depth + col.rgb * (1. - depth);
|
||||
|
||||
FragColor = vec4(final, colOriginal.a);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
uniform int idx;
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = u_shadow_projection_view_matrices[idx] * vec4(Position, 1.);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125;
|
||||
|
||||
FragColor = sum;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
|
||||
// Gaussian separated blur with radius 3.
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
vec4 sum = vec4(0.0);
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
sum += texture(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125;
|
||||
sum += texture(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y)) * 0.273438;
|
||||
sum += texture(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125;
|
||||
sum += texture(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125;
|
||||
|
||||
FragColor = sum;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
uniform sampler2D source;
|
||||
layout(rgba16f) restrict writeonly uniform image2D dest;
|
||||
uniform vec2 pixel;
|
||||
uniform float weights[7];
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
shared vec4 local_src[8 + 2 * 6][8];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(6, 0)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(6, 0)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m);
|
||||
local_src[x + 6][y] = texture(source, uv);
|
||||
local_src[x + 12][y] = texture(source, uv_p);
|
||||
|
||||
barrier();
|
||||
|
||||
vec4 sum = local_src[x + 6][y] * weights[0];
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += local_src[6 + x - i][y] * weights[i];
|
||||
sum += local_src[6 + x + i][y] * weights[i];
|
||||
}
|
||||
|
||||
imageStore(dest, iuv, sum);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += texture(tex, vec2(X - float(i) * pixel.x, Y)) * g0;
|
||||
sum += texture(tex, vec2(X + float(i) * pixel.x, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
uniform sampler2D source;
|
||||
layout(rgba16f) restrict writeonly uniform image2D dest;
|
||||
uniform vec2 pixel;
|
||||
uniform float weights[7];
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
layout (local_size_x = 8, local_size_y = 8) in;
|
||||
|
||||
shared vec4 local_src[8][8 + 2 * 6];
|
||||
|
||||
void main()
|
||||
{
|
||||
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
|
||||
ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
|
||||
vec2 uv_m = (iuv - ivec2(0, 6)) * pixel;
|
||||
vec2 uv = iuv * pixel;
|
||||
vec2 uv_p = (iuv + ivec2(0, 6)) * pixel;
|
||||
|
||||
local_src[x][y] = texture(source, uv_m);
|
||||
local_src[x][y + 6] = texture(source, uv);
|
||||
local_src[x][y + 12] = texture(source, uv_p);
|
||||
|
||||
barrier();
|
||||
|
||||
vec4 sum = local_src[x][y + 6] * weights[0];
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += local_src[x][6 + y - i] * weights[i];
|
||||
sum += local_src[x][6 + y + i] * weights[i];
|
||||
}
|
||||
|
||||
imageStore(dest, iuv, sum);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 pixel;
|
||||
uniform float sigma;
|
||||
|
||||
// Gaussian separated blur with radius 6.
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy * pixel;
|
||||
float X = uv.x;
|
||||
float Y = uv.y;
|
||||
|
||||
float g0, g1, g2;
|
||||
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
|
||||
g1 = exp(-0.5 / (sigma * sigma));
|
||||
g2 = g1 * g1;
|
||||
vec4 sum = texture(tex, vec2(X, Y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
for (int i = 1; i < 6; i++) {
|
||||
sum += texture(tex, vec2(X, Y - float(i) * pixel.y)) * g0;
|
||||
sum += texture(tex, vec2(X, Y + float(i) * pixel.y)) * g0;
|
||||
g0 *= g1;
|
||||
g1 *= g2;
|
||||
}
|
||||
|
||||
FragColor = sum;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
layout(location = 0) in vec4 f_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 2) flat in int f_sampler_index;
|
||||
|
||||
#ifdef BIND_TEXTURES_AT_ONCE
|
||||
layout(binding = 0) uniform sampler2D f_tex[SAMPLER_SIZE];
|
||||
#else
|
||||
layout(binding = 0) uniform sampler2D f_tex;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef BIND_TEXTURES_AT_ONCE
|
||||
vec4 tex_color = texture(f_tex[GE_SAMPLE_TEX_INDEX(f_sampler_index)], f_uv);
|
||||
#else
|
||||
vec4 tex_color = texture(f_tex, f_uv);
|
||||
#endif
|
||||
o_color = tex_color * f_color;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
layout(location = 0) in vec2 v_position;
|
||||
layout(location = 1) in vec4 v_color;
|
||||
layout(location = 2) in vec2 v_uv;
|
||||
layout(location = 3) in int v_sampler_index;
|
||||
|
||||
layout(location = 0) out vec4 f_color;
|
||||
layout(location = 1) out vec2 f_uv;
|
||||
layout(location = 2) flat out int f_sampler_index;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||
f_color = v_color.zyxw;
|
||||
f_uv = v_uv;
|
||||
f_sampler_index = v_sampler_index;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 4) in float f_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
#ifdef PBR_ENABLED
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
if (tex_color.a * f_vertex_color.a < 0.5)
|
||||
discard;
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
vec2 new_xy = vec2(f_hue_change, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, tex_color.a);
|
||||
}
|
||||
#ifndef PBR_ENABLED
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
o_color = vec4(mixed_color, 1.0);
|
||||
#else
|
||||
vec3 diffuse_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
vec3 normal = normalize(f_normal.xyz);
|
||||
vec3 pbr = sampleMeshTexture2(f_material_id, f_uv).xyz;
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(diffuse_color, pbr.z);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = pbr.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(handlePBR(diffuse_color, pbr, f_world_position, normal),
|
||||
1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
if (tex_color.a * f_vertex_color.a < 0.5)
|
||||
discard;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 2) in vec2 f_uv_two;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
#ifdef PBR_ENABLED
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#ifdef PBR_ENABLED
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
vec4 layer_two_tex = sampleMeshTexture1(f_material_id, f_uv_two);
|
||||
layer_two_tex.rgb = layer_two_tex.a * layer_two_tex.rgb;
|
||||
vec3 final_color = layer_two_tex.rgb + color.rgb * (1.0 - layer_two_tex.a);
|
||||
#ifndef PBR_ENABLED
|
||||
o_color = vec4(final_color, 1.0);
|
||||
#else
|
||||
vec3 normal = normalize(f_normal.xyz);
|
||||
vec3 pbr = sampleMeshTexture2(f_material_id, f_uv).xyz;
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(final_color, pbr.z);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = pbr.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(handlePBR(final_color, pbr, f_world_position, normal),
|
||||
1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
layout (input_attachment_index = 0, binding = 0) uniform subpassInput u_hdr;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/constants_utils.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
o_color = vec4(convertColor(subpassLoad(u_hdr).xyz), 1.0);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
layout (input_attachment_index = 0, binding = 0) uniform subpassInput u_color;
|
||||
layout (input_attachment_index = 1, binding = 1) uniform subpassInput u_normal;
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInput u_depth;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
int m_fullscreen_light_count;
|
||||
} u_push_constants;
|
||||
|
||||
#include "utils/unproject_position.glsl"
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/decodeNormal.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
float depth = subpassLoad(u_depth).x;
|
||||
if (!u_has_skybox && depth == 1.0)
|
||||
discard;
|
||||
vec3 diffuse_color = subpassLoad(u_color).xyz;
|
||||
vec3 pbr = vec3(subpassLoad(u_normal).zw, subpassLoad(u_color).w);
|
||||
vec3 world_normal = DecodeNormal(subpassLoad(u_normal).xy);
|
||||
vec3 xpos = getPosFromUVDepth(vec3(gl_FragCoord.xy, depth),
|
||||
u_camera.m_viewport, u_camera.m_inverse_projection_matrix);
|
||||
vec3 eyedir = -normalize(xpos);
|
||||
vec3 normal = (u_camera.m_view_matrix * vec4(world_normal, 0.0)).xyz;
|
||||
vec3 hdr = handlePBRDeferred(diffuse_color, pbr, world_normal, eyedir,
|
||||
normal, 1.0 - pbr.x);
|
||||
hdr += accumulateLights(u_push_constants.m_fullscreen_light_count,
|
||||
diffuse_color, normal, xpos, eyedir, 1.0 - pbr.x, pbr.y);
|
||||
o_color = vec4(hdr, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
layout (input_attachment_index = 0, binding = 0) uniform subpassInput u_color;
|
||||
layout (input_attachment_index = 1, binding = 1) uniform subpassInput u_normal;
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInput u_depth;
|
||||
|
||||
layout(location = 0) flat in int light_idx;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/unproject_position.glsl"
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/decodeNormal.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
float depth = subpassLoad(u_depth).x;
|
||||
if (depth == 1.0)
|
||||
{
|
||||
o_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
vec3 diffuse_color = subpassLoad(u_color).xyz;
|
||||
vec3 pbr = vec3(subpassLoad(u_normal).zw, subpassLoad(u_color).w);
|
||||
vec3 world_normal = DecodeNormal(subpassLoad(u_normal).xy);
|
||||
vec3 xpos = getPosFromUVDepth(vec3(gl_FragCoord.xy, depth),
|
||||
u_camera.m_viewport, u_camera.m_inverse_projection_matrix);
|
||||
vec3 eyedir = -normalize(xpos);
|
||||
vec3 normal = (u_camera.m_view_matrix * vec4(world_normal, 0.0)).xyz;
|
||||
vec3 light = calculateLight(light_idx, diffuse_color, normal, xpos,
|
||||
eyedir, 1.0 - pbr.x, pbr.y);
|
||||
o_color = vec4(light, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/global_light_data.glsl"
|
||||
#include "utils/spm_data.glsl"
|
||||
#include "../utils/get_world_location.vert"
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 m_billboard_rotation;
|
||||
int m_fullscreen_light;
|
||||
} u_push_constants;
|
||||
|
||||
layout(location = 0) flat out int light_idx;
|
||||
|
||||
const vec3 g_vertices[4] =
|
||||
vec3[]
|
||||
(
|
||||
vec3( 1.0, 1.0, 0.0),
|
||||
vec3( 1.0, -1.0, 0.0),
|
||||
vec3(-1.0, 1.0, 0.0),
|
||||
vec3(-1.0, -1.0, 0.0)
|
||||
);
|
||||
|
||||
void main()
|
||||
{
|
||||
// Get the light index from the instance ID
|
||||
light_idx = gl_InstanceIndex + u_push_constants.m_fullscreen_light;
|
||||
LightData light = u_global_light.m_lights[light_idx];
|
||||
vec4 pos_radius = light.m_position_radius;
|
||||
|
||||
// Get camera position from inverse view matrix
|
||||
vec3 camera_pos = vec3(u_camera.m_inverse_view_matrix[3]);
|
||||
|
||||
// Calculate vector from light to camera
|
||||
vec3 light_to_camera = normalize(camera_pos - pos_radius.xyz);
|
||||
|
||||
/* The lights which cover the whole screen have been rendered already
|
||||
// Calculate distance from light to camera
|
||||
float dist_to_camera = distance(camera_pos, pos_radius.xyz);
|
||||
|
||||
// If camera is within light radius, move the billboard quad towards the
|
||||
// near plane
|
||||
if (dist_to_camera < pos_radius.w)
|
||||
{
|
||||
gl_Position = vec4(g_vertices[gl_VertexIndex], 1.0);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// Move the billboard towards camera by one radius unit
|
||||
vec4 world_pos = getWorldPosition(
|
||||
pos_radius.xyz + light_to_camera * pos_radius.w,
|
||||
u_push_constants.m_billboard_rotation,
|
||||
vec3(pos_radius.w), g_vertices[gl_VertexIndex]);
|
||||
vec4 pv = u_camera.m_projection_view_matrix * world_pos;
|
||||
if (pv.z < 0.0)
|
||||
gl_Position = vec4(pv.xy, 0.0, 1.0);
|
||||
else
|
||||
gl_Position = pv;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
void main()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
// Binding for the input skybox cubemap.
|
||||
layout(set = 0, binding = 0) uniform samplerCube uSkybox;
|
||||
// Binding for the output irradiance (diffuse) cube map stored as a 2D array (each layer is one face).
|
||||
#ifdef SHADER_STORAGE_IMAGE_EXTENDED_FORMATS
|
||||
layout(set = 0, binding = 1, rgb10_a2) uniform restrict writeonly image2DArray uIrradianceMap;
|
||||
#else
|
||||
layout(set = 0, binding = 1, rgba8) uniform restrict writeonly image2DArray uIrradianceMap;
|
||||
#endif
|
||||
|
||||
#include "utils/environment_map.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 pix = ivec2(gl_GlobalInvocationID.xy);
|
||||
if (pix.x >= pc.size || pix.y >= pc.size) return;
|
||||
|
||||
// Get normalized UV for current pixel.
|
||||
vec2 uv = (vec2(pix) + 0.5) / vec2(pc.size, pc.size);
|
||||
int face = int(gl_GlobalInvocationID.z);
|
||||
vec3 normal = FaceUVtoDir(face, uv);
|
||||
|
||||
// Establish a tangent space basis.
|
||||
vec3 up = abs(normal.y) < 0.999 ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 right = normalize(cross(up, normal));
|
||||
vec3 tangent = cross(normal, right);
|
||||
|
||||
vec3 irradiance = vec3(0.0);
|
||||
float weight = 0.0;
|
||||
uint sampleCount = uint(pc.sampleCount);
|
||||
|
||||
for (uint i = 0u; i < sampleCount; i++)
|
||||
{
|
||||
vec2 xi = Hammersley(i, sampleCount);
|
||||
// Cosine-weighted hemisphere sampling.
|
||||
float phi = 2.0 * PI * xi.x;
|
||||
float cosTheta = sqrt(1.0 - xi.y); // weight factor equals cos(theta)
|
||||
float sinTheta = sqrt(xi.y);
|
||||
vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
|
||||
|
||||
// Transform sample direction from tangent space to world space.
|
||||
vec3 sampleVec = normalize(right * sampleDir.x + tangent * sampleDir.y + normal * sampleDir.z);
|
||||
|
||||
vec3 sampleColor = texture(uSkybox, sampleVec).rgb;
|
||||
irradiance += sampleColor * cosTheta;
|
||||
weight += cosTheta;
|
||||
}
|
||||
irradiance /= weight;
|
||||
|
||||
imageStore(uIrradianceMap, ivec3(pix, face), vec4(irradiance, 1.0));
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
layout(binding = 0) uniform sampler2D u_displace_mask;
|
||||
layout(binding = 2) uniform sampler2D u_displace_color;
|
||||
|
||||
layout(location = 0) in vec2 f_uv;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
bool m_has_displace;
|
||||
} u_push_constants;
|
||||
|
||||
#include "utils/camera.glsl"
|
||||
#include "../utils/displace_utils.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef PBR_ENABLED
|
||||
ivec2 uv = ivec2(gl_FragCoord.xy);
|
||||
if (u_push_constants.m_has_displace)
|
||||
{
|
||||
vec2 mask = texelFetch(u_displace_mask, uv, 0).xy;
|
||||
if (!(mask.x == 0.0 && mask.y == 0.0))
|
||||
{
|
||||
vec2 shift = 2.0 * mask - 1.0;
|
||||
uv = getDisplaceUV(shift, u_camera.m_viewport, u_displace_mask);
|
||||
}
|
||||
}
|
||||
o_color = texelFetch(u_displace_color, uv, 0);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
|
||||
layout(location = 0) out vec2 o_displace_mask;
|
||||
layout(location = 1) out vec4 o_displace_ssr;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 m_displace_direction;
|
||||
} u_push_constants;
|
||||
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/constants_utils.glsl"
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/displace_utils.frag"
|
||||
#include "../utils/screen_space_reflection.frag"
|
||||
|
||||
layout (set = 2, binding = 2) uniform samplerCube u_skybox_texture;
|
||||
layout (set = 3, binding = 0) uniform sampler2D u_displace_color;
|
||||
layout (set = 3, binding = 1) uniform sampler2DShadow u_depth;
|
||||
layout (set = 3, binding = 2) uniform sampler2D u_hiz_depth;
|
||||
|
||||
#ifdef PBR_ENABLED
|
||||
|
||||
// Start tracing in this level.
|
||||
#define HIZ_START_LEVEL 0
|
||||
// Stop tracing if current level is higher than this. (higher level means lower value)
|
||||
#define HIZ_STOP_LEVEL 0
|
||||
#define HIZ_MAX_LEVEL 6
|
||||
|
||||
// Set to 1 to disable HiZ and perform naive linear search.
|
||||
#define DEBUG_LINEAR_SEARCH 0
|
||||
#define MAX_THICKNESS 0.001
|
||||
|
||||
vec3 intersectDepthPlane(vec3 o, vec3 d, float z)
|
||||
{
|
||||
return o + d * z;
|
||||
}
|
||||
|
||||
// Index of the cell that contains the given 2D position.
|
||||
ivec2 getCell(vec2 screenUV, ivec2 cellCount)
|
||||
{
|
||||
return ivec2(screenUV * cellCount);
|
||||
}
|
||||
|
||||
// The number of cells in the quad tree at the given level.
|
||||
ivec2 getCellCount(int level)
|
||||
{
|
||||
return textureSize(u_hiz_depth, level);
|
||||
}
|
||||
|
||||
// Returns screen space position of the intersection
|
||||
// between o + d*t and the closest cell boundary at current HiZ level.
|
||||
vec3 intersectCellBoundary(
|
||||
vec3 pos, vec3 dir,
|
||||
ivec2 cell, ivec2 cellCount,
|
||||
vec2 crossStep, vec2 crossOffset)
|
||||
{
|
||||
vec3 intersection = vec3(0.0);
|
||||
|
||||
vec2 index = cell + crossStep;
|
||||
vec2 boundary = index / vec2(cellCount); // Screen space position of the boundary
|
||||
boundary += crossOffset;
|
||||
|
||||
vec2 delta = boundary - pos.xy;
|
||||
delta /= dir.xy;
|
||||
float t = min(delta.x, delta.y);
|
||||
|
||||
intersection = intersectDepthPlane(pos, dir, t);
|
||||
return intersection;
|
||||
}
|
||||
|
||||
bool crossedCellBoundary(ivec2 oldCellIx, ivec2 newCellIx)
|
||||
{
|
||||
return any(notEqual(oldCellIx, newCellIx));
|
||||
}
|
||||
|
||||
// Minimum depth of the current cell in the current HiZ level.
|
||||
float getMinDepthPlane(ivec2 cellIx, int level)
|
||||
{
|
||||
return texelFetch(u_hiz_depth, cellIx, level).x;
|
||||
}
|
||||
|
||||
float getMaxTraceDistance(vec3 p, vec3 v)
|
||||
{
|
||||
vec3 traceDistances;
|
||||
if (v.x < 0.0)
|
||||
traceDistances.x = p.x / (-v.x);
|
||||
else
|
||||
traceDistances.x = (1.0 - p.x) / v.x;
|
||||
|
||||
if (v.y < 0.0)
|
||||
traceDistances.y = p.y / (-v.y);
|
||||
else
|
||||
traceDistances.y = (1.0 - p.y) / v.y;
|
||||
|
||||
if (v.z < 0.0)
|
||||
traceDistances.z = p.z / (-v.z);
|
||||
else
|
||||
traceDistances.z = (1.0 - p.z) / v.z;
|
||||
|
||||
return min(traceDistances.x, min(traceDistances.y, traceDistances.z));
|
||||
}
|
||||
|
||||
// p : Screen space position
|
||||
// v : Screen space reflection direction
|
||||
// hitPointSS : Returns screen space hit point
|
||||
// Return value : Whether RT actually hit a surface
|
||||
bool traceHiZ(vec3 p, vec3 v, out vec2 hitPointSS)
|
||||
{
|
||||
const int maxLevel = min(HIZ_MAX_LEVEL, textureQueryLevels(u_hiz_depth) - 1); // Last mip level
|
||||
float maxTraceDistance = getMaxTraceDistance(p, v);
|
||||
|
||||
// Get the cell cross direction and a small offset to enter
|
||||
// the next cell when doing cell crossing.
|
||||
vec2 crossStep = vec2(v.x >= 0 ? 1 : -1, v.y >= 0 ? 1 : -1);
|
||||
vec2 crossOffset = crossStep / u_camera.m_viewport.zw / 128.;
|
||||
crossStep = clamp(crossStep, 0.0, 1.0);
|
||||
|
||||
// Set current ray to the original screen coordinate and depth.
|
||||
vec3 ray = p;
|
||||
float minZ = ray.z;
|
||||
float maxZ = ray.z + v.z * maxTraceDistance;
|
||||
float deltaZ = maxZ - minZ;
|
||||
|
||||
vec3 o = ray;
|
||||
vec3 d = v * maxTraceDistance;
|
||||
|
||||
int level = HIZ_START_LEVEL;
|
||||
int deepestLevel = level;
|
||||
#if DEBUG_LINEAR_SEARCH
|
||||
level = 0;
|
||||
#endif
|
||||
uint iterations = 0;
|
||||
bool isBackwardRay = v.z < 0;
|
||||
float rayDir = isBackwardRay ? -1.0 : 1.0;
|
||||
|
||||
// Cross to next cell s.t. we don't get a self-intersection immediately.
|
||||
ivec2 startCellCount = getCellCount(level);
|
||||
ivec2 rayCell = getCell(ray.xy, startCellCount);
|
||||
ray = intersectCellBoundary(o, d, rayCell, startCellCount, crossStep, crossOffset * 64.);
|
||||
|
||||
while (level >= HIZ_STOP_LEVEL && ray.z * rayDir <= maxZ * rayDir &&
|
||||
iterations < u_hiz_iterations)
|
||||
{
|
||||
// Get the cell number of our current ray.
|
||||
ivec2 cellCount = getCellCount(level);
|
||||
ivec2 oldCellIx = getCell(ray.xy, cellCount);
|
||||
|
||||
// Get the minimum depth plane in which the current ray resides.
|
||||
float cellMinZ = getMinDepthPlane(oldCellIx, level);
|
||||
|
||||
// Intersect only if ray depth is below the minimum depth plane.
|
||||
vec3 tempRay;
|
||||
if (cellMinZ > ray.z && !isBackwardRay)
|
||||
tempRay = intersectDepthPlane(o, d, (cellMinZ - minZ) / deltaZ);
|
||||
else
|
||||
tempRay = ray;
|
||||
|
||||
ivec2 newCellIx = getCell(tempRay.xy, cellCount);
|
||||
float thickness = level == 0 ? (ray.z - cellMinZ) : 0;
|
||||
|
||||
bool crossed = (isBackwardRay && (cellMinZ > ray.z))
|
||||
|| (thickness > MAX_THICKNESS) || crossedCellBoundary(oldCellIx, newCellIx);
|
||||
|
||||
if (crossed)
|
||||
{
|
||||
ray = intersectCellBoundary(o, d, oldCellIx, cellCount, crossStep, crossOffset);
|
||||
level = min(maxLevel, level + 1);
|
||||
deepestLevel = max(deepestLevel, level);
|
||||
#if DEBUG_LINEAR_SEARCH
|
||||
level = 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ray = tempRay;
|
||||
level = level - 1;
|
||||
}
|
||||
|
||||
iterations += 1;
|
||||
}
|
||||
|
||||
// Results
|
||||
//debugDeepestLevel = deepestLevel;
|
||||
//debugIterations = iterations;
|
||||
hitPointSS = ray.xy;
|
||||
return level < HIZ_STOP_LEVEL && iterations < u_hiz_iterations;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef PBR_ENABLED
|
||||
float horiz = sampleMeshTexture2(f_material_id, f_uv + u_push_constants.m_displace_direction.xy * 150.).x;
|
||||
float vert = sampleMeshTexture2(f_material_id, (f_uv.yx + u_push_constants.m_displace_direction.zw * 150.) * vec2(0.9)).x;
|
||||
vec2 mask = getDisplaceShift(horiz, vert);
|
||||
mask = (mask + 1.0) * 0.5;
|
||||
o_displace_mask = mask;
|
||||
if (u_ssr)
|
||||
{
|
||||
float alpha = sampleMeshTexture0(f_material_id, f_uv).a;
|
||||
if (alpha == 0.0)
|
||||
{
|
||||
o_displace_ssr = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
// eye-space position
|
||||
vec3 xpos = (u_camera.m_view_matrix * f_world_position).xyz;
|
||||
// eye-space view direction (points from surface toward eye at origin)
|
||||
vec3 eyedir = -normalize(xpos);
|
||||
// eye-space normal
|
||||
vec3 normal = (u_camera.m_view_matrix * vec4(normalize(f_normal), 0)).xyz;
|
||||
|
||||
// bail out immediately if normal is facing away from the camera,
|
||||
// dot(normal, eyedir) <= 0 means back-facing
|
||||
float NdotV = dot(normal, eyedir);
|
||||
if (NdotV <= 0.0)
|
||||
{
|
||||
o_displace_ssr = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// compute reflection in eye-space
|
||||
vec3 reflected = reflect(-eyedir, normal);
|
||||
// bring it back into world-space
|
||||
vec3 world_reflection = (u_camera.m_inverse_view_matrix *
|
||||
vec4(reflected, 0.0)).xyz;
|
||||
|
||||
// fallback to skybox
|
||||
vec4 fallback = texture(u_skybox_texture, world_reflection);
|
||||
|
||||
// early exit if normal is facing camera too directly (no meaningful reflection)
|
||||
if (normal.z < -0.75)
|
||||
{
|
||||
o_displace_ssr = fallback;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 result;
|
||||
vec2 viewport_scale = u_camera.m_viewport.zw / u_camera.m_screensize;
|
||||
vec2 viewport_offset = u_camera.m_viewport.xy / u_camera.m_screensize;
|
||||
bool hit = true;
|
||||
vec2 coords;
|
||||
if (u_hiz_iterations == 0)
|
||||
{
|
||||
coords = RayCast(reflected, xpos, u_camera.m_projection_matrix,
|
||||
viewport_scale, viewport_offset, u_depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 positionSS = CalcCoordFromPosition(xpos,
|
||||
u_camera.m_projection_matrix, vec2(1.0), vec2(0.0));
|
||||
vec3 positionCS = positionSS;
|
||||
positionCS.xy = 2.0 * positionCS.xy - 1.0;
|
||||
vec3 position2VS = xpos + 1000.0 * reflected;
|
||||
vec4 position2CS = u_camera.m_projection_matrix * vec4(position2VS, 1.0);
|
||||
position2CS /= position2CS.w;
|
||||
vec3 position2SS = position2CS.xyz;
|
||||
position2SS.xy = vec2(0.5) + 0.5 * position2SS.xy;
|
||||
vec3 reflectionDirSS = normalize(position2SS - positionSS);
|
||||
// Trace HiZ to find the hit point.
|
||||
hit = traceHiZ(positionSS, reflectionDirSS, coords);
|
||||
coords = coords * viewport_scale + viewport_offset;
|
||||
}
|
||||
vec2 viewport_coords = (coords - viewport_offset) / viewport_scale;
|
||||
if (!hit || viewport_coords.x < 0. || viewport_coords.x > 1. ||
|
||||
viewport_coords.y < 0. || viewport_coords.y > 1.)
|
||||
{
|
||||
result = fallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = texture(u_displace_color, coords);
|
||||
float edge = GetEdgeFade(coords, viewport_scale, viewport_offset);
|
||||
//float fresnel = pow(1.0 - NdotV, 2.0);
|
||||
float fresnel = (1.0 - NdotV) * (1.0 - NdotV);
|
||||
float blend_weight = edge * fresnel;
|
||||
result = mix(fallback, result, blend_weight);
|
||||
}
|
||||
o_displace_ssr = result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec4 m_displace_direction;
|
||||
} u_push_constants;
|
||||
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/constants_utils.glsl"
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/displace_utils.frag"
|
||||
|
||||
layout (set = 3, binding = 0) uniform sampler2D u_displace_mask;
|
||||
layout (set = 3, binding = 1) uniform sampler2D u_displace_ssr;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef PBR_ENABLED
|
||||
vec4 color = sampleMeshTexture0(f_material_id, f_uv) * f_vertex_color;
|
||||
vec3 mixed_color = color.xyz;
|
||||
float alpha = color.w;
|
||||
mixed_color = convertColor(mixed_color);
|
||||
if (u_ssr)
|
||||
{
|
||||
float alpha = sampleMeshTexture0(f_material_id, f_uv).a;
|
||||
if (alpha == 0.0)
|
||||
{
|
||||
o_color = vec4(mixed_color * alpha, alpha);
|
||||
return;
|
||||
}
|
||||
float horiz = sampleMeshTexture2(f_material_id, f_uv + u_push_constants.m_displace_direction.xy * 150.).x;
|
||||
float vert = sampleMeshTexture2(f_material_id, (f_uv.yx + u_push_constants.m_displace_direction.zw * 150.) * vec2(0.9)).x;
|
||||
vec2 shift = getDisplaceShift(horiz, vert);
|
||||
ivec2 uv = getDisplaceUV(shift, u_camera.m_viewport, u_displace_mask);
|
||||
vec3 reflection = texelFetch(u_displace_ssr, uv, 0).xyz;
|
||||
o_color = vec4(mixed_color * alpha * 0.5 + reflection * alpha * 0.5 ,
|
||||
alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(mixed_color * alpha, alpha);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
layout (location = 0) out vec2 f_uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
f_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(f_uv * 2.0 - 1.0, 1.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 4) in float f_hue_change;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/constants_utils.glsl"
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
float mask = tex_color.a;
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#ifndef PBR_ENABLED
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(f_hue_change,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, 1.0);
|
||||
}
|
||||
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
#ifdef PBR_ENABLED
|
||||
mixed_color = convertColor(mixed_color);
|
||||
#endif
|
||||
o_color = vec4(mixed_color * 0.5, 0.5);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/spm_data.glsl"
|
||||
#include "utils/spm_layout.vert"
|
||||
#include "../utils/get_world_location.vert"
|
||||
|
||||
layout(push_constant) uniform Constants
|
||||
{
|
||||
vec3 m_wind_direction;
|
||||
} u_push_constants;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 offset = sin(u_push_constants.m_wind_direction * (v_position.y * 0.1));
|
||||
offset += vec3(cos(u_push_constants.m_wind_direction) * 0.7);
|
||||
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation + offset *
|
||||
v_color.r,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale, v_position);
|
||||
f_world_position = v_world_position;
|
||||
gl_Position = u_camera.m_projection_view_matrix * v_world_position;
|
||||
f_vertex_color = vec4(1.0);
|
||||
f_uv = v_uv;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
if (f_material_id < 0)
|
||||
f_material_id = u_material_ids.m_material_id[gl_DrawIDARB];
|
||||
#endif
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
f_normal = rotateVector(u_object_buffer.m_objects[gl_InstanceIndex].m_rotation, v_normal.xyz);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
layout(binding = 0) uniform sampler2D u_depth;
|
||||
layout(binding = 1, r32f) uniform writeonly image2D u_hiz_depth;
|
||||
|
||||
layout(push_constant) uniform PushConstants
|
||||
{
|
||||
ivec3 u_offset_miplevel;
|
||||
} pc;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 dst = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 current_size = imageSize(u_hiz_depth);
|
||||
|
||||
if (dst.x >= current_size.x || dst.y >= current_size.y)
|
||||
return;
|
||||
|
||||
if (pc.u_offset_miplevel.z == 0)
|
||||
{
|
||||
// at level 0, do a 1:1 copy
|
||||
float d = texelFetch(u_depth, dst + pc.u_offset_miplevel.xy, 0).r;
|
||||
imageStore(u_hiz_depth, dst, vec4(d));
|
||||
}
|
||||
else
|
||||
{
|
||||
// at higher mip levels, read a 2×2 block from previous level
|
||||
ivec2 src = dst * 2;
|
||||
int prev_level = pc.u_offset_miplevel.z - 1;
|
||||
ivec2 prev_size = textureSize(u_depth, prev_level);
|
||||
float d0 = texelFetch(u_depth, src + ivec2(0, 0), prev_level).r;
|
||||
float d1 = texelFetch(u_depth, src + ivec2(1, 0), prev_level).r;
|
||||
float d2 = texelFetch(u_depth, src + ivec2(0, 1), prev_level).r;
|
||||
float d3 = texelFetch(u_depth, src + ivec2(1, 1), prev_level).r;
|
||||
float min_depth = min(min(d0, d1), min(d2, d3));
|
||||
//float max_depth = max(max(d0, d1), max(d2, d3));
|
||||
bool extra_sample_x = (current_size.x * 2) < prev_size.x;
|
||||
bool extra_sample_y = (current_size.y * 2) < prev_size.y;
|
||||
if (extra_sample_x)
|
||||
{
|
||||
float d4 = texelFetch(u_depth, src + ivec2(2, 0), prev_level).r;
|
||||
float d5 = texelFetch(u_depth, src + ivec2(2, 1), prev_level).r;
|
||||
min_depth = min(min_depth, min(d4, d5));
|
||||
//max_depth = max(max_depth, max(d4, d5));
|
||||
}
|
||||
if (extra_sample_y)
|
||||
{
|
||||
float d6 = texelFetch(u_depth, src + ivec2(0, 2), prev_level).r;
|
||||
float d7 = texelFetch(u_depth, src + ivec2(1, 2), prev_level).r;
|
||||
min_depth = min(min_depth, min(d6, d7));
|
||||
//max_depth = max(max_depth, max(d6, d7));
|
||||
}
|
||||
if (extra_sample_x && extra_sample_y)
|
||||
{
|
||||
float d8 = texelFetch(u_depth, src + ivec2(2, 2), prev_level).r;
|
||||
min_depth = min(min_depth, d8);
|
||||
//max_depth = max(max_depth, d8);
|
||||
}
|
||||
imageStore(u_hiz_depth, dst, vec4(min_depth));
|
||||
//imageStore(u_hiz_depth, dst, vec4(min_depth, max_depth, 0.0, 0.0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 4) in float f_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 6) in vec3 f_tangent;
|
||||
layout(location = 7) in vec3 f_bitangent;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
#ifdef PBR_ENABLED
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
float mask = tex_color.a;
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#ifndef PBR_ENABLED
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(f_hue_change,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, 1.0);
|
||||
}
|
||||
#ifndef PBR_ENABLED
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
o_color = vec4(mixed_color, 1.0);
|
||||
#else
|
||||
vec3 diffuse_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
|
||||
vec4 layer_3 = sampleMeshTexture3(f_material_id, f_uv);
|
||||
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
|
||||
vec3 frag_tangent = normalize(f_tangent);
|
||||
vec3 frag_bitangent = normalize(f_bitangent);
|
||||
vec3 frag_normal = normalize(f_normal);
|
||||
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
|
||||
|
||||
vec3 normal = normalize(t_b_n * tangent_space_normal);
|
||||
vec3 pbr = sampleMeshTexture2(f_material_id, f_uv).xyz;
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(diffuse_color, pbr.z);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = pbr.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(handlePBR(diffuse_color, pbr, f_world_position, normal),
|
||||
1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<shader-settings>
|
||||
<setting name="solid">
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>solid.frag</fragment>
|
||||
<depth>depth_only.frag</depth>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="normalmap">
|
||||
<properties>
|
||||
<nonpbr-fallback>solid</nonpbr-fallback>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>normalmap.frag</fragment>
|
||||
<depth>depth_only.frag</depth>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="decal">
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>decal.frag</fragment>
|
||||
<depth>depth_only.frag</depth>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="splatting">
|
||||
<properties>
|
||||
<nonpbr-fallback>solid</nonpbr-fallback>
|
||||
<srgb-settings>YNYYYY</srgb-settings>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>splatting.frag</fragment>
|
||||
<depth>depth_only.frag</depth>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="alphatest">
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>alphatest.frag</fragment>
|
||||
<depth>alphatest_depth.frag</depth>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="unlit">
|
||||
<properties>
|
||||
<nonpbr-fallback>alphatest</nonpbr-fallback>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>unlit.frag</fragment>
|
||||
<depth>alphatest_depth.frag</depth>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="grass">
|
||||
<shaders>
|
||||
<vertex>grass.vert</vertex>
|
||||
<fragment>alphatest.frag</fragment>
|
||||
<depth>alphatest_depth.frag</depth>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="alphablend">
|
||||
<properties>
|
||||
<alphablend>true</alphablend>
|
||||
<depth-write>false</depth-write>
|
||||
<backface-culling>false</backface-culling>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>transparent.frag</fragment>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="additive">
|
||||
<properties>
|
||||
<additive>true</additive>
|
||||
<depth-write>false</depth-write>
|
||||
<backface-culling>false</backface-culling>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>transparent.frag</fragment>
|
||||
<skinning-vertex>spm_skinning.vert</skinning-vertex>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
<setting name="displace">
|
||||
<properties>
|
||||
<alphablend>true</alphablend>
|
||||
<depth-write>false</depth-write>
|
||||
<backface-culling>false</backface-culling>
|
||||
<nonpbr-fallback>alphablend</nonpbr-fallback>
|
||||
</properties>
|
||||
<shaders>
|
||||
<vertex>spm.vert</vertex>
|
||||
<fragment>displace_transparent.frag</fragment>
|
||||
</shaders>
|
||||
</setting>
|
||||
|
||||
</shader-settings>
|
||||
@@ -0,0 +1,20 @@
|
||||
layout(location = 0) in vec2 f_uv;
|
||||
layout(binding = 2) uniform samplerCube f_skybox_texture;
|
||||
layout(binding = 3) uniform samplerCube f_skybox_texture_srgb;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/constants_utils.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = 2.0f * f_uv - 1.0f;
|
||||
vec4 front = u_camera.m_inverse_projection_view_matrix * vec4(uv, -1.0, 1.0);
|
||||
vec4 back = u_camera.m_inverse_projection_view_matrix * vec4(uv, 1.0, 1.0);
|
||||
vec3 dir = back.xyz / back.w - front.xyz / front.w;
|
||||
if (u_deferred)
|
||||
o_color = texture(f_skybox_texture_srgb, dir);
|
||||
else
|
||||
o_color = texture(f_skybox_texture, dir);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 4) in float f_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
#endif
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
#ifdef PBR_ENABLED
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
float mask = tex_color.a;
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#ifndef PBR_ENABLED
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(f_hue_change,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, 1.0);
|
||||
}
|
||||
#ifndef PBR_ENABLED
|
||||
vec3 mixed_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
o_color = vec4(mixed_color, 1.0);
|
||||
#else
|
||||
vec3 diffuse_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
vec3 normal = normalize(f_normal.xyz);
|
||||
vec3 pbr = sampleMeshTexture2(f_material_id, f_uv).xyz;
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(diffuse_color, pbr.z);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = pbr.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(handlePBR(diffuse_color, pbr, f_world_position, normal),
|
||||
1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
// Binding for the input skybox cubemap.
|
||||
layout(set = 0, binding = 0) uniform samplerCube uSkybox;
|
||||
// Output prefiltered environment specular map (stored as a 2D array for cube faces).
|
||||
#ifdef SHADER_STORAGE_IMAGE_EXTENDED_FORMATS
|
||||
layout(set = 0, binding = 1, rgb10_a2) uniform restrict writeonly image2DArray uPrefilterMap;
|
||||
#else
|
||||
layout(set = 0, binding = 1, rgba8) uniform restrict writeonly image2DArray uPrefilterMap;
|
||||
#endif
|
||||
|
||||
#include "utils/environment_map.glsl"
|
||||
#include "utils/pbr_utils.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 pix = ivec2(gl_GlobalInvocationID.xy);
|
||||
if (pix.x >= pc.size || pix.y >= pc.size) return;
|
||||
|
||||
// Get normalized UV for current pixel.
|
||||
vec2 uv = (vec2(pix) + 0.5) / vec2(pc.size, pc.size);
|
||||
int face = int(gl_GlobalInvocationID.z);
|
||||
|
||||
float roughness = float(pc.mipmapLevel) / float(pc.mipmapCount - 1);
|
||||
vec3 R = FaceUVtoDir(face, uv);
|
||||
vec3 V = normalize(R);
|
||||
// Don't need to sample skybox when roughness is 0.
|
||||
// Since it's a perfect reflector.
|
||||
if (roughness == 0.0)
|
||||
{
|
||||
vec4 color = textureLod(uSkybox, V, 0);
|
||||
imageStore(uPrefilterMap, ivec3(pix, face), color);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 prefilteredColor = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
uint sampleCount = uint(pc.sampleCount);
|
||||
for (uint i = 0u; i < sampleCount; ++i)
|
||||
{
|
||||
vec2 xi = Hammersley(i, sampleCount);
|
||||
// Importance sampling with a GGX distribution.
|
||||
float a = roughness * roughness;
|
||||
float phi = 2.0 * PI * xi.x;
|
||||
// GGX importance sampling for the cosine of the angle.
|
||||
float cosTheta = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
|
||||
vec3 H = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
|
||||
|
||||
// Construct TBN basis from view direction V.
|
||||
vec3 up = abs(V.y) < 0.999 ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, V));
|
||||
vec3 bitangent = cross(V, tangent);
|
||||
mat3 TBN = mat3(tangent, bitangent, V);
|
||||
H = normalize(TBN * H);
|
||||
|
||||
// Compute reflection vector L.
|
||||
vec3 L = normalize(reflect(-V, H));
|
||||
float NdotL = max(dot(V, L), 0.0);
|
||||
|
||||
if (NdotL > 0.0)
|
||||
{
|
||||
// Calculate the mip level based on the PDF.
|
||||
// In a skybox/environment map scenario, N = V.
|
||||
float NoH = max(dot(V, H), 0.0);
|
||||
float VoH = max(dot(V, H), 0.0);
|
||||
|
||||
float D = D_GGX(roughness, NoH);
|
||||
float pdf = D * NoH / (4.0 * VoH);
|
||||
float omegaS = 1.0 / (float(sampleCount) * pdf);
|
||||
float omegaP = 4.0 * PI / (6.0 * float(pc.size * pc.size));
|
||||
float mipLevel = 0.5 * log2(omegaS / omegaP);
|
||||
|
||||
vec3 sampleColor = textureLod(uSkybox, L, mipLevel).rgb;
|
||||
prefilteredColor += sampleColor * NdotL;
|
||||
totalWeight += NdotL;
|
||||
}
|
||||
}
|
||||
prefilteredColor = prefilteredColor / totalWeight;
|
||||
|
||||
imageStore(uPrefilterMap, ivec3(pix, face), vec4(prefilteredColor, 1.0));
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 2) in vec2 f_uv_two;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
|
||||
#define HIGH_RES_SAMPLER 1.0f
|
||||
#define LOW_RES_SAMPLER 0.5f
|
||||
|
||||
#ifdef PBR_ENABLED
|
||||
vec4 sampleMultiResTextureLayer2(float factor, int material_id, vec2 uv)
|
||||
{
|
||||
return mix(sampleMeshTexture2(material_id, uv * HIGH_RES_SAMPLER), sampleMeshTexture2(material_id, uv * LOW_RES_SAMPLER), factor);
|
||||
}
|
||||
|
||||
vec4 sampleMultiResTextureLayer3(float factor, int material_id, vec2 uv)
|
||||
{
|
||||
return mix(sampleMeshTexture3(material_id, uv * HIGH_RES_SAMPLER), sampleMeshTexture3(material_id, uv * LOW_RES_SAMPLER), factor);
|
||||
}
|
||||
|
||||
vec4 sampleMultiResTextureLayer4(float factor, int material_id, vec2 uv)
|
||||
{
|
||||
return mix(sampleMeshTexture4(material_id, uv * HIGH_RES_SAMPLER), sampleMeshTexture4(material_id, uv * LOW_RES_SAMPLER), factor);
|
||||
}
|
||||
|
||||
vec4 sampleMultiResTextureLayer5(float factor, int material_id, vec2 uv)
|
||||
{
|
||||
return mix(sampleMeshTexture5(material_id, uv * HIGH_RES_SAMPLER), sampleMeshTexture5(material_id, uv * LOW_RES_SAMPLER), factor);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef PBR_ENABLED
|
||||
// mitigate repetitive patterns
|
||||
float cam_dist = length(u_camera.m_view_matrix * f_world_position);
|
||||
float mitigation = clamp(pow(cam_dist * 0.01, 2.0) - 0., 0., 1.);
|
||||
|
||||
// Splatting part
|
||||
vec4 splatting = sampleMeshTexture1(f_material_id, f_uv_two);
|
||||
vec4 detail0 = sampleMultiResTextureLayer2(mitigation, f_material_id, f_uv);
|
||||
vec4 detail1 = sampleMultiResTextureLayer3(mitigation, f_material_id, f_uv);
|
||||
vec4 detail2 = sampleMultiResTextureLayer4(mitigation, f_material_id, f_uv);
|
||||
vec4 detail3 = sampleMultiResTextureLayer5(mitigation, f_material_id, f_uv);
|
||||
|
||||
vec4 splatted = splatting.r * detail0 +
|
||||
splatting.g * detail1 +
|
||||
splatting.b * detail2 +
|
||||
max(0.0, (1.0 - splatting.r - splatting.g - splatting.b)) * detail3;
|
||||
|
||||
vec3 normal = normalize(f_normal.xyz);
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(splatted.xyz, 0.0);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = vec2(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
o_color = vec4(handlePBR(splatted.xyz, vec3(0.0), f_world_position,
|
||||
normal), 1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/get_vertex_color.glsl"
|
||||
#include "utils/spm_data.glsl"
|
||||
#include "utils/spm_layout.vert"
|
||||
#include "../utils/get_world_location.vert"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale, v_position);
|
||||
f_world_position = v_world_position;
|
||||
gl_Position = u_camera.m_projection_view_matrix * v_world_position;
|
||||
f_vertex_color = v_color.zyxw * getVertexColor(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_custom_vertex_color);
|
||||
f_uv = v_uv + u_object_buffer.m_objects[gl_InstanceIndex].m_texture_trans;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
if (f_material_id < 0)
|
||||
f_material_id = u_material_ids.m_material_id[gl_DrawIDARB];
|
||||
#endif
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
vec3 world_normal = rotateVector(u_object_buffer.m_objects[gl_InstanceIndex].m_rotation, v_normal.xyz);
|
||||
vec3 world_tangent = rotateVector(u_object_buffer.m_objects[gl_InstanceIndex].m_rotation, v_tangent.xyz);
|
||||
f_bitangent = cross(world_normal, world_tangent) * v_tangent.w;
|
||||
f_tangent = world_tangent;
|
||||
f_normal = world_normal;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "utils/camera.glsl"
|
||||
#include "utils/get_vertex_color.glsl"
|
||||
#include "utils/spm_data.glsl"
|
||||
#include "utils/spm_layout.vert"
|
||||
#include "../utils/get_world_location.vert"
|
||||
|
||||
void main()
|
||||
{
|
||||
int offset = u_object_buffer.m_objects[gl_InstanceIndex].m_skinning_offset;
|
||||
mat4 joint_matrix =
|
||||
v_weight[0] * u_skinning_matrices.m_mat[max(v_joint[0] + offset, 0)] +
|
||||
v_weight[1] * u_skinning_matrices.m_mat[max(v_joint[1] + offset, 0)] +
|
||||
v_weight[2] * u_skinning_matrices.m_mat[max(v_joint[2] + offset, 0)] +
|
||||
v_weight[3] * u_skinning_matrices.m_mat[max(v_joint[3] + offset, 0)];
|
||||
vec4 v_skinning_position = joint_matrix * vec4(v_position, 1.0);
|
||||
vec4 v_world_position = getWorldPosition(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_translation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_rotation,
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_scale,
|
||||
v_skinning_position.xyz);
|
||||
f_world_position = v_world_position;
|
||||
gl_Position = u_camera.m_projection_view_matrix * v_world_position;
|
||||
f_vertex_color = v_color.zyxw * getVertexColor(
|
||||
u_object_buffer.m_objects[gl_InstanceIndex].m_custom_vertex_color);
|
||||
f_uv = v_uv + u_object_buffer.m_objects[gl_InstanceIndex].m_texture_trans;
|
||||
f_uv_two = v_uv_two;
|
||||
f_material_id = u_object_buffer.m_objects[gl_InstanceIndex].m_material_id;
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
if (f_material_id < 0)
|
||||
f_material_id = u_material_ids.m_material_id[gl_DrawIDARB];
|
||||
#endif
|
||||
f_hue_change = u_object_buffer.m_objects[gl_InstanceIndex].m_hue_change;
|
||||
#ifdef PBR_ENABLED
|
||||
vec4 skinned_normal = joint_matrix * v_normal;
|
||||
vec4 skinned_tangent = joint_matrix * vec4(v_tangent.xyz, 0.0);
|
||||
vec3 world_normal = rotateVector(u_object_buffer.m_objects[gl_InstanceIndex].m_rotation, skinned_normal.xyz);
|
||||
vec3 world_tangent = rotateVector(u_object_buffer.m_objects[gl_InstanceIndex].m_rotation, skinned_tangent.xyz);
|
||||
f_bitangent = cross(world_normal, world_tangent) * v_tangent.w;
|
||||
f_tangent = world_tangent;
|
||||
f_normal = world_normal;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
#include "utils/constants_utils.glsl"
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = sampleMeshTexture0(f_material_id, f_uv) * f_vertex_color;
|
||||
vec3 mixed_color = color.xyz;
|
||||
float alpha = color.w;
|
||||
#ifdef PBR_ENABLED
|
||||
mixed_color = convertColor(mixed_color);
|
||||
#endif
|
||||
o_color = vec4(mixed_color * alpha, alpha);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
layout(location = 0) in vec4 f_vertex_color;
|
||||
layout(location = 1) in vec2 f_uv;
|
||||
layout(location = 3) flat in int f_material_id;
|
||||
layout(location = 4) in float f_hue_change;
|
||||
layout(location = 5) in vec3 f_normal;
|
||||
layout(location = 8) in vec4 f_world_position;
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
layout(location = 1) out vec4 o_normal;
|
||||
|
||||
#include "utils/sample_mesh_texture.glsl"
|
||||
#include "../utils/rgb_conversion.frag"
|
||||
#include "utils/handle_pbr.glsl"
|
||||
#include "../utils/encode_normal.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef PBR_ENABLED
|
||||
vec4 tex_color = sampleMeshTexture0(f_material_id, f_uv);
|
||||
if (tex_color.a * f_vertex_color.a < 0.5)
|
||||
discard;
|
||||
|
||||
if (f_hue_change > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(tex_color.rgb);
|
||||
vec2 new_xy = vec2(f_hue_change, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
tex_color = vec4(new_color.r, new_color.g, new_color.b, tex_color.a);
|
||||
}
|
||||
vec3 diffuse_color = tex_color.xyz * f_vertex_color.xyz;
|
||||
vec3 normal = normalize(f_normal.xyz);
|
||||
if (u_deferred)
|
||||
{
|
||||
o_color = vec4(diffuse_color, 0.4);
|
||||
o_normal.xy = EncodeNormal(normal);
|
||||
o_normal.zw = vec2(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 pbr = vec3(0.0, 0.0, 0.4);
|
||||
o_color = vec4(handlePBR(diffuse_color, pbr, f_world_position, normal),
|
||||
1.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
layout(std140, set = 1, binding = 0) uniform CameraBuffer
|
||||
{
|
||||
mat4 m_view_matrix;
|
||||
mat4 m_projection_matrix;
|
||||
mat4 m_inverse_view_matrix;
|
||||
mat4 m_inverse_projection_matrix;
|
||||
mat4 m_projection_view_matrix;
|
||||
mat4 m_inverse_projection_view_matrix;
|
||||
vec4 m_viewport;
|
||||
vec2 m_screensize;
|
||||
vec2 m_padding;
|
||||
} u_camera;
|
||||
@@ -0,0 +1,20 @@
|
||||
layout (constant_id = 0) const bool u_ibl = true;
|
||||
layout (constant_id = 1) const float u_specular_levels_minus_one = 0.0;
|
||||
layout (constant_id = 2) const bool u_deferred = false;
|
||||
layout (constant_id = 3) const bool u_has_skybox = true;
|
||||
layout (constant_id = 4) const bool u_ssr = false;
|
||||
layout (constant_id = 5) const uint u_hiz_iterations = 0;
|
||||
|
||||
vec3 convertColor(vec3 input_color)
|
||||
{
|
||||
if (u_ibl)
|
||||
{
|
||||
return (input_color * (6.5 * input_color + 0.45)) /
|
||||
(input_color * (5.0 * input_color + 1.75) + 0.05);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (input_color * (7.0 * input_color + 0.75)) /
|
||||
(input_color * (5.0 * input_color + 1.75) + 0.05);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Push constants to pass face index, dimensions, and sample count.
|
||||
layout(push_constant) uniform PushConstants {
|
||||
int size; // width and height for current mipmap level
|
||||
int sampleCount; // number of samples for integration
|
||||
int mipmapLevel; // current mipmap level
|
||||
int mipmapCount; // total mipmap levels
|
||||
} pc;
|
||||
|
||||
// Returns the radical inverse of "bits" with base 2.
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10;
|
||||
}
|
||||
|
||||
// Generate a 2D Hammersley sequence value.
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i) / float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
|
||||
// Converts face index and UV coordinates in [0,1] to a normalized direction vector.
|
||||
vec3 FaceUVtoDir(int face, vec2 uv)
|
||||
{
|
||||
// Map UV from [0, 1] to [-1, 1]
|
||||
uv = uv * 2.0 - 1.0;
|
||||
vec3 dir;
|
||||
if (face == 0) // +X
|
||||
dir = vec3(1.0, -uv.y, -uv.x);
|
||||
else if (face == 1) // -X
|
||||
dir = vec3(-1.0, -uv.y, uv.x);
|
||||
else if (face == 2) // +Y
|
||||
dir = vec3(uv.x, 1.0, uv.y);
|
||||
else if (face == 3) // -Y
|
||||
dir = vec3(uv.x, -1.0, -uv.y);
|
||||
else if (face == 4) // +Z
|
||||
dir = vec3(uv.x, -uv.y, 1.0);
|
||||
else if (face == 5) // -Z
|
||||
dir = vec3(-uv.x, -uv.y, -1.0);
|
||||
return normalize(dir);
|
||||
}
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
@@ -0,0 +1,9 @@
|
||||
vec4 getVertexColor(uint packed)
|
||||
{
|
||||
vec4 vertex_color;
|
||||
vertex_color.a = float(packed >> 24) / 255.0;
|
||||
vertex_color.r = float((packed >> 16) & 0xff) / 255.0;
|
||||
vertex_color.g = float((packed >> 8) & 0xff) / 255.0;
|
||||
vertex_color.b = float(packed & 0xff) / 255.0;
|
||||
return vertex_color;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
struct LightData
|
||||
{
|
||||
vec4 m_position_radius;
|
||||
vec4 m_color_inverse_square_range;
|
||||
vec4 m_direction_scale_offset; // Spotlight only
|
||||
};
|
||||
|
||||
const int MAX_LIGHT = 32;
|
||||
layout(std140, set = 1, binding = 3) uniform GlobalLightBuffer
|
||||
{
|
||||
vec3 m_ambient_color;
|
||||
float m_sun_scatter;
|
||||
vec3 m_sun_color;
|
||||
float m_sun_angle_tan_half;
|
||||
vec3 m_sun_direction;
|
||||
float m_fog_density;
|
||||
vec4 m_fog_color;
|
||||
vec3 m_skytop_color;
|
||||
int m_light_count;
|
||||
LightData m_lights[MAX_LIGHT];
|
||||
} u_global_light;
|
||||
@@ -0,0 +1,60 @@
|
||||
layout (set = 2, binding = 0) uniform samplerCube u_diffuse;
|
||||
layout (set = 2, binding = 1) uniform samplerCube u_specular;
|
||||
|
||||
#include "camera.glsl"
|
||||
#include "constants_utils.glsl"
|
||||
#include "spm_data.glsl"
|
||||
#include "pbr_utils.glsl"
|
||||
#include "global_light_data.glsl"
|
||||
|
||||
#include "pbr_light.glsl"
|
||||
#include "sun_direction.glsl"
|
||||
|
||||
vec3 handlePBRDeferred(vec3 diffuse_color, vec3 pbr, vec3 world_normal,
|
||||
vec3 eyedir, vec3 normal, float perceptual_roughness)
|
||||
{
|
||||
float radiance_level = perceptual_roughness * u_specular_levels_minus_one;
|
||||
vec3 reflection = reflect(-eyedir, normal);
|
||||
|
||||
vec3 irradiance = vec3(0.0);
|
||||
vec3 radiance = vec3(0.0);
|
||||
if (u_ibl)
|
||||
{
|
||||
vec3 world_reflection = (u_camera.m_inverse_view_matrix *
|
||||
vec4(reflection, 0.0)).xyz;
|
||||
irradiance = texture(u_diffuse, world_normal).rgb;
|
||||
radiance = textureLod(u_specular, world_reflection, radiance_level).rgb;
|
||||
}
|
||||
|
||||
vec3 lightdir = sunDirection(reflection,
|
||||
u_global_light.m_sun_direction, u_global_light.m_sun_angle_tan_half,
|
||||
u_camera.m_inverse_view_matrix);
|
||||
|
||||
vec3 mixed_color = PBRSunAmbientEmitLight(
|
||||
normal, eyedir, lightdir, diffuse_color,
|
||||
irradiance, radiance,
|
||||
u_global_light.m_sun_color,
|
||||
u_global_light.m_ambient_color,
|
||||
perceptual_roughness, pbr.y, pbr.z);
|
||||
|
||||
return mixed_color;
|
||||
}
|
||||
|
||||
vec3 handlePBR(vec3 diffuse_color, vec3 pbr, vec4 world_position,
|
||||
vec3 world_normal)
|
||||
{
|
||||
vec3 xpos = (u_camera.m_view_matrix * world_position).xyz;
|
||||
vec3 eyedir = -normalize(xpos);
|
||||
vec3 normal = (u_camera.m_view_matrix * vec4(world_normal, 0.0)).xyz;
|
||||
float perceptual_roughness = 1.0 - pbr.x;
|
||||
|
||||
vec3 mixed_color = handlePBRDeferred(diffuse_color, pbr, world_normal,
|
||||
eyedir, normal, perceptual_roughness);
|
||||
mixed_color += accumulateLights(u_global_light.m_light_count,
|
||||
diffuse_color, normal, xpos, eyedir, perceptual_roughness, pbr.y);
|
||||
|
||||
//Disable for deferred shading
|
||||
//float factor = (1.0 - exp(length(xpos) * -0.0001));
|
||||
//mixed_color = mixed_color + vec3(0.5) * factor;
|
||||
return convertColor(mixed_color);
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
vec3 PBRLight(
|
||||
vec3 normal,
|
||||
vec3 eyedir,
|
||||
vec3 lightdir,
|
||||
vec3 color,
|
||||
float perceptual_roughness,
|
||||
float metallic)
|
||||
{
|
||||
float NdotV = max(dot(normal, eyedir), 0.0001);
|
||||
float NdotL = clamp(dot(normal, lightdir), 0.0, 1.0);
|
||||
|
||||
vec2 F_ab = F_AB(perceptual_roughness, NdotV);
|
||||
|
||||
vec3 H = normalize(eyedir + lightdir);
|
||||
float NdotH = clamp(dot(normal, H), 0.0, 1.0);
|
||||
float LdotH = clamp(dot(lightdir, H), 0.0, 1.0);
|
||||
|
||||
vec3 diffuse_color = color * (1.0 - metallic);
|
||||
vec3 F0 = mix(vec3(0.04), color, metallic);
|
||||
// No real world material has specular values under 0.02, so we use this range as a
|
||||
// "pre-baked specular occlusion" that extinguishes the fresnel term, for artistic control.
|
||||
// See: https://google.github.io/filament/Filament.html#specularocclusion
|
||||
float F90 = clamp(dot(F0, vec3(50.0 * 0.33)), 0.0, 1.0);
|
||||
|
||||
float roughness = perceptualRoughnessToRoughness(perceptual_roughness);
|
||||
|
||||
vec3 diffuse = diffuse_color * Fd_Burley(roughness, NdotV, NdotL, NdotH);
|
||||
|
||||
float D = D_GGX(roughness, NdotH);
|
||||
float V = V_Smith_GGX_Correlated(roughness, NdotV, NdotL);
|
||||
vec3 F = fresnel(F0, F90, LdotH);
|
||||
vec3 specular = D * V * F * (1.0 + F0 * (1.0 / F_ab.x - 1.0));
|
||||
|
||||
return NdotL * (diffuse + specular);
|
||||
}
|
||||
|
||||
vec3 PBRSunAmbientEmitLight(
|
||||
vec3 normal,
|
||||
vec3 eyedir,
|
||||
vec3 sundir,
|
||||
vec3 color,
|
||||
vec3 irradiance,
|
||||
vec3 radiance,
|
||||
vec3 sun_color,
|
||||
vec3 ambient_color,
|
||||
float perceptual_roughness,
|
||||
float metallic,
|
||||
float emissive)
|
||||
{
|
||||
// Copied from PBRLight to use F_ab and F90 again
|
||||
float NdotV = max(dot(normal, eyedir), 0.0001);
|
||||
float NdotL = clamp(dot(normal, sundir), 0.0, 1.0);
|
||||
|
||||
vec2 F_ab = F_AB(perceptual_roughness, NdotV);
|
||||
|
||||
vec3 H = normalize(eyedir + sundir);
|
||||
float NdotH = clamp(dot(normal, H), 0.0, 1.0);
|
||||
float LdotH = clamp(dot(sundir, H), 0.0, 1.0);
|
||||
|
||||
vec3 diffuse_color = color * (1.0 - metallic);
|
||||
vec3 F0 = mix(vec3(0.04), color, metallic);
|
||||
// No real world material has specular values under 0.02, so we use this range as a
|
||||
// "pre-baked specular occlusion" that extinguishes the fresnel term, for artistic control.
|
||||
// See: https://google.github.io/filament/Filament.html#specularocclusion
|
||||
float F90 = clamp(dot(F0, vec3(50.0 * 0.33)), 0.0, 1.0);
|
||||
|
||||
float roughness = perceptualRoughnessToRoughness(perceptual_roughness);
|
||||
|
||||
vec3 diffuse = diffuse_color * Fd_Burley(roughness, NdotV, NdotL, NdotH);
|
||||
|
||||
float D = D_GGX(roughness, NdotH);
|
||||
float V = V_Smith_GGX_Correlated(roughness, NdotV, NdotL);
|
||||
vec3 F = fresnel(F0, F90, LdotH);
|
||||
vec3 specular = D * V * F * (1.0 + F0 * (1.0 / F_ab.x - 1.0));
|
||||
|
||||
vec3 sunlight = NdotL * (diffuse + specular);
|
||||
|
||||
vec3 diffuse_ambient = envBRDFApprox(diffuse_color, F_AB(1.0, NdotV));
|
||||
|
||||
vec3 specular_ambient = F90 * envBRDFApprox(F0, F_ab);
|
||||
|
||||
// Other 0.6 comes from skybox
|
||||
ambient_color *= 0.4;
|
||||
vec3 environment;
|
||||
if (u_ibl)
|
||||
{
|
||||
environment = environmentLight(irradiance, radiance, roughness,
|
||||
diffuse_color, F_ab, F0, F90, NdotV);
|
||||
}
|
||||
else
|
||||
{
|
||||
environment = u_global_light.m_skytop_color * ambient_color *
|
||||
diffuse_color;
|
||||
}
|
||||
|
||||
vec3 emit = emissive * color * 4.0;
|
||||
|
||||
return sun_color * sunlight
|
||||
+ environment + emit
|
||||
+ (diffuse_ambient + specular_ambient) * ambient_color;
|
||||
}
|
||||
|
||||
vec3 accumulateLights(int light_count, vec3 diffuse_color, vec3 normal,
|
||||
vec3 xpos, vec3 eyedir, float perceptual_roughness,
|
||||
float metallic)
|
||||
{
|
||||
vec3 accumulated_color = vec3(0.0);
|
||||
for (int i = 0; i < light_count; i++)
|
||||
{
|
||||
vec3 light_to_frag = (u_camera.m_view_matrix *
|
||||
vec4(u_global_light.m_lights[i].m_position_radius.xyz,
|
||||
1.0)).xyz - xpos;
|
||||
float invrange = u_global_light.m_lights[i].m_color_inverse_square_range.w;
|
||||
float distance_sq = dot(light_to_frag, light_to_frag);
|
||||
if (distance_sq * invrange > 1.)
|
||||
continue;
|
||||
// SpotLight
|
||||
float sattenuation = 1.;
|
||||
float sscale = u_global_light.m_lights[i].m_direction_scale_offset.z;
|
||||
float distance = sqrt(distance_sq);
|
||||
float distance_inverse = 1. / distance;
|
||||
vec3 L = light_to_frag * distance_inverse;
|
||||
if (sscale != 0.)
|
||||
{
|
||||
vec3 sdir =
|
||||
vec3(u_global_light.m_lights[i].m_direction_scale_offset.xy, 0.);
|
||||
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
|
||||
sdir = (u_camera.m_view_matrix * vec4(sdir, 0.0)).xyz;
|
||||
sattenuation = clamp(dot(-sdir, L) *
|
||||
abs(sscale) +
|
||||
u_global_light.m_lights[i].m_direction_scale_offset.w, 0.0, 1.0);
|
||||
#ifndef TILED_GPU
|
||||
// Reduce branching in tiled GPU
|
||||
if (sattenuation == 0.)
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
vec3 diffuse_specular = PBRLight(normal, eyedir, L, diffuse_color,
|
||||
perceptual_roughness, metallic);
|
||||
float attenuation = 20. / (1. + distance_sq);
|
||||
float radius = u_global_light.m_lights[i].m_position_radius.w;
|
||||
attenuation *= (radius - distance) / radius;
|
||||
attenuation *= sattenuation * sattenuation;
|
||||
vec3 light_color =
|
||||
u_global_light.m_lights[i].m_color_inverse_square_range.xyz;
|
||||
accumulated_color += light_color * attenuation * diffuse_specular;
|
||||
}
|
||||
return accumulated_color;
|
||||
}
|
||||
|
||||
// Copied because reusing in a loop will be slower
|
||||
vec3 calculateLight(int i, vec3 diffuse_color, vec3 normal, vec3 xpos,
|
||||
vec3 eyedir, float perceptual_roughness, float metallic)
|
||||
{
|
||||
vec3 light_to_frag = (u_camera.m_view_matrix *
|
||||
vec4(u_global_light.m_lights[i].m_position_radius.xyz,
|
||||
1.0)).xyz - xpos;
|
||||
float invrange = u_global_light.m_lights[i].m_color_inverse_square_range.w;
|
||||
float distance_sq = dot(light_to_frag, light_to_frag);
|
||||
if (distance_sq * invrange > 1.)
|
||||
return vec3(0.0);
|
||||
// SpotLight
|
||||
float sattenuation = 1.;
|
||||
float sscale = u_global_light.m_lights[i].m_direction_scale_offset.z;
|
||||
float distance = sqrt(distance_sq);
|
||||
float distance_inverse = 1. / distance;
|
||||
vec3 L = light_to_frag * distance_inverse;
|
||||
if (sscale != 0.)
|
||||
{
|
||||
vec3 sdir =
|
||||
vec3(u_global_light.m_lights[i].m_direction_scale_offset.xy, 0.);
|
||||
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
|
||||
sdir = (u_camera.m_view_matrix * vec4(sdir, 0.0)).xyz;
|
||||
sattenuation = clamp(dot(-sdir, L) *
|
||||
abs(sscale) +
|
||||
u_global_light.m_lights[i].m_direction_scale_offset.w, 0.0, 1.0);
|
||||
if (sattenuation == 0.)
|
||||
return vec3(0.0);
|
||||
}
|
||||
vec3 diffuse_specular = PBRLight(normal, eyedir, L, diffuse_color,
|
||||
perceptual_roughness, metallic);
|
||||
float attenuation = 20. / (1. + distance_sq);
|
||||
float radius = u_global_light.m_lights[i].m_position_radius.w;
|
||||
attenuation *= (radius - distance) / radius;
|
||||
attenuation *= sattenuation * sattenuation;
|
||||
vec3 light_color =
|
||||
u_global_light.m_lights[i].m_color_inverse_square_range.xyz;
|
||||
return light_color * attenuation * diffuse_specular;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
vec2 F_AB(float perceptual_roughness, float NdotV)
|
||||
{
|
||||
vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
|
||||
vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
|
||||
vec4 r = perceptual_roughness * c0 + c1;
|
||||
float a004 = min(r.x * r.x, pow(2.0, -9.28 * NdotV)) * r.x + r.y;
|
||||
return vec2(-1.04, 1.04) * a004 + r.zw;
|
||||
}
|
||||
|
||||
// Lambert model
|
||||
float F_Schlick(float f0, float f90, float VdotH)
|
||||
{
|
||||
return mix(f0, f90, pow(1.0 - VdotH, 5.0));
|
||||
}
|
||||
|
||||
float Fd_Burley(float roughness, float NdotV, float NdotL, float LdotH)
|
||||
{
|
||||
// Don't divide by Pi to avoid light being too dim.
|
||||
float f90 = 0.5 + 2.0 * roughness * LdotH * LdotH;
|
||||
float lightScatter = F_Schlick(1.0, f90, NdotL);
|
||||
float viewScatter = F_Schlick(1.0, f90, NdotV);
|
||||
return lightScatter * viewScatter;
|
||||
}
|
||||
|
||||
// Calculate distribution.
|
||||
// Based on https://google.github.io/filament/Filament.html#citation-walter07
|
||||
// D_GGX(h,α) = α^2 / { π ((n⋅h)^2 (α2−1) + 1)^2 }
|
||||
// Simple implementation, has precision problems when using fp16 instead of fp32
|
||||
// see https://google.github.io/filament/Filament.html#listing_speculardfp16
|
||||
float D_GGX(float roughness, float NdotH)
|
||||
{
|
||||
float oneMinusNdotHSquared = 1.0 - NdotH * NdotH;
|
||||
float a = NdotH * roughness;
|
||||
float k = roughness / (oneMinusNdotHSquared + a * a);
|
||||
return k * k * (1.0 / 3.14159265359);
|
||||
}
|
||||
|
||||
// Calculate visibility.
|
||||
// Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces"
|
||||
// see https://google.github.io/filament/Filament.html#listing_approximatedspecularv
|
||||
float V_Smith_GGX_Correlated(float roughness, float NdotV, float NdotL)
|
||||
{
|
||||
return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, roughness);
|
||||
}
|
||||
|
||||
// Fresnel function
|
||||
// see https://google.github.io/filament/Filament.html#citation-schlick94
|
||||
// F_Schlick(v,h,f_0,f_90) = f_0 + (f_90 − f_0) (1 − v⋅h)^5
|
||||
vec3 fresnel(vec3 f0, float f90, float VdotH)
|
||||
{
|
||||
return f0 + (f90 - f0) * pow(1.0 - VdotH, 5.0);
|
||||
}
|
||||
|
||||
vec3 envBRDFApprox(vec3 F0, vec2 F_ab)
|
||||
{
|
||||
return F0 * F_ab.x + F_ab.y;
|
||||
}
|
||||
|
||||
float perceptualRoughnessToRoughness(float perceptual_roughness)
|
||||
{
|
||||
float roughness = clamp(perceptual_roughness, 0.089, 1.0);
|
||||
return roughness * roughness;
|
||||
}
|
||||
|
||||
vec3 environmentLight(
|
||||
vec3 irradiance,
|
||||
vec3 radiance,
|
||||
float roughness,
|
||||
vec3 diffuse_color,
|
||||
vec2 F_ab,
|
||||
vec3 F0,
|
||||
float F90,
|
||||
float NdotV)
|
||||
{
|
||||
// Multiscattering approximation: https://www.jcgt.org/published/0008/01/03/paper.pdf
|
||||
// Useful reference: https://bruop.github.io/ibl
|
||||
vec3 Fr = max(vec3(1.0 - roughness), F0) - F0;
|
||||
vec3 kS = F0 + Fr * pow(1.0 - NdotV, 5.0);
|
||||
float Ess = F_ab.x + F_ab.y;
|
||||
vec3 FssEss = kS * Ess * F90;
|
||||
float Ems = 1.0 - Ess;
|
||||
vec3 Favg = F0 + (1.0 - F0) / 21.0;
|
||||
vec3 Fms = FssEss * Favg / (1.0 - Ems * Favg);
|
||||
vec3 FmsEms = Fms * Ems;
|
||||
vec3 Edss = 1.0 - (FssEss + FmsEms);
|
||||
vec3 kD = diffuse_color * Edss;
|
||||
|
||||
vec3 diffuse = (FmsEms + kD) * irradiance;
|
||||
vec3 specular = FssEss * radiance;
|
||||
return diffuse + specular;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
layout(binding = 0) uniform sampler2D f_mesh_textures[SAMPLER_SIZE * TOTAL_MESH_TEXTURE_LAYER];
|
||||
|
||||
vec4 sampleMeshTexture0(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 0;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture1(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 1;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture2(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 2;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture3(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 3;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture4(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 4;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture5(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 5;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture6(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 6;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture7(int material_id, vec2 uv)
|
||||
{
|
||||
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 7;
|
||||
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
|
||||
}
|
||||
#else
|
||||
layout(binding = 0) uniform sampler2D f_mesh_texture_0;
|
||||
layout(binding = 1) uniform sampler2D f_mesh_texture_1;
|
||||
#ifdef PBR_ENABLED
|
||||
layout(binding = 2) uniform sampler2D f_mesh_texture_2;
|
||||
layout(binding = 3) uniform sampler2D f_mesh_texture_3;
|
||||
layout(binding = 4) uniform sampler2D f_mesh_texture_4;
|
||||
layout(binding = 5) uniform sampler2D f_mesh_texture_5;
|
||||
layout(binding = 6) uniform sampler2D f_mesh_texture_6;
|
||||
layout(binding = 7) uniform sampler2D f_mesh_texture_7;
|
||||
#endif
|
||||
|
||||
vec4 sampleMeshTexture0(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_0, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture1(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_1, uv);
|
||||
}
|
||||
|
||||
#ifdef PBR_ENABLED
|
||||
vec4 sampleMeshTexture2(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_2, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture3(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_3, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture4(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_4, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture5(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_5, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture6(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_6, uv);
|
||||
}
|
||||
|
||||
vec4 sampleMeshTexture7(int material_id, vec2 uv)
|
||||
{
|
||||
return texture(f_mesh_texture_7, uv);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
#extension GL_ARB_shader_draw_parameters : enable
|
||||
#endif
|
||||
struct ObjectData
|
||||
{
|
||||
vec3 m_translation;
|
||||
float m_hue_change;
|
||||
vec4 m_rotation;
|
||||
vec3 m_scale;
|
||||
uint m_custom_vertex_color;
|
||||
int m_skinning_offset;
|
||||
int m_material_id;
|
||||
vec2 m_texture_trans;
|
||||
};
|
||||
|
||||
layout(std140, set = 1, binding = 1) readonly buffer ObjectBuffer
|
||||
{
|
||||
ObjectData m_objects[];
|
||||
} u_object_buffer;
|
||||
|
||||
layout(std140, set = 1, binding = 2) readonly buffer SkinningMatrices
|
||||
{
|
||||
mat4 m_mat[];
|
||||
} u_skinning_matrices;
|
||||
|
||||
#ifdef BIND_MESH_TEXTURES_AT_ONCE
|
||||
layout(std430, set = 1, binding = 4) readonly buffer MaterialIDs
|
||||
{
|
||||
int m_material_id[];
|
||||
} u_material_ids;
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
layout(location = 0) in vec3 v_position;
|
||||
layout(location = 1) in vec4 v_normal;
|
||||
layout(location = 2) in vec4 v_color;
|
||||
layout(location = 3) in vec2 v_uv;
|
||||
layout(location = 4) in vec2 v_uv_two;
|
||||
layout(location = 5) in vec4 v_tangent;
|
||||
layout(location = 6) in ivec4 v_joint;
|
||||
layout(location = 7) in vec4 v_weight;
|
||||
|
||||
layout(location = 0) out vec4 f_vertex_color;
|
||||
layout(location = 1) out vec2 f_uv;
|
||||
layout(location = 2) out vec2 f_uv_two;
|
||||
layout(location = 3) flat out int f_material_id;
|
||||
layout(location = 4) out float f_hue_change;
|
||||
layout(location = 5) out vec3 f_normal;
|
||||
layout(location = 6) out vec3 f_tangent;
|
||||
layout(location = 7) out vec3 f_bitangent;
|
||||
layout(location = 8) out vec4 f_world_position;
|
||||
@@ -0,0 +1,14 @@
|
||||
// Sun Most Representative Point (used for MRP area lighting method)
|
||||
// From "Frostbite going PBR" paper
|
||||
|
||||
vec3 sunDirection(vec3 R, vec3 sun_direction, float sun_angle_tan_half, mat4 inverse_view_matrix)
|
||||
{
|
||||
sun_direction = normalize((transpose(inverse_view_matrix) * vec4(sun_direction, 0.)).xyz);
|
||||
float DdotR = dot(sun_direction, R);
|
||||
vec3 S = normalize(R - DdotR * sun_direction);
|
||||
float sun_angle_tan_half2 = 1 + sun_angle_tan_half * sun_angle_tan_half;
|
||||
vec2 sun_angle_sin_cos = vec2(2 * sun_angle_tan_half, 2 - sun_angle_tan_half2) / sun_angle_tan_half2;
|
||||
// Equivalent to DdotR < cos(sun_angle)
|
||||
float factor = step(DdotR, sun_angle_sin_cos.y);
|
||||
return mix(R, normalize(sun_direction * sun_angle_sin_cos.y + S * sun_angle_sin_cos.x), factor);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
vec3 getPosFromFragCoord(vec4 frag_coord, vec4 viewport, mat4 inverse_projection_matrix)
|
||||
{
|
||||
vec2 ndc = vec2((frag_coord.x - viewport.x) / viewport.z * 2.0 - 1.0,
|
||||
(frag_coord.y - viewport.y) / viewport.w * 2.0 - 1.0);
|
||||
vec4 clip = vec4(ndc, 1.0, 1.0);
|
||||
vec4 view_space = inverse_projection_matrix * clip;
|
||||
return view_space.xyz / frag_coord.w;
|
||||
}
|
||||
|
||||
vec3 getPosFromUVDepth(vec3 uv_depth, vec4 viewport, mat4 inverse_projection_matrix)
|
||||
{
|
||||
vec2 ndc = vec2((uv_depth.x - viewport.x) / viewport.z * 2.0 - 1.0,
|
||||
(uv_depth.y - viewport.y) / viewport.w * 2.0 - 1.0);
|
||||
vec4 clip = vec4(ndc, uv_depth.z, 1.0);
|
||||
vec4 view_space = inverse_projection_matrix * clip;
|
||||
return view_space.xyz / view_space.w;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 coords = uv;
|
||||
|
||||
vec4 col = texture(tex, coords);
|
||||
float alpha = col.a;
|
||||
|
||||
if (alpha < 0.04 || length(col.xyz) < 0.2) discard;
|
||||
|
||||
col *= vec4(vec3(4.0), 1.5);
|
||||
col.a *= 0.6;
|
||||
|
||||
FragColor = col;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec3 col;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Use quarter resolution
|
||||
vec2 uv = 4. * gl_FragCoord.xy / u_screen;
|
||||
vec4 res = texture(tex, uv);
|
||||
|
||||
// Keep the sun fully bright, but fade the sky
|
||||
float mul = distance(res.xyz, col);
|
||||
mul = step(mul, 0.02);
|
||||
mul *= 0.97;
|
||||
|
||||
res = res * vec4(mul);
|
||||
|
||||
FragColor = res;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 sunpos;
|
||||
|
||||
#define SAMPLES 12
|
||||
|
||||
const float decaystep = 0.88;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = 4. * gl_FragCoord.xy / u_screen;
|
||||
vec2 texc = uv;
|
||||
vec2 tosun = sunpos - texc;
|
||||
|
||||
// if (dot(tosun, tosun) > 0.49) discard;
|
||||
|
||||
vec2 dist = tosun * 1.0/(float(SAMPLES) * 1.12);
|
||||
|
||||
vec3 col = texture(tex, texc).xyz;
|
||||
float decay = 1.0;
|
||||
|
||||
for (int i = 0; i < SAMPLES; i++) {
|
||||
texc += dist;
|
||||
vec3 here = texture(tex, texc).xyz;
|
||||
here *= decay;
|
||||
col += here;
|
||||
decay *= decaystep;
|
||||
}
|
||||
|
||||
FragColor = vec4(col, 1.0) * 0.8;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#ifndef HEADER_TXT
|
||||
#define HEADER_TXT
|
||||
#ifdef UBO_DISABLED
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 InverseViewMatrix;
|
||||
uniform mat4 InverseProjectionMatrix;
|
||||
uniform mat4 ProjectionViewMatrix;
|
||||
uniform vec2 screen;
|
||||
|
||||
uniform vec3 sun_direction;
|
||||
uniform vec3 sun_col;
|
||||
uniform float sun_angle;
|
||||
uniform float blueLmn[9];
|
||||
uniform float greenLmn[9];
|
||||
uniform float redLmn[9];
|
||||
|
||||
#else
|
||||
|
||||
layout (std140) uniform Matrices
|
||||
{
|
||||
mat4 u_view_matrix;
|
||||
mat4 u_projection_matrix;
|
||||
mat4 u_inverse_view_matrix;
|
||||
mat4 u_inverse_projection_matrix;
|
||||
mat4 u_projection_view_matrix;
|
||||
mat4 u_shadow_projection_view_matrices[4];
|
||||
vec2 u_screen;
|
||||
};
|
||||
|
||||
// Expand because of catalyst (14.12) not correctly associating array in UBO
|
||||
layout (std140) uniform LightingData
|
||||
{
|
||||
vec3 sun_direction;
|
||||
vec3 sun_col;
|
||||
float sun_angle;
|
||||
float bL00;
|
||||
float bL1m1;
|
||||
float bL10;
|
||||
float bL11;
|
||||
float bL2m2;
|
||||
float bL2m1;
|
||||
float bL20;
|
||||
float bL21;
|
||||
float bL22;
|
||||
|
||||
float gL00;
|
||||
float gL1m1;
|
||||
float gL10;
|
||||
float gL11;
|
||||
float gL2m2;
|
||||
float gL2m1;
|
||||
float gL20;
|
||||
float gL21;
|
||||
float gL22;
|
||||
|
||||
float rL00;
|
||||
float rL1m1;
|
||||
float rL10;
|
||||
float rL11;
|
||||
float rL2m2;
|
||||
float rL2m1;
|
||||
float rL20;
|
||||
float rL21;
|
||||
float rL22;
|
||||
};
|
||||
|
||||
layout (std140) uniform SPFogData
|
||||
{
|
||||
// x: fog_start, y: fog_end, z: fog_max, w: fog_density
|
||||
vec4 u_fog_data;
|
||||
vec4 u_fog_color;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // HEADER_TXT
|
||||
@@ -0,0 +1,34 @@
|
||||
uniform samplerCube tex;
|
||||
uniform sampler2D samples;
|
||||
uniform float ViewportSize;
|
||||
|
||||
uniform mat4 PermutationMatrix;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / ViewportSize;
|
||||
vec3 RayDir = 2. * vec3(uv, 1.) - 1.;
|
||||
RayDir = normalize((PermutationMatrix * vec4(RayDir, 0.)).xyz);
|
||||
|
||||
vec4 FinalColor = vec4(0.);
|
||||
vec3 up = (RayDir.y < .99) ? vec3(0., 1., 0.) : vec3(0., 0., 1.);
|
||||
vec3 Tangent = normalize(cross(up, RayDir));
|
||||
vec3 Bitangent = cross(RayDir, Tangent);
|
||||
float weight = 0.;
|
||||
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
vec2 texel = texelFetch(samples, ivec2(i, 0), 0).rg;
|
||||
float Theta = texel.r;
|
||||
float Phi = texel.g;
|
||||
|
||||
vec3 L = cos(Theta) * RayDir + sin(Theta) * cos(Phi) * Tangent + sin(Theta) * sin(Phi) * Bitangent;
|
||||
float NdotL = clamp(dot(RayDir, L), 0., 1.);
|
||||
FinalColor += textureLod(tex, L, 0.) * NdotL;
|
||||
weight += NdotL;
|
||||
}
|
||||
|
||||
FragColor = FinalColor / weight;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
precision mediump float;
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define Solid 0
|
||||
#define Solid2Layer 1
|
||||
#define LightMap 2
|
||||
#define DetailMap 3
|
||||
#define SphereMap 4
|
||||
#define Reflection2Layer 5
|
||||
#define TransparentAlphaChannel 6
|
||||
#define TransparentAlphaChannelRef 7
|
||||
#define TransparentVertexAlpha 8
|
||||
#define TransparentReflection2Layer 9
|
||||
#define StkGrass 10
|
||||
#define StkBlend 11
|
||||
|
||||
/* Uniforms */
|
||||
|
||||
uniform int uMaterialType;
|
||||
|
||||
uniform float uHueChange;
|
||||
uniform vec4 uVertexColor;
|
||||
|
||||
uniform bool uTextureUsage0;
|
||||
//uniform bool uTextureUsage1;
|
||||
|
||||
uniform sampler2D uTextureUnit0;
|
||||
//uniform sampler2D uTextureUnit1;
|
||||
|
||||
/* Varyings */
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
//varying vec2 varTexCoord1;
|
||||
varying vec4 varVertexColor;
|
||||
varying float varEyeDist;
|
||||
|
||||
vec3 rgbToHsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsvToRgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
vec4 renderSolid()
|
||||
{
|
||||
vec4 Color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
if(uTextureUsage0)
|
||||
{
|
||||
Color *= texture2D(uTextureUnit0, varTexCoord0);
|
||||
if (uHueChange > 0.0)
|
||||
{
|
||||
float f_hue_change = 0.66;
|
||||
float mask = Color.a;
|
||||
vec3 old_hsv = rgbToHsv(Color.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
float saturation = mask * 1.825;
|
||||
vec2 new_xy = mix(vec2(old_hsv.x, old_hsv.y), vec2(uHueChange,
|
||||
max(old_hsv.y, saturation)), vec2(mask_step, mask_step));
|
||||
Color.rgb = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
}
|
||||
vec3 mixed_color = varVertexColor.rgb * uVertexColor.rgb;
|
||||
Color.rgb *= mixed_color;
|
||||
Color.a = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Color = varVertexColor * uVertexColor;
|
||||
Color.a = 1.0;
|
||||
}
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 render2LayerSolid()
|
||||
{
|
||||
float BlendFactor = varVertexColor.a;
|
||||
|
||||
vec4 Texel0 = texture2D(uTextureUnit0, varTexCoord0);
|
||||
//vec4 Texel1 = texture2D(uTextureUnit1, varTexCoord1);
|
||||
|
||||
vec4 Color = Texel0 * BlendFactor;
|
||||
//vec4 Color += Texel1 * (1.0 - BlendFactor);
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 renderLightMap()
|
||||
{
|
||||
vec4 Texel0 = texture2D(uTextureUnit0, varTexCoord0);
|
||||
//vec4 Texel1 = texture2D(uTextureUnit1, varTexCoord1);
|
||||
|
||||
vec4 Color = Texel0 * 4.0;
|
||||
//Color *= Texel1;
|
||||
Color.a = Texel0.a * Texel0.a;
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 renderDetailMap()
|
||||
{
|
||||
vec4 Texel0 = texture2D(uTextureUnit0, varTexCoord0);
|
||||
//vec4 Texel1 = texture2D(uTextureUnit1, varTexCoord1);
|
||||
|
||||
vec4 Color = Texel0;
|
||||
//Color += Texel1 - 0.5;
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 renderReflection2Layer()
|
||||
{
|
||||
vec4 Color = varVertexColor;
|
||||
|
||||
vec4 Texel0 = texture2D(uTextureUnit0, varTexCoord0);
|
||||
//vec4 Texel1 = texture2D(uTextureUnit1, varTexCoord1);
|
||||
|
||||
Color *= Texel0;
|
||||
//Color *= Texel1;
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 renderTransparent()
|
||||
{
|
||||
vec4 Color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
if(uTextureUsage0)
|
||||
{
|
||||
Color *= texture2D(uTextureUnit0, varTexCoord0);
|
||||
if (uHueChange > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(Color.rgb);
|
||||
vec2 new_xy = vec2(uHueChange, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
Color.rgb = vec3(new_color.r, new_color.g, new_color.b);
|
||||
}
|
||||
}
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
vec4 renderTransparentVertexColor()
|
||||
{
|
||||
vec4 Color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
if(uTextureUsage0)
|
||||
{
|
||||
Color *= texture2D(uTextureUnit0, varTexCoord0);
|
||||
if (uHueChange > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(Color.rgb);
|
||||
vec2 new_xy = vec2(uHueChange, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
Color.rgb = vec3(new_color.r, new_color.g, new_color.b);
|
||||
}
|
||||
vec4 mixed_color = varVertexColor * uVertexColor;
|
||||
Color *= mixed_color;
|
||||
}
|
||||
|
||||
return Color;
|
||||
}
|
||||
|
||||
void main ()
|
||||
{
|
||||
if (uMaterialType == Solid)
|
||||
gl_FragColor = renderSolid();
|
||||
else if(uMaterialType == Solid2Layer)
|
||||
gl_FragColor = render2LayerSolid();
|
||||
else if(uMaterialType == LightMap)
|
||||
gl_FragColor = renderSolid();
|
||||
else if(uMaterialType == DetailMap)
|
||||
gl_FragColor = renderDetailMap();
|
||||
else if(uMaterialType == SphereMap)
|
||||
gl_FragColor = renderSolid();
|
||||
else if(uMaterialType == Reflection2Layer)
|
||||
gl_FragColor = renderReflection2Layer();
|
||||
else if(uMaterialType == TransparentAlphaChannel)
|
||||
gl_FragColor = renderTransparent();
|
||||
else if(uMaterialType == TransparentAlphaChannelRef)
|
||||
{
|
||||
vec4 Color = renderTransparentVertexColor();
|
||||
if (Color.a < 0.5)
|
||||
discard;
|
||||
gl_FragColor = Color;
|
||||
}
|
||||
else if(uMaterialType == StkGrass)
|
||||
{
|
||||
vec4 Color = renderTransparent();
|
||||
if (Color.a < 0.5)
|
||||
discard;
|
||||
gl_FragColor = Color;
|
||||
}
|
||||
else if(uMaterialType == StkBlend)
|
||||
{
|
||||
gl_FragColor = renderTransparentVertexColor();
|
||||
}
|
||||
else if(uMaterialType == TransparentVertexAlpha)
|
||||
{
|
||||
vec4 Color = renderTransparent();
|
||||
Color.a = varVertexColor.a;
|
||||
|
||||
gl_FragColor = Color * uVertexColor;
|
||||
}
|
||||
else if(uMaterialType == TransparentReflection2Layer)
|
||||
{
|
||||
vec4 Color = renderReflection2Layer();
|
||||
Color.a = varVertexColor.a;
|
||||
|
||||
gl_FragColor = Color;
|
||||
}
|
||||
else
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* Attributes */
|
||||
|
||||
attribute vec3 inVertexPosition;
|
||||
attribute vec3 inVertexNormal;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec2 inTexCoord0;
|
||||
//attribute vec2 inTexCoord1;
|
||||
|
||||
/* Uniforms */
|
||||
|
||||
uniform mat4 uMvpMatrix;
|
||||
|
||||
uniform vec2 uTextureTrans0;
|
||||
//uniform mat4 uTextureMatrix1;
|
||||
|
||||
/* Varyings */
|
||||
|
||||
varying vec2 varTexCoord0;
|
||||
//varying vec2 varTexCoord1;
|
||||
varying vec4 varVertexColor;
|
||||
varying float varEyeDist;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = uMvpMatrix * vec4(inVertexPosition,1.0);
|
||||
|
||||
varTexCoord0 = inTexCoord0 + uTextureTrans0;
|
||||
|
||||
//vec4 TexCoord1 = vec4(inTexCoord1.x, inTexCoord1.y, 0.0, 0.0);
|
||||
//varTexCoord1 = vec4(uTextureMatrix1 * TexCoord1).xy;
|
||||
|
||||
varVertexColor = inVertexColor.zyxw;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
#define MAX_LIGHTS 2
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
varying vec4 varTexCoord;
|
||||
varying vec3 varLightVector[MAX_LIGHTS];
|
||||
varying vec4 varLightColor[MAX_LIGHTS];
|
||||
|
||||
varying vec4 debug;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// fetch color and normal map
|
||||
vec4 normalMap = texture2D(texture1, varTexCoord.xy) * 2.0 - 1.0;
|
||||
vec4 colorMap = texture2D(texture0, varTexCoord.xy);
|
||||
|
||||
// calculate color of light 0
|
||||
vec4 color = clamp(varLightColor[0], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[0].xyz));
|
||||
|
||||
// calculate color of light 1
|
||||
color += clamp(varLightColor[1], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[1].xyz));
|
||||
|
||||
//luminance * base color
|
||||
color *= colorMap;
|
||||
color.a = varLightColor[0].a;
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
#define MAX_LIGHTS 2
|
||||
|
||||
attribute vec4 inVertexPosition;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec4 inTexCoord0;
|
||||
attribute vec3 inVertexNormal;
|
||||
attribute vec3 inVertexTangent;
|
||||
attribute vec3 inVertexBinormal;
|
||||
|
||||
uniform mat4 uMvpMatrix;
|
||||
uniform vec4 uLightPos[MAX_LIGHTS];
|
||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||
|
||||
varying vec4 varTexCoord;
|
||||
varying vec3 varLightVector[MAX_LIGHTS];
|
||||
varying vec4 varLightColor[MAX_LIGHTS];
|
||||
|
||||
varying vec4 debug;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
debug = vec4(inVertexNormal, 1.0);
|
||||
// transform position to clip space
|
||||
gl_Position = uMvpMatrix * inVertexPosition;
|
||||
|
||||
// vertex - lightpositions
|
||||
vec4 tempLightVector0 = uLightPos[0] - inVertexPosition;
|
||||
vec4 tempLightVector1 = uLightPos[1] - inVertexPosition;
|
||||
|
||||
// transform the light vector 1 with U, V, W
|
||||
varLightVector[0].x = dot(inVertexTangent, tempLightVector0.xyz);
|
||||
varLightVector[0].y = dot(inVertexBinormal, tempLightVector0.xyz);
|
||||
varLightVector[0].z = dot(inVertexNormal, tempLightVector0.xyz);
|
||||
|
||||
|
||||
// transform the light vector 2 with U, V, W
|
||||
varLightVector[1].x = dot(inVertexTangent, tempLightVector1.xyz);
|
||||
varLightVector[1].y = dot(inVertexBinormal, tempLightVector1.xyz);
|
||||
varLightVector[1].z = dot(inVertexNormal, tempLightVector1.xyz);
|
||||
|
||||
// calculate attenuation of light 0
|
||||
varLightColor[0].w = 0.0;
|
||||
varLightColor[0].x = dot(tempLightVector0, tempLightVector0);
|
||||
varLightColor[0].x *= uLightColor[0].w;
|
||||
varLightColor[0] = vec4(inversesqrt(varLightColor[0].x));
|
||||
varLightColor[0] *= uLightColor[0];
|
||||
|
||||
// normalize light vector 0
|
||||
varLightVector[0] = normalize(varLightVector[0]);
|
||||
|
||||
// calculate attenuation of light 1
|
||||
varLightColor[1].w = 0.0;
|
||||
varLightColor[1].x = dot(tempLightVector1, tempLightVector1);
|
||||
varLightColor[1].x *= uLightColor[1].w;
|
||||
varLightColor[1] = vec4(inversesqrt(varLightColor[1].x));
|
||||
varLightColor[1] *= uLightColor[1];
|
||||
|
||||
// normalize light vector 1
|
||||
varLightVector[1] = normalize(varLightVector[1]);
|
||||
|
||||
// move out texture coordinates and original alpha value
|
||||
varTexCoord = inTexCoord0;
|
||||
varLightColor[0].a = inVertexColor.a;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
#define MAX_LIGHTS 2
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
//uniform vec4 uLightDiffuse[MAX_LIGHTS];
|
||||
uniform float uHeightScale;
|
||||
|
||||
varying vec4 varTexCoord;
|
||||
varying vec3 varLightVector[MAX_LIGHTS];
|
||||
varying vec4 varLightColor[MAX_LIGHTS];
|
||||
varying vec3 varEyeVector;
|
||||
|
||||
varying vec4 debug;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// fetch color and normal map
|
||||
vec4 normalMap = texture2D(texture1, varTexCoord.xy) * 2.0 - 1.0;
|
||||
|
||||
// height = height * scale
|
||||
normalMap *= uHeightScale;
|
||||
|
||||
// calculate new texture coord: height * eye + oldTexCoord
|
||||
vec2 offset = varEyeVector.xy * normalMap.w + varTexCoord.xy;
|
||||
|
||||
// fetch new textures
|
||||
vec4 colorMap = texture2D(texture0, offset);
|
||||
normalMap = normalize(texture2D(texture1, offset) * 2.0 - 1.0);
|
||||
|
||||
// calculate color of light 0
|
||||
vec4 color = clamp(varLightColor[0], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[0].xyz));
|
||||
|
||||
// calculate color of light 1
|
||||
color += clamp(varLightColor[1], 0.0, 1.0) * dot(normalMap.xyz, normalize(varLightVector[1].xyz));
|
||||
|
||||
//luminance * base color
|
||||
color *= colorMap;
|
||||
color.a = varLightColor[0].a;
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
#define MAX_LIGHTS 2
|
||||
|
||||
attribute vec4 inVertexPosition;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec4 inTexCoord0;
|
||||
attribute vec3 inVertexNormal;
|
||||
attribute vec3 inVertexTangent;
|
||||
attribute vec3 inVertexBinormal;
|
||||
|
||||
uniform mat4 uMvpMatrix;
|
||||
uniform vec4 uLightPos[MAX_LIGHTS];
|
||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
||||
uniform vec3 uEyePos;
|
||||
|
||||
varying vec4 varTexCoord;
|
||||
varying vec3 varLightVector[MAX_LIGHTS];
|
||||
varying vec4 varLightColor[MAX_LIGHTS];
|
||||
varying vec3 varEyeVector;
|
||||
|
||||
varying vec4 debug;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
debug = vec4(inVertexNormal, 1.0);
|
||||
// transform position to clip space
|
||||
gl_Position = uMvpMatrix * inVertexPosition;
|
||||
|
||||
// vertex - lightpositions
|
||||
vec4 tempLightVector0 = uLightPos[0] - inVertexPosition;
|
||||
vec4 tempLightVector1 = uLightPos[1] - inVertexPosition;
|
||||
|
||||
// eye vector
|
||||
vec4 Temp = vec4(uEyePos, 1.0) - inVertexPosition;
|
||||
|
||||
// transform the light vector 1 with U, V, W
|
||||
varLightVector[0].x = dot(inVertexTangent, tempLightVector0.xyz);
|
||||
varLightVector[0].y = dot(inVertexBinormal, tempLightVector0.xyz);
|
||||
varLightVector[0].z = dot(inVertexNormal, tempLightVector0.xyz);
|
||||
|
||||
|
||||
// transform the light vector 2 with U, V, W
|
||||
varLightVector[1].x = dot(inVertexTangent, tempLightVector1.xyz);
|
||||
varLightVector[1].y = dot(inVertexBinormal, tempLightVector1.xyz);
|
||||
varLightVector[1].z = dot(inVertexNormal, tempLightVector1.xyz);
|
||||
|
||||
// transform the eye vector with U, V, W
|
||||
varEyeVector.x = dot(inVertexTangent, Temp.xyz);
|
||||
varEyeVector.y = dot(inVertexBinormal, Temp.xyz);
|
||||
varEyeVector.z = dot(inVertexNormal, Temp.xyz);
|
||||
varEyeVector *= vec3(1.0,-1.0, -1.0);
|
||||
varEyeVector = normalize(varEyeVector);
|
||||
|
||||
// calculate attenuation of light 0
|
||||
varLightColor[0].w = 0.0;
|
||||
varLightColor[0].x = dot(tempLightVector0, tempLightVector0);
|
||||
varLightColor[0].x *= uLightColor[0].w;
|
||||
varLightColor[0] = vec4(inversesqrt(varLightColor[0].x));
|
||||
varLightColor[0] *= uLightColor[0];
|
||||
|
||||
// normalize light vector 0
|
||||
varLightVector[0] = normalize(varLightVector[0]);
|
||||
|
||||
// calculate attenuation of light 1
|
||||
varLightColor[1].w = 0.0;
|
||||
varLightColor[1].x = dot(tempLightVector1, tempLightVector1);
|
||||
varLightColor[1].x *= uLightColor[1].w;
|
||||
varLightColor[1] = vec4(inversesqrt(varLightColor[1].x));
|
||||
varLightColor[1] *= uLightColor[1];
|
||||
|
||||
// normalize light vector 1
|
||||
varLightVector[1] = normalize(varLightVector[1]);
|
||||
|
||||
// move out texture coordinates and original alpha value
|
||||
varTexCoord = inTexCoord0;
|
||||
varLightColor[0].a = inVertexColor.a;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform bool uUseTexture;
|
||||
uniform sampler2D uTextureUnit;
|
||||
|
||||
varying vec4 vVertexColor;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 Color = vVertexColor;
|
||||
|
||||
if(uUseTexture)
|
||||
Color *= texture2D(uTextureUnit, vTexCoord);
|
||||
|
||||
gl_FragColor = Color;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2009-2010 Amundis
|
||||
// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
|
||||
// and OpenGL ES driver implemented by Christian Stehno
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Irrlicht.h
|
||||
|
||||
attribute vec4 inVertexPosition;
|
||||
attribute vec4 inVertexColor;
|
||||
attribute vec2 inTexCoord0;
|
||||
|
||||
uniform mat4 uOrthoMatrix;
|
||||
|
||||
varying vec4 vVertexColor;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = uOrthoMatrix * inVertexPosition;
|
||||
vVertexColor = inVertexColor.bgra;
|
||||
vTexCoord = inTexCoord0;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
uniform sampler2DArray tex;
|
||||
uniform int layer;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(tex, vec3(uv, float(layer)));
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Lens flare blend
|
||||
based on bloomblend.frag
|
||||
author: samuncle
|
||||
*/
|
||||
uniform sampler2D tex_128;
|
||||
uniform sampler2D tex_256;
|
||||
uniform sampler2D tex_512;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec4 col = .125 * texture(tex_128, uv);
|
||||
col += .25 * texture(tex_256, uv);
|
||||
col += .5 * texture(tex_512, uv);
|
||||
|
||||
// Blue color for lens flare
|
||||
/*col *= 0.5;
|
||||
float final = max(col.r,max(col.g,col.b));
|
||||
final = final * 2;
|
||||
vec3 blue = vec3(final * 0.1, final * 0.2, final);*/
|
||||
|
||||
FragColor = vec4(col.rgb, 1.);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
uniform vec3 intensity;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(intensity, 1.0f);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
uniform sampler2D tex;
|
||||
uniform float zn;
|
||||
uniform float zf;
|
||||
|
||||
out float Depth;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
float d = texture(tex, uv).x;
|
||||
float c0 = zn * zf, c1 = zn - zf, c2 = zf;
|
||||
Depth = c0 / (d * c1 + c2);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
uniform sampler2D edgesMap;
|
||||
uniform sampler2D areaMap;
|
||||
|
||||
#define MAX_SEARCH_STEPS 8.0
|
||||
#define MAX_DISTANCE 33.0
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
/**
|
||||
* This one just returns the first level of a mip map chain, which allow us to
|
||||
* avoid the nasty ddx/ddy warnings, even improving the performance a little
|
||||
* bit.
|
||||
*/
|
||||
vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) {
|
||||
return textureLod(map, texcoord + offset / u_screen, 0.0);
|
||||
}
|
||||
|
||||
float SearchXLeft(vec2 texcoord) {
|
||||
// We compare with 0.9 to prevent bilinear access precision problems.
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchXRight(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchYDown(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
float SearchYUp(vec2 texcoord) {
|
||||
float i;
|
||||
float e = 0.0;
|
||||
for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
|
||||
e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
|
||||
if (e < 0.9) break;
|
||||
}
|
||||
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
vec2 Area(vec2 distance, float e1, float e2) {
|
||||
// * By dividing by areaSize - 1.0 below we are implicitely offsetting to
|
||||
// always fall inside of a pixel
|
||||
// * Rounding prevents bilinear access precision problems
|
||||
float areaSize = MAX_DISTANCE * 5.0;
|
||||
vec2 pixcoord = MAX_DISTANCE * round(4.0 * vec2(e1, e2)) + distance;
|
||||
vec2 texcoord = pixcoord / (areaSize - 1.0);
|
||||
return textureLod(areaMap, texcoord, 0.0).ra;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 areas = vec4(0.0);
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
|
||||
vec2 e = texture(edgesMap, uv).rg;
|
||||
|
||||
if (e.g != 0.0) { // Edge at north
|
||||
|
||||
// Search distances to the left and to the right:
|
||||
vec2 d = vec2(SearchXLeft(uv), SearchXRight(uv));
|
||||
|
||||
// Now fetch the crossing edges. Instead of sampling between edgels, we
|
||||
// sample at 0.25, to be able to discern what value has each edgel:
|
||||
vec4 coords = vec4(d.x, 0.25, d.y + 1.0, 0.25) / u_screen.xyxy + uv.xyxy;
|
||||
float e1 = textureLod(edgesMap, coords.xy, 0.0).r;
|
||||
float e2 = textureLod(edgesMap, coords.zw, 0.0).r;
|
||||
|
||||
// Ok, we know how this pattern looks like, now it is time for getting
|
||||
// the actual area:
|
||||
areas.rg = Area(abs(d), e1, e2);
|
||||
}
|
||||
|
||||
if (e.r != 0.0) { // Edge at west
|
||||
|
||||
// Search distances to the top and to the bottom:
|
||||
vec2 d = vec2(SearchYUp(uv), SearchYDown(uv));
|
||||
|
||||
// Now fetch the crossing edges (yet again):
|
||||
vec4 coords = vec4(-0.25, d.x, -0.25, d.y - 1.0) / u_screen.xyxy + uv.xyxy;
|
||||
float e1 = textureLod(edgesMap, coords.xy, 0.0).g;
|
||||
float e2 = textureLod(edgesMap, coords.zw, 0.0).g;
|
||||
|
||||
// Get the area for this direction:
|
||||
areas.ba = Area(abs(d), e1, e2);
|
||||
}
|
||||
|
||||
FragColor = areas;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
uniform sampler2D colorMapG;
|
||||
|
||||
const float threshold = 0.1;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec3 weights = vec3(0.2126,0.7152, 0.0722); // ITU-R BT. 709
|
||||
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec2 uv_left = uv + vec2(-1., 0.) / u_screen;
|
||||
vec2 uv_top = uv + vec2(0., 1.) / u_screen;
|
||||
vec2 uv_right = uv + vec2(1., 0.) / u_screen;
|
||||
vec2 uv_bottom = uv + vec2(0., -1.) / u_screen;
|
||||
|
||||
/**
|
||||
* Luma calculation requires gamma-corrected colors:
|
||||
*/
|
||||
float L = dot(texture(colorMapG, uv).rgb, weights);
|
||||
float Lleft = dot(texture(colorMapG, uv_left).rgb, weights);
|
||||
float Ltop = dot(texture(colorMapG, uv_top).rgb, weights);
|
||||
float Lright = dot(texture(colorMapG, uv_right).rgb, weights);
|
||||
float Lbottom = dot(texture(colorMapG, uv_bottom).rgb, weights);
|
||||
|
||||
vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom));
|
||||
vec4 edges = step(vec4(threshold), delta);
|
||||
|
||||
if (dot(edges, vec4(1.0)) == 0.0)
|
||||
discard;
|
||||
|
||||
FragColor = edges;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
uniform sampler2D blendMap;
|
||||
uniform sampler2D colorMap;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / u_screen;
|
||||
vec2 uv_left = uv + vec2(-1., 0.) / u_screen;
|
||||
vec2 uv_top = uv + vec2(0., 1.) / u_screen;
|
||||
vec2 uv_right = uv + vec2(1., 0.) / u_screen;
|
||||
vec2 uv_bottom = uv + vec2(0., -1.) / u_screen;
|
||||
|
||||
// Fetch the blending weights for current pixel:
|
||||
vec4 topLeft = texture(blendMap, uv);
|
||||
float bottom = texture(blendMap, uv_bottom).g;
|
||||
float right = texture(blendMap, uv_right).a;
|
||||
vec4 a = vec4(topLeft.r, bottom, topLeft.b, right);
|
||||
|
||||
// Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
|
||||
// a weighted average, where the weight of each line is 'a' cubed, which
|
||||
// favors blending and works well in practice.
|
||||
vec4 w = a * a * a;
|
||||
|
||||
// There is some blending weight with a value greater than 0.0?
|
||||
float sum = dot(w, vec4(1.0));
|
||||
if (sum < 1e-5)
|
||||
discard;
|
||||
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
// Add the contributions of the possible 4 lines that can cross this pixel:
|
||||
vec4 C = texture(colorMap, uv);
|
||||
vec4 Cleft = texture(colorMap, uv_left);
|
||||
vec4 Ctop = texture(colorMap, uv_top);
|
||||
vec4 Cright = texture(colorMap, uv_right);
|
||||
vec4 Cbottom = texture(colorMap, uv_bottom);
|
||||
color = mix(C, Ctop, a.r) * w.r + color;
|
||||
color = mix(C, Cbottom, a.g) * w.g + color;
|
||||
color = mix(C, Cleft, a.b) * w.b + color;
|
||||
color = mix(C, Cright, a.a) * w.a + color;
|
||||
|
||||
// Normalize the resulting color and we are finished!
|
||||
FragColor = vec4(color / sum);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
// motion_blur.frag
|
||||
|
||||
// The actual boost amount (which linearly scales the blur to be shown).
|
||||
// should be in the range [0.0, 1.0], though a larger value might make
|
||||
// the blurring too string. Atm we are using [0, 0.5].
|
||||
uniform float boost_amount;
|
||||
|
||||
// The color buffer to use.
|
||||
uniform sampler2D color_buffer;
|
||||
uniform sampler2D dtex;
|
||||
|
||||
// Center (in texture coordinates) at which the kart is. A small circle
|
||||
// around this center is not blurred (see mask_radius below)
|
||||
uniform vec2 center;
|
||||
|
||||
// Radius of mask around the character in which no blurring happens
|
||||
// so that the kart doesn't get blurred.
|
||||
uniform float mask_radius;
|
||||
|
||||
uniform mat4 previous_viewproj;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// Number of samples used for blurring
|
||||
#define NB_SAMPLES 8
|
||||
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texcoords = gl_FragCoord.xy / u_screen;
|
||||
|
||||
// Sample the color buffer
|
||||
vec3 color = texture(color_buffer, texcoords).rgb;
|
||||
|
||||
float z = texture(dtex, texcoords).x;
|
||||
vec4 ViewPos = getPosFromUVDepth(vec3(texcoords, z), u_inverse_projection_matrix);
|
||||
vec4 OldScreenPos = previous_viewproj * u_inverse_view_matrix * ViewPos;
|
||||
OldScreenPos /= OldScreenPos.w;
|
||||
OldScreenPos = .5 * OldScreenPos + .5;
|
||||
|
||||
// Compute the blur direction.
|
||||
// IMPORTANT: we don't normalize it so that it avoids a glitch around 'center',
|
||||
// plus it naturally scales the motion blur in a cool way :)
|
||||
vec2 blur_dir = texcoords - OldScreenPos.xy;
|
||||
|
||||
// Compute the blurring factor:
|
||||
// - apply the mask, i.e. no blurring in a small circle around the kart
|
||||
float blur_factor = max(0.0, length(texcoords - center) - mask_radius);
|
||||
|
||||
// - apply the boost amount
|
||||
blur_factor *= boost_amount;
|
||||
|
||||
// Scale the blur direction
|
||||
blur_dir *= blur_factor;
|
||||
|
||||
// Compute the blur
|
||||
vec2 inc_vec = blur_dir / vec2(NB_SAMPLES);
|
||||
vec2 blur_texcoords = texcoords - inc_vec * float(NB_SAMPLES) / 2.;
|
||||
for(int i=1 ; i < NB_SAMPLES ; i++)
|
||||
{
|
||||
color += texture(color_buffer, blur_texcoords).rgb;
|
||||
blur_texcoords += inc_vec;
|
||||
}
|
||||
color /= vec3(NB_SAMPLES);
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
uniform sampler2D tex;
|
||||
uniform int width;
|
||||
uniform int height;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = gl_FragCoord.xy / vec2(width, height);
|
||||
FragColor = texture(tex, uv);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
uniform sampler2D ntex;
|
||||
#if defined(GL_ES) && defined(GL_FRAGMENT_PRECISION_HIGH)
|
||||
uniform highp sampler2D dtex;
|
||||
#else
|
||||
uniform sampler2D dtex;
|
||||
#endif
|
||||
|
||||
flat in vec3 center;
|
||||
flat in float energy;
|
||||
flat in vec3 col;
|
||||
flat in float radius;
|
||||
flat in vec4 direction_scale_offset;
|
||||
|
||||
#ifdef GL_ES
|
||||
layout (location = 0) out vec4 Diff;
|
||||
layout (location = 1) out vec4 Spec;
|
||||
#else
|
||||
out vec4 Diff;
|
||||
out vec4 Spec;
|
||||
#endif
|
||||
|
||||
#stk_include "utils/decodeNormal.frag"
|
||||
#stk_include "utils/SpecularBRDF.frag"
|
||||
#stk_include "utils/DiffuseBRDF.frag"
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texc = gl_FragCoord.xy / u_screen;
|
||||
float z = texture(dtex, texc).x;
|
||||
vec3 norm = (u_view_matrix * vec4(DecodeNormal(texture(ntex, texc).xy), 0)).xyz;
|
||||
float roughness = texture(ntex, texc).z;
|
||||
|
||||
vec4 xpos = getPosFromUVDepth(vec3(texc, z), u_inverse_projection_matrix);
|
||||
vec3 eyedir = -normalize(xpos.xyz);
|
||||
|
||||
vec4 pseudocenter = u_view_matrix * vec4(center.xyz, 1.0);
|
||||
pseudocenter /= pseudocenter.w;
|
||||
vec3 light_pos = pseudocenter.xyz;
|
||||
vec3 light_col = col.xyz;
|
||||
vec3 light_to_frag = light_pos - xpos.xyz;
|
||||
float d = length(light_to_frag);
|
||||
float att = energy * 20. / (1. + d * d);
|
||||
att *= (radius - d) / radius;
|
||||
if (att <= 0.) discard;
|
||||
|
||||
// Light Direction
|
||||
vec3 L = light_to_frag / d;
|
||||
// Spotlight
|
||||
float sscale = direction_scale_offset.z;
|
||||
if (sscale != 0.)
|
||||
{
|
||||
vec3 sdir = vec3(direction_scale_offset.xy, 0.);
|
||||
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
|
||||
sdir = (u_view_matrix * vec4(sdir, 0.0)).xyz;
|
||||
float offset = direction_scale_offset.w;
|
||||
float sattenuation = clamp(dot(-sdir, L) *
|
||||
abs(sscale) + offset, 0.0, 1.0);
|
||||
if (sattenuation == 0.)
|
||||
discard;
|
||||
att *= sattenuation * sattenuation;
|
||||
}
|
||||
|
||||
float NdotL = clamp(dot(norm, L), 0., 1.);
|
||||
vec3 Specular = SpecularBRDF(norm, eyedir, L, vec3(1.), roughness);
|
||||
vec3 Diffuse = DiffuseBRDF(norm, eyedir, L, vec3(1.), roughness);
|
||||
|
||||
Diff = vec4(Diffuse * NdotL * light_col * att, 1.);
|
||||
Spec = vec4(Specular * NdotL * light_col * att, 1.);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
in vec3 Position;
|
||||
in float Energy;
|
||||
in vec3 Color;
|
||||
in float Radius;
|
||||
in vec4 Direction_scale_offset;
|
||||
|
||||
flat out vec3 center;
|
||||
flat out float energy;
|
||||
flat out vec3 col;
|
||||
flat out float radius;
|
||||
flat out vec4 direction_scale_offset;
|
||||
|
||||
const float zNear = 1.;
|
||||
|
||||
// Code borrowed from https://software.intel.com/en-us/articles/deferred-rendering-for-current-and-future-rendering-pipelines
|
||||
// Maths explanations are found here http://www.gamasutra.com/view/feature/131351/the_mechanics_of_robust_stencil_.php?page=6
|
||||
|
||||
vec2 UpdateClipRegionRoot(float nc, /* Tangent plane x/y normal coordinate (view space) */
|
||||
float lc, /* Light x/y coordinate (view space) */
|
||||
float lz, /* Light z coordinate (view space) */
|
||||
float lightRadius,
|
||||
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
|
||||
{
|
||||
float nz = (lightRadius - nc * lc) / lz;
|
||||
float pz = (lc * lc + lz * lz - lightRadius * lightRadius) /
|
||||
(lz - (nz / nc) * lc);
|
||||
|
||||
if (pz > 0.) {
|
||||
float c = -nz * cameraScale / nc;
|
||||
if (nc > 0.) // Left side boundary
|
||||
return vec2(c, 1.);
|
||||
else // Right side boundary
|
||||
return vec2(-1., c);
|
||||
}
|
||||
return vec2(-1., 1.);
|
||||
}
|
||||
|
||||
vec2 UpdateClipRegion(float lc, /* Light x/y coordinate (view space) */
|
||||
float lz, /* Light z coordinate (view space) */
|
||||
float lightRadius,
|
||||
float cameraScale /* Project scale for coordinate (_11 or _22 for x/y respectively) */)
|
||||
{
|
||||
float rSq = lightRadius * lightRadius;
|
||||
float lcSqPluslzSq = lc * lc + lz * lz;
|
||||
float d = rSq * lc * lc - lcSqPluslzSq * (rSq - lz * lz);
|
||||
|
||||
// The camera is inside lignt bounding sphere, quad fits whole screen
|
||||
if (d <= 0.)
|
||||
return vec2(-1., 1.);
|
||||
|
||||
float a = lightRadius * lc;
|
||||
float b = sqrt(d);
|
||||
float nx0 = (a + b) / lcSqPluslzSq;
|
||||
float nx1 = (a - b) / lcSqPluslzSq;
|
||||
|
||||
vec2 clip0 = UpdateClipRegionRoot(nx0, lc, lz, lightRadius, cameraScale);
|
||||
vec2 clip1 = UpdateClipRegionRoot(nx1, lc, lz, lightRadius, cameraScale);
|
||||
return vec2(max(clip0.x, clip1.x), min(clip0.y, clip1.y));
|
||||
}
|
||||
|
||||
// Returns bounding box [min.x, max.x, min.y, max.y] in clip [-1, 1] space.
|
||||
vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius)
|
||||
{
|
||||
if (lightPosView.z + lightRadius >= zNear) {
|
||||
vec2 clipX = UpdateClipRegion(lightPosView.x, lightPosView.z, lightRadius, u_projection_matrix[0][0]);
|
||||
vec2 clipY = UpdateClipRegion(lightPosView.y, lightPosView.z, lightRadius, u_projection_matrix[1][1]);
|
||||
|
||||
return vec4(clipX, clipY);
|
||||
}
|
||||
|
||||
return vec4(0.);
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 Center = u_view_matrix * vec4(Position, 1.);
|
||||
Center /= Center.w;
|
||||
|
||||
vec2 ProjectedCornerPosition;
|
||||
vec4 clip = ComputeClipRegion(Center.xyz, Radius);
|
||||
switch (gl_VertexID)
|
||||
{
|
||||
case 0:
|
||||
ProjectedCornerPosition = clip.xz;
|
||||
break;
|
||||
case 1:
|
||||
ProjectedCornerPosition = clip.xw;
|
||||
break;
|
||||
case 2:
|
||||
ProjectedCornerPosition = clip.yz;
|
||||
break;
|
||||
case 3:
|
||||
ProjectedCornerPosition = clip.yw;
|
||||
break;
|
||||
}
|
||||
|
||||
// Work out nearest depth for quad Z
|
||||
// Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped
|
||||
float quadDepth = max(zNear, Center.z - Radius);
|
||||
|
||||
// Project quad depth into clip space
|
||||
vec4 quadClip = u_projection_matrix * vec4(0., 0., quadDepth, 1.0f);
|
||||
gl_Position = vec4(ProjectedCornerPosition, quadClip.z / quadClip.w, 1.);
|
||||
|
||||
col = Color;
|
||||
center = Position;
|
||||
energy = Energy;
|
||||
radius = Radius;
|
||||
direction_scale_offset = Direction_scale_offset;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
uniform sampler2D dtex;
|
||||
uniform float density;
|
||||
uniform vec3 fogcol;
|
||||
|
||||
flat in vec3 center;
|
||||
flat in float energy;
|
||||
flat in vec3 col;
|
||||
flat in float radius;
|
||||
flat in vec4 direction_scale_offset;
|
||||
|
||||
out vec4 Fog;
|
||||
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pseudocenter = u_view_matrix * vec4(center.xyz, 1.0);
|
||||
pseudocenter /= pseudocenter.w;
|
||||
vec3 light_pos = pseudocenter.xyz;
|
||||
vec3 light_col = col.xyz;
|
||||
|
||||
// Compute pixel position
|
||||
vec2 texc = 2. * gl_FragCoord.xy / u_screen;
|
||||
float z = texture(dtex, texc).x;
|
||||
vec4 pixelpos = getPosFromUVDepth(vec3(texc, z), u_inverse_projection_matrix);
|
||||
vec3 eyedir = -normalize(pixelpos.xyz);
|
||||
|
||||
vec3 farthestpoint = - eyedir * (min(dot(-eyedir, light_pos) + radius, length(pixelpos.xyz)));
|
||||
vec3 closestpoint = - eyedir * (dot(-eyedir, light_pos) - radius);
|
||||
if (closestpoint.z < 1.) closestpoint = vec3(0.);
|
||||
|
||||
float stepsize = length(farthestpoint - closestpoint) / 16.;
|
||||
vec3 fog = vec3(0.);
|
||||
vec3 xpos = farthestpoint;
|
||||
vec3 fog_factor = light_col * density * stepsize * energy * 20.;
|
||||
vec3 xpos_step = eyedir * stepsize;
|
||||
|
||||
// Spotlight direction calculation
|
||||
float sscale = direction_scale_offset.z;
|
||||
vec3 sdir;
|
||||
if (sscale != 0.)
|
||||
{
|
||||
sdir = vec3(direction_scale_offset.xy, 0.);
|
||||
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
|
||||
sdir = (u_view_matrix * vec4(sdir, 0.0)).xyz;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
vec3 light_to_pos = light_pos - xpos;
|
||||
float d = length(light_to_pos);
|
||||
float l = (16. - float(i)) * stepsize;
|
||||
vec3 base_att = fog_factor / (1. + d * d) * max((radius - d) / radius, 0.) * exp(- density * d) * exp(- density * l);
|
||||
|
||||
// Apply spotlight attenuation
|
||||
if (sscale != 0.)
|
||||
{
|
||||
float offset = direction_scale_offset.w;
|
||||
float sattenuation = clamp(dot(-sdir, normalize(light_to_pos)) *
|
||||
abs(sscale) + offset, 0.0, 1.0);
|
||||
base_att *= sattenuation * sattenuation;
|
||||
}
|
||||
|
||||
fog += base_att;
|
||||
xpos += xpos_step;
|
||||
}
|
||||
|
||||
Fog = vec4(fogcol * fog, 0.);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 4) in vec2 SecondTexcoord;
|
||||
layout(location = 5) in vec3 Tangent;
|
||||
layout(location = 6) in vec3 Bitangent;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec4 Color;
|
||||
in vec2 Texcoord;
|
||||
in vec2 SecondTexcoord;
|
||||
in vec3 Tangent;
|
||||
in vec3 Bitangent;
|
||||
#endif
|
||||
|
||||
uniform vec2 fullscreen;
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
color = Color.zyxw;
|
||||
vec2 point = Position.xy / fullscreen;
|
||||
point = 2.0 * point - 1.0;
|
||||
point.y *= -1.0;
|
||||
gl_Position = vec4(point, 0.0, 1.0);
|
||||
uv = Texcoord;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec2 Position;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
#else
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
#endif
|
||||
|
||||
out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
uv = Texcoord;
|
||||
gl_Position = vec4(Position, 0., 1.);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D dtex;
|
||||
uniform float billboard;
|
||||
|
||||
in vec2 tc;
|
||||
in vec4 pc;
|
||||
out vec4 FragColor;
|
||||
|
||||
#stk_include "utils/getPosFromUVDepth.frag"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = texture(tex, tc) * pc;
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec2 xy = gl_FragCoord.xy / u_screen;
|
||||
float FragZ = gl_FragCoord.z;
|
||||
vec4 FragmentPos = getPosFromUVDepth(vec3(xy, FragZ), u_inverse_projection_matrix);
|
||||
float EnvZ = texture(dtex, xy).x;
|
||||
vec4 EnvPos = getPosFromUVDepth(vec3(xy, EnvZ), u_inverse_projection_matrix);
|
||||
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
||||
// TODO remove this later if possible when implementing GE
|
||||
alpha = mix(alpha, texture(tex, tc).a, billboard);
|
||||
#else
|
||||
float alpha = 1.0;
|
||||
#endif
|
||||
color = vec4(color.rgb * color.a * alpha, color.a * alpha);
|
||||
FragColor = color;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
uniform int flips;
|
||||
uniform int sky;
|
||||
uniform vec3 view_position;
|
||||
uniform float billboard;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec4 color_lifetime;
|
||||
layout(location = 2) in vec2 size;
|
||||
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 4) in vec2 quadcorner;
|
||||
|
||||
layout(location = 6) in float anglespeed;
|
||||
#else
|
||||
|
||||
in vec3 Position;
|
||||
in vec4 color_lifetime;
|
||||
in vec2 size;
|
||||
|
||||
in vec2 Texcoord;
|
||||
in vec2 quadcorner;
|
||||
|
||||
in float anglespeed;
|
||||
#endif
|
||||
|
||||
out vec2 tc;
|
||||
out vec4 pc;
|
||||
|
||||
vec4 getQuat(float half_sin, float half_cos)
|
||||
{
|
||||
return normalize(vec4(vec3(0.0, 1.0, 0.0) * half_sin, half_cos));
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if (size.x == 0.0 && size.y == 0.0)
|
||||
{
|
||||
gl_Position = vec4(0.);
|
||||
pc = vec4(0.0);
|
||||
tc = vec2(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
float lifetime = size.y;
|
||||
vec2 particle_size = mix(size.xx, size, billboard);
|
||||
tc = Texcoord;
|
||||
pc = color_lifetime.zyxw;
|
||||
|
||||
vec4 viewpos = vec4(0.);
|
||||
if (flips == 1 || sky == 1)
|
||||
{
|
||||
vec4 quat = vec4(0.0);
|
||||
if (flips == 1)
|
||||
{
|
||||
float angle = lifetime * anglespeed;
|
||||
float sin_a = sin(mod(angle / 2.0, 6.283185307179586));
|
||||
float cos_a = cos(mod(angle / 2.0, 6.283185307179586));
|
||||
quat = getQuat(sin_a, cos_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 diff = Position - view_position;
|
||||
float angle = atan(diff.x, diff.z);
|
||||
quat = getQuat(sin(angle / -2.0), cos(angle / -2.0));
|
||||
}
|
||||
vec3 newquadcorner = vec3(particle_size * quadcorner, 0.0);
|
||||
newquadcorner = newquadcorner + 2.0 * cross(cross(newquadcorner,
|
||||
quat.xyz) + quat.w * newquadcorner, quat.xyz);
|
||||
viewpos = u_view_matrix * vec4(Position + newquadcorner, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewpos = u_view_matrix * vec4(Position, 1.0);
|
||||
viewpos += vec4(particle_size * quadcorner, 0.0, 0.0);
|
||||
}
|
||||
gl_Position = u_projection_matrix * viewpos;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
uniform samplerCube tex;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 eyedir = vec3(mod(gl_FragCoord.xy, u_screen) / u_screen, 1.);
|
||||
eyedir = 2.0 * eyedir - 1.0;
|
||||
vec4 tmp = (u_inverse_projection_matrix * vec4(eyedir, 1.));
|
||||
tmp /= tmp.w;
|
||||
eyedir = (u_inverse_view_matrix * vec4(tmp.xyz, 0.)).xyz;
|
||||
vec4 color = texture(tex, eyedir);
|
||||
FragColor = vec4(color.xyz, 1.);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec3 Position;
|
||||
#else
|
||||
in vec3 Position;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position, 1.);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
in float hue_change;
|
||||
|
||||
in vec4 color;
|
||||
in vec3 normal;
|
||||
in vec2 uv;
|
||||
|
||||
layout(location = 0) out vec4 o_diffuse_color;
|
||||
layout(location = 1) out vec4 o_normal_color;
|
||||
|
||||
#stk_include "utils/encode_normal.frag"
|
||||
#stk_include "utils/rgb_conversion.frag"
|
||||
#stk_include "utils/sp_texture_sampling.frag"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (col.a * color.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
if (hue_change > 0.0)
|
||||
{
|
||||
vec3 old_hsv = rgbToHsv(col.rgb);
|
||||
vec2 new_xy = vec2(hue_change, old_hsv.y);
|
||||
vec3 new_color = hsvToRgb(vec3(new_xy.x, new_xy.y, old_hsv.z));
|
||||
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
|
||||
}
|
||||
col.xyz *= color.xyz;
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_diffuse_color = vec4(col.xyz, layer_2.z);
|
||||
|
||||
o_normal_color.xy = EncodeNormal(normalize(normal));
|
||||
o_normal_color.zw = layer_2.xy;
|
||||
#else
|
||||
o_diffuse_color = vec4(col.xyz, 1.0);
|
||||
#endif
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user