41 lines
1.5 KiB
GLSL
41 lines
1.5 KiB
GLSL
//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);
|
|
}
|