Reconstruct pos from gbuffer using ray interpolation.

This commit is contained in:
Lubos Lenco 2016-04-20 19:35:22 +02:00
parent e2bc96ecb5
commit 8d0b1f7e0b
26 changed files with 262 additions and 545 deletions

View file

@ -2028,7 +2028,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
#return
ArmoryExporter.option_geometry_only = False
ArmoryExporter.option_geometry_per_file = True
ArmoryExporter.option_minimize = False
ArmoryExporter.option_minimize = bpy.data.worlds[0].CGMinimize
# Only one pipeline for scene for now
# Used for material shader export and khafile

View file

@ -27,7 +27,6 @@ class DrawGeometryNode(Node, CGPipelineTreeNode):
def init(self, context):
self.inputs.new('NodeSocketShader', "Stage")
self.inputs.new('NodeSocketString', "Context")
# self.inputs.new('NodeSocketBool', "Bind World")
self.outputs.new('NodeSocketShader', "Stage")
@ -324,8 +323,10 @@ def unregister():
# Generating pipeline resources
class Object:
def to_JSON(self):
# return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
if bpy.data.worlds[0].CGMinimize == True:
return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
else:
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
def buildNodeTrees(shader_references, asset_references):
s = bpy.data.filepath.split(os.path.sep)

View file

@ -17,8 +17,10 @@ def unregister():
# Generating world resources
class Object:
def to_JSON(self):
# return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
if bpy.data.worlds[0].CGMinimize == True:
return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
else:
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
def buildNodeTrees(shader_references, asset_references):
s = bpy.data.filepath.split(os.path.sep)

View file

@ -27,6 +27,8 @@ project.addLibrary('cyclesgame');
for ref in asset_references: # Assets
f.write("project.addAssets('" + ref + "');\n")
f.write("\nproject.addDefine('WITH_PROFILE')\n")
if bpy.data.worlds[0]['CGPhysics'] != 0:
f.write("\nproject.addDefine('WITH_PHYSICS')\n")
f.write("project.addLibrary('haxebullet')\n")

View file

@ -10,13 +10,11 @@ in vec2 texCoord;
void main() {
vec4 col = texture(tex, texCoord);
float brightness = dot(col.rgb, vec3(0.2126, 0.7152, 0.0722));
if (brightness > 0.99) {
gl_FragColor = vec4(col.rgb, 1.0);
gl_FragColor.rgb = vec3(col.rgb);
return;
}
gl_FragColor = vec4(0.0);
// gl_FragColor = col;
gl_FragColor.rgb = vec3(0.0);
}

View file

