生成OpenSimplex2噪声写入JPG后图像全黑问题排查
问题原因与修复方案
核心问题
- 噪声值范围不匹配:
fnlGetNoise2D返回的是**-1到1之间的浮点数**,直接赋值给uint8_t类型时,负数会被强制截断为0,小于1的正数也会被取整为0,最终所有像素都是0,呈现全黑。 - 通道数据不完整:调用函数时传入了3通道(RGB),但代码里每个像素只写入了1个值,导致图像数据错位,进一步加剧显示异常。
修复后的代码
void write_noise_2d(int w, int h, int channels_num) { // 初始化噪声 fnl_state noise = fnlCreateState(); noise.noise_type = FNL_NOISE_OPENSIMPLEX2; // 分配图像数据内存 uint8_t* noise_data = malloc(w * h * channels_num * sizeof(uint8_t)); int index = 0; // 遍历生成每个像素的噪声值 for(int x=0; x<w; x++) { for(int y=0; y<h; y++) { // 获取噪声值并映射到0-255范围,同时缩放坐标避免图案过密 float noise_val = fnlGetNoise2D(&noise, (float)x/64.0f, (float)y/64.0f); uint8_t mapped_val = (uint8_t)((noise_val + 1.0f) * 127.5f); // 为每个通道填充相同的灰度值 for(int c=0; c<channels_num; c++) { noise_data[index++] = mapped_val; } } } stbi_write_jpg("textures/noisemap.jpg", w, h, channels_num, noise_data, w * channels_num); free(noise_data); } write_noise_2d(512, 512, 3);
关键修改点
- 值范围映射:用
(noise_val + 1.0f) * 127.5f把[-1,1]的浮点数转换为[0,255]的整数,确保噪声值能正确显示为灰度。 - 缩放噪声坐标:把
x和y除以64.0f,避免原整数坐标导致的噪声图案过于密集、无法分辨纹理的问题。 - 填充多通道数据:每个像素循环写入对应通道数的值,保证RGB通道数据完整,不会出现数据错位。
内容的提问来源于stack exchange,提问作者Chillzy
相关产品推荐
相关产品推荐

