Initial commit: Final state of the master project
This commit is contained in:
189
Research/shaders/SSDS.frag
Normal file
189
Research/shaders/SSDS.frag
Normal file
@@ -0,0 +1,189 @@
|
||||
#version 430 core
|
||||
|
||||
#define $Material$
|
||||
#if defined(MT_NORMAL) | defined(MT_COLORNORMAL) | defined(MT_COLORNORMALREFLECTIVITY)
|
||||
const bool SHADE_DIFFUSE = false;
|
||||
#else
|
||||
const bool SHADE_DIFFUSE = true;
|
||||
#endif
|
||||
|
||||
in vec2 UV;
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D depthTexture;
|
||||
uniform sampler2D renderTexture;
|
||||
uniform sampler2D voxelPositionsTexture;
|
||||
layout(location = $width$) uniform int width;
|
||||
layout(location = $height$) uniform int height;
|
||||
layout(location = $MVP$) uniform mat4x4 MVP;
|
||||
|
||||
layout(location = $lightDirection$) uniform vec3 lightDirection;
|
||||
layout(location = $lightType$) uniform int lightType;
|
||||
|
||||
const uint range = 1 << ($max_level$ + 1);
|
||||
const float extent = $extent$;
|
||||
const float rangeF = float(range);
|
||||
const float scale = rangeF / (extent * 2.);
|
||||
const float offset = extent + 0.5 / scale;
|
||||
|
||||
const int SAMPLE_DISTANCE = 3;
|
||||
const float MAX_DISTANCE = 0.02 * rangeF;
|
||||
|
||||
const float ssaoRadius = 2.0;
|
||||
const float ssaoPower = 2.0;
|
||||
|
||||
#define SSAO_KERNEL_SIZE 10
|
||||
|
||||
const vec3[SSAO_KERNEL_SIZE] SSAO_KERNEL = {
|
||||
vec3(-0.013627260795642221, -0.08986502062675834, 0.04169623281496606),
|
||||
vec3(0.1530762079182679, -0.07153954612140453, 0.08688940044738859),
|
||||
vec3(0.07090584436998379, 0.1490828023178984, 0.22615631604538947),
|
||||
vec3(-0.15616336851550036, -0.26564930875054044, 0.20480099388003975),
|
||||
vec3(0.26677241220752623, 0.28676826613128037, 0.2412393865541797),
|
||||
vec3(-0.3475187558492847, -0.15578006191669713, 0.39681643948076967),
|
||||
vec3(0.3887426730563284, 0.02398677725666013, 0.5078422675022826),
|
||||
vec3(0.49626198926704007, -0.21014511667561903, 0.49240538984266874),
|
||||
vec3(-0.5032145340980271, 0.5942213554886051, 0.2570527443031691),
|
||||
vec3(0.5983551080400994, 0.25120169632241235, 0.6379411198904361)
|
||||
};
|
||||
|
||||
#define PI 3.14159265
|
||||
|
||||
//vec3 screenToWorld(vec3 screen) {
|
||||
|
||||
// vec4 homogeniousWorld = invMVP * vec4(screen * 2.0 - 1.0, 1);
|
||||
// homogeniousWorld /= homogeniousWorld.z;
|
||||
// return homogeniousWorld.xyz;
|
||||
//}
|
||||
|
||||
vec3 NormalFromTriangleVertices(vec3 triangleVertices[3])
|
||||
{
|
||||
// now is same as RedBook (OpenGL Programming Guide)
|
||||
vec3 u = triangleVertices[0] - triangleVertices[1];
|
||||
vec3 v = triangleVertices[1] - triangleVertices[2];
|
||||
return normalize(cross(u, v));
|
||||
}
|
||||
|
||||
float getDiffuseLight(vec3 normal, vec3 position)
|
||||
{
|
||||
if (lightType == 0) return 1.0;
|
||||
else if (lightType == 1) return max(dot(-lightDirection, normal), 0);
|
||||
else if (lightType == 2)
|
||||
{
|
||||
vec3 toLight = lightDirection / scale - position;
|
||||
vec3 lightDir = normalize(toLight);
|
||||
return max(dot(lightDir, normal), 0);
|
||||
}
|
||||
}
|
||||
|
||||
float rand(vec2 n)
|
||||
{
|
||||
return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
|
||||
}
|
||||
|
||||
vec3 getTangent(vec3 normal)
|
||||
{
|
||||
vec3 tangent;
|
||||
vec3 c1 = cross(normal, vec3(0.0, 0.0, 1.0));
|
||||
vec3 c2 = cross(normal, vec3(0.0, 1.0, 0.0));
|
||||
|
||||
if (length(c1)>length(c2))
|
||||
tangent = c1;
|
||||
else
|
||||
tangent = c2;
|
||||
|
||||
return normalize(tangent);
|
||||
}
|
||||
|
||||
vec3 voxelGridToWorld(vec3 voxelGridCoord)
|
||||
{
|
||||
return (voxelGridCoord / scale) - offset;
|
||||
}
|
||||
|
||||
vec4 worldToScreen(vec3 sam)
|
||||
{
|
||||
vec4 samUV = vec4(sam , 1.0);
|
||||
samUV = MVP * samUV;
|
||||
samUV.xy /= samUV.w;
|
||||
samUV.xy = samUV.xy * 0.5 + 0.5;
|
||||
return samUV;
|
||||
}
|
||||
|
||||
// Calculates the SSAO occlusion
|
||||
float SSAO(vec3 pos, vec3 normal)
|
||||
{
|
||||
// Rotate our kernel
|
||||
vec3 rvec = vec3(rand(UV), rand(normal.xy), rand(pos.xy));
|
||||
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
mat3 tbn = mat3(tangent, bitangent, normal);
|
||||
|
||||
float occlusion = 0.0;
|
||||
for (int i = 0; i < SSAO_KERNEL_SIZE; i++) {
|
||||
// get sample position:
|
||||
vec3 sam = tbn * SSAO_KERNEL[i];
|
||||
sam = sam * ssaoRadius + pos;
|
||||
vec3 towardsSam = sam - pos;
|
||||
float samDot = dot(normal, towardsSam);
|
||||
|
||||
|
||||
// project sample position:
|
||||
vec4 samUV = worldToScreen(sam);
|
||||
|
||||
// get sample depth:
|
||||
vec3 sampledPos = voxelGridToWorld(texture(voxelPositionsTexture, samUV.xy).xyz);
|
||||
vec3 towardsSampledPos = sampledPos - pos;
|
||||
float sampledDot = dot(normal, towardsSampledPos);
|
||||
|
||||
//color = vec4(towardsSampledPos, 1);
|
||||
|
||||
//return abs(sampledDot * 1.0) / rangeF;
|
||||
|
||||
// range check & accumulate:
|
||||
float rangeCheck = abs(sampledDot) < ssaoRadius ? 1.0 : 0.0;
|
||||
occlusion += (sampledDot >= samDot ? 1.0 : 0.0) * rangeCheck;
|
||||
}
|
||||
return pow(1.0 - (occlusion / float(SSAO_KERNEL_SIZE)), ssaoPower);
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
color = texture(renderTexture, UV);
|
||||
|
||||
// Get the voxel positions in the center, left, right, top bottom:
|
||||
ivec2 screenCoord = ivec2(UV * vec2(width, height));
|
||||
vec3 c = texelFetch(voxelPositionsTexture, screenCoord, 0).xyz;
|
||||
vec3 pos = voxelGridToWorld(c);
|
||||
|
||||
if (c == vec3(0)) return; // If no vertex position is known, don't do further processing
|
||||
vec3 l = texelFetch(voxelPositionsTexture, screenCoord + ivec2(-SAMPLE_DISTANCE, 0), 0).xyz;
|
||||
vec3 r = texelFetch(voxelPositionsTexture, screenCoord + ivec2(+SAMPLE_DISTANCE, 0), 0).xyz;
|
||||
vec3 t = texelFetch(voxelPositionsTexture, screenCoord + ivec2(0, +SAMPLE_DISTANCE), 0).xyz;
|
||||
vec3 b = texelFetch(voxelPositionsTexture, screenCoord + ivec2(0, -SAMPLE_DISTANCE), 0).xyz;
|
||||
|
||||
// Check if we need to dispose any location as they are too far away (in world space);
|
||||
bool ignoreL = length(l - c) > MAX_DISTANCE;
|
||||
bool ignoreR = length(r - c) > MAX_DISTANCE;
|
||||
bool ignoreT = length(t - c) > MAX_DISTANCE;
|
||||
bool ignoreB = length(t - b) > MAX_DISTANCE;
|
||||
|
||||
vec3 normal = vec3(0);
|
||||
|
||||
// Make some triangles and calculate the normal based on those triangles
|
||||
if (!ignoreT && !ignoreR) { vec3 triangle1[3] = { t, c, r }; normal += NormalFromTriangleVertices(triangle1); }
|
||||
if (!ignoreR && !ignoreB) { vec3 triangle2[3] = { r, c, b }; normal += NormalFromTriangleVertices(triangle2); }
|
||||
if (!ignoreB && !ignoreL) { vec3 triangle3[3] = { b, c, l }; normal += NormalFromTriangleVertices(triangle3); }
|
||||
if (!ignoreL && !ignoreT) { vec3 triangle4[3] = { l, c, t }; normal += NormalFromTriangleVertices(triangle4); }
|
||||
|
||||
normal = normalize(normal);
|
||||
//color = vec4(normal == vec3(0) ? 1.0 : 0.0); return;
|
||||
//color = vec4(normal, 1); return;
|
||||
|
||||
if (SHADE_DIFFUSE)
|
||||
color *= (0.4 + 0.6 * getDiffuseLight(normal, pos));
|
||||
|
||||
float occlusion = SSAO(pos, normal);
|
||||
color *= occlusion;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user