@ -9,12 +9,11 @@ uniform vec2 dir;
in vec2 texCoord;
// const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
const vec2 screenSize = vec2(800, 600);
const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
void main() {
// vec2 step = dir / vec2(400, 300);
vec2 step = dir / vec2(960, 540);
// vec2 step = dir / vec2(800, 600);
vec2 step = dir / screenSize;
// vec3 result = texture(tex, texCoord).rgb * weight[0];
// result += texture(tex, texCoord + step * 1).rgb * weight[1];
@ -27,18 +26,18 @@ void main() {
// result += texture(tex, texCoord - step * 4).rgb * weight[4];
// gl_FragColor = vec4(vec3(result), 1.0);
float res = texture( tex, texCoord + (step * 4.0) ).r;
res += texture( tex, texCoord + (step * 3.0) ).r;
res += texture( tex, texCoord + (step * 2.0) ).r;
res += texture( tex, texCoord + step ).r;
res += texture( tex, texCoord ).r;
res += texture( tex, texCoord -step ).r;
res += texture( tex, texCoord -(step * 2.0) ).r;
res += texture( tex, texCoord -(step * 3.0) ).r;
res += texture( tex, texCoord -(step * 4.0) ).r;
float res = texture(tex, texCoord + (step * 4.0)).r;
res += texture(tex, texCoord + (step * 3.0)).r;
res += texture(tex, texCoord + (step * 2.0)).r;
res += texture(tex, texCoord + step).r;
res += texture(tex, texCoord).r;
res += texture(tex, texCoord -step).r;
res += texture(tex, texCoord -(step * 2.0)).r;
res += texture(tex, texCoord -(step * 3.0)).r;
res += texture(tex, texCoord -(step * 4.0)).r;
res /= 9.0;
gl_FragColor = vec4(vec3(res), 1.0);
gl_FragColor.rgb = vec3(res);
// gl_FragColor = texture(tex, texCoord);
}

View file

@ -26,6 +26,5 @@ void main() {
// result = pow(result, vec3(1.0 / gamma));
// gl_FragColor = vec4(result, 1.0f);
gl_FragColor = vec4(col, 1.0);
gl_FragColor.rgb = col;
}

View file

@ -7,7 +7,6 @@ precision highp float;
uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform vec3 eye;
uniform vec3 light;

View file

@ -10,7 +10,6 @@ precision mediump float;
uniform sampler2D tex;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
const float znear = 0.1;
const float zfar = 100.0;

View file

@ -29,23 +29,25 @@ uniform float metalness;
#endif
uniform float mask;
in vec3 position;
in float depth;
in vec4 mvpposition;
#ifdef _AMTex
in vec2 texCoord;
#endif
in vec4 lPos;
in vec4 matColor;
in vec3 lightDir;
in vec3 eyeDir;
#ifdef _NMTex
in mat3 TBN;
#else
in vec3 normal;
// in vec3 vnormal;
#endif
float packFloat(float f1, float f2) {
int index = int(f1 * 1000);
float alpha = f2 == 0.0 ? f2 : (f2 - 0.0001);
float result = index + alpha;
return result;
}
vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
@ -57,7 +59,6 @@ void main() {
n = normalize(TBN * normalize(n));
#else
vec3 n = normalize(normal);
// vec3 vn = normalize(vnormal);
#endif
#ifdef _AMTex
@ -86,14 +87,11 @@ void main() {
float occlusion = 1.0;
#endif
// float depth = mvpposition.z / mvpposition.w;
// occlusion - pack with mask
n /= (abs(n.x) + abs(n.y) + abs(n.z));
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
gl_FragData[0] = vec4(n.xy, mask, depth);
gl_FragData[1] = vec4(position.xyz, roughness);
gl_FragData[2] = vec4(baseColor.rgb, metalness);
gl_FragData[0] = vec4(n.xy, mask, 1.0 - (mvpposition.z / mvpposition.w));
gl_FragData[1] = vec4(baseColor.rgb, packFloat(roughness, metalness));
}

View file

@ -29,7 +29,6 @@ in vec3 off;
uniform mat4 M;
uniform mat4 NM;
// uniform mat4 VNM;
uniform mat4 V;
uniform mat4 MV;
uniform mat4 P;
@ -41,8 +40,6 @@ uniform vec3 eye;
uniform float skinBones[50 * 12];
#endif
out vec3 position;
out float depth;
out vec4 mvpposition;
#ifdef _AMTex
out vec2 texCoord;
@ -55,7 +52,6 @@ out vec3 eyeDir;
out mat3 TBN;
#else
out vec3 normal;
out vec3 vnormal;
#endif
#ifdef _Skinning
@ -104,8 +100,6 @@ void main() {
#endif
lPos = LMVP * sPos;
// mat4 MV = V * M;
#ifdef _Billboard
// Spherical
MV[0][0] = 1.0; MV[0][1] = 0.0; MV[0][2] = 0.0;
@ -126,7 +120,6 @@ void main() {
vec3 _normal = normalize(mat3(NM) * (nor * skinningMatVec));
#else
vec3 _normal = normalize(mat3(NM) * nor);
// vec3 _vnormal = normalize(mat3(VNM) * nor);
#endif
matColor = albedo_color;
@ -135,18 +128,7 @@ void main() {
matColor *= col;
#endif
vec3 mPos = vec4(M * sPos).xyz;
position = mPos;
vec4 vp = V * vec4(mPos, 1.0);
vec3 vposition = vp.xyz / vp.w;
float zNear = 0.1;
float zFar = 1000.0;
depth = (-vposition.z-zNear)/(zFar-zNear);
mvpposition = gl_Position;
lightDir = light - mPos;
eyeDir = eye - mPos;
#ifdef _NMTex
vec3 tangent = (mat3(NM) * (tan));
@ -154,6 +136,5 @@ void main() {
TBN = mat3(tangent, bitangent, _normal);
#else
normal = _normal;
// vnormal = _vnormal;
#endif
}

View file

@ -12,11 +12,12 @@ in vec4 position;
void main() {
float depth = position.z / position.w;
// float depth = position.z / position.w;
// depth += 0.005;
// gl_FragDepth = depth;
gl_FragColor = vec4(depth, 0.0, 0.0, 1.0);
// gl_FragColor = vec4(depth, 0.0, 0.0, 1.0);
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
// VSM
// float dx = dFdx(depth);

View file

@ -9,7 +9,7 @@ precision mediump float;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer2;
uniform sampler2D ssaotex;
@ -18,15 +18,14 @@ uniform sampler2D senvmapRadiance;
uniform sampler2D senvmapIrradiance;
uniform sampler2D senvmapBrdf;
uniform mat4 invP;
uniform mat4 invV;
uniform mat4 invVP;
// uniform mat4 invVP;
uniform mat4 LMVP;
uniform vec3 light;
uniform vec3 eye;
uniform vec3 eyeLook;
in vec2 texCoord;
in vec3 vViewRay;
in vec3 viewRay;
vec2 envMapEquirect(vec3 normal) {
float phi = acos(normal.z);
@ -36,7 +35,8 @@ vec2 envMapEquirect(vec3 normal) {
float getMipLevelFromRoughness(float roughness) {
// First mipmap level = roughness 0, last = roughness = 1
// 6 mipmaps + base
// 6 mipmaps + baseColor
// TODO: set number of mipmaps
return roughness * 7.0;
}
@ -138,32 +138,38 @@ vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
vec3 worldPosFromDepth(float zOverW) {
// Get the depth buffer value at this pixel
// float zOverW = depth; // * 2.0 - 1.0
// H is the viewport position at this pixel in the range -1 to 1
// vec4 H = vec4(texCoord.x * 2.0 - 1.0, (texCoord.y) * 2.0 - 1.0, zOverW, 1.0);
// Transform by the view-projection inverse
// vec4 D = invVP * H;
// Divide by w to get the world position
// vec4 worldPos = D / D.w;
// return vec3(D.xyz / D.w);
vec3 getPos(float depth) {
// vec4 pos = vec4(coord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
// vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
// pos = invVP * pos;
// pos.xyz /= pos.w;
// return pos.xyz;
vec3 ndc = vec3(texCoord*2.0-1.0, zOverW*2.0-1.0);
vec4 v0 = invP*vec4(ndc, 1.0);
vec3 reconViewPos = v0.xyz/v0.w;
vec4 reconWorldPos = invV * v0;
return reconWorldPos.xyz / reconWorldPos.w;
vec3 vray = normalize(viewRay);
const float znear = 0.1;
const float zfar = 1000.0;
const float projectionA = zfar / (zfar - znear);
const float projectionB = (-zfar * znear) / (zfar - znear);
// float linearDepth = projectionB / (depth - projectionA);
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
float viewZDist = dot(eyeLook, vray);
vec3 wposition = eye + vray * (linearDepth / viewZDist);
return wposition;
}
vec2 unpackFloat(float f) {
float index = floor(f) / 1000.0;
float alpha = fract(f);
return vec2(index, alpha);
}
void main() {
vec4 g0 = texture(gbuffer0, texCoord); // Normals, depth
float depth = g0.a;
if (depth >= 1.0) discard;
float depth = 1.0 - g0.a;
if (depth == 0.0) discard;
vec4 g1 = texture(gbuffer1, texCoord); // Positions, roughness
vec4 g2 = texture(gbuffer2, texCoord); // Base color, metalness
vec4 g1 = texture(gbuffer1, texCoord); // Base color, roughness
vec4 g2 = texture(gbuffer2, texCoord); // 0,0,0, metalness
float ao = texture(ssaotex, texCoord).r;
vec2 enc = g0.rg;
@ -172,20 +178,11 @@ void main() {
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);
// vec3 n = g0.rgb;
// vec3 p = worldPosFromDepth(depth);
const float zNear = 0.1;
const float zFar = 1000.0;
vec3 reconViewPos = vViewRay * (-(depth*(zFar-zNear)+zNear));
vec3 p = vec4(invV * vec4(reconViewPos, 1.0)).xyz;
// vec3 p = g1.rgb;
//n = normalize(n);
vec3 baseColor = g2.rgb;
float roughness = g1.a;
float metalness = g2.a;
vec3 p = getPos(depth);
vec3 baseColor = g1.rgb;
vec2 roughmet = unpackFloat(g1.a);
float roughness = roughmet.x;
float metalness = roughmet.y;
// float occlusion = g2.a;
vec3 lightDir = light - p.xyz;

View file

@ -25,18 +25,14 @@
"id": "eye",
"link": "_cameraPosition"
},
{
"id": "eyeLook",
"link": "_cameraLook"
},
{
"id": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"id": "invV",
"link": "_inverseViewMatrix"
},
{
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "LMVP",
"link": "_lightModelViewProjectionMatrix"

View file

@ -4,24 +4,25 @@
precision highp float;
#endif
uniform mat4 invP;
uniform mat4 invVP;
uniform vec3 eye;
in vec2 pos;
out vec2 texCoord;
out vec3 vViewRay;
out vec3 viewRay;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0); //ndc (at the back of cube)
v = invP * v;
v /= v.w; //view coordinate
v /= v.z; //normalize by z for scaling
vViewRay = v.xyz;
gl_Position = vec4(pos.xy, 0.0, 1.0);
// NDC (at the back of cube)
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
v = vec4(invVP * v);
v.xyz /= v.w;
viewRay = v.xyz - eye;
}

View file

@ -7,44 +7,36 @@ precision mediump float;
#endif
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer1;
uniform sampler2D tex;
uniform mat4 prevVP;
uniform mat4 invVP;
uniform mat4 invV;
uniform vec3 eye;
uniform vec3 eyeLook;
in vec3 vViewRay;
in vec3 viewRay;
in vec2 texCoord;
const int samples = 8;
vec2 getVelocity(vec2 texCoord, float depth) {
const float zNear = 0.1;
const float zFar = 1000.0;
float delinDepth = (-(depth*(zFar-zNear)+zNear));
// Get the depth buffer value at this pixel
// float zOverW = depth; // * 2.0 - 1.0
// H is the viewport position at this pixel in the range -1 to 1
// vec4 H = vec4(texCoord.x * 2.0 - 1.0, (texCoord.y) * 2.0 - 1.0, zOverW, 1.0);
vec4 H = vec4(texCoord.x * 2.0 - 1.0, (texCoord.y) * 2.0 - 1.0, delinDepth, 1.0);
// Transform by the view-projection inverse
// vec4 D = invVP * H;
// Divide by w to get the world position
// vec4 worldPos = D / D.w;
vec3 reconViewPos = vViewRay * delinDepth;
vec3 p = vec4(invV * vec4(reconViewPos, 1.0)).xyz;
vec4 worldPos = vec4(p, 1.0);
// Current viewport position
vec4 currentPos = H;
// Use the world position, and transform by the previous view-projection matrix
vec3 getPos(float depth, vec2 coord) {
vec3 vray = normalize(viewRay);
const float znear = 0.1;
const float zfar = 1000.0;
const float projectionA = zfar / (zfar - znear);
const float projectionB = (-zfar * znear) / (zfar - znear);
float linearDepth = projectionB / (depth * 0.5 + 0.5 - projectionA);
float viewZDist = dot(eyeLook, vray);
vec3 wposition = eye + vray * (linearDepth / viewZDist);
return wposition;
}
vec2 getVelocity(vec2 coord, float depth) {
vec4 currentPos = vec4(coord.xy * 2.0 - 1.0, depth, 1.0);
vec4 worldPos = vec4(getPos(depth, coord), 1.0);
vec4 previousPos = prevVP * worldPos;
previousPos /= previousPos.w;
// Use this frame's position and last frame's to compute the pixel velocity
vec2 velocity = (currentPos - previousPos).xy / 40.0;
return velocity;
}
@ -58,18 +50,18 @@ void main() {
return;
}
vec4 g0 = texture(gbuffer0, texCoord);
float depth = g0.a;
float depth = 1.0 - texture(gbuffer0, texCoord).a;
if (depth == 0.0) {
gl_FragColor = color;
return;
}
float blurScale = 1.0; //currentFps / targeFps;
vec2 velocity = getVelocity(texCoord, depth) * blurScale * (-1.0);
vec2 offset = texCoord;
int processed = 1;
// for(int i = 1; i < samples; ++i) {
// Sample the color buffer along the velocity vector
// offset += velocity;
// color += texture(tex, offset);
offset += velocity;
if (texture(gbuffer0, offset).b != 1.0) {
color += texture(tex, offset);
@ -118,8 +110,7 @@ void main() {
processed++;
}
// }
// vec4 finalColor = color / samples;
vec4 finalColor = color / processed;
gl_FragColor = finalColor;
}

View file

@ -26,12 +26,12 @@
"link": "_inverseViewProjectionMatrix"
},
{
"id": "invV",
"link": "_inverseViewMatrix"
"id": "eye",
"link": "_cameraPosition"
},
{
"id": "invP",
"link": "_inverseProjectionMatrix"
"id": "eyeLook",
"link": "_cameraLook"
}
],
"texture_params": [],

View file

@ -4,24 +4,25 @@
precision highp float;
#endif
uniform mat4 invP;
uniform mat4 invVP;
uniform vec3 eye;
in vec2 pos;
out vec2 texCoord;
out vec3 vViewRay;
out vec3 viewRay;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
gl_Position = vec4(pos.xy, 0.0, 1.0);
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0); //ndc (at the back of cube)
v = invP * v;
v /= v.w; //view coordinate
v /= v.z; //normalize by z for scaling
vViewRay = v.xyz;
// NDC (at the back of cube)
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
v = vec4(invVP * v);
v.xyz /= v.w;
viewRay = v.xyz - eye;
}

View file

@ -11,7 +11,6 @@
// y1 = Std.int(y1 * 10000000) / 10000000;
// trace(x1, y1);
// }
#version 450
#ifdef GL_ES
@ -19,54 +18,58 @@ precision mediump float;
#endif
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer1;
uniform sampler2D snoise;
uniform mat4 invV;
uniform mat4 invP;
uniform mat4 invVP;
uniform vec3 eye;
const float PI = 3.1415926535;
const vec2 screenSize = vec2(800.0, 600.0);
// const vec2 screenSize = vec2(1920.0, 1080.0);
const float aoSize = 0.2;//0.43;
const int kernelSize = 8;
const float strength = 0.1;//0.55;
const vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
const int kernelSize = 8;
const float aoSize = 0.04;
const float strength = 0.3;
in vec3 vViewRay;
in vec2 texCoord;
float linearize(float depth, float znear, float zfar) {
return -zfar * znear / (depth * (zfar - znear) - zfar);
}
// float rand(vec2 co) { // Unreliable
// return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
// return fract(sin(dot(co.xy ,vec2(12.9898, 78.233))) * 43758.5453);
// }
vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
vec3 getWorldPos(vec2 coord) {
const float zNear = 0.1;
const float zFar = 1000.0;
float depth = texture(gbuffer0, coord).a;
vec3 reconViewPos = vViewRay * (-(depth*(zFar-zNear)+zNear));
vec4 wp = invV * vec4(reconViewPos, 1.0);
return wp.xyz;
vec3 getPos(float depth, vec2 coord) {
// vec4 pos = vec4(coord * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
vec4 pos = vec4(coord * 2.0 - 1.0, depth, 1.0);
pos = invVP * pos;
pos.xyz /= pos.w;
return pos.xyz - eye;
}
// vec3 getViewPos(vec2 coord) {
// float x = coord.s * 2.0 - 1.0;
// float y = coord.t * 2.0 - 1.0;
// float z = texture(gbuffer0, coord).b;
// z = z * 2.0 - 1.0;
// vec4 posProj = vec4(x, y, z, 1.0);
// vec4 posView = invP * posProj;
// }
float doAO(vec2 kernelVec, vec2 randomVec, mat2 rotMat, vec3 currentPos, vec3 currentNormal, float currentDistance) {
kernelVec.xy *= aspectRatio;
float radius = aoSize * randomVec.y;
kernelVec.xy = ((rotMat * kernelVec.xy) / currentDistance) * radius;
vec2 coord = texCoord + kernelVec.xy;
float depth = 1.0 - texture(gbuffer0, coord).a;
vec3 pos = getPos(depth, coord) - currentPos;
float angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) / min(currentDistance * 0.25, 1.0) + 0.00001; // Fix darkening
return angle;
}
void main() {
void main() {
float depth = 1.0 - texture(gbuffer0, texCoord).a;
if (depth == 0.0) {
gl_FragColor = vec4(1.0);
return;
}
vec2 kernel[kernelSize];
kernel[0] = vec2(1.0, 0.0);
kernel[1] = vec2(0.7071067, 0.7071067);
@ -89,239 +92,30 @@ void main() {
// kernel[10] = vec2(0.4999999, -0.8660254);
// kernel[11] = vec2(0.8660254, -0.5);
vec4 g0 = texture(gbuffer0, texCoord);
vec4 g1 = texture(gbuffer1, texCoord);
vec2 enc = texture(gbuffer0, texCoord).rg;
vec3 currentNormal;
currentNormal.z = 1.0 - abs(enc.x) - abs(enc.y);
currentNormal.xy = currentNormal.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
currentNormal = normalize(currentNormal);
vec2 enc = g0.rg;
vec3 N;
N.z = 1.0 - abs(enc.x) - abs(enc.y);
N.xy = N.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
N = normalize(N);
vec3 currentPos = getPos(depth, texCoord);
float currentDistance = length(currentPos);
vec3 P = getWorldPos(texCoord);
// vec3 P = g1.rgb;
// Get the current pixel's positiom
vec3 currentPos = P;
float currentDistance = distance(currentPos, eye);
// float currentDistance = linearize(g0.b, 0.1, 1000.0);
vec3 currentNormal = N;
vec2 aspectRatio = vec2(min(1.0, screenSize.y / screenSize.x), min(1.0, screenSize.x / screenSize.y));
// Grab a random vector from a 8x8 tiled random texture
// vec2 randomVec = vec2(rand(texCoord), rand(texCoord * 2.0));
vec2 randomVec = texture(snoise, (0.5 * texCoord * screenSize) / 8.0).xy;
randomVec *= 2.0;
randomVec -= 1.0;
mat2 rotMat = mat2( vec2( cos( randomVec.x * PI ), -sin( randomVec.x * PI ) ),
vec2( sin( randomVec.x * PI ), cos( randomVec.x * PI ) ) );
vec2 randomVec = texture(snoise, (texCoord * screenSize) / 8.0).xy;
randomVec = randomVec * 2.0 - 1.0;
mat2 rotMat = mat2(vec2(cos(randomVec.x * PI), -sin(randomVec.x * PI)),
vec2(sin(randomVec.x * PI), cos(randomVec.x * PI)));
float amount = 0.0;
// for (int i = 0; i < kernelSize; i++) {
vec2 kernelVec = kernel[0];
kernelVec.xy *= aspectRatio;
float radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
vec3 pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
float angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[1];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[2];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[3];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[4];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[5];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[6];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[7];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
/*
kernelVec = kernel[8];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[9];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[10];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;
kernelVec = kernel[11];
kernelVec.xy *= aspectRatio;
radius = aoSize * randomVec.y;
kernelVec.xy = (rotMat * kernelVec.xy);
kernelVec.xy = (kernelVec.xy / currentDistance) * radius;
pos = texture(gbuffer1, texCoord + kernelVec.xy).rgb;
pos = pos - currentPos;
angle = dot(pos, currentNormal);
angle *= step(0.3, angle / length(pos)); // Fix intersect
angle -= currentDistance * 0.001;
angle = max(0.0, angle);
angle /= dot(pos, pos) + 0.00001; // Fix darkening
// angle /= dot( pos, pos ) / min( currentDistance * 0.25, 1.0 ) + 0.00001;
amount += angle;*/
amount += doAO(kernel[0], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[1], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[2], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[3], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[4], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[5], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[6], randomVec, rotMat, currentPos, currentNormal, currentDistance);
amount += doAO(kernel[7], randomVec, rotMat, currentPos, currentNormal, currentDistance);
// }
amount *= strength / kernelSize;

View file

@ -22,24 +22,12 @@
"link": "_noise8"
},
{
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "invV",
"link": "_inverseViewMatrix"
"id": "invVP",
"link": "_inverseViewProjectionMatrix"
},
{
"id": "eye",
"link": "_cameraPosition"
},
{
"id": "tiV",
"link": "_transposeInverseViewMatrix"
},
{
"id": "P",
"link": "_projectionMatrix"
}
],
"texture_params": [],

View file

@ -4,24 +4,15 @@
precision highp float;
#endif
uniform mat4 invP;
in vec2 pos;
out vec2 texCoord;
out vec3 vViewRay;
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);
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0); //ndc (at the back of cube)
v = invP * v;
v /= v.w; //view coordinate
v /= v.z; //normalize by z for scaling
vViewRay = v.xyz;
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
}

View file

@ -19,8 +19,7 @@ precision mediump float;
uniform mat4 invP;
uniform sampler2D gbuffer0;
uniform sampler2D gbuffer1;
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer1;
in vec2 texCoord;

View file

@ -6,10 +6,8 @@ precision mediump float;
uniform sampler2D tex;
uniform sampler2D gbuffer0; // Normal, depth
uniform sampler2D gbuffer1; // Position, roughness
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer1; // Color, roughness
uniform mat4 P;
uniform mat4 V;
uniform mat4 tiV;
const int maxSteps = 20;
@ -19,12 +17,8 @@ const float rayStep = 0.04;
const float minRayStep = 0.05;
const float searchDist = 4.4;
const float falloffExp = 3.0;
// uniform float rayStep;
// uniform float minRayStep;
// uniform float searchDist;
// uniform float falloffExp;
in vec3 vViewRay;
in vec3 viewRay;
in vec2 texCoord;
vec3 hitCoord;
@ -41,23 +35,19 @@ vec4 getProjectedCoord(vec3 hitCoord) {
return projectedCoord;
}
float getDeltaDepth(vec3 hitCoord) {
float d = texture(gbuffer0, getProjectedCoord(hitCoord).xy).a;
const float zNear = 0.1;
const float zFar = 1000.0;
float delinDepth = (-(d*(zFar-zNear)+zNear));
// vec3 reconViewPos = vViewRay * delinDepth;
// vec3 p = vec4(invV * vec4(reconViewPos, 1.0)).xyz;
// vec4 worldPos = vec4(p, 1.0);
// vec4 viewPos = vec4(texture(gbuffer1, getProjectedCoord(hitCoord).xy).rgb, 1.0);
// viewPos = V * viewPos;
// float depth = viewPos.z;
// return depth - hitCoord.z;
vec3 getPos(float depth) {
const float znear = 0.1;
const float zfar = 1000.0;
const float projectionA = zfar / (zfar - znear);
const float projectionB = (-zfar * znear) / (zfar - znear);
float linearDepth = projectionB / (projectionA - depth);
return viewRay * linearDepth;
}
return delinDepth - hitCoord.z;
float getDeltaDepth(vec3 hitCoord) {
depth = 1.0 - texture(gbuffer0, getProjectedCoord(hitCoord).xy).a;
vec3 viewPos = getPos(depth);
return viewPos.z - hitCoord.z;
}
vec3 binarySearch(vec3 dir) {
@ -82,7 +72,7 @@ vec3 binarySearch(vec3 dir) {
hitCoord -= dir;
if (getDeltaDepth(hitCoord) < 0.0) hitCoord += dir;
// }
return vec3(getProjectedCoord(hitCoord).xy, depth);
return vec3(getProjectedCoord(hitCoord).xy, 0.0);
}
vec4 rayCast(vec3 dir) {
@ -149,27 +139,26 @@ vec4 rayCast(vec3 dir) {
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
hitCoord += dir;
if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// hitCoord += dir;
// if (getDeltaDepth(hitCoord) > 0.0) return vec4(binarySearch(dir), 1.0);
// }
return vec4(0.0, 0.0, 0.0, 0.0);
}
@ -178,44 +167,36 @@ vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
vec2 unpackFloat(float f) {
float index = floor(f) / 1000.0;
float alpha = fract(f);
return vec2(index, alpha);
}
void main() {
float roughness = texture(gbuffer1, texCoord).a;
float roughness = unpackFloat(texture(gbuffer1, texCoord).a).x;
float reflectivity = 1.0 - roughness;
if (reflectivity == 0.0) {
discard;
}
if (reflectivity == 0.0) discard;
vec4 g0 = vec4(texture(gbuffer0, texCoord).rgb, 1.0);
vec4 g0 = texture(gbuffer0, texCoord);
vec2 enc = g0.rg;
vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);
vec4 viewNormal = vec4(n, 1.0);//vec4(texture(gbuffer0, texCoord).rgb, 1.0);
vec4 viewNormal = vec4(n, 1.0);
if (viewNormal.z <= 0.9) discard; // Only up facing surfaces for now
viewNormal = tiV * normalize(viewNormal);
// vec4 viewPos = vec4(texture(gbuffer1, texCoord).rgb, 1.0);
// viewPos = V * viewPos;
float d = texture(gbuffer0, texCoord).a;
const float zNear = 0.1;
const float zFar = 1000.0;
float delinDepth = (-(d*(zFar-zNear)+zNear));
vec3 viewPos = vViewRay * delinDepth;
float d = 1.0 - g0.a;
vec3 viewPos = getPos(d);
vec3 reflected = normalize(reflect((viewPos.xyz), normalize(viewNormal.xyz)));
hitCoord = viewPos.xyz;
vec3 dir = reflected * max(minRayStep, -viewPos.z);// * (1.0 - rand(texCoord) * 0.5);
vec4 coords = rayCast(dir);
// TODO: prevent sampling coords from envmap
vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);

View file

@ -21,17 +21,13 @@
"id": "P",
"link": "_projectionMatrix"
},
{
"id": "invP",
"link": "_inverseProjectionMatrix"
},
{
"id": "V",
"link": "_viewMatrix"
},
{
"id": "tiV",
"link": "_transposeInverseViewMatrix"
},
{
"id": "invP",
"link": "_inverseProjectionMatrix"
}
],
"texture_params": [],

View file

@ -9,19 +9,23 @@ uniform mat4 invP;
in vec2 pos;
out vec2 texCoord;
out vec3 vViewRay;
out vec3 viewRay;
const vec2 madd = vec2(0.5, 0.5);
void main() {
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
// Scale vertex attribute to [0-1] range
texCoord = pos.xy * madd + madd;
gl_Position = vec4(pos.xy, 0.0, 1.0);
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0); //ndc (at the back of cube)
v = invP * v;
v /= v.w; //view coordinate
v /= v.z; //normalize by z for scaling
vViewRay = v.xyz;
gl_Position = vec4(pos.xy, 0.0, 1.0);
// NDC (at the back of cube)
vec4 v = vec4(pos.x, pos.y, 1.0, 1.0);
// v = vec4(invVP * v);
// v.xyz /= v.w;
// viewRay = v.xyz - eye;
v = vec4(invP * v);
// v.xyz /= v.w;
viewRay = vec3(v.xy / v.z, 1.0);
}

View file

@ -8,8 +8,7 @@ precision mediump float;
uniform sampler2D tex;
uniform sampler2D gbuffer0; // Normal, depth
uniform sampler2D gbuffer1; // Position, roughness
uniform sampler2D gbuffer2;
uniform sampler2D gbuffer1; // Color, roughness
uniform mat4 P;
uniform mat4 invP;
uniform mat4 V;