function addBlendLayer() {
let layer0 = new Layer({
type: 'image',
url: './RTI_panneau_1_test2_7360/plane_0.jpg',
layout: 'image',
zindex: 0,
transform: { x: 0, y: 0, z: 1, a: 0 },
visible: false
});
let layer1 = new Layer({
type: 'image',
url: './RTI_panneau_1_test2_7360/plane_1.jpg',
layout: 'image',
zindex: 0,
transform: { x: 0, y: 0, z: 1, a: 0 },
visible: false
});
let blendLayerCombiner = new LayerCombiner({
layers: [layer0, layer1]
});
// Create the existing shaders
let shaderDiff = new ShaderCombiner();
shaderDiff.mode = 'diff';
let shaderMean = new ShaderCombiner();
shaderMean.mode = 'mean';
// Create the blend shader with initial weight
let shaderBlend = new ShaderCombinerBlend({
blendWeight: 0.5 // Start at 50/50
});
// Add all shaders
blendLayerCombiner.shaders = {
'standarddiff': shaderDiff,
'standardmean': shaderMean,
'blend': shaderBlend // Add blend shader
};
// shaderBlend.modes = ['blend', 'standarddiff', 'standardmean']
// shaderBlend.mode = 'blend'
// Start with blend mode
blendLayerCombiner.setShader('blend');
// Override getModes() to return the shader names
blendLayerCombiner.getModes = function() {
return Object.keys(this.shaders);
};
// Override setMode() to switch shaders instead
blendLayerCombiner.setMode = function(shaderName) {
this.setShader(shaderName);
};
// Override getMode() to return current shader name
blendLayerCombiner.getMode = function() {
for (let [name, shader] of Object.entries(this.shaders)) {
if (shader === this.shader) return name;
}
return 'blend';
};
limeViewer.canvas.addLayer('blend-layer0', layer0);
limeViewer.canvas.addLayer('blend-layer1', layer1);
limeViewer.canvas.addLayer('blendLayerCombiner', blendLayerCombiner);
window.blendLayerCombiner = blendLayerCombiner
}
/**
* A shader for blending two layers with adjustable weight.
* Works with the standard LayerCombiner without any modifications.
*
* @extends Shader
* @example
* ```javascript
* // Use with existing LayerCombiner
* const combiner = new OpenLIME.LayerCombiner({
* layers: [layer1, layer2]
* });
*
* const blendShader = new ShaderCombinerBlend({
* blendWeight: 0.5
* });
*
* combiner.shaders = { 'blend': blendShader };
* combiner.setShader('blend');
*
* // Change blend weight directly through shader
* blendShader.setUniform('uBlendWeight', 0.7);
* combiner.emit('update');
*
* // Or add UI control for it
* uiBasic.addUniformUI(
* combiner,
* 'uBlendWeight',
* 'Blend',
* 'slider',
* 0, 100, // display range
* 0.0, 1.0, // actual uniform range
* 100 // steps
* );
* ```
*/
class ShaderCombinerBlend extends Shader {
constructor(options = {}) {
super(options);
const blendWeight = options.blendWeight !== undefined ? options.blendWeight : 0.5;
// Match the sampler names from ShaderCombiner
this.samplers = [
{ id: 0, name: 'source1', type: 'vec3' },
{ id: 1, name: 'source2', type: 'vec3' }
];
this.uniforms = {
uBlendWeight: { type: 'float', needsUpdate: true, size: 1, value: blendWeight }
};
}
/**
* Gets fragment shader source code.
* Implements texture blending with adjustable weight.
* @param {WebGLRenderingContext} gl - WebGL context
* @returns {string} Fragment shader source code
* @private
*/
fragShaderSrc(gl) {
return `
in vec2 v_texcoord;
uniform float uBlendWeight;
vec4 data() {
vec4 c1 = texture(source1, v_texcoord);
vec4 c2 = texture(source2, v_texcoord);
// Blend between the two layers
// uBlendWeight = 0.0 -> 100% layer 0 (c1)
// uBlendWeight = 1.0 -> 100% layer 1 (c2)
vec4 color = mix(c1, c2, uBlendWeight);
return color;
}
`;
}
/**
* Gets vertex shader source code.
* Provides basic vertex transformation and texture coordinate passing.
* @param {WebGLRenderingContext} gl - WebGL context
* @returns {string} Vertex shader source code
* @private
*/
vertShaderSrc(gl) {
return `#version 300 es
in vec4 a_position;
in vec2 a_texcoord;
out vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_texcoord;
}`;
}
}
Thanks for getting back on the release thread here. First of all, thanks for this amazing OpenLime utility, really great playing with multi-layer RTI, deepzoom, BRDF and relight layers as well as lens, shaders, filters, annotations, lightsphere etc.
Here are some question after playing a bit with the library during the past few days - feel free to tell me to open a dedicated issue/discussion thread for some points in case it makes more sense. Sorry for the lengthy read.
RelightLab convert to
*.relight: RelightLab can convert an existing*.rti/*.ptmfile to relight directory (info.json + plane_k.jpgimages), but not to*.relightformat, correct? If so, it would be great for the convert function to also allow exporting .relight file. In the meantime, looks like the ony way to extract normals from an existing*.rtiproject is to either:RTIViewerlayer.visible = false should hide layers: From my understanding, layers which have property
visible: falseshould not appear in the layers sidepanel fromUIBasic. Or is there a reason for displaying them in the tree view sidepanel? Probably this line can be prefixed with a check on layer.visible, or better, the for loop can start with a continue statement if layer.visible is falsefor (let [id, layer] of Object.entries(this.viewer.canvas.layers)) { + if (!layer.visible) continue let modes = [] // ...new tests to index.js: After spending some time parsing through the source, I've added tests (mostly shaders) that were previously not existing to src/index.js . Do you want me to submit a PR for these? Also, it could be useful to add a note in the doc pointing to this index.js file which is very useful while doc gets more complete. These are the code blocks that might be useful:
testLightSphere, testEdge, testOtherFilters, testAnisotropic, testVectorShaderCombinerBlend: Would it make sense to add a
blend/mixmode toLayerCombiner, that would be parametrized by a 0-1 coefficient. I've added such a shader in a folded code section below, with claude helping for the openlime Shader wrapper. I'm probably messing withlayer.modes and layer.shader, so I had to overwritelayer.getMode, getModes, setModeto switch between shaders in the layers sidepanel.ShaderCombinerBlend
BRDF: If no ks/gloss maps are provided, it would be useful to allow controlling the constant specular/gloss of the whole surface. One can create fake white/gray textures, but it's not the most interactive way to control the overall glossiness of the surface.
addUniformUI vec/array support I wanted to edit brightness and gamma from the BRDF shader, so I thought it would be useful for ui.addUniformUI slider controls to support array/vec uniforms like
brdf uBrightnessGamma or ShaderFilterGrayscale.weights. Might be a too specific use-case, but I edited slightlyopenlime/src/UIBasic.js
Lines 1106 to 1139 in 4f34630
controlWrapper.innerHTML, see below folded code block.I then realized the
uBrightnessGammais actually not used because applyGamma is set to false, so I tweaked the below line for the sliders to work:addUniformUI vec/array support
LayerandLayerCombineralways displays all modes, despite specifying a sub-selection of shaders incombinerTest. But again, I might be messing up with modes and shaders.