examples/Sponza no longer built natively (#164). Its closest-hit declared a descriptor_heap sampler2D, which glslang has rejected since c8253623 ("Reject descriptor_heap combined image samplers"), and main.cpp wrote it through VkResourceDescriptorDataEXT::pCombinedImageSampler, which that union no longer has: the descriptor heap has no combined image samplers. Both went unnoticed because nothing builds the examples. Sponza - closesthit.glsl declares texture2D and sampler heap arrays and joins them where it samples, as ui-shared.glsl and HeapDynamicIndexHit do. The sampler slot is a second spec constant beside the image slot, so the shader assumes nothing about where the host put it, and a constant index keeps the example running on NVIDIA 610.43.02 (see its README). The comment no longer says the image slot is offset by bufferStartElement; only buffer slots are. - main.cpp gives the heap a sampler slot, writes the albedo as a SAMPLED_IMAGE from a view create-info, and writes the sampler into the sampler heap from a VkSamplerCreateInfo with vkWriteSamplerDescriptorsEXT, as UIRenderer::RegisterSampler does. SamplerVulkan's VkSampler had no use left. The sampler keeps its linear filtering and repeat addressing and drops anisotropy, which a hit shader cannot use: it samples at LOD 0, without derivatives. Docs - README.md and examples/Sponza/README.md quote the new declarations, and the Sponza README says why the texture and the sampler are two descriptors. Its texture2DArray materials pattern declared a descriptor_heap sampler2DArray, which glslang rejects as well; it now joins a texture2DArray and a sampler. - examples/SponzaBench/README.md drops its caveat that Sponza does not compile. Tests - ExampleShaders compiles every GLSL shader under examples/ with glslang as crafter-build does for the example (Vulkan rules, SPIR-V 1.4, shaders/ on the include path, and the descriptor-set build where the example registers one), so a glslang that starts rejecting one fails a test rather than an example build nobody runs. It fails on Sponza's old closest-hit and needs glslang only. Closes #164. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
1.4 KiB
GLSL
31 lines
1.4 KiB
GLSL
//SPDX-License-Identifier: MIT
|
|
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
#version 460
|
|
#extension GL_EXT_ray_tracing : enable
|
|
#extension GL_EXT_shader_image_load_formatted : enable
|
|
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable
|
|
#extension GL_EXT_descriptor_heap : enable
|
|
#extension GL_EXT_nonuniform_qualifier : enable
|
|
|
|
// Specialization constants: the albedo's slot in the resource heap and its
|
|
// sampler's slot in the sampler heap, as the host allocated them (image and
|
|
// sampler slots index their heaps directly; only buffer slots are offset by
|
|
// bufferStartElement). The descriptor heap has no combined image samplers,
|
|
// and glslang rejects a descriptor_heap sampler2D (#164), so the texture
|
|
// and the sampler are separate descriptors, joined where they are sampled.
|
|
// Sampling uses gl_HitAttributeEXT barycentrics as UVs — proof-of-binding
|
|
// rather than UV-correct shading. Per-vertex UV interpolation lands when
|
|
// Mesh on Vulkan exposes the data-region buffer.
|
|
layout(constant_id = 0) const uint16_t albedoSlot = 0us;
|
|
layout(constant_id = 1) const uint16_t samplerSlot = 0us;
|
|
layout(descriptor_heap) uniform texture2D textures[];
|
|
layout(descriptor_heap) uniform sampler samplers[];
|
|
|
|
hitAttributeEXT vec2 hitAttrs;
|
|
layout(location = 0) rayPayloadInEXT vec3 hitValue;
|
|
|
|
void main() {
|
|
vec2 bary = vec2(hitAttrs.x, hitAttrs.y);
|
|
hitValue = texture(sampler2D(textures[albedoSlot], samplers[samplerSlot]), bary).rgb;
|
|
}
|