merge groups
This commit is contained in:
parent
401ee86c38
commit
0ab343894b
|
|
@ -29,15 +29,48 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
private renderProgram!: WebGLProgram; // Shader program for final rendering
|
private renderProgram!: WebGLProgram; // Shader program for final rendering
|
||||||
private seedProgram!: WebGLProgram; // Shader program for rendering seed points
|
private seedProgram!: WebGLProgram; // Shader program for rendering seed points
|
||||||
|
|
||||||
private positionBufferEven: WebGLBuffer | null = null;
|
|
||||||
private positionBufferOdd: WebGLBuffer | null = null;
|
|
||||||
|
|
||||||
private isPingTextureEven: boolean = true;
|
private isPingTextureEven: boolean = true;
|
||||||
private isPingTextureOdd: boolean = true;
|
private isPingTextureOdd: boolean = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups data for handling different sets of shapes.
|
||||||
|
* 'mergeA' and 'mergeB' shapes will have their distance fields merged in rendering,
|
||||||
|
* while 'others' will be processed separately.
|
||||||
|
*/
|
||||||
|
private groups: {
|
||||||
|
[groupName: string]: {
|
||||||
|
textures: WebGLTexture[];
|
||||||
|
isPingTexture: boolean;
|
||||||
|
shapeVAO: WebGLVertexArrayObject;
|
||||||
|
positionBuffer: WebGLBuffer | null;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
|
// Initialize groups for 'mergeA', 'mergeB', and 'others'
|
||||||
|
this.groups = {
|
||||||
|
mergeA: {
|
||||||
|
textures: [],
|
||||||
|
isPingTexture: true,
|
||||||
|
shapeVAO: null!,
|
||||||
|
positionBuffer: null,
|
||||||
|
},
|
||||||
|
mergeB: {
|
||||||
|
textures: [],
|
||||||
|
isPingTexture: true,
|
||||||
|
shapeVAO: null!,
|
||||||
|
positionBuffer: null,
|
||||||
|
},
|
||||||
|
others: {
|
||||||
|
textures: [],
|
||||||
|
isPingTexture: true,
|
||||||
|
shapeVAO: null!,
|
||||||
|
positionBuffer: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
this.initWebGL();
|
this.initWebGL();
|
||||||
this.initShaders();
|
this.initShaders();
|
||||||
this.initPingPongTextures();
|
this.initPingPongTextures();
|
||||||
|
|
@ -94,14 +127,14 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes textures and framebuffer for ping-pong rendering.
|
* Initializes textures and framebuffer for ping-pong rendering.
|
||||||
* Now supports separate textures for even and odd distance fields.
|
* Supports separate textures for 'mergeA', 'mergeB', and 'others' groups.
|
||||||
*/
|
*/
|
||||||
private initPingPongTextures() {
|
private initPingPongTextures() {
|
||||||
// Initialize textures for even distance field
|
// Initialize textures for each group
|
||||||
this.texturesEven = this.createPingPongTextures();
|
for (const groupName in this.groups) {
|
||||||
|
this.groups[groupName].textures = this.createPingPongTextures();
|
||||||
// Initialize textures for odd distance field
|
this.groups[groupName].isPingTexture = true;
|
||||||
this.texturesOdd = this.createPingPongTextures();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -140,18 +173,21 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes rendering of seed points (shapes) into textures.
|
* Populates seed points and assigns shapes to 'mergeA', 'mergeB', or 'others' groups.
|
||||||
* Separates seed points into even and odd groups.
|
* Shapes with index 0 and 1 are assigned to 'mergeA' and 'mergeB' respectively.
|
||||||
*/
|
*/
|
||||||
private populateSeedPoints() {
|
private populateSeedPoints() {
|
||||||
const gl = this.glContext;
|
const gl = this.glContext;
|
||||||
const positionsEven: number[] = [];
|
const groupPositions: { [groupName: string]: number[] } = {
|
||||||
const positionsOdd: number[] = [];
|
mergeA: [],
|
||||||
|
mergeB: [],
|
||||||
|
others: [],
|
||||||
|
};
|
||||||
|
|
||||||
const containerWidth = this.clientWidth;
|
const containerWidth = this.clientWidth;
|
||||||
const containerHeight = this.clientHeight;
|
const containerHeight = this.clientHeight;
|
||||||
|
|
||||||
// Collect positions and assign unique IDs to all shapes
|
// Collect positions and assign shapes to groups
|
||||||
this.sourceRects.forEach((rect, index) => {
|
this.sourceRects.forEach((rect, index) => {
|
||||||
let topLeftParent: Point;
|
let topLeftParent: Point;
|
||||||
let topRightParent: Point;
|
let topRightParent: Point;
|
||||||
|
|
@ -205,51 +241,51 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
shapeID,
|
shapeID,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (index % 2 === 0) {
|
// Assign shapes to groups based on index or any other criteria
|
||||||
// Even index
|
let groupName: string;
|
||||||
positionsEven.push(...rectPositions);
|
if (index === 0) {
|
||||||
|
groupName = 'mergeA';
|
||||||
|
} else if (index === 1) {
|
||||||
|
groupName = 'mergeB';
|
||||||
} else {
|
} else {
|
||||||
// Odd index
|
groupName = 'others';
|
||||||
positionsOdd.push(...rectPositions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groupPositions[groupName].push(...rectPositions);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize buffers and VAOs for even seed points
|
// Initialize buffers and VAOs for each group
|
||||||
if (!this.shapeVAOEven) {
|
for (const groupName in groupPositions) {
|
||||||
this.shapeVAOEven = gl.createVertexArray()!;
|
const positions = groupPositions[groupName];
|
||||||
gl.bindVertexArray(this.shapeVAOEven);
|
const group = this.groups[groupName];
|
||||||
this.positionBufferEven = gl.createBuffer()!;
|
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBufferEven);
|
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionsEven), gl.DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
const positionLocation = gl.getAttribLocation(this.seedProgram, 'a_position');
|
if (!group.shapeVAO) {
|
||||||
gl.enableVertexAttribArray(positionLocation);
|
group.shapeVAO = gl.createVertexArray()!;
|
||||||
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
|
gl.bindVertexArray(group.shapeVAO);
|
||||||
gl.bindVertexArray(null);
|
group.positionBuffer = gl.createBuffer()!;
|
||||||
} else {
|
gl.bindBuffer(gl.ARRAY_BUFFER, group.positionBuffer);
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBufferEven!);
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.DYNAMIC_DRAW);
|
||||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(positionsEven));
|
|
||||||
|
const positionLocation = gl.getAttribLocation(this.seedProgram, 'a_position');
|
||||||
|
gl.enableVertexAttribArray(positionLocation);
|
||||||
|
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
|
||||||
|
gl.bindVertexArray(null);
|
||||||
|
} else {
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, group.positionBuffer!);
|
||||||
|
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(positions));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize buffers and VAOs for odd seed points
|
// Render the seed points into the textures for each group
|
||||||
if (!this.shapeVAOOdd) {
|
for (const groupName in groupPositions) {
|
||||||
this.shapeVAOOdd = gl.createVertexArray()!;
|
const positions = groupPositions[groupName];
|
||||||
gl.bindVertexArray(this.shapeVAOOdd);
|
const vertexCount = positions.length / 3;
|
||||||
this.positionBufferOdd = gl.createBuffer()!;
|
this.renderSeedPointsForGroup(
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBufferOdd);
|
this.groups[groupName].shapeVAO,
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionsOdd), gl.DYNAMIC_DRAW);
|
this.groups[groupName].textures[this.groups[groupName].isPingTexture ? 0 : 1],
|
||||||
|
vertexCount
|
||||||
const positionLocation = gl.getAttribLocation(this.seedProgram, 'a_position');
|
);
|
||||||
gl.enableVertexAttribArray(positionLocation);
|
|
||||||
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
|
|
||||||
gl.bindVertexArray(null);
|
|
||||||
} else {
|
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBufferOdd!);
|
|
||||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, new Float32Array(positionsOdd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the seed points into the textures
|
|
||||||
this.renderSeedPoints(positionsEven.length / 3, positionsOdd.length / 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -299,22 +335,25 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the Jump Flooding Algorithm (JFA) separately for even and odd distance fields.
|
* Executes the Jump Flooding Algorithm (JFA) for each group separately.
|
||||||
|
* 'mergeA' and 'mergeB' groups will have their distance fields merged in rendering.
|
||||||
*/
|
*/
|
||||||
private runJumpFloodingAlgorithm() {
|
private runJumpFloodingAlgorithm() {
|
||||||
// Compute initial step size
|
// Compute initial step size
|
||||||
let stepSize = 1 << Math.floor(Math.log2(Math.max(this.canvas.width, this.canvas.height)));
|
let stepSize = 1 << Math.floor(Math.log2(Math.max(this.canvas.width, this.canvas.height)));
|
||||||
|
|
||||||
// Perform passes with decreasing step sizes for even distance field
|
// Perform passes with decreasing step sizes for each group
|
||||||
for (let size = stepSize; size >= 1; size >>= 1) {
|
for (const groupName in this.groups) {
|
||||||
this.renderPass(size, this.texturesEven, this.isPingTextureEven);
|
const group = this.groups[groupName];
|
||||||
this.isPingTextureEven = !this.isPingTextureEven;
|
const textures = group.textures;
|
||||||
}
|
let isPingTexture = group.isPingTexture;
|
||||||
|
|
||||||
// Perform passes with decreasing step sizes for odd distance field
|
for (let size = stepSize; size >= 1; size >>= 1) {
|
||||||
for (let size = stepSize; size >= 1; size >>= 1) {
|
this.renderPass(size, textures, isPingTexture);
|
||||||
this.renderPass(size, this.texturesOdd, this.isPingTextureOdd);
|
isPingTexture = !isPingTexture;
|
||||||
this.isPingTextureOdd = !this.isPingTextureOdd;
|
}
|
||||||
|
|
||||||
|
group.isPingTexture = isPingTexture; // Update the ping-pong status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the final result to the screen
|
// Render the final result to the screen
|
||||||
|
|
@ -357,7 +396,7 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the final distance field to the screen using the render shader program.
|
* Renders the final distance field to the screen using the render shader program.
|
||||||
* Combines both distance fields using a 'soft merge' function.
|
* Merges 'mergeA' and 'mergeB' distance fields during rendering, while 'others' are not merged.
|
||||||
*/
|
*/
|
||||||
private renderToScreen() {
|
private renderToScreen() {
|
||||||
const gl = this.glContext;
|
const gl = this.glContext;
|
||||||
|
|
@ -369,17 +408,16 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
// Use the render shader program
|
// Use the render shader program
|
||||||
gl.useProgram(this.renderProgram);
|
gl.useProgram(this.renderProgram);
|
||||||
|
|
||||||
// Bind the final texture from even distance field
|
// Bind the final textures from each group
|
||||||
const finalTextureEven = this.texturesEven[this.isPingTextureEven ? 0 : 1];
|
let textureUnit = 0;
|
||||||
gl.activeTexture(gl.TEXTURE0);
|
for (const groupName in this.groups) {
|
||||||
gl.bindTexture(gl.TEXTURE_2D, finalTextureEven);
|
const group = this.groups[groupName];
|
||||||
gl.uniform1i(gl.getUniformLocation(this.renderProgram, 'u_textureEven'), 0);
|
const finalTexture = group.textures[group.isPingTexture ? 0 : 1];
|
||||||
|
gl.activeTexture(gl.TEXTURE0 + textureUnit);
|
||||||
// Bind the final texture from odd distance field
|
gl.bindTexture(gl.TEXTURE_2D, finalTexture);
|
||||||
const finalTextureOdd = this.texturesOdd[this.isPingTextureOdd ? 0 : 1];
|
gl.uniform1i(gl.getUniformLocation(this.renderProgram, `u_texture_${groupName}`), textureUnit);
|
||||||
gl.activeTexture(gl.TEXTURE1);
|
textureUnit++;
|
||||||
gl.bindTexture(gl.TEXTURE_2D, finalTextureOdd);
|
}
|
||||||
gl.uniform1i(gl.getUniformLocation(this.renderProgram, 'u_textureOdd'), 1);
|
|
||||||
|
|
||||||
// Draw a fullscreen quad to display the result
|
// Draw a fullscreen quad to display the result
|
||||||
this.drawFullscreenQuad();
|
this.drawFullscreenQuad();
|
||||||
|
|
@ -481,27 +519,34 @@ export class FolkDistanceField extends FolkBaseSet {
|
||||||
private cleanupWebGLResources() {
|
private cleanupWebGLResources() {
|
||||||
const gl = this.glContext;
|
const gl = this.glContext;
|
||||||
|
|
||||||
// Delete textures
|
// Delete resources for each group
|
||||||
this.texturesEven.forEach((texture) => gl.deleteTexture(texture));
|
for (const groupName in this.groups) {
|
||||||
this.texturesEven = [];
|
const group = this.groups[groupName];
|
||||||
this.texturesOdd.forEach((texture) => gl.deleteTexture(texture));
|
|
||||||
this.texturesOdd = [];
|
// Delete textures
|
||||||
|
group.textures.forEach((texture) => gl.deleteTexture(texture));
|
||||||
|
group.textures = [];
|
||||||
|
|
||||||
|
// Delete VAOs
|
||||||
|
if (group.shapeVAO) {
|
||||||
|
gl.deleteVertexArray(group.shapeVAO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete buffers
|
||||||
|
if (group.positionBuffer) {
|
||||||
|
gl.deleteBuffer(group.positionBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Delete framebuffer
|
// Delete framebuffer
|
||||||
if (this.framebuffer) {
|
if (this.framebuffer) {
|
||||||
gl.deleteFramebuffer(this.framebuffer);
|
gl.deleteFramebuffer(this.framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete VAOs
|
// Delete fullscreen quad VAO
|
||||||
if (this.fullscreenQuadVAO) {
|
if (this.fullscreenQuadVAO) {
|
||||||
gl.deleteVertexArray(this.fullscreenQuadVAO);
|
gl.deleteVertexArray(this.fullscreenQuadVAO);
|
||||||
}
|
}
|
||||||
if (this.shapeVAOEven) {
|
|
||||||
gl.deleteVertexArray(this.shapeVAOEven);
|
|
||||||
}
|
|
||||||
if (this.shapeVAOOdd) {
|
|
||||||
gl.deleteVertexArray(this.shapeVAOOdd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete shader programs
|
// Delete shader programs
|
||||||
if (this.jfaProgram) {
|
if (this.jfaProgram) {
|
||||||
|
|
@ -576,21 +621,23 @@ void main() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment shader for rendering the final distance field.
|
* Fragment shader for rendering the final distance field.
|
||||||
* Converts distances to colors for visualization.
|
* Merges 'mergeA' and 'mergeB' distance fields during rendering.
|
||||||
*/
|
*/
|
||||||
const renderFragShader = glsl`#version 300 es
|
const renderFragShader = glsl`#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
#define DEBUG_MODULO true
|
#define DEBUG_MODULO false
|
||||||
|
#define DEBUG_HARD_CUTOFF false
|
||||||
#define FALLOFF_FACTOR 10.0
|
#define FALLOFF_FACTOR 10.0
|
||||||
#define SMOOTHING_FACTOR 0.1
|
#define SMOOTHING_FACTOR 0.1
|
||||||
#define MERGE_DISTANCES true
|
#define DEBUG_HARD_CUTOFF_DISTANCE 0.2
|
||||||
|
|
||||||
in vec2 v_texCoord;
|
in vec2 v_texCoord;
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
uniform sampler2D u_textureEven;
|
uniform sampler2D u_texture_mergeA;
|
||||||
uniform sampler2D u_textureOdd;
|
uniform sampler2D u_texture_mergeB;
|
||||||
|
uniform sampler2D u_texture_others;
|
||||||
|
|
||||||
vec3 hsv2rgb(vec3 c) {
|
vec3 hsv2rgb(vec3 c) {
|
||||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
|
@ -605,63 +652,71 @@ float smoothMin(float a, float b, float k) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 texelEven = texture(u_textureEven, v_texCoord);
|
vec4 texelMergeA = texture(u_texture_mergeA, v_texCoord);
|
||||||
vec4 texelOdd = texture(u_textureOdd, v_texCoord);
|
vec4 texelMergeB = texture(u_texture_mergeB, v_texCoord);
|
||||||
|
vec4 texelOthers = texture(u_texture_others, v_texCoord);
|
||||||
|
|
||||||
// Extract shape IDs and distances
|
// Extract shape IDs and distances
|
||||||
float shapeIDEven = texelEven.z;
|
float shapeIDMergeA = texelMergeA.z;
|
||||||
float distanceEven = texelEven.a;
|
float distanceMergeA = texelMergeA.a;
|
||||||
|
|
||||||
float shapeIDOdd = texelOdd.z;
|
float shapeIDMergeB = texelMergeB.z;
|
||||||
float distanceOdd = texelOdd.a;
|
float distanceMergeB = texelMergeB.a;
|
||||||
|
|
||||||
// Compute colors for both shapes first
|
float shapeIDOthers = texelOthers.z;
|
||||||
float hueEven = fract(shapeIDEven * 0.61803398875);
|
float distanceOthers = texelOthers.a;
|
||||||
vec3 colorEven = hsv2rgb(vec3(hueEven, 0.5, 0.95));
|
|
||||||
|
|
||||||
float hueOdd = fract(shapeIDOdd * 0.61803398875);
|
// Compute colors for mergeA and mergeB
|
||||||
vec3 colorOdd = hsv2rgb(vec3(hueOdd, 0.5, 0.95));
|
float hueMergeA = fract(shapeIDMergeA * 0.61803398875);
|
||||||
|
vec3 colorMergeA = hsv2rgb(vec3(hueMergeA, 0.5, 0.95));
|
||||||
|
|
||||||
float mergedDistance;
|
float hueMergeB = fract(shapeIDMergeB * 0.61803398875);
|
||||||
vec3 mergedColor;
|
vec3 colorMergeB = hsv2rgb(vec3(hueMergeB, 0.5, 0.95));
|
||||||
|
|
||||||
if (MERGE_DISTANCES) {
|
// Merge distances of mergeA and mergeB
|
||||||
// Use smooth minimum to merge distances
|
float mergedDistanceAB = smoothMin(distanceMergeA, distanceMergeB, SMOOTHING_FACTOR);
|
||||||
mergedDistance = smoothMin(distanceEven, distanceOdd, SMOOTHING_FACTOR);
|
|
||||||
|
// Calculate blend factor for colors
|
||||||
// Calculate blend factor using the same smoothing parameter
|
float hAB = clamp(0.5 + 0.5 * (distanceMergeB - distanceMergeA) / SMOOTHING_FACTOR, 0.0, 1.0);
|
||||||
float h = clamp(0.5 + 0.5 * (distanceOdd - distanceEven) / SMOOTHING_FACTOR, 0.0, 1.0);
|
vec3 mergedColorAB = mix(colorMergeB, colorMergeA, hAB);
|
||||||
|
|
||||||
// Interpolate between the two colors
|
// Compute color and distance for others
|
||||||
mergedColor = mix(colorOdd, colorEven, h);
|
float hueOthers = fract(shapeIDOthers * 0.61803398875);
|
||||||
|
vec3 colorOthers = hsv2rgb(vec3(hueOthers, 0.5, 0.95));
|
||||||
|
|
||||||
|
// Decide between merged distances and others
|
||||||
|
float finalDistance;
|
||||||
|
vec3 finalColor;
|
||||||
|
|
||||||
|
if (mergedDistanceAB <= distanceOthers) {
|
||||||
|
finalDistance = mergedDistanceAB;
|
||||||
|
finalColor = mergedColorAB;
|
||||||
} else {
|
} else {
|
||||||
// Simply use the closest distance and its corresponding color
|
finalDistance = distanceOthers;
|
||||||
if (distanceEven <= distanceOdd) {
|
finalColor = colorOthers;
|
||||||
mergedDistance = distanceEven;
|
|
||||||
mergedColor = colorEven;
|
|
||||||
} else {
|
|
||||||
mergedDistance = distanceOdd;
|
|
||||||
mergedColor = colorOdd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 finalColor = mergedColor;
|
|
||||||
|
|
||||||
if (DEBUG_MODULO) {
|
if (DEBUG_MODULO) {
|
||||||
// Visualize distance bands using modulo
|
// Visualize distance bands using modulo
|
||||||
float bandWidth = 0.02; // Adjust this value to change the width of the bands
|
float bandWidth = 0.02; // Adjust this value to change the width of the bands
|
||||||
float distanceBand = mod(mergedDistance, bandWidth) / bandWidth;
|
float distanceBand = mod(finalDistance, bandWidth) / bandWidth;
|
||||||
|
|
||||||
// Create alternating black and white bands
|
// Create alternating black and white bands
|
||||||
float bandColor = step(0.1, distanceBand);
|
float bandColor = step(0.1, distanceBand);
|
||||||
|
|
||||||
// Mix the band visualization with the merged color
|
// Mix the band visualization with the merged color
|
||||||
finalColor = mix(vec3(0.0), mergedColor, bandColor);
|
finalColor = mix(vec3(0.0), finalColor, bandColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before applying any effects, check if we should use hard cutoff
|
||||||
|
if (DEBUG_HARD_CUTOFF) {
|
||||||
|
// If distance is greater than cutoff, set intensity to 0, otherwise 1
|
||||||
|
finalColor *= finalDistance > DEBUG_HARD_CUTOFF_DISTANCE ? 0.0 : exp(-finalDistance * FALLOFF_FACTOR);
|
||||||
|
} else {
|
||||||
|
// Use the original smooth falloff
|
||||||
|
finalColor *= exp(-finalDistance * FALLOFF_FACTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply intensity-based falloff (from pre-pretty commit)
|
|
||||||
float intensity = exp(-mergedDistance * FALLOFF_FACTOR);
|
|
||||||
finalColor *= intensity;
|
|
||||||
|
|
||||||
outColor = vec4(finalColor, 1.0);
|
outColor = vec4(finalColor, 1.0);
|
||||||
}`;
|
}`;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue