At present, I am implementing to encode the height value into canvas and then pass it to RawTexture through toDataUrl method for use, but during this process, I found that Canvas.fillstyle can only accept standard CSS color values. How do I encode the position information with many decimal places correctly into the canvas? I think I might need an algorithm.
Some example code is as follows:
const canvas = document.createElement('canvas')
canvas.width = 8192
canvas.height = 8192
const ctx = canvas.getContext('2d')
const pickingInfo = scene.pick(x, y)
const center = pickingInfo.pickedPoint
cxt.fillStyle = `rgb(${center.y}, 0, 0)` // FIXME: Something needs to change here
cxt.beginPath()
cxt.arc(center.x, center.z, 10, 0, Math.PI * 2)
cxt.fill()
I have terrain information in my gltf and I want to modify the height of the topographical vertices by reading the colors in the RawTexture through the shader in the MaterialPlugin.
Any ideas from the guys?
Convert range 0 - 8192 data to range of the result - 255.
let colorChannel = Math.round(255 * (center.y / 8192));
cxt.fillStyle = `rgb(${colorChannel}, 0, 0)`;
~
You can also use hexadecimal with the â#â sign followed by RGB channel. Each channel take two characters space of 0 to F which make a total of 256 possibilities. In hexa, F = 16 and FF = 255.
This is for converting to hexadecimal:
hexa = number.toString(16);
I hope this help.
2 Likes
Itâs a great idea, But will there be a loss of accuracy when performing inverse operations in shader?
vec4 _mix_terrain_texture_color = texture2D(
_mix_terrain_texture, // the raw texture object
_mix_terrain_texture_uv
);
float height = _mix_terrain_texture_color.r / 255 * 8192; // do this conversion here?
gl_Position= viewProjection * vec4(vPositionW.x, height, vPositionW.z, 1.0);
Whether there is a reversible algorithm or a method with a small error value?
I came up with a way to encode decimals, integers, and symbols separately into color channels.
const factor = 3000
const height = -123.1234567
const symbol = 100 or 0 // Store the sign bits separately, 100 if they are integers and 0 if they are negative
const r = rgba(255 * (123 / factor), symbol + 12, 34, 56)
in shader
vec4 _mix_terrain_texture_color = texture2D(
_mix_terrain_texture, // the raw texture object
_mix_terrain_texture_uv
);
float d1 = _mix_terrain_texture_color.r
if (d1 > 0) {
float d2 = _mix_terrain_texture_color.g > 100 ? (_mix_terrain_texture_color.g - 100) * 0.01 : _mix_terrain_texture_color.g * 0.01
float d3 = _mix_terrain_texture_color.b * 0.0001
float d4 = _mix_terrain_texture_color.a * 0.00001
float height = d1 + d2 + d3 + d4;
float y = height / 255 * _mix_terrain_texture_color_factor
gl_Position= viewProjection * vec4(vPositionW.x, y, vPositionW.z, 1.0);
}
Math.max(0, num);
For replacing negative with 0
Const num = -123.456;
const int = Math.max(0, num);
console.log(int);
Should output 0 in the console when changing ânumâ constant
I also found a problem why Canvas canât change the rgba value to hexadecimal and transparent channels disappear. Do you know why?
You canât draw transparency on a canvas I guess.
Change itâs CSS value âbackgroundâ or âbackground-colorâ if you need to change the whole canvas color.
canvas.backgroundColor = "#00ff00";
Oops sorry I forgot to add the alpha (transparency) channel at the end.
Here I use â80â which if half âFFâ in hexadecimal.
const alpha = "80";
const color = "00FF00";
canvas.background = "#" + color + alpha;
Now I have another problem, this may require a new topic, when I use the same material plugin to operate on the ground material, changing some of the position offset parameters shows a different effect. Can someone help me figure this out?
You can swap comment lines to see the correct effect