-
-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
multiple textures for smooth terrain #93
Comments
You cannot use Transvoxel polygonizes a block by taking corners of a cube (which is why it uses 8 voxels instead of one), which are interpolated to generate vertices. Then the process repeats for every voxel of the block ("marching" cubes). |
@Zylann I'll try to use UV2 and pack multiple texture ids into one float like so https://stackoverflow.com/questions/32915724/pack-two-floats-within-range-into-one-float. About |
This is the shader I use in my local demo: shader_type spatial;
uniform sampler2D u_texture_top : hint_albedo;
uniform sampler2D u_texture_sides : hint_albedo;
uniform int u_transition_mask;
varying vec3 v_world_pos;
varying vec3 v_world_normal;
vec3 get_triplanar_blend(vec3 world_normal) {
vec3 blending = abs(world_normal);
blending = normalize(max(blending, vec3(0.00001))); // Force weights to sum to 1.0
float b = blending.x + blending.y + blending.z;
return blending / vec3(b, b, b);
}
vec4 texture_triplanar(sampler2D tex, vec3 world_pos, vec3 blend) {
vec4 xaxis = texture(tex, world_pos.yz);
vec4 yaxis = texture(tex, world_pos.xz);
vec4 zaxis = texture(tex, world_pos.xy);
// blend the results of the 3 planar projections.
return xaxis * blend.x + yaxis * blend.y + zaxis * blend.z;
}
vec3 get_transvoxel_position(vec3 vertex_pos, vec4 vertex_col) {
int border_mask = int(vertex_col.a);
int cell_border_mask = border_mask & 63; // Which sides the cell is touching
int vertex_border_mask = (border_mask >> 6) & 63; // Which sides the vertex is touching
// If the vertex is near a side where there is a low-resolution neighbor,
// move it to secondary position
int m = u_transition_mask & (cell_border_mask & 63);
float t = float(m != 0);
// If the vertex lies on one or more sides, and at least one side has no low-resolution neighbor,
// don't move the vertex.
t *= float((vertex_border_mask & ~u_transition_mask) == 0);
// Position to use when border mask matches
vec3 secondary_position = vertex_col.rgb;
return mix(vertex_pos, secondary_position, t);
}
void vertex() {
VERTEX = get_transvoxel_position(VERTEX, COLOR);
vec3 world_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz;
v_world_pos = world_pos;
v_world_normal = NORMAL;
}
void fragment() {
vec3 normal = v_world_normal;//normalize(v_world_normal);
vec3 wpos = v_world_pos * 0.2;
vec3 blending = get_triplanar_blend(normal);
vec3 top_col = texture_triplanar(u_texture_top, wpos, blending).rgb;
vec3 side_col = texture_triplanar(u_texture_sides, wpos, blending).rgb;
float r = top_col.r;
ALBEDO = mix(side_col, top_col, clamp(normal.y * 10.0 - 4.0 - 8.0*r, 0.0, 1.0));
} |
I'm not sure that understood I hope that you said about const int cornerMaterials[8] =
{
fvoxels.get_voxel(cell_positions[0], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[1], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[2], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[3], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[4], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[5], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[6], VoxelBuffer::CHANNEL_DATA2),
fvoxels.get_voxel(cell_positions[7], VoxelBuffer::CHANNEL_DATA2),
};
dominant_texture_idx = (float)FindDominantMaterial(cornerMaterials); I'm going to use function similar to Note that noise function must mark air voxels with empty texture ( |
BTW, is generation prioritized by distance to the camera? |
You can tell if a voxel is air if its SDF value is above zero (though with Transvoxel it would be the opposite). Then a cell is all air if the 8 corner voxels are air. I can't really tell what to do for materials, all I can say is that I would follow the Transvoxel paper.
The order of blocks scheduled for processing is sorted by distance to viewer. However scheduling is controlled by octrees and regions. See #87 |
from https://transvoxel.org/Lengyel-VoxelTerrain.pdf Any ideas how to do that will be useful |
The feature is now in master. |
I`m trying to add support for multiple textures based on texarray and COLOR attributes of vertices.
Key idea is to texture differently shape created by
do_point
ordo_sphere
. For example, it may be useful in games where player can place voxel with chosen texture https://youtu.be/Xm1KVjMePBA?t=85I managed to pass texture ID via
_output_extra
fromvoxel_mesher_transvoxel.cpp
and addingCHANNEL_DATA2
tochannels_mask
like sounsigned int channels_mask = (1 << VoxelBuffer::CHANNEL_SDF) | (1 << VoxelBuffer::CHANNEL_DATA2);
But i don't know which element to choose from
corner_positions
to use inget_voxel
(voxel_mesher_transvoxel.cpp
)Now i'm using
corner_positions[0]
But
corner_positions[0]
seems related not to voxel, but to voxel nearby to it. That's why when i calldo_point
texture applies not to created voxel (but to part of mesh created bydo_point
).Thanks in advance for any help provided.
The text was updated successfully, but these errors were encountered: