//SPDX-License-Identifier: MIT //SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® #version 460 #extension GL_EXT_ray_tracing : enable // RTVolume closest-hit — shades the committed procedural sphere hit by // its surface normal with a fixed sun + ambient, tinted per instance // (gl_InstanceCustomIndexEXT). Mirrors closesthit.wgsl on the WebGPU // path. hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT vec3 hitValue; const vec3 SUN_DIR_TO_LIGHT = vec3(0.40, 0.85, 0.35); const vec3 SUN_COLOR = vec3(1.20, 1.10, 0.95); const vec3 AMBIENT_COLOR = vec3(0.16, 0.18, 0.24); vec3 instanceAlbedo(uint i) { uint h = i * 2654435761u; return vec3( 0.35 + 0.6 * float((h >> 0) & 255u) / 255.0, 0.35 + 0.6 * float((h >> 8) & 255u) / 255.0, 0.35 + 0.6 * float((h >> 16) & 255u) / 255.0); } void main() { // Object-space hit point on the unit sphere is its object-space // normal; gl_ObjectToWorldEXT's rotation part takes it to world. vec3 posObj = gl_ObjectRayOriginEXT + gl_ObjectRayDirectionEXT * gl_HitTEXT; vec3 nObj = normalize(posObj); vec3 nWorld = normalize(gl_ObjectToWorldEXT * vec4(nObj, 0.0)); vec3 albedo = instanceAlbedo(uint(gl_InstanceCustomIndexEXT)); vec3 viewDir = -gl_WorldRayDirectionEXT; vec3 nFacing = dot(nWorld, viewDir) > 0.0 ? nWorld : -nWorld; vec3 sunDir = normalize(SUN_DIR_TO_LIGHT); float nDotL = max(0.0, dot(nFacing, sunDir)); hitValue = albedo * (AMBIENT_COLOR + SUN_COLOR * nDotL); }