178 lines
5.9 KiB
GLSL
178 lines
5.9 KiB
GLSL
/* Copyright (c) 2021-2024 Holochip Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 the "License";
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#version 460
|
|
#extension GL_EXT_ray_tracing : enable
|
|
#extension GL_EXT_nonuniform_qualifier : enable
|
|
#define RENDER_DEFAULT 0
|
|
#define RENDER_BARYCENTRIC 1
|
|
#define RENDER_INSTANCE_ID 2
|
|
#define RENDER_DISTANCE 3
|
|
#define RENDER_GLOBAL_XYZ 4
|
|
#define RENDER_SHADOW_MAP 5
|
|
#define RENDER_AO 6
|
|
|
|
struct Payload
|
|
{
|
|
vec4 color;
|
|
vec4 intersection; // {x, y, z, intersectionType}
|
|
vec4 normal; // {nx, ny, nz, distance}
|
|
};
|
|
|
|
layout(location = 0) rayPayloadInEXT Payload hitValue;
|
|
hitAttributeEXT vec3 attribs;
|
|
|
|
layout(binding=4, set = 0) readonly buffer VertexBuffer
|
|
{
|
|
vec4[] data;
|
|
} vertex_buffer;
|
|
|
|
layout(binding=5, set = 0) readonly buffer IndexBuffer
|
|
{
|
|
uint[] indices;
|
|
} index_buffer;
|
|
|
|
layout(binding=6, set = 0) readonly buffer DataMap
|
|
{
|
|
uint[] indices;
|
|
} data_map;
|
|
|
|
layout(binding=7, set = 0) uniform sampler2D textures[26];
|
|
|
|
layout(binding=8, set = 0) readonly buffer DynamicVertexBuffer
|
|
{
|
|
vec4[] data;
|
|
} dynamic_vertex_buffer;
|
|
|
|
layout(binding=9, set = 0) readonly buffer DynamicIndexBuffer
|
|
{
|
|
uint[] indices;
|
|
} dynamic_index_buffer;
|
|
|
|
layout (constant_id = 0) const uint render_mode = RENDER_DEFAULT;
|
|
|
|
vec3 heatmap(float value, float minValue, float maxValue)
|
|
{
|
|
float scaled = (min(max(value, minValue), maxValue) - minValue) / (maxValue - minValue);
|
|
float r = scaled * (3.14159265359 / 2.);
|
|
return vec3(sin(r), sin(2 * r), cos(r));
|
|
}
|
|
|
|
/*
|
|
// Geometry instance ids
|
|
in int gl_PrimitiveID;
|
|
in int gl_InstanceID;
|
|
in int gl_InstanceCustomIndexEXT;
|
|
in int gl_GeometryIndexEXT;
|
|
*/
|
|
|
|
struct Vertex
|
|
{
|
|
vec3 pt;
|
|
vec3 normal;
|
|
vec2 coordinate;
|
|
};
|
|
|
|
Vertex getVertex(uint vertexOffset, uint index, bool is_static)
|
|
{
|
|
uint base_index = 2 * (vertexOffset + index);
|
|
vec4 A = is_static ? vertex_buffer.data[base_index] : dynamic_vertex_buffer.data[base_index];
|
|
vec4 B = is_static ? vertex_buffer.data[base_index + 1] : dynamic_vertex_buffer.data[base_index + 1];
|
|
|
|
Vertex v;
|
|
v.pt = A.xyz;
|
|
v.normal = vec3(A.w, B.x, B.y);
|
|
v.coordinate = vec2(B.z, B.w);
|
|
return v;
|
|
}
|
|
|
|
uvec3 getIndices(uint triangle_offset, uint primitive_id, bool is_static)
|
|
{
|
|
uint base_index = 3 * (triangle_offset + primitive_id);
|
|
uint index0 = is_static ? index_buffer.indices[base_index] : dynamic_index_buffer.indices[base_index];
|
|
uint index1 = is_static ? index_buffer.indices[base_index + 1] : dynamic_index_buffer.indices[base_index + 1];
|
|
uint index2 = is_static ? index_buffer.indices[base_index + 2] : dynamic_index_buffer.indices[base_index + 2];
|
|
|
|
return uvec3(index0, index1, index2);
|
|
}
|
|
|
|
void handleDraw()
|
|
{
|
|
uint index = gl_InstanceCustomIndexEXT;
|
|
|
|
uint vertexOffset = data_map.indices[4 * index];
|
|
uint triangleOffset = data_map.indices[4*index + 1];
|
|
uint imageOffset = data_map.indices[4 * index + 2];
|
|
uint objectType = data_map.indices[4 * index + 3];
|
|
bool is_static = objectType != 1;
|
|
|
|
uvec3 indices = getIndices(triangleOffset, gl_PrimitiveID, is_static);
|
|
Vertex A = getVertex(vertexOffset, indices.x, is_static), B = getVertex(vertexOffset, indices.y, is_static), C = getVertex(vertexOffset, indices.z, is_static);
|
|
|
|
// interpolate and obtain world point
|
|
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
|
|
float alpha = barycentricCoords.x, beta = barycentricCoords.y, gamma = barycentricCoords.z;
|
|
vec3 pt = alpha * A.pt + beta * B.pt + gamma * C.pt;
|
|
mat4x3 transform = gl_WorldToObjectEXT;
|
|
vec3 worldPt = gl_WorldRayOriginEXT + gl_HitTEXT * gl_WorldRayDirectionEXT;//transform * vec4(pt, 0) + vec3(transform[3][0], transform[3][1], transform[3][2]);
|
|
vec3 normal = normalize(alpha * A.normal + beta * B.normal + gamma * C.normal);
|
|
vec3 worldNormal = normalize(cross(B.pt - A.pt, C.pt - A.pt));
|
|
|
|
vec2 texcoord = alpha * A.coordinate + beta * B.coordinate + gamma * C.coordinate;
|
|
|
|
hitValue.intersection = vec4(worldPt.xyz, objectType);
|
|
hitValue.normal = vec4(worldNormal.xyz, gl_HitTEXT);
|
|
if (render_mode == RENDER_GLOBAL_XYZ) { // global xyz
|
|
hitValue.color = vec4(heatmap(worldPt.x, -10, 10), 1);
|
|
return;
|
|
}
|
|
if ((objectType == 0 || objectType == 2)){
|
|
if (imageOffset >= 26){
|
|
return; // this shouldn't happen
|
|
}
|
|
// obtain texture coordinate
|
|
// NB: texture() is valid here as well as mipmaps are not used in this demo.
|
|
vec4 tex_value = textureLod(textures[nonuniformEXT(imageOffset)], texcoord, 0);
|
|
hitValue.color = tex_value;
|
|
} else {
|
|
// the refraction itself is colorless, so
|
|
// encode the index of refraction in the color
|
|
const float base_IOR = 1.01;
|
|
const float x = texcoord.x, y = texcoord.y;
|
|
const float t = min(min(min(min(x, 1-x), y), 1-y), 0.5) / 0.5;
|
|
const float IOR = t * base_IOR + (1 - t) * 1;
|
|
hitValue.color = vec4(IOR, 0, 0, 0);
|
|
hitValue.normal = vec4(normal.x, normal.y, normal.z, gl_HitTEXT);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void main()
|
|
{
|
|
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
|
|
if (render_mode == RENDER_BARYCENTRIC ){
|
|
hitValue.color = vec4(barycentricCoords, 1);
|
|
} else if (render_mode == RENDER_INSTANCE_ID){
|
|
hitValue.color = vec4(heatmap(gl_InstanceCustomIndexEXT, 0, 25), 1);
|
|
} else if (render_mode == RENDER_DISTANCE){
|
|
hitValue.color = vec4(heatmap(log(1 + gl_HitTEXT), 0, log(1 + 25)), 1);
|
|
} else {
|
|
handleDraw();
|
|
}
|
|
}
|