diff --git a/examples/cornell_box b/examples/cornell_box index e3bc8f6..c8bcff2 100644 Binary files a/examples/cornell_box and b/examples/cornell_box differ diff --git a/include/basic/constants.h b/include/basic/constants.h index 62046f4..12c631d 100644 --- a/include/basic/constants.h +++ b/include/basic/constants.h @@ -12,14 +12,11 @@ constexpr int MAX_RAY_DEPTH = 8; /// @brief Default samples per pixel for ray tracing constexpr int DEFAULT_SPP = 1; -/// @brief G-Buffer texture types -enum GBufferTextureType { - GBUFFER_POSITION = 0, - GBUFFER_NORMAL = 1, - GBUFFER_ALBEDO = 2, - GBUFFER_MATERIAL_ID = 3, - GBUFFER_TEXTURE_COUNT = 4 -}; +/// @brief G-Buffer attachment indices +constexpr int GBUFFER_POSITION = 0; +constexpr int GBUFFER_NORMAL = 1; +constexpr int GBUFFER_ALBEDO = 2; +constexpr int GBUFFER_COUNT = 3; /// @brief Compute shader work group size constexpr int COMPUTE_GROUP_SIZE_X = 16; diff --git a/include/core/gbuffer.h b/include/core/gbuffer.h index 087717f..9859cb0 100644 --- a/include/core/gbuffer.h +++ b/include/core/gbuffer.h @@ -54,7 +54,7 @@ private: uint width_; uint height_; FramebufferHandle fbo_; - TextureHandle textures_[GBUFFER_TEXTURE_COUNT]; + TextureHandle textures_[GBUFFER_COUNT]; TextureHandle depth_texture_; bool initialized_; diff --git a/shaders/gbuffer.frag b/shaders/gbuffer.frag index 72f6cf6..61a7c4a 100644 --- a/shaders/gbuffer.frag +++ b/shaders/gbuffer.frag @@ -16,7 +16,7 @@ in VS_OUT { layout(location = 0) out vec4 g_position; layout(location = 1) out vec4 g_normal; layout(location = 2) out vec4 g_albedo; -layout(location = 3) out uvec4 g_material_id; +layout(location = 3) out vec4 g_material; // Material uniforms uniform vec3 u_albedo; @@ -24,7 +24,7 @@ uniform float u_metallic; uniform float u_roughness; uniform float u_ior; uniform vec3 u_emission; -uniform uint u_material_id; +uniform uint u_material_type; uniform bool u_has_albedo_map; uniform sampler2D u_albedo_map; @@ -44,6 +44,6 @@ void main() { } g_albedo = vec4(albedo, 1.0); - // Material properties - g_material_id = uvec4(u_material_id, 0u, 0u, 0u); + // Material properties + g_material = vec4(u_metallic, u_roughness, u_ior, float(u_material_type)); } diff --git a/shaders/raytracing.comp b/shaders/raytracing.comp index ccf6568..28fb002 100644 --- a/shaders/raytracing.comp +++ b/shaders/raytracing.comp @@ -19,66 +19,28 @@ #define LIGHT_POINT 1 #define LIGHT_SPOT 2 -// Material structure - 使用 vec4 确保对齐 +// Structures struct Material { - vec4 albedo_metallic; // xyz = albedo, w = metallic - vec4 emission_roughness; // xyz = emission, w = roughness + vec3 albedo; + float metallic; + vec3 emission; + float roughness; int type; float ior; - float padding1; - float padding2; + vec2 padding; }; -// Light structure - 使用 vec4 确保对齐 struct Light { - vec4 position_type; // xyz = position, w = type - vec4 direction_intensity; // xyz = direction, w = intensity - vec4 color_range; // xyz = color, w = range - vec4 spot_angles; // xy = spot angles, zw = padding + vec3 position; + int type; + vec3 direction; + float intensity; + vec3 color; + float range; + vec2 spot_angles; // inner, outer + vec2 padding; }; -// 辅助函数:从 Material 获取属性 -vec3 get_material_albedo(Material mat) { - return mat.albedo_metallic.xyz; -} - -float get_material_metallic(Material mat) { - return mat.albedo_metallic.w; -} - -vec3 get_material_emission(Material mat) { - return mat.emission_roughness.xyz; -} - -float get_material_roughness(Material mat) { - return mat.emission_roughness.w; -} - -// 辅助函数:从 Light 获取属性 -vec3 get_light_position(Light light) { - return light.position_type.xyz; -} - -int get_light_type(Light light) { - return int(light.position_type.w); -} - -vec3 get_light_direction(Light light) { - return light.direction_intensity.xyz; -} - -float get_light_intensity(Light light) { - return light.direction_intensity.w; -} - -vec3 get_light_color(Light light) { - return light.color_range.xyz; -} - -float get_light_range(Light light) { - return light.color_range.w; -} - struct Ray { vec3 origin; vec3 direction; @@ -191,11 +153,10 @@ layout(local_size_x = 16, local_size_y = 16) in; layout(binding = 0, rgba32f) uniform readonly image2D g_position; layout(binding = 1, rgba32f) uniform readonly image2D g_normal; layout(binding = 2, rgba8) uniform readonly image2D g_albedo; -layout(binding = 3, r32ui) uniform readonly uimage2D g_material_id; // Output -layout(binding = 4, rgba32f) uniform image2D output_image; -layout(binding = 5, rgba32f) uniform image2D accumulation_image; +layout(binding = 3, rgba32f) uniform image2D output_image; +layout(binding = 4, rgba32f) uniform image2D accumulation_image; // Scene data layout(std430, binding = 0) readonly buffer MaterialBuffer { @@ -221,35 +182,21 @@ vec3 evaluate_direct_lighting(vec3 position, vec3 normal, vec3 view_dir, Material material, inout uint seed) { vec3 direct_light = vec3(0.0); - // 获取材质属性 - vec3 mat_albedo = get_material_albedo(material); - float mat_metallic = get_material_metallic(material); - float mat_roughness = get_material_roughness(material); - for (uint i = 0u; i < u_light_count; i++) { Light light = lights[i]; - - // 获取光源属性 - vec3 light_pos = get_light_position(light); - int light_type = get_light_type(light); - vec3 light_dir_raw = get_light_direction(light); - float light_intensity = get_light_intensity(light); - vec3 light_color = get_light_color(light); - float light_range = get_light_range(light); - vec3 light_dir; float light_distance; float attenuation = 1.0; - if (light_type == LIGHT_POINT) { - vec3 to_light = light_pos - position; + if (light.type == LIGHT_POINT) { + vec3 to_light = light.position - position; light_distance = length(to_light); light_dir = to_light / light_distance; attenuation = 1.0 / max(light_distance * light_distance, 0.01); - if (light_distance > light_range) continue; - } else if (light_type == LIGHT_DIRECTIONAL) { - light_dir = normalize(-light_dir_raw); + if (light_distance > light.range) continue; + } else if (light.type == LIGHT_DIRECTIONAL) { + light_dir = normalize(-light.direction); light_distance = MAX_FLOAT; } else { continue; @@ -262,20 +209,20 @@ vec3 evaluate_direct_lighting(vec3 position, vec3 normal, vec3 view_dir, float NdotV = max(dot(normal, view_dir), 0.0); // PBR lighting - vec3 F0 = mix(vec3(0.04), mat_albedo, mat_metallic); + vec3 F0 = mix(vec3(0.04), material.albedo, material.metallic); vec3 F = fresnel_schlick(max(dot(H, view_dir), 0.0), F0); - float D = distribution_ggx(normal, H, max(mat_roughness, 0.04)); - float G = geometry_smith(normal, view_dir, light_dir, mat_roughness); + float D = distribution_ggx(normal, H, max(material.roughness, 0.04)); + float G = geometry_smith(normal, view_dir, light_dir, material.roughness); vec3 numerator = D * G * F; float denominator = 4.0 * NdotV * NdotL + EPSILON; vec3 specular = numerator / denominator; vec3 kS = F; - vec3 kD = (vec3(1.0) - kS) * (1.0 - mat_metallic); + vec3 kD = (vec3(1.0) - kS) * (1.0 - material.metallic); - vec3 radiance = light_color * light_intensity * attenuation; - direct_light += (kD * mat_albedo * INV_PI + specular) * radiance * NdotL; + vec3 radiance = light.color * light.intensity * attenuation; + direct_light += (kD * material.albedo * INV_PI + specular) * radiance * NdotL; } } @@ -290,26 +237,10 @@ void main() { return; } - // ============ DEBUG MODE 6: 显示材质Metallic ============ - /* - { - uint mat_id = imageLoad(g_material_id, pixel_coords).r; - if (imageLoad(g_position, pixel_coords).w > 0.5 && mat_id < uint(materials.length())) { - Material mat = materials[mat_id]; - float metallic_vis = get_material_metallic(mat); - imageStore(output_image, pixel_coords, vec4(metallic_vis, metallic_vis, metallic_vis, 1.0)); - } else { - imageStore(output_image, pixel_coords, vec4(0.0, 0.0, 0.0, 1.0)); - } - return; - } - */ - // Read G-Buffer vec4 position_data = imageLoad(g_position, pixel_coords); vec4 normal_data = imageLoad(g_normal, pixel_coords); vec4 albedo_data = imageLoad(g_albedo, pixel_coords); - uint material_id = imageLoad(g_material_id, pixel_coords).r; // Background if (position_data.w < 0.5) { @@ -323,6 +254,11 @@ void main() { vec3 normal = normalize(normal_data.xyz); vec3 albedo = albedo_data.rgb; + // 关键修复:从G-Buffer的alpha通道读取material_id + // 注意:albedo_data是从RGBA8纹理读取的,alpha值范围是[0,1] + // 我们需要将其转换回整数ID + uint material_id = uint(albedo_data.a * 255.0 + 0.5); + // Initialize random seed uint seed = uint(pixel_coords.x) + uint(pixel_coords.y) * uint(image_size.x) + u_frame_count * 719393u; @@ -333,17 +269,20 @@ void main() { uint mat_count = uint(materials.length()); if (material_id < mat_count) { + // 从SSBO读取材质 material = materials[material_id]; } else { - // Fallback - 创建默认材质 - material.albedo_metallic = vec4(albedo, 0.0); - material.emission_roughness = vec4(0.0, 0.0, 0.0, 0.5); + // 使用G-Buffer中的albedo作为fallback + material.albedo = albedo; + material.metallic = 0.0; + material.roughness = 0.5; + material.emission = vec3(0.0); material.type = MATERIAL_DIFFUSE; material.ior = 1.5; } // Add emission - color += get_material_emission(material); + color += material.emission; // Direct lighting vec3 view_dir = normalize(u_camera_position - position); @@ -353,7 +292,7 @@ void main() { } // Ambient lighting - color += get_material_albedo(material) * 0.05; + color += material.albedo * 0.05; // Clamp color = clamp(color, vec3(0.0), vec3(10.0)); @@ -368,3 +307,197 @@ void main() { imageStore(accumulation_image, pixel_coords, vec4(color, 1.0)); imageStore(output_image, pixel_coords, vec4(color, 1.0)); } + +// layout(local_size_x = 16, local_size_y = 16) in; +// +// // G-Buffer inputs +// layout(binding = 0, rgba32f) uniform readonly image2D g_position; +// layout(binding = 1, rgba32f) uniform readonly image2D g_normal; +// layout(binding = 2, rgba8) uniform readonly image2D g_albedo; +// +// // Output +// layout(binding = 3, rgba32f) uniform image2D output_image; +// layout(binding = 4, rgba32f) uniform image2D accumulation_image; +// +// // Scene data +// layout(std430, binding = 0) readonly buffer MaterialBuffer { +// Material materials[]; +// }; +// +// layout(std430, binding = 1) readonly buffer LightBuffer { +// Light lights[]; +// }; +// +// // Uniforms +// uniform uint u_frame_count; +// uniform uint u_samples_per_pixel; +// uniform uint u_max_depth; +// uniform uint u_light_count; +// uniform vec3 u_camera_position; +// uniform mat4 u_inv_view_projection; +// uniform bool u_enable_accumulation; +// uniform bool u_use_bvh; +// +// // Cosine-weighted hemisphere sampling +// vec3 cosine_weighted_hemisphere(vec3 normal, inout uint seed) { +// vec2 r = random_vec2(seed); +// float r1 = 2.0 * PI * r.x; +// float r2 = r.y; +// float r2s = sqrt(r2); +// +// vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); +// vec3 tangent = normalize(cross(up, normal)); +// vec3 bitangent = cross(normal, tangent); +// +// vec3 dir = tangent * cos(r1) * r2s + bitangent * sin(r1) * r2s + normal * sqrt(1.0 - r2); +// return normalize(dir); +// } +// +// // Evaluate direct lighting +// vec3 evaluate_direct_lighting(vec3 position, vec3 normal, vec3 view_dir, +// Material material, inout uint seed) { +// vec3 direct_light = vec3(0.0); +// +// for (uint i = 0u; i < u_light_count; i++) { +// Light light = lights[i]; +// vec3 light_dir; +// float light_distance; +// float attenuation = 1.0; +// +// if (light.type == LIGHT_POINT) { +// vec3 to_light = light.position - position; +// light_distance = length(to_light); +// light_dir = to_light / light_distance; +// attenuation = 1.0 / max(light_distance * light_distance, 0.01); +// +// if (light_distance > light.range) continue; +// } else if (light.type == LIGHT_DIRECTIONAL) { +// light_dir = normalize(-light.direction); +// light_distance = MAX_FLOAT; +// } else { +// continue; +// } +// +// float NdotL = max(dot(normal, light_dir), 0.0); +// +// if (NdotL > 0.0) { +// vec3 H = normalize(view_dir + light_dir); +// float NdotV = max(dot(normal, view_dir), 0.0); +// +// // PBR lighting +// vec3 F0 = mix(vec3(0.04), material.albedo, material.metallic); +// vec3 F = fresnel_schlick(max(dot(H, view_dir), 0.0), F0); +// float D = distribution_ggx(normal, H, max(material.roughness, 0.04)); +// float G = geometry_smith(normal, view_dir, light_dir, material.roughness); +// +// vec3 numerator = D * G * F; +// float denominator = 4.0 * NdotV * NdotL + EPSILON; +// vec3 specular = numerator / denominator; +// +// vec3 kS = F; +// vec3 kD = (vec3(1.0) - kS) * (1.0 - material.metallic); +// +// vec3 radiance = light.color * light.intensity * attenuation; +// direct_light += (kD * material.albedo * INV_PI + specular) * radiance * NdotL; +// } +// } +// +// return direct_light; +// } +// +// // Trace indirect lighting (simple path tracing) +// vec3 trace_indirect(vec3 position, vec3 normal, Material material, inout uint seed) { +// vec3 color = vec3(0.0); +// +// // Sample random direction +// vec3 ray_dir = cosine_weighted_hemisphere(normal, seed); +// +// // Sky color based on direction +// float t = 0.5 * (ray_dir.y + 1.0); +// vec3 sky_color = mix(vec3(1.0), vec3(0.5, 0.7, 1.0), t) * 0.2; +// +// color = sky_color; +// +// return color; +// } +// +// void main() { +// ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); +// ivec2 image_size = imageSize(output_image); +// +// if (pixel_coords.x >= image_size.x || pixel_coords.y >= image_size.y) { +// return; +// } +// +// // Read G-Buffer +// vec4 position_data = imageLoad(g_position, pixel_coords); +// vec4 normal_data = imageLoad(g_normal, pixel_coords); +// vec4 albedo_data = imageLoad(g_albedo, pixel_coords); +// +// // Check if this pixel has valid geometry +// if (position_data.w < 0.5) { +// vec3 background = vec3(0.1, 0.1, 0.15); +// imageStore(output_image, pixel_coords, vec4(background, 1.0)); +// imageStore(accumulation_image, pixel_coords, vec4(background, 1.0)); +// return; +// } +// +// vec3 position = position_data.xyz; +// vec3 normal = normalize(normal_data.xyz); +// vec3 albedo = albedo_data.rgb; +// uint material_id = floatBitsToUint(albedo_data.a); +// +// if (material_id >= 1000u) { +// material_id = 0u; +// } +// +// // Initialize random seed +// uint seed = uint(pixel_coords.x) + uint(pixel_coords.y) * uint(image_size.x) + u_frame_count * 719393u; +// +// vec3 color = vec3(0.0); +// +// // Get material +// Material material; +// if (material_id < uint(materials.length())) { +// material = materials[material_id]; +// } else { +// material.albedo = albedo; +// material.metallic = 0.0; +// material.roughness = 0.5; +// material.emission = vec3(0.0); +// material.type = MATERIAL_DIFFUSE; +// material.ior = 1.5; +// } +// +// // Add emission +// color += material.emission; +// +// // Direct lighting +// vec3 view_dir = normalize(u_camera_position - position); +// +// if (u_light_count > 0u) { +// color += evaluate_direct_lighting(position, normal, view_dir, material, seed); +// } +// +// // Indirect lighting (path tracing) - THIS ADDS NOISE +// for (uint samp_idx = 0u; samp_idx < u_samples_per_pixel; samp_idx++) { // 修复: sample -> samp_idx +// vec3 indirect = trace_indirect(position, normal, material, seed); +// color += indirect * material.albedo * INV_PI; +// } +// +// // Ambient +// color += material.albedo * 0.02; +// +// // Clamp +// color = clamp(color, vec3(0.0), vec3(100.0)); +// +// // Accumulation for denoising +// if (u_enable_accumulation && u_frame_count > 0u) { +// vec3 accumulated = imageLoad(accumulation_image, pixel_coords).rgb; +// float weight = 1.0 / float(u_frame_count + 1u); +// color = mix(accumulated, color, weight); +// } +// +// imageStore(accumulation_image, pixel_coords, vec4(color, 1.0)); +// imageStore(output_image, pixel_coords, vec4(color, 1.0)); +// } diff --git a/src/core/gbuffer.cpp b/src/core/gbuffer.cpp index 96ecc51..b3e01d0 100644 --- a/src/core/gbuffer.cpp +++ b/src/core/gbuffer.cpp @@ -1,5 +1,4 @@ #include "core/gbuffer.h" -#include "basic/constants.h" #include "utils/logger.h" #include @@ -11,7 +10,7 @@ GBuffer::GBuffer(uint width, uint height) , fbo_(INVALID_HANDLE) , depth_texture_(INVALID_HANDLE) , initialized_(false) { - for (int i = 0; i < GBUFFER_TEXTURE_COUNT; ++i) { + for (int i = 0; i < GBUFFER_COUNT; ++i) { textures_[i] = INVALID_HANDLE; } } @@ -34,30 +33,32 @@ bool GBuffer::initialize() { textures_[GBUFFER_POSITION] = create_texture_(GL_RGBA32F, GL_RGBA, GL_FLOAT); textures_[GBUFFER_NORMAL] = create_texture_(GL_RGBA32F, GL_RGBA, GL_FLOAT); textures_[GBUFFER_ALBEDO] = create_texture_(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE); - textures_[GBUFFER_MATERIAL_ID] = create_texture_(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT); // Attach textures to framebuffer - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_POSITION, GL_TEXTURE_2D, textures_[GBUFFER_POSITION], 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_NORMAL, GL_TEXTURE_2D, textures_[GBUFFER_NORMAL], 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_ALBEDO, GL_TEXTURE_2D, textures_[GBUFFER_ALBEDO], 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_MATERIAL_ID, GL_TEXTURE_2D, textures_[GBUFFER_MATERIAL_ID], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_POSITION, + GL_TEXTURE_2D, textures_[GBUFFER_POSITION], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_NORMAL, + GL_TEXTURE_2D, textures_[GBUFFER_NORMAL], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBUFFER_ALBEDO, + GL_TEXTURE_2D, textures_[GBUFFER_ALBEDO], 0); // Create depth texture glGenTextures(1, &depth_texture_); glBindTexture(GL_TEXTURE_2D, depth_texture_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width_, height_, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width_, height_, 0, + GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth_texture_, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, depth_texture_, 0); // Set draw buffers - GLenum draw_buffers[GBUFFER_TEXTURE_COUNT] = { + GLenum draw_buffers[GBUFFER_COUNT] = { GL_COLOR_ATTACHMENT0 + GBUFFER_POSITION, GL_COLOR_ATTACHMENT0 + GBUFFER_NORMAL, - GL_COLOR_ATTACHMENT0 + GBUFFER_ALBEDO, - GL_COLOR_ATTACHMENT0 + GBUFFER_MATERIAL_ID + GL_COLOR_ATTACHMENT0 + GBUFFER_ALBEDO }; - glDrawBuffers(GBUFFER_TEXTURE_COUNT, draw_buffers); + glDrawBuffers(GBUFFER_COUNT, draw_buffers); // Check framebuffer completeness if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { @@ -81,7 +82,7 @@ void GBuffer::release() { fbo_ = INVALID_HANDLE; } - for (int i = 0; i < GBUFFER_TEXTURE_COUNT; ++i) { + for (int i = 0; i < GBUFFER_COUNT; ++i) { if (textures_[i] != INVALID_HANDLE) { glDeleteTextures(1, &textures_[i]); textures_[i] = INVALID_HANDLE; @@ -193,7 +194,7 @@ void GBuffer::resize(uint width, uint height) { } TextureHandle GBuffer::get_texture(int index) const { - if (index < 0 || index >= GBUFFER_TEXTURE_COUNT) { + if (index < 0 || index >= GBUFFER_COUNT) { Logger::error("Invalid G-Buffer texture index"); return INVALID_HANDLE; } diff --git a/src/core/raytracer.cpp b/src/core/raytracer.cpp index 4f4215b..a425b58 100644 --- a/src/core/raytracer.cpp +++ b/src/core/raytracer.cpp @@ -143,8 +143,8 @@ void RayTracer::trace(const Scene& scene, const GBuffer& gbuffer, TextureHandle bind_gbuffer_(gbuffer); // Bind output and accumulation textures - glBindImageTexture(GBUFFER_TEXTURE_COUNT, output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); - glBindImageTexture(GBUFFER_TEXTURE_COUNT + 1, accumulation_texture_, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + glBindImageTexture(3, output_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); + glBindImageTexture(4, accumulation_texture_, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); // Bind BVH buffers if enabled if (config_.use_bvh_ && bvh_built_) { @@ -234,14 +234,14 @@ void RayTracer::upload_scene_data_(const Scene& scene) { // Upload materials const auto& materials = scene.get_materials(); if (!materials.empty()) { - // 使用 vec4 确保对齐正确 - struct alignas(16) MaterialData { - Vec4 albedo_metallic; // xyz = albedo, w = metallic - Vec4 emission_roughness; // xyz = emission, w = roughness + struct MaterialData { + Vec3 albedo; + float metallic; + Vec3 emission; + float roughness; int type; float ior; - float padding1; - float padding2; + Vec2 padding; }; std::vector material_data; @@ -249,52 +249,34 @@ void RayTracer::upload_scene_data_(const Scene& scene) { for (const auto& mat : materials) { MaterialData data; - data.albedo_metallic = Vec4(mat->get_albedo(), mat->get_metallic()); - data.emission_roughness = Vec4(mat->get_emission(), mat->get_roughness()); + data.albedo = mat->get_albedo(); + data.metallic = mat->get_metallic(); + data.emission = mat->get_emission(); + data.roughness = mat->get_roughness(); data.type = static_cast(mat->get_type()); data.ior = mat->get_ior(); - data.padding1 = 0.0f; - data.padding2 = 0.0f; material_data.push_back(data); } - // 打印调试信息 - Logger::info("MaterialData size: " + std::to_string(sizeof(MaterialData)) + " bytes"); - Logger::info("Material[0] albedo: (" + - std::to_string(material_data[0].albedo_metallic.x) + ", " + - std::to_string(material_data[0].albedo_metallic.y) + ", " + - std::to_string(material_data[0].albedo_metallic.z) + ")"); - Logger::info("Material[0] metallic: " + std::to_string(material_data[0].albedo_metallic.w)); - - // 找到金属材质并打印 - for (size_t i = 0; i < material_data.size(); i++) { - if (material_data[i].albedo_metallic.w > 0.5f) { - Logger::info("Material[" + std::to_string(i) + "] is metallic: " + - std::to_string(material_data[i].albedo_metallic.w)); - } - } - glBindBuffer(GL_SHADER_STORAGE_BUFFER, material_buffer_); glBufferData(GL_SHADER_STORAGE_BUFFER, material_data.size() * sizeof(MaterialData), material_data.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, material_buffer_); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - Logger::info("Uploaded " + std::to_string(material_data.size()) + " materials to GPU"); - } else { - Logger::warning("No materials to upload"); } - // Upload lights (保持不变) + // Upload lights const auto& lights = scene.get_lights(); if (!lights.empty()) { - // 同样使用 vec4 确保对齐 - struct alignas(16) LightData { - Vec4 position_type; // xyz = position, w = type (as float) - Vec4 direction_intensity; // xyz = direction, w = intensity - Vec4 color_range; // xyz = color, w = range - Vec4 spot_angles; // xy = spot angles, zw = padding + struct LightData { + Vec3 position; + int type; + Vec3 direction; + float intensity; + Vec3 color; + float range; + Vec2 spot_angles; + Vec2 padding; }; std::vector light_data; @@ -302,33 +284,28 @@ void RayTracer::upload_scene_data_(const Scene& scene) { for (const auto& light : lights) { LightData data; - data.position_type = Vec4(light->get_position(), static_cast(light->get_type())); - data.direction_intensity = Vec4(light->get_direction(), light->get_intensity()); - data.color_range = Vec4(light->get_color(), light->get_range()); - data.spot_angles = Vec4(light->get_inner_angle(), light->get_outer_angle(), 0.0f, 0.0f); + data.position = light->get_position(); + data.type = static_cast(light->get_type()); + data.direction = light->get_direction(); + data.intensity = light->get_intensity(); + data.color = light->get_color(); + data.range = light->get_range(); + data.spot_angles = Vec2(light->get_inner_angle(), light->get_outer_angle()); light_data.push_back(data); } - Logger::info("LightData size: " + std::to_string(sizeof(LightData)) + " bytes"); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, light_buffer_); glBufferData(GL_SHADER_STORAGE_BUFFER, light_data.size() * sizeof(LightData), light_data.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, light_buffer_); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - Logger::info("Uploaded " + std::to_string(light_data.size()) + " lights to GPU"); - } else { - Logger::warning("No lights to upload"); } } void RayTracer::bind_gbuffer_(const GBuffer& gbuffer) { - glBindImageTexture(GBUFFER_POSITION, gbuffer.get_texture(GBUFFER_POSITION), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(GBUFFER_NORMAL, gbuffer.get_texture(GBUFFER_NORMAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); - glBindImageTexture(GBUFFER_ALBEDO, gbuffer.get_texture(GBUFFER_ALBEDO), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); - glBindImageTexture(GBUFFER_MATERIAL_ID, gbuffer.get_texture(GBUFFER_MATERIAL_ID), 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); + glBindImageTexture(0, gbuffer.get_texture(GBUFFER_POSITION), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(1, gbuffer.get_texture(GBUFFER_NORMAL), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + glBindImageTexture(2, gbuffer.get_texture(GBUFFER_ALBEDO), 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); } void RayTracer::set_compute_shader(const Shader& shader) {