diff --git a/Assets/blur_material.json b/Assets/blur_material.json new file mode 100644 index 00000000..e73b143d --- /dev/null +++ b/Assets/blur_material.json @@ -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" + } + ] +} diff --git a/Assets/combine_material.json b/Assets/combine_material.json new file mode 100644 index 00000000..2e25cbd2 --- /dev/null +++ b/Assets/combine_material.json @@ -0,0 +1,15 @@ +{ + "material_resources": [ + { + "contexts": [ + { + "bind_constants": [], + "bind_textures": [], + "id": "combine_pass" + } + ], + "id": "combine_material", + "shader": "combine_pass/combine_pass" + } + ] +} diff --git a/Assets/deferred_material.json b/Assets/deferred_material.json deleted file mode 100644 index 231e2120..00000000 --- a/Assets/deferred_material.json +++ /dev/null @@ -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": [] - } - ] - } - ] -} diff --git a/Assets/noise.png b/Assets/noise.png new file mode 100644 index 00000000..84e0e668 Binary files /dev/null and b/Assets/noise.png differ diff --git a/Assets/noise2.png b/Assets/noise2.png new file mode 100644 index 00000000..75f850bc Binary files /dev/null and b/Assets/noise2.png differ diff --git a/Assets/ssao_material.json b/Assets/ssao_material.json new file mode 100644 index 00000000..c9627178 --- /dev/null +++ b/Assets/ssao_material.json @@ -0,0 +1,15 @@ +{ + "material_resources": [ + { + "contexts": [ + { + "bind_constants": [], + "bind_textures": [], + "id": "ssao_pass" + } + ], + "id": "ssao_material", + "shader": "ssao_pass/ssao_pass" + } + ] +} diff --git a/blender/armory.py b/blender/armory.py index af1122ee..63ac08b3 100644 --- a/blender/armory.py +++ b/blender/armory.py @@ -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 diff --git a/blender/nodes_pipeline.py b/blender/nodes_pipeline.py index ddddfeec..7f8eb9a5 100755 --- a/blender/nodes_pipeline.py +++ b/blender/nodes_pipeline.py @@ -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: diff --git a/blender/project.py b/blender/project.py index 6f663a89..51b3ab01 100755 --- a/blender/project.py +++ b/blender/project.py @@ -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...") diff --git a/raw/pipeline_resource.json b/raw/_/pipeline_resource.json similarity index 100% rename from raw/pipeline_resource.json rename to raw/_/pipeline_resource.json diff --git a/raw/blur_pass/blur_pass.frag.glsl b/raw/blur_pass/blur_pass.frag.glsl new file mode 100644 index 00000000..7b3724fb --- /dev/null +++ b/raw/blur_pass/blur_pass.frag.glsl @@ -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); +} diff --git a/raw/blur_pass/blur_pass.shader.json b/raw/blur_pass/blur_pass.shader.json new file mode 100755 index 00000000..8208c6d9 --- /dev/null +++ b/raw/blur_pass/blur_pass.shader.json @@ -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" + } + ] +} diff --git a/raw/deferred_pass/deferred_pass.vert.glsl b/raw/blur_pass/blur_pass.vert.glsl similarity index 100% rename from raw/deferred_pass/deferred_pass.vert.glsl rename to raw/blur_pass/blur_pass.vert.glsl diff --git a/raw/blur_pass/blur_pass_compined.frag.glsl b/raw/blur_pass/blur_pass_compined.frag.glsl new file mode 100644 index 00000000..dd74289a --- /dev/null +++ b/raw/blur_pass/blur_pass_compined.frag.glsl @@ -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); +} diff --git a/raw/combine_pass/combine_pass.frag.glsl b/raw/combine_pass/combine_pass.frag.glsl new file mode 100644 index 00000000..239d7030 --- /dev/null +++ b/raw/combine_pass/combine_pass.frag.glsl @@ -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); +} diff --git a/raw/combine_pass/combine_pass.shader.json b/raw/combine_pass/combine_pass.shader.json new file mode 100755 index 00000000..c15075b1 --- /dev/null +++ b/raw/combine_pass/combine_pass.shader.json @@ -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" + } + ] +} diff --git a/raw/combine_pass/combine_pass.vert.glsl b/raw/combine_pass/combine_pass.vert.glsl new file mode 100644 index 00000000..e1cc9c08 --- /dev/null +++ b/raw/combine_pass/combine_pass.vert.glsl @@ -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); +} diff --git a/raw/compile.py b/raw/compile.py index ae60dd62..35e48028 100644 --- a/raw/compile.py +++ b/raw/compile.py @@ -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') diff --git a/raw/attrib_pass/attrib_pass.frag.glsl b/raw/deferred_attrib/_deferred_attrib.frag.glsl similarity index 100% rename from raw/attrib_pass/attrib_pass.frag.glsl rename to raw/deferred_attrib/_deferred_attrib.frag.glsl diff --git a/raw/attrib_pass/attrib_pass.shader.json b/raw/deferred_attrib/deferred_attrib.shader.json similarity index 87% rename from raw/attrib_pass/attrib_pass.shader.json rename to raw/deferred_attrib/deferred_attrib.shader.json index d3b0c5c5..183a1b49 100755 --- a/raw/attrib_pass/attrib_pass.shader.json +++ b/raw/deferred_attrib/deferred_attrib.shader.json @@ -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" } ] } diff --git a/raw/attrib_pass/attrib_pass.vert.glsl b/raw/deferred_attrib/deferred_attrib.vert.glsl similarity index 100% rename from raw/attrib_pass/attrib_pass.vert.glsl rename to raw/deferred_attrib/deferred_attrib.vert.glsl diff --git a/raw/deferred_pass/deferred_pass.frag.glsl b/raw/deferred_light/deferred_light.frag.glsl similarity index 100% rename from raw/deferred_pass/deferred_pass.frag.glsl rename to raw/deferred_light/deferred_light.frag.glsl diff --git a/raw/deferred_pass/deferred_pass.shader.json b/raw/deferred_light/deferred_light.shader.json similarity index 78% rename from raw/deferred_pass/deferred_pass.shader.json rename to raw/deferred_light/deferred_light.shader.json index 76aa3b11..f29cb009 100755 --- a/raw/deferred_pass/deferred_pass.shader.json +++ b/raw/deferred_light/deferred_light.shader.json @@ -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" } ] } diff --git a/raw/deferred_light/deferred_light.vert.glsl b/raw/deferred_light/deferred_light.vert.glsl new file mode 100644 index 00000000..e1cc9c08 --- /dev/null +++ b/raw/deferred_light/deferred_light.vert.glsl @@ -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); +} diff --git a/raw/forward/depthmap.frag.glsl b/raw/forward/depthmap.frag.glsl new file mode 100644 index 00000000..5a46f3b0 --- /dev/null +++ b/raw/forward/depthmap.frag.glsl @@ -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); +} diff --git a/raw/forward/depthmap.vert.glsl b/raw/forward/depthmap.vert.glsl new file mode 100644 index 00000000..2947fe24 --- /dev/null +++ b/raw/forward/depthmap.vert.glsl @@ -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; +} diff --git a/raw/forward/forward.frag.glsl b/raw/forward/forward.frag.glsl index 2a8cf03e..f1f78bc0 100644 --- a/raw/forward/forward.frag.glsl +++ b/raw/forward/forward.frag.glsl @@ -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; } } diff --git a/raw/ssao_pass/ssao_pass.frag.glsl b/raw/ssao_pass/ssao_pass.frag.glsl new file mode 100644 index 00000000..3451db37 --- /dev/null +++ b/raw/ssao_pass/ssao_pass.frag.glsl @@ -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 0.0 ? vec3(1.0-occ*uGiBoost/occCnt) : vec3(1.0); + // gl_FragColor = vec4(vocc, 1.0); +} diff --git a/raw/ssao_pass/ssao_pass.shader.json b/raw/ssao_pass/ssao_pass.shader.json new file mode 100755 index 00000000..30d284df --- /dev/null +++ b/raw/ssao_pass/ssao_pass.shader.json @@ -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" + } + ] +} diff --git a/raw/ssao_pass/ssao_pass.vert.glsl b/raw/ssao_pass/ssao_pass.vert.glsl new file mode 100644 index 00000000..e1cc9c08 --- /dev/null +++ b/raw/ssao_pass/ssao_pass.vert.glsl @@ -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); +}