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
|
||||
public static Matrix4f hueShift(float rot) {
|
||||
public static Matrix4f hueShiftRGB(float rot) {
|
||||
Matrix4f mat = new Matrix4f();
|
||||
|
||||
mat.loadIdentity();
|
||||
|
@ -78,4 +78,14 @@ public class ColorMatrices {
|
|||
|
||||
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();
|
||||
program.bindInverseView(inverseView);
|
||||
|
||||
Vector3d pos1 = new Vector3d(330, 0, 110);
|
||||
Vector3d pos1 = new Vector3d(852, 79, -204);
|
||||
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||
|
||||
program.setCameraPos(cameraPos.inverse());
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||
.setCenter(pos1.subtract(cameraPos).add(0, 0, i * 10))
|
||||
.setRadius(15)
|
||||
.setFeather(0f)
|
||||
.setFilter(ColorMatrices.hueShift((float) i / 16 * 360 + AnimationTickHolder.getRenderTime())));
|
||||
}
|
||||
// int n = 20;
|
||||
// double rad = 15;
|
||||
// for (int i = 0; i < n; i++) {
|
||||
// double angle = ((double) i) / n * Math.PI * 2;
|
||||
// program.addSphere(new SphereFilterProgram.FilterSphere()
|
||||
// .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();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public class SphereFilterProgram extends GlProgram {
|
|||
protected static final int UBO_BINDING = 4;
|
||||
|
||||
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 ALL_FILTERS_SIZE = MAX_FILTERS * SPHERE_FILTER_SIZE;
|
||||
|
@ -126,6 +126,8 @@ public class SphereFilterProgram extends GlProgram {
|
|||
public Vector3d center;
|
||||
public float radius;
|
||||
public float feather;
|
||||
public float strength = 1;
|
||||
public boolean hsv;
|
||||
|
||||
public Matrix4f filter;
|
||||
|
||||
|
@ -144,6 +146,16 @@ public class SphereFilterProgram extends GlProgram {
|
|||
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) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
|
@ -156,9 +168,9 @@ public class SphereFilterProgram extends GlProgram {
|
|||
(float) center.z,
|
||||
radius,
|
||||
feather,
|
||||
0, // padding, we could add more parameters here
|
||||
0,
|
||||
0
|
||||
strength,
|
||||
hsv ? 1f : 0f,
|
||||
0 // padding, we could add more parameters here
|
||||
});
|
||||
|
||||
buf.put(RenderUtil.writeMatrix(filter));
|
||||
|
|
|
@ -16,11 +16,11 @@ uniform vec3 uCameraPos;
|
|||
|
||||
struct SphereFilter {
|
||||
vec4 sphere;// <vec3 position, float radius>
|
||||
float feather;
|
||||
vec3 data;// <float feather, float strength, float hsv marker>
|
||||
mat4 colorOp;
|
||||
};
|
||||
|
||||
#define N 16
|
||||
#define N 256
|
||||
layout (std140) uniform Filters {
|
||||
int uCount;
|
||||
SphereFilter uSpheres[N];
|
||||
|
@ -31,11 +31,11 @@ float linearizeDepth(float d, float zNear, float zFar) {
|
|||
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
|
||||
vec4 i = vec4(frag.rgb, 1.);
|
||||
vec4 i = vec4(color, 1.);
|
||||
i *= colorOp;
|
||||
return vec4(i.rgb, frag.a);
|
||||
return i.rgb;
|
||||
}
|
||||
|
||||
float getDepth() {
|
||||
|
@ -44,16 +44,65 @@ float getDepth() {
|
|||
return linearizeDepth(depth, uNearPlane, uFarPlane);
|
||||
}
|
||||
|
||||
vec4 applyFilters(vec3 worldPos, vec4 diffuse) {
|
||||
vec4 accum = diffuse;
|
||||
float overlayFilterAmount(in vec3 worldPos, in vec4 sphere, in float feather) {
|
||||
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++) {
|
||||
SphereFilter s = uSpheres[i];
|
||||
|
||||
float distance = distance(s.sphere.xyz, worldPos);
|
||||
float strength = 1 - smoothstep(s.sphere.w - s.feather, s.sphere.w + s.feather, distance);
|
||||
//float strength = overlayFilterAmount(worldPos, s.sphere, s.data.x);
|
||||
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;
|
||||
|
@ -69,10 +118,9 @@ vec4 debugGrid(vec3 worldPos, vec4 diffuse) {
|
|||
|
||||
void main() {
|
||||
float depth = getDepth();
|
||||
vec3 worldPos = WorldDir * depth;
|
||||
|
||||
vec4 diffuse = texture2D(uColor, ScreenCoord);
|
||||
|
||||
Color = applyFilters(worldPos, diffuse);
|
||||
//Color = debugGrid(worldPos, diffuse);
|
||||
Color = vec4(applyFilters(WorldDir, depth, diffuse.rgb), diffuse.a);
|
||||
//Color = debugGrid(WorldDir * depth, Color);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue