mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-03 19:06:27 +01:00
Basic spherical effect
This commit is contained in:
parent
fafd7c84be
commit
83dc241cd2
4 changed files with 108 additions and 26 deletions
|
@ -59,7 +59,7 @@ public class ColorMatrices {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/a/8510751
|
// https://stackoverflow.com/a/8510751
|
||||||
public static Matrix4f hueShift(float rot) {
|
public static Matrix4f hueShiftRGB(float rot) {
|
||||||
Matrix4f mat = new Matrix4f();
|
Matrix4f mat = new Matrix4f();
|
||||||
|
|
||||||
mat.loadIdentity();
|
mat.loadIdentity();
|
||||||
|
@ -78,4 +78,14 @@ public class ColorMatrices {
|
||||||
|
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matrix4f hueShiftHSV(float rot) {
|
||||||
|
Matrix4f mat = new Matrix4f();
|
||||||
|
|
||||||
|
mat.loadIdentity();
|
||||||
|
|
||||||
|
//mat.a03 = 0.5f;
|
||||||
|
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,18 +106,30 @@ public class EffectsHandler {
|
||||||
inverseView.invert();
|
inverseView.invert();
|
||||||
program.bindInverseView(inverseView);
|
program.bindInverseView(inverseView);
|
||||||
|
|
||||||
Vector3d pos1 = new Vector3d(330, 0, 110);
|
Vector3d pos1 = new Vector3d(852, 79, -204);
|
||||||
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
|
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||||
|
|
||||||
program.setCameraPos(cameraPos.inverse());
|
program.setCameraPos(cameraPos.inverse());
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
// int n = 20;
|
||||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
// double rad = 15;
|
||||||
.setCenter(pos1.subtract(cameraPos).add(0, 0, i * 10))
|
// for (int i = 0; i < n; i++) {
|
||||||
.setRadius(15)
|
// double angle = ((double) i) / n * Math.PI * 2;
|
||||||
.setFeather(0f)
|
// program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||||
.setFilter(ColorMatrices.hueShift((float) i / 16 * 360 + AnimationTickHolder.getRenderTime())));
|
// .setCenter(pos1.subtract(cameraPos).add(Math.sin(angle) * rad, 0, Math.cos(angle) * rad))
|
||||||
}
|
// .setRadius(10)
|
||||||
|
// .setFeather(0f)
|
||||||
|
// .setFilter(ColorMatrices.hueShiftRGB((float) i / n * 360 + i / 2f)));
|
||||||
|
// }
|
||||||
|
|
||||||
|
Matrix4f filter = ColorMatrices.sepia(1f);
|
||||||
|
|
||||||
|
program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||||
|
.setCenter(pos1.subtract(cameraPos))
|
||||||
|
.setRadius(40)
|
||||||
|
.setFeather(20f)
|
||||||
|
.setHsv(false)
|
||||||
|
.setFilter(filter));
|
||||||
|
|
||||||
program.uploadFilters();
|
program.uploadFilters();
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
protected static final int UBO_BINDING = 4;
|
protected static final int UBO_BINDING = 4;
|
||||||
|
|
||||||
protected static final int SPHERE_FILTER_SIZE = 24 * 4; // <vec4, float + padding, mat4>
|
protected static final int SPHERE_FILTER_SIZE = 24 * 4; // <vec4, float + padding, mat4>
|
||||||
protected static final int MAX_FILTERS = 16; // arbitrary
|
protected static final int MAX_FILTERS = 256; // arbitrary
|
||||||
|
|
||||||
protected static final int EXTRA_INFO = 16; // array length: int + padding
|
protected static final int EXTRA_INFO = 16; // array length: int + padding
|
||||||
protected static final int ALL_FILTERS_SIZE = MAX_FILTERS * SPHERE_FILTER_SIZE;
|
protected static final int ALL_FILTERS_SIZE = MAX_FILTERS * SPHERE_FILTER_SIZE;
|
||||||
|
@ -126,6 +126,8 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
public Vector3d center;
|
public Vector3d center;
|
||||||
public float radius;
|
public float radius;
|
||||||
public float feather;
|
public float feather;
|
||||||
|
public float strength = 1;
|
||||||
|
public boolean hsv;
|
||||||
|
|
||||||
public Matrix4f filter;
|
public Matrix4f filter;
|
||||||
|
|
||||||
|
@ -144,6 +146,16 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FilterSphere setStrength(float strength) {
|
||||||
|
this.strength = strength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterSphere setHsv(boolean hsv) {
|
||||||
|
this.hsv = hsv;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public FilterSphere setFilter(Matrix4f filter) {
|
public FilterSphere setFilter(Matrix4f filter) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
return this;
|
return this;
|
||||||
|
@ -156,9 +168,9 @@ public class SphereFilterProgram extends GlProgram {
|
||||||
(float) center.z,
|
(float) center.z,
|
||||||
radius,
|
radius,
|
||||||
feather,
|
feather,
|
||||||
0, // padding, we could add more parameters here
|
strength,
|
||||||
0,
|
hsv ? 1f : 0f,
|
||||||
0
|
0 // padding, we could add more parameters here
|
||||||
});
|
});
|
||||||
|
|
||||||
buf.put(RenderUtil.writeMatrix(filter));
|
buf.put(RenderUtil.writeMatrix(filter));
|
||||||
|
|
|
@ -16,11 +16,11 @@ uniform vec3 uCameraPos;
|
||||||
|
|
||||||
struct SphereFilter {
|
struct SphereFilter {
|
||||||
vec4 sphere;// <vec3 position, float radius>
|
vec4 sphere;// <vec3 position, float radius>
|
||||||
float feather;
|
vec3 data;// <float feather, float strength, float hsv marker>
|
||||||
mat4 colorOp;
|
mat4 colorOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define N 16
|
#define N 256
|
||||||
layout (std140) uniform Filters {
|
layout (std140) uniform Filters {
|
||||||
int uCount;
|
int uCount;
|
||||||
SphereFilter uSpheres[N];
|
SphereFilter uSpheres[N];
|
||||||
|
@ -31,11 +31,11 @@ float linearizeDepth(float d, float zNear, float zFar) {
|
||||||
return zNear * zFar / (zFar + zNear - clipZ * (zFar - zNear));
|
return zNear * zFar / (zFar + zNear - clipZ * (zFar - zNear));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 filterColor(mat4 colorOp, vec4 frag) {
|
vec3 filterColor(mat4 colorOp, vec3 color) {
|
||||||
// preserve alpha while transforming color
|
// preserve alpha while transforming color
|
||||||
vec4 i = vec4(frag.rgb, 1.);
|
vec4 i = vec4(color, 1.);
|
||||||
i *= colorOp;
|
i *= colorOp;
|
||||||
return vec4(i.rgb, frag.a);
|
return i.rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getDepth() {
|
float getDepth() {
|
||||||
|
@ -44,16 +44,65 @@ float getDepth() {
|
||||||
return linearizeDepth(depth, uNearPlane, uFarPlane);
|
return linearizeDepth(depth, uNearPlane, uFarPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 applyFilters(vec3 worldPos, vec4 diffuse) {
|
float overlayFilterAmount(in vec3 worldPos, in vec4 sphere, in float feather) {
|
||||||
vec4 accum = diffuse;
|
float distance = distance(sphere.xyz, worldPos);
|
||||||
|
return 1 - smoothstep(sphere.w, sphere.w + feather, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sphereFilterAmount(in vec3 worldDir, in float depth, in vec4 sphere, in float feather) {
|
||||||
|
float feathering = 1 - smoothstep(sphere.w, sphere.w + feather, length(sphere.xyz));
|
||||||
|
feathering += overlayFilterAmount(worldDir * depth, sphere, feather);
|
||||||
|
vec3 oc = -sphere.xyz;
|
||||||
|
|
||||||
|
float rayLengthSqr = dot(worldDir, worldDir);
|
||||||
|
float b = 2.0 * dot(-sphere.xyz, worldDir);
|
||||||
|
float sphereDistSqr = dot(sphere.xyz, sphere.xyz);
|
||||||
|
float b2 = b*b;
|
||||||
|
float d = 4. * rayLengthSqr;
|
||||||
|
float e = 1. / (2.0*rayLengthSqr);
|
||||||
|
|
||||||
|
float radius = sphere.w;
|
||||||
|
float c = sphereDistSqr - radius*radius;
|
||||||
|
float discriminant = b2 - d * c;
|
||||||
|
float hitDepth = (-b - sqrt(discriminant)) * e;
|
||||||
|
|
||||||
|
|
||||||
|
if (discriminant > 0 && hitDepth > 0 && hitDepth < depth) {
|
||||||
|
// float c = sphereDistSqr - sphere.w*sphere.w;
|
||||||
|
// float discriminant = b2 - d * c;
|
||||||
|
// float hitDepth = (-b - sqrt(discriminant)) * e;
|
||||||
|
|
||||||
|
vec3 hitPos = worldDir * hitDepth;
|
||||||
|
|
||||||
|
vec3 normal = normalize(hitPos - sphere.xyz);
|
||||||
|
|
||||||
|
return feathering - dot(normal, normalize(worldDir)) * 1.3 - 0.1;
|
||||||
|
} else {
|
||||||
|
return feathering;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 applyFilters(in vec3 worldDir, in float depth, in vec3 diffuse) {
|
||||||
|
vec3 worldPos = worldDir * depth;
|
||||||
|
|
||||||
|
vec3 accum = diffuse;
|
||||||
|
vec3 diffuseHSV = rgb2hsv(accum);
|
||||||
|
|
||||||
for (int i = 0; i < uCount; i++) {
|
for (int i = 0; i < uCount; i++) {
|
||||||
SphereFilter s = uSpheres[i];
|
SphereFilter s = uSpheres[i];
|
||||||
|
|
||||||
float distance = distance(s.sphere.xyz, worldPos);
|
//float strength = overlayFilterAmount(worldPos, s.sphere, s.data.x);
|
||||||
float strength = 1 - smoothstep(s.sphere.w - s.feather, s.sphere.w + s.feather, distance);
|
float strength = sphereFilterAmount(worldDir, depth, s.sphere, s.data.x);
|
||||||
|
|
||||||
accum = mix(accum, filterColor(s.colorOp, diffuse), strength);
|
//accum = vec3(strength, strength, strength);
|
||||||
|
|
||||||
|
vec3 toFilter = mix(diffuse, diffuseHSV, s.data.z);
|
||||||
|
|
||||||
|
vec3 filtered = filterColor(s.colorOp, diffuse);
|
||||||
|
|
||||||
|
filtered = mix(filtered, hsv2rgbWrapped(filtered), s.data.z);
|
||||||
|
|
||||||
|
accum = mix(accum, filtered, clamp(strength * s.data.y, 0., 1.));
|
||||||
}
|
}
|
||||||
|
|
||||||
return accum;
|
return accum;
|
||||||
|
@ -69,10 +118,9 @@ vec4 debugGrid(vec3 worldPos, vec4 diffuse) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float depth = getDepth();
|
float depth = getDepth();
|
||||||
vec3 worldPos = WorldDir * depth;
|
|
||||||
|
|
||||||
vec4 diffuse = texture2D(uColor, ScreenCoord);
|
vec4 diffuse = texture2D(uColor, ScreenCoord);
|
||||||
|
|
||||||
Color = applyFilters(worldPos, diffuse);
|
Color = vec4(applyFilters(WorldDir, depth, diffuse.rgb), diffuse.a);
|
||||||
//Color = debugGrid(worldPos, diffuse);
|
//Color = debugGrid(WorldDir * depth, Color);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue