#Trouble generating collision heightmap

84 messages · Page 1 of 1 (latest)

stable cipher
#

Hi, I'm trying to create a CollisionHeightMap based on my current heightmap calculations. Here is the code.


@export var terrain : MeshInstance3D


var _simplex3dNoise : NoiseTexture2D
var _cellular2dNoise : NoiseTexture2D 
var _cellular_height : Image
var _simplex_height : Image
var Height_Dune 
var Height_Detail

var collisoin_decimation := 2

var material : ShaderMaterial 

var offsetUVs : Vector2 
@export var sc : float = 2
func _ready():
    material = terrain.get_surface_override_material(0)
    _cellular2dNoise = material.get_shader_parameter("_cellular2dNoise") as NoiseTexture2D
    _simplex3dNoise = material.get_shader_parameter("_simplex3dNoise") as NoiseTexture2D
    await _cellular2dNoise.changed
    await _simplex3dNoise.changed
    create_collision()
    get_parent().start_generating_collision = true
func create_collision():
    
    var float_array : PackedFloat32Array = []
    
    Height_Dune = material.get_shader_parameter("Height_Dune")
    Height_Detail = material.get_shader_parameter("Height_Detail")
    
   scale.x = terrain.scale.x * 2243/_cellular2dNoise.get_height() * collisoin_decimation
    scale.z = terrain.scale.z * 2243/_cellular2dNoise.get_width()* collisoin_decimation
    
    _cellular_height = _cellular2dNoise.get_image() as Image
    _simplex_height = _simplex3dNoise.get_image() as Image
    
    var collision_height = _cellular_height.get_height()/ collisoin_decimation + 1
    var collision_width = _simplex_height.get_width()/ collisoin_decimation + 1

    
    
    var shap = HeightMapShape3D.new()
    shape = shap
    shap.map_width = collision_width
    shap.map_depth = collision_height
    
    for y in collision_height:
        for x in collision_width:
            var c = Vector2(fposmod(x,collision_height ), fposmod(y,collision_width))
            float_array.push_back(CalculateHeight(c))
    shape.map_data = float_array
    
    #create_collision_anchors
    
    
    


func CalculateHeight(uv : Vector2) -> float:
    
    
    
    var offsetUV = uv + offsetUVs
    
    
    
    var SimplexNoise = _simplex_height.get_pixel(offsetUV.x, offsetUV.y).r;
    var simplexed_uv = lerp(offsetUV, Vector2(SimplexNoise, SimplexNoise), .1);
    
    var DunesWorleyNoise = _cellular_height.get_pixel(simplexed_uv.x, simplexed_uv.y).r * Height_Dune;
    
    var DetailWorleyNoise = _cellular_height.get_pixel(simplexed_uv.x, simplexed_uv.y * 0.05).r;
    var DetailSimplexNoise = _simplex_height.get_pixel(simplexed_uv.x, simplexed_uv.y).r;

    var overlayed_details
    if (DetailWorleyNoise < 0.5):
            overlayed_details = 2.0 * DetailWorleyNoise * DetailSimplexNoise;
    else:
        overlayed_details = 1.0 - 2.0 * (1.0 - DetailSimplexNoise) * (1.0 - DetailWorleyNoise);
    
    overlayed_details *= Height_Detail;

    var overlayed_height;
    if (DunesWorleyNoise < 0.5):
        overlayed_height = 2.0 * DunesWorleyNoise * overlayed_details;
    else:
        overlayed_height = 1.0 - 2.0 * (1.0 - overlayed_details) * (1.0 - DunesWorleyNoise);
        
    
    return overlayed_height;


#

I can't seem to get the generated collision shape to align with my mesh...

#

in here, 2243 is my mesh dimensions, as a square. Height_Dune and Height_Detail are taken from my vertex shader and are pretty self explanatory. collisoin_decimation is my horrible misspell for the amount of detail in the heightmap. the CalculateHeight function is the same as my vertex shader.

#

the noise textures are set to seamless, which is why I'm using fposmod, but I don't know if it's needed honestly.

#

The previous attempts used the .resize() method to first resize the image to the new "level of detail" dimensions, and then sample it and make the collisionheightmap based on the new resized dimensions/

stable cipher
#

<@&486235350839197726> (Should I use this role?)

#

(If not, sorry for pinging.)

amber zealot
tribal lake
stable cipher
#

yus

thick tangle
#

I think that looks pretty good, I have no idea how to help you though.

Maybe use a displacement shader to align the veiw model with the collision?

amber zealot
stable cipher
#

Thanks for the suggestion, tho it should be quite the opposite- same code generated in the shader is used on the CPU side

amber zealot
#

is it possible that the mesh or collider is rotated in some way? looking at the screenshots I feel like that may be the case

stable cipher
#

I tried rotatin it in all directions honestly

amber zealot
#

also can you post the shader? I mean if it's the same code then it shouldn't be needed, but sometimes it's easy to miss some minor differences

stable cipher
#

it can be
rotated
mirrored
maybe even inversed??

#

float CalculateHeight(vec2 uv) {
    vec2 SimplexNoise = textureLod(_simplex3dNoise, uv, 0).rg;
    vec2 simplexed_uv = mix(uv, SimplexNoise, .1);
    
    vec2 DunesWorleyNoise = textureLod(_cellular2dNoise, simplexed_uv, 0).rg * Height_Dune;
    
    vec2 DetailWorleyNoise = textureLod(_cellular2dNoise, simplexed_uv * vec2(1.0, 0.05), 0).rg;
    float DetailSimplexNoise = textureLod(_simplex3dNoise, simplexed_uv, 0).r;
    
    
    

        float overlayed_details;
        if (DetailWorleyNoise.x < 0.5) {
            overlayed_details = 2.0 * DetailWorleyNoise.x * DetailSimplexNoise;
        } else {
            overlayed_details = 1.0 - 2.0 * (1.0 - DetailSimplexNoise) * (1.0 - DetailWorleyNoise.x);
        }
        overlayed_details *= Height_Detail;

        float overlayed_height;
        if (DunesWorleyNoise.x < 0.5) {
            overlayed_height = 2.0 * DunesWorleyNoise.x * overlayed_details;
        } else {
            overlayed_height = 1.0 - 2.0 * (1.0 - overlayed_details) * (1.0 - DunesWorleyNoise.x);
        }
        
        return overlayed_height;
        
        
}```
thick tangle
#

Looks to me that some values do align properly, maybe a misplaced negative sign?

stable cipher
#

It looks like general shapes might align, but that's about it

amber zealot
stable cipher
#

with a v simple VERTEX.y += CalculateHeight(UV);

thick tangle
#

What's with the 1.0 - 2.0?

stable cipher
#

All vertex start at 0. I am using a mesh that is more subdivided on the inside.

stable cipher
thick tangle
#

Alright.
Well I gtg.
Good luck.

stable cipher
#

Thank you

amber zealot
# stable cipher with a v simple VERTEX.y += CalculateHeight(UV);

I have no idea yet for the cause of this, but a few ideas how to debug this further.

so UV starts at 0,0 at one corner of your mesh, and ends at 1,1 at another corner. Which corners that are can be debugged by setting the albedo color to the UV:

void fragment() {
    ALBEDO = vec3(UV.x, UV.y, 1.0);
}

with this the white corner is UV 1,1 and the opposite colourful corner is 0,0

then compare this with how you supply the UV in your GDScript code. Make sure that the calculated UV there is aligned with the one of the mesh

stable cipher
#

I don't think I have a way to visualize this UV on the collision shape

#

got one idea tho

#

seems to go from 0 to 1 as well

#

tho the 1 here seems big

amber zealot
#

I'm afraid I'm out of ideas then, sorry :/

#

it does look correct to me

stable cipher
#

it does

#

I think it's with the math that takes care of the decimation

stable cipher
#

I give up for today ^^;

stable cipher
#

Day 2, I'm in pain

glad ivy
#

I dont remember helping this help chat out

#

what seems to be the problem?

#

oh because he probably pinged helper role out

stable cipher
#

She*

#

basically, a lot of trouble creating a collision shape from a vertex displacement shader

glad ivy
#

I am not good with shaders and 3D coding

#

I am only good with 3D map building

#

I only hvae a little experince

stable cipher
#

Ok, slowly figuring this out

stable cipher
#

OK SO

#

narrowed this down to this linear interpolation line

#

simplexed_uv

#

for some reason the same calculation results in different values

stable cipher
#

It's ok if not ^^

#

how tf do both of those produce different values??

#

maybe floating point bs?

amber zealot
stable cipher
amber zealot
#

It's just that I don't know when I will have time, so I wanted to manage expectations so that you don't think I'll look into it immediately

stable cipher
#

Then worst case it'll be zipped over to ya

stable cipher
#

Ok, so the problem is actually with the color spaces

#

idk what godot does with this

#

but it's messing me up bad

glad ivy
#

I have no idea what is happening here

stable cipher
#

AND IT IS SOLVED :D

glad ivy
#

good

#

Took so long

stable cipher
#

Yeah, it's a very small detail

#

But @amber zealot helped me :D

#

Now the collision shape works

glad ivy
#

nice

stable cipher
#

Anyone knows how does a seamless noise texture works when you get it via get_image()?
I'm trying to have chunks of noise offsetted by their position, so they'll connect properly

stable cipher
#
    #this shit doesn't work again lmfao
    var new_uv = Vector2(fposmod(uv.x - (offset.x/ div), _cellular_height.get_width()), fposmod(uv.y - (offset.y / div), _cellular_height.get_height()))
    var SimplexNoise = _simplex_height.get_pixelv(new_uv).r * _simplex_height.get_height();
    var simplexed_uv = lerp(uv, Vector2(SimplexNoise, SimplexNoise), .1);
    var DunesWorleyNoise = _cellular_height.get_pixelv(simplexed_uv).r * Height_Dune * 2;
    return DunesWorleyNoise

this gets run for every chunk. trying to offset the uv to match the chunk's position(as they are placed near eachother).