Depth, SSAO and blur passes

This commit is contained in:
Lubos Lenco 2016-03-15 11:29:53 +01:00
parent 41f2a799c9
commit 18a1add122
30 changed files with 665 additions and 39 deletions

42
Assets/blur_material.json Normal file
View file

@ -0,0 +1,42 @@
{
"material_resources": [
{
"contexts": [
{
"bind_constants": [
{
"id": "dir",
"vec2": [
1.0,
0.0
]
}
],
"bind_textures": [],
"id": "blur_pass"
}
],
"id": "blur_material_hor",
"shader": "blur_pass/blur_pass"
},
{
"contexts": [
{
"bind_constants": [
{
"id": "dir",
"vec2": [
0.0,
1.0
]
}
],
"bind_textures": [],
"id": "blur_pass"
}
],
"id": "blur_material_ver",
"shader": "blur_pass/blur_pass"
}
]
}

View file

@ -0,0 +1,15 @@
{
"material_resources": [
{
"contexts": [
{
"bind_constants": [],
"bind_textures": [],
"id": "combine_pass"
}
],
"id": "combine_material",
"shader": "combine_pass/combine_pass"
}
]
}

View file

@ -1,16 +0,0 @@
{
"material_resources": [
{
"id": "material_deferred",
"shader": "deferred_pass_resource/deferred_pass",
"cast_shadow": true,
"contexts": [
{
"id": "deferred_pass",
"bind_constants": [],
"bind_textures": []
}
]
}
]
}

BIN
Assets/noise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

BIN
Assets/noise2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

15
Assets/ssao_material.json Normal file
View file

@ -0,0 +1,15 @@
{
"material_resources": [
{
"contexts": [
{
"bind_constants": [],
"bind_textures": [],
"id": "ssao_pass"
}
],
"id": "ssao_material",
"shader": "ssao_pass/ssao_pass"
}
]
}

View file

@ -2214,10 +2214,11 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
for d in defs:
ext += d
ArmoryExporter.asset_references.append('compiled/ShaderResources/' + ArmoryExporter.pipeline_id + '/' + ArmoryExporter.pipeline_id + ext + '.json')
shader_res_name = ArmoryExporter.pipeline_id + ext
o.shader = shader_res_name + '/' + shader_res_name
# Process all passes from pipeline
for pipe_pass in ArmoryExporter.pipeline_passes:
shader_name = pipe_pass + ext
o.shader = shader_name + '/' + shader_name
ArmoryExporter.shader_references.append('compiled/Shaders/' + ArmoryExporter.pipeline_id + '/' + shader_name)
else:
# TODO: gather defs from vertex data when custom shader is used

View file

@ -233,7 +233,7 @@ class Object:
# return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
def buildNodeTrees():
def buildNodeTrees(shader_references, asset_references):
s = bpy.data.filepath.split(os.path.sep)
s.pop()
fp = os.path.sep.join(s)
@ -243,12 +243,12 @@ def buildNodeTrees():
if not os.path.exists('Assets/generated/pipelines'):
os.makedirs('Assets/generated/pipelines')
# Export pipelines
for node_group in bpy.data.node_groups:
if node_group.bl_idname == 'CGPipelineTreeType': # Build only render pipeline trees
buildNodeTree(node_group)
# Export selected pipeline
# node_group.bl_idname == 'CGPipelineTreeType'
node_group = bpy.data.node_groups[bpy.data.cameras[0].pipeline_path]
buildNodeTree(node_group, shader_references, asset_references)
def buildNodeTree(node_group):
def buildNodeTree(node_group, shader_references, asset_references):
output = Object()
res = Object()
output.pipeline_resources = [res]
@ -263,16 +263,23 @@ def buildNodeTree(node_group):
rn = getRootNode(node_group)
if rn == None:
return
buildNode(res, rn, node_group)
# Used to merge bind target nodes into one stage
last_bind_target = None
buildNode(res, rn, node_group, last_bind_target, shader_references, asset_references)
with open(path + node_group_name + '.json', 'w') as f:
f.write(output.to_JSON())
def buildNode(res, node, node_group):
def buildNode(res, node, node_group, last_bind_target, shader_references, asset_references):
stage = Object()
stage.params = []
append_stage = True
if node.bl_idname == 'SetTargetNodeType':
last_bind_target = None
stage.command = 'set_target'
targetNode = findNodeByLink(node_group, node, node.inputs[1])
if targetNode.bl_idname == 'TargetNodeType':
@ -293,6 +300,11 @@ def buildNode(res, node, node_group):
stage.params.append(node.inputs[1].default_value) # Context
elif node.bl_idname == 'BindTargetNodeType':
if last_bind_target is not None:
stage = last_bind_target
append_stage = False
last_bind_target = stage
stage.command = 'bind_target'
targetNode = findNodeByLink(node_group, node, node.inputs[1])
if targetNode.bl_idname == 'TargetNodeType':
@ -304,18 +316,23 @@ def buildNode(res, node, node_group):
stage.command = 'draw_quad'
material_context = node.inputs[1].default_value
stage.params.append(material_context)
# Include resource and shaders
res_name = material_context.rsplit('/', 1)[1]
asset_references.append('compiled/ShaderResources/' + res_name + '/' + res_name + '.json')
shader_references.append('compiled/Shaders/' + res_name + '/' + res_name)
elif node.bl_idname == 'DrawWorldNodeType':
stage.command = 'draw_quad'
wname = bpy.data.worlds[0].name
stage.params.append(wname + '_material/' + wname + '_material/env_map') # Only one world for now
res.stages.append(stage)
if append_stage:
res.stages.append(stage)
# Build next stage
if node.outputs[0].is_linked:
stageNode = findNodeByFromLink(node_group, node, node.outputs[0])
buildNode(res, stageNode, node_group)
buildNode(res, stageNode, node_group, last_bind_target, shader_references, asset_references)
def findNodeByLink(node_group, to_node, inp):
for link in node_group.links:

View file

@ -115,9 +115,10 @@ def exportGameData():
shader_references = []
asset_references = []
# Build nodes # TODO: only if needed
# Build nodes
# TODO: cache
nodes_logic.buildNodeTrees()
nodes_pipeline.buildNodeTrees()
nodes_pipeline.buildNodeTrees(shader_references, asset_references)
nodes_world.buildNodeTrees(shader_references, asset_references) # TODO: Have to build nodes everytime to collect env map resources, should be cached
# TODO: Set armatures to center of world so skin transform is zero
@ -213,9 +214,8 @@ def buildProject(self, build_type=0):
# Build
blender_path = bpy.app.binary_path
blend_path = bpy.data.filepath
p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'lib/build.py', '--', bashCommand, str(build_type), str(bpy.data.worlds[0]['CGProjectTarget'])])
#p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'lib/build.py', '--', prefix + bashCommand, str(build_type), str(bpy.data.worlds[0]['CGProjectTarget'])])
atexit.register(p.terminate)
# p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'lib/build.py', '--', bashCommand, str(build_type), str(bpy.data.worlds[0]['CGProjectTarget'])])
# atexit.register(p.terminate)
self.report({'INFO'}, "Building, see console...")

View file

@ -0,0 +1,111 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D aomap;
uniform sampler2D gmap;
uniform vec2 dir;
in vec2 texCoord;
vec3 normalFromDepth(float depth, vec2 texcoords) {
const vec2 offset1 = vec2(0.0, 0.001);
const vec2 offset2 = vec2(0.001, 0.0);
float depth1 = (texture(gmap, texcoords + offset1).r - 0.5) * 2.0;
float depth2 = (texture(gmap, texcoords + offset2).r - 0.5) * 2.0;
vec3 p1 = vec3(offset1, depth1 - depth);
vec3 p2 = vec3(offset2, depth2 - depth);
vec3 normal = cross(p1, p2);
normal.z = -normal.z;
return normalize(normal);
}
void main() {
float weights[9];
weights[0] = 0.013519569015984728;
weights[1] = 0.047662179108871855;
weights[2] = 0.11723004402070096;
weights[3] = 0.20116755999375591;
weights[4] = 0.240841295721373;
weights[5] = 0.20116755999375591;
weights[6] = 0.11723004402070096;
weights[7] = 0.047662179108871855;
weights[8] = 0.013519569015984728;
float indices[9];
indices[0] = -4;
indices[1] = -3;
indices[2] = -2;
indices[3] = -1;
indices[4] = 0;
indices[5] = 1;
indices[6] = 2;
indices[7] = 3;
indices[8] = 4;
vec2 step = dir / vec2(1136.0, 640.0); //g_resolution.xy;
vec3 normal[9];
float depth = (texture(gmap, texCoord + indices[0]*step).r - 0.5) * 2.0;
normal[0] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[1]*step).r - 0.5) * 2.0;
normal[1] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[2]*step).r - 0.5) * 2.0;
normal[2] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[3]*step).r - 0.5) * 2.0;
normal[3] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[4]*step).r - 0.5) * 2.0;
normal[4] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[5]*step).r - 0.5) * 2.0;
normal[5] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[6]*step).r - 0.5) * 2.0;
normal[6] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[7]*step).r - 0.5) * 2.0;
normal[7] = normalFromDepth(depth, texCoord);
depth = (texture(gmap, texCoord + indices[8]*step).r - 0.5) * 2.0;
normal[8] = normalFromDepth(depth, texCoord);
// normal[0] = texture(gmap, texCoord + indices[0]*step).r;
// normal[1] = texture(gmap, texCoord + indices[1]*step).r;
// normal[2] = texture(gmap, texCoord + indices[2]*step).r;
// normal[3] = texture(gmap, texCoord + indices[3]*step).r;
// normal[4] = texture(gmap, texCoord + indices[4]*step).r;
// normal[5] = texture(gmap, texCoord + indices[5]*step).r;
// normal[6] = texture(gmap, texCoord + indices[6]*step).r;
// normal[7] = texture(gmap, texCoord + indices[7]*step).r;
// normal[8] = texture(gmap, texCoord + indices[8]*step).r;
float total_weight = 1.0;
float discard_threshold = 0.85;
int i;
for(i = 0; i < 9; ++i) {
if (dot(normal[i], normal[4]) < discard_threshold) {
total_weight -= weights[i];
weights[i] = 0;
}
}
float res = 0.0;
for (i = 0; i < 9; ++i) {
res += texture(aomap, texCoord + indices[i]*step).r * weights[i];
}
res /= total_weight;
gl_FragColor = vec4(vec3(res), 1.0);
}

View file

@ -0,0 +1,33 @@
{
"contexts": [
{
"id": "blur_pass",
"params": [
{
"id": "depth_write",
"value": "true"
},
{
"id": "compare_mode",
"value": "always"
},
{
"id": "cull_mode",
"value": "none"
},
{
"id": "blend_source",
"value": "blend_one"
},
{
"id": "blend_destination",
"value": "blend_zero"
}
],
"links": [],
"texture_params": [],
"vertex_shader": "blur_pass.vert.glsl",
"fragment_shader": "blur_pass.frag.glsl"
}
]
}

View file

@ -0,0 +1,35 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D aomap;
in vec2 texCoord;
void main() {
// float depth = (texture(aomap, texCoord).r - 0.5) * 2.0;
float step = 0.002;
// TOP ROW
float s11 = (texture( aomap, texCoord + vec2( -step ) ).r); // LEFT
float s12 = (texture( aomap, texCoord + vec2( 0, -step ) ).r); // MIDDLE
float s13 = (texture( aomap, texCoord + vec2( step , -step ) ).r); // RIGHT
// MIDDLE ROW
float s21 = (texture( aomap, texCoord + vec2( -step, 0.0 ) ).r); // LEFT
float col = (texture( aomap, texCoord ).r); // DEAD CENTER
float s23 = (texture( aomap, texCoord + vec2( -step, 0.0 ) ).r); // RIGHT
// LAST ROW
float s31 = (texture( aomap, texCoord + vec2( -step, step ) ).r); // LEFT
float s32 = (texture( aomap, texCoord + vec2( 0, step ) ).r); // MIDDLE
float s33 = (texture( aomap, texCoord + vec2( step ) ).r); // RIGHT
// Average the color with surrounding samples
col = (col + s11 + s12 + s13 + s21 + s23 + s31 + s32 + s33) / 9.0;
gl_FragColor = vec4(vec3(col), 1.0);
}

View file

@ -0,0 +1,19 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D lightmap;
uniform sampler2D aomap;
in vec2 texCoord;
void main() {
vec3 lcol = texture(lightmap, texCoord).rgb;
vec3 aocol = texture(aomap, texCoord).rgb;
gl_FragColor = vec4(lcol * aocol, 1.0);
// gl_FragColor = vec4(aocol, 1.0);
// gl_FragColor = vec4(lcol, 1.0);
}

View file

@ -0,0 +1,33 @@
{
"contexts": [
{
"id": "combine_pass",
"params": [
{
"id": "depth_write",
"value": "true"
},
{
"id": "compare_mode",
"value": "always"
},
{
"id": "cull_mode",
"value": "none"
},
{
"id": "blend_source",
"value": "blend_one"
},
{
"id": "blend_destination",
"value": "blend_zero"
}
],
"links": [],
"texture_params": [],
"vertex_shader": "combine_pass.vert.glsl",
"fragment_shader": "combine_pass.frag.glsl"
}
]
}

View file

@ -0,0 +1,18 @@
#version 450
#ifdef GL_ES
precision highp float;
#endif
in vec2 pos;
out vec2 texCoord;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
}

View file

@ -14,3 +14,15 @@ make_variants.make('forward.shader.json')
os.chdir('../env_map')
make_resources.make('env_map.shader.json')
make_variants.make('env_map.shader.json')
os.chdir('../ssao_pass')
make_resources.make('ssao_pass.shader.json')
make_variants.make('ssao_pass.shader.json')
os.chdir('../blur_pass')
make_resources.make('blur_pass.shader.json')
make_variants.make('blur_pass.shader.json')
os.chdir('../combine_pass')
make_resources.make('combine_pass.shader.json')
make_variants.make('combine_pass.shader.json')

View file

@ -1,7 +1,7 @@
{
"contexts": [
{
"id": "attrib_pass",
"id": "deferred_attrib",
"params": [
{
"id": "depth_write",
@ -59,8 +59,8 @@
"ifdef": "_Skinning"
}
],
"vertex_shader": "attrib_pass.vert.glsl",
"fragment_shader": "attrib_pass.frag.glsl"
"vertex_shader": "deferred_attrib.vert.glsl",
"fragment_shader": "deferred_attrib.frag.glsl"
}
]
}

View file

@ -1,7 +1,7 @@
{
"contexts": [
{
"id": "deferred_pass",
"id": "deferred_light",
"params": [
{
"id": "depth_write",
@ -30,8 +30,8 @@
"link": "_cameraPosition"
}
],
"vertex_shader": "deferred_pass.vert.glsl",
"fragment_shader": "deferred_pass.frag.glsl"
"vertex_shader": "deferred_light.vert.glsl",
"fragment_shader": "deferred_light.frag.glsl"
}
]
}

View file

@ -0,0 +1,18 @@
#version 450
#ifdef GL_ES
precision highp float;
#endif
in vec2 pos;
out vec2 texCoord;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
}

View file

@ -0,0 +1,16 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
#ifdef _NMTex
#define _AMTex
#endif
in vec4 position;
void main() {
float depth = position.z / position.w;
gl_FragColor = vec4(depth, 0.0, 0.0, 1.0);
}

View file

@ -0,0 +1,48 @@
#version 450
#ifdef GL_ES
precision highp float;
#endif
#ifdef _NMTex
#define _AMTex
#endif
in vec3 pos;
in vec3 nor;
#ifdef _AMTex
in vec2 tex;
#endif
#ifdef _VCols
in vec4 col;
#endif
#ifdef _NMTex
in vec3 tan;
in vec3 bitan;
#endif
#ifdef _Skinning
in vec4 bone;
in vec4 weight;
#endif
#ifdef _Instancing
in vec3 off;
#endif
uniform mat4 M;
uniform mat4 NM;
uniform mat4 V;
uniform mat4 P;
out vec4 position;
void main() {
// #ifdef _Instancing
// gl_Position = M * vec4(pos + off, 1.0);
// #else
// gl_Position = M * vec4(pos, 1.0);
// #endif
gl_Position = P * V * M * vec4(pos, 1.0);
position = gl_Position;
}

View file

@ -18,6 +18,7 @@ uniform sampler2D shadowMap;
uniform sampler2D senvmapRadiance;
uniform sampler2D senvmapIrradiance;
uniform sampler2D senvmapBrdf;
uniform sampler2D gimap;
#ifdef _NMTex
uniform sampler2D snormal;
#endif
@ -65,6 +66,11 @@ in vec3 normal;
// return clamp(max(p, p_max), 0.0, 1.0);
// }
// Just for testing, unrealiable on low precisions
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898, 78.233))) * 43758.5453);
}
float texture2DCompare(vec2 uv, float compare){
float depth = (texture(shadowMap, uv).r - 0.5) * 2.0;
return step(compare, depth);
@ -262,7 +268,7 @@ void main() {
if (receiveShadow) {
if (lPos.w > 0.0) {
visibility = shadowTest(lPos, dotNL);
// visibility = 1.0;
visibility = 1.0;
}
}

View file

@ -0,0 +1,127 @@
#version 450
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D gmap;
uniform float u1;
uniform float u2;
uniform float u3;
uniform float u4;
uniform float u5;
uniform float u6;
in vec2 texCoord;
vec3 rand(vec2 coord) {
float noiseX = fract(sin(dot(coord, vec2(12.9898,78.233))) * 43758.5453) * 2.0 - 1.0;
float noiseY = fract(sin(dot(coord, vec2(12.9898,78.233)*2.0)) * 43758.5453) * 2.0 - 1.0;
float noiseZ = fract(sin(dot(coord, vec2(12.9898,78.233)*3.0)) * 43758.5453) * 2.0 - 1.0;
return vec3(noiseX, noiseY, noiseZ) * 0.001;
}
vec3 normalFromDepth(float depth, vec2 texcoords) {
const vec2 offset1 = vec2(0.0, 0.001);
const vec2 offset2 = vec2(0.001, 0.0);
float depth1 = texture(gmap, texcoords + offset1).r * 2.0 - 1.0;
float depth2 = texture(gmap, texcoords + offset2).r * 2.0 - 1.0;
vec3 p1 = vec3(offset1, depth1 - depth);
vec3 p2 = vec3(offset2, depth2 - depth);
vec3 normal = cross(p1, p2);
normal.z = -normal.z;
return normalize(normal);
}
// vec3 ndc_to_view(vec2 ndc, float depth, vec2 clipPlanes, vec2 tanFov) {
// float z = depth * clipPlanes.x + clipPlanes.y; // go from [0,1] to [zNear, zFar]
// return vec3(ndc * tanFov, -1.0) * z; // view space position
// }
// vec2 view_to_ndc(vec3 view, vec2 clipPlanes, vec2 tanFov) {
// return -view.xy / (tanFov*view.z);
// }
void main() {
const float zn = 1.0;
const float zf = 100.0;
// float zscale = 0.8;
// float total_strength = 1.0;
// float base = 0.15;
// float area = 0.05 * zscale;
// float falloff = 0.002 * zscale;
// float radius = 0.01 * zscale;
float zscale = u1;
float total_strength = u2;
float base = u3;
float area = u4;
float falloff = u5 * zscale;
float radius = u6 * zscale;
const int samples = 16;
vec3 sample_sphere[samples];
sample_sphere[0] = vec3( 0.5381, 0.1856,-0.4319);
sample_sphere[1] = vec3( 0.1379, 0.2486, 0.4430);
sample_sphere[2] = vec3( 0.3371, 0.5679,-0.0057);
sample_sphere[3] = vec3(-0.6999,-0.0451,-0.0019);
sample_sphere[4] = vec3( 0.0689,-0.1598,-0.8547);
sample_sphere[5] = vec3( 0.0560, 0.0069,-0.1843);
sample_sphere[6] = vec3(-0.0146, 0.1402, 0.0762);
sample_sphere[7] = vec3( 0.0100,-0.1924,-0.0344);
sample_sphere[8] = vec3(-0.3577,-0.5301,-0.4358);
sample_sphere[9] = vec3(-0.3169, 0.1063, 0.0158);
sample_sphere[10] = vec3( 0.0103,-0.5869, 0.0046);
sample_sphere[11] = vec3(-0.0897,-0.4940, 0.3287);
sample_sphere[12] = vec3( 0.7119,-0.0154,-0.0918);
sample_sphere[13] = vec3(-0.0533, 0.0596,-0.5411);
sample_sphere[14] = vec3( 0.0352,-0.0631, 0.5460);
sample_sphere[15] = vec3(-0.4776, 0.2847,-0.0271);
vec3 rvec = normalize(rand(texCoord)) * 0.4;
float depth = texture(gmap, texCoord).r * 2.0 - 1.0;
vec3 normal = normalFromDepth(depth, texCoord);
vec3 position = vec3(texCoord, depth);
float radius_depth = radius / (depth);
float occlusion = 0.0;
for (int i = 0; i < samples; ++i) {
vec3 ray = radius_depth * reflect(sample_sphere[i], rvec);
vec3 hemi_ray = position + sign(dot(ray,normal)) * ray;
float occ_depth = texture(gmap, clamp(hemi_ray.xy, 0.0, 1.0)).r * 2.0 - 1.0;
float difference = depth - occ_depth;
occlusion += step(falloff, difference) * (1.0 - smoothstep(falloff, area, difference));
}
float ao = 1.0 - total_strength * occlusion * (1.0 / samples);
float aocol = clamp(ao + base, 0.0, 1.0);
gl_FragColor = vec4(aocol, 0.0, 0.0, 1.0);
// vec2 uTanFovs = vec2(0.83632286848, 0.41398034288);
// float uRadius = 100;
// float uGiBoost = 1.0;
// int uSampleCnt = 16;
// vec2 uClipZ = vec2(0.1, 100.0);
// const float ATTF = 1e-5;
// vec3 p = ndc_to_view(texCoord*2.0-1.0, depth, uClipZ, uTanFovs); // get view pos
// float occ = 0.0;
// float occCnt = 0.0;
// for(int i=0; i<uSampleCnt && depth < 1.0; ++i) {
// vec3 dir = reflect(sample_sphere[i].xyz, rvec); // a la Crysis
// dir -= 2.0*dir*step(dot(normal,dir),0.0); // a la Starcraft
// vec3 sp = p + (dir * uRadius) * (depth * 1e2); // scale radius with depth
// vec2 spNdc = view_to_ndc(sp, uClipZ, uTanFovs); // get sample ndc coords
// float spNd = (texture(gmap, (spNdc*0.5 + 0.5)).r - 0.5) * 2.0;
// vec3 occEye = -sp/sp.z*(spNd*uClipZ.x+uClipZ.y); // compute correct pos
// vec3 occVec = occEye - p; // vector
// float att2 = 1.0+ATTF*length(occVec); // quadratic attenuation
// occ += max(0.0,dot(normalize(occVec),normal)-0.25) / (att2*att2);
// ++occCnt;
// }
// vec3 vocc = occCnt > 0.0 ? vec3(1.0-occ*uGiBoost/occCnt) : vec3(1.0);
// gl_FragColor = vec4(vocc, 1.0);
}

View file

@ -0,0 +1,58 @@
{
"contexts": [
{
"id": "ssao_pass",
"params": [
{
"id": "depth_write",
"value": "true"
},
{
"id": "compare_mode",
"value": "always"
},
{
"id": "cull_mode",
"value": "none"
},
{
"id": "blend_source",
"value": "blend_one"
},
{
"id": "blend_destination",
"value": "blend_zero"
}
],
"links": [
{
"id": "u1",
"link": "_u1"
},
{
"id": "u2",
"link": "_u2"
},
{
"id": "u3",
"link": "_u3"
},
{
"id": "u4",
"link": "_u4"
},
{
"id": "u5",
"link": "_u5"
},
{
"id": "u6",
"link": "_u6"
}
],
"texture_params": [],
"vertex_shader": "ssao_pass.vert.glsl",
"fragment_shader": "ssao_pass.frag.glsl"
}
]
}

View file

@ -0,0 +1,18 @@
#version 450
#ifdef GL_ES
precision highp float;
#endif
in vec2 pos;
out vec2 texCoord;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
}