Using buffer reference instead of un-sized array

This commit is contained in:
mklefrancois 2021-06-11 12:25:06 +02:00
parent e3a57e6d63
commit c8a0122dd6
248 changed files with 2593 additions and 2660 deletions

View file

@ -16,13 +16,16 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#extension GL_EXT_buffer_reference2 : require
#include "wavefront.glsl"
@ -37,30 +40,32 @@ pushC;
// clang-format off
// Incoming
//layout(location = 0) flat in int matIndex;
layout(location = 1) in vec2 fragTexCoord;
layout(location = 2) in vec3 fragNormal;
layout(location = 3) in vec3 viewDir;
layout(location = 4) in vec3 worldPos;
// Outgoing
layout(location = 0) out vec4 outColor;
// Buffers
layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
layout(binding = 3) uniform sampler2D[] textureSamplers;
layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[];
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
layout(binding = 2) uniform sampler2D[] textureSamplers;
// clang-format on
void main()
{
// Object of this instance
int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object
int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
SceneDesc objResource = sceneDesc.i[pushC.instanceId];
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
Materials materials = Materials(objResource.materialAddress);
int matIndex = matIndices.i[gl_PrimitiveID];
WaveFrontMaterial mat = materials.m[matIndex];
vec3 N = normalize(fragNormal);
@ -84,7 +89,7 @@ void main()
vec3 diffuse = computeDiffuse(mat, L, N);
if(mat.textureId >= 0)
{
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt;

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
@ -37,6 +37,6 @@ void main()
{
// Just look up this lantern's color. Self-illuminating, so no lighting calculations.
LanternIndirectEntry lantern = lanterns.lanterns[nonuniformEXT(gl_InstanceCustomIndexEXT)];
prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue);
prd.additiveBlending = false;
prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue);
prd.additiveBlending = false;
}

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable

View file

@ -16,9 +16,9 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
layout (location = 0) out vec2 outUV;
layout(location = 0) out vec2 outUV;
out gl_PerVertex
@ -29,6 +29,6 @@ out gl_PerVertex
void main()
{
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f);
}

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
layout(location = 0) in vec2 outUV;
layout(location = 0) out vec4 fragColor;

View file

@ -30,8 +30,8 @@ layout(push_constant) uniform Constants
vec4 clearColor;
vec3 lightPosition;
float lightIntensity;
int lightType; // 0: point, 1: infinite
int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters.
int lightType; // 0: point, 1: infinite
int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters.
int screenX;
int screenY;
int lanternDebug;

View file

@ -16,12 +16,16 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#extension GL_EXT_buffer_reference2 : require
#include "raycommon.glsl"
#include "wavefront.glsl"
@ -32,66 +36,65 @@ layout(location = 0) rayPayloadInEXT hitPayload prd;
layout(location = 1) rayPayloadEXT bool isShadowed;
layout(location = 2) rayPayloadEXT int hitLanternInstance;
layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object
layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices
layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object
layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
layout(binding = 2, set = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns;
layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[];
layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
layout(binding = 3, set = 1) uniform sampler2D textureSamplers[];
layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[];
layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[];
layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
layout(binding = 2, set = 1) uniform sampler2D textureSamplers[];
// clang-format on
void main()
{
// Object of this instance
uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId;
// Object data
SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT];
MatIndices matIndices = MatIndices(objResource.materialIndexAddress);
Materials materials = Materials(objResource.materialAddress);
Indices indices = Indices(objResource.indexAddress);
Vertices vertices = Vertices(objResource.vertexAddress);
// Indices of the triangle
ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
ivec3 ind = indices.i[gl_PrimitiveID];
// Vertex of the triangle
Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
Vertex v0 = vertices.v[ind.x];
Vertex v1 = vertices.v[ind.y];
Vertex v2 = vertices.v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
// Computing the normal at hit position
vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z;
// Transforming the normal to world space
normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0)));
// Computing the coordinates of the hit position
vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z;
// Transforming the position to world space
worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0));
// Vector toward the light
vec3 L;
vec3 colorIntensity = vec3(pushC.lightIntensity);
float lightDistance = 100000.0;
vec3 colorIntensity = vec3(pushC.lightIntensity);
float lightDistance = 100000.0;
// ray direction is towards lantern, if in lantern pass.
if (pushC.lanternPassNumber >= 0)
if(pushC.lanternPassNumber >= 0)
{
LanternIndirectEntry lantern = lanterns.lanterns[pushC.lanternPassNumber];
vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos;
lightDistance = length(lDir);
vec3 color = vec3(lantern.red, lantern.green, lantern.blue);
vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos;
lightDistance = length(lDir);
vec3 color = vec3(lantern.red, lantern.green, lantern.blue);
// Lantern light decreases linearly. Not physically accurate, but looks good
// and avoids a hard "edge" at the radius limit. Use a constant value
// if lantern debug is enabled to clearly see the covered screen rectangle.
float distanceFade =
pushC.lanternDebug != 0
? 0.3
: max(0, (lantern.radius - lightDistance) / lantern.radius);
colorIntensity = color * lantern.brightness * distanceFade;
L = normalize(lDir);
float distanceFade = pushC.lanternDebug != 0 ? 0.3 : max(0, (lantern.radius - lightDistance) / lantern.radius);
colorIntensity = color * lantern.brightness * distanceFade;
L = normalize(lDir);
}
// Non-lantern pass may have point light...
else if(pushC.lightType == 0)
@ -107,17 +110,16 @@ void main()
}
// Material of the object
int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
int matIdx = matIndices.i[gl_PrimitiveID];
WaveFrontMaterial mat = materials.m[matIdx];
// Diffuse
vec3 diffuse = computeDiffuse(mat, L, normal);
if(mat.textureId >= 0)
{
uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset;
vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z;
diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz;
}
@ -133,10 +135,10 @@ void main()
vec3 rayDir = L;
// Ordinary shadow from the simple tutorial.
if (pushC.lanternPassNumber < 0) {
if(pushC.lanternPassNumber < 0)
{
isShadowed = true;
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT
| gl_RayFlagsSkipClosestHitShaderEXT;
uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
traceRayEXT(topLevelAS, // acceleration structure
flags, // rayFlags
0xFF, // cullMask
@ -153,25 +155,28 @@ void main()
// Lantern shadow ray. Cast a ray towards the lantern whose lighting is being
// added this pass. Only the closest hit shader for lanterns will set
// hitLanternInstance (payload 2) to non-negative value.
else {
else
{
// Skip ray if no light would be added anyway.
if (colorIntensity == vec3(0)) {
if(colorIntensity == vec3(0))
{
isShadowed = true;
}
else {
uint flags = gl_RayFlagsOpaqueEXT;
else
{
uint flags = gl_RayFlagsOpaqueEXT;
hitLanternInstance = -1;
traceRayEXT(topLevelAS, // acceleration structure
flags, // rayFlags
0xFF, // cullMask
2, // sbtRecordOffset : lantern shadow hit groups start at index 2.
0, // sbtRecordStride
2, // missIndex : lantern shadow miss shader is number 2.
origin, // ray origin
tMin, // ray min range
rayDir, // ray direction
tMax, // ray max range
2 // payload (location = 2)
traceRayEXT(topLevelAS, // acceleration structure
flags, // rayFlags
0xFF, // cullMask
2, // sbtRecordOffset : lantern shadow hit groups start at index 2.
0, // sbtRecordStride
2, // missIndex : lantern shadow miss shader is number 2.
origin, // ray origin
tMin, // ray min range
rayDir, // ray direction
tMax, // ray max range
2 // payload (location = 2)
);
// Did we hit the lantern we expected?
isShadowed = (hitLanternInstance != pushC.lanternPassNumber);
@ -189,6 +194,6 @@ void main()
}
}
prd.hitValue = colorIntensity * (attenuation * (diffuse + specular));
prd.hitValue = colorIntensity * (attenuation * (diffuse + specular));
prd.additiveBlending = true;
}

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable
@ -36,23 +36,27 @@ layout(binding = 0, set = 1) uniform CameraProperties
}
cam;
layout(binding = 2, set = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns;
layout(binding = 2, set = 0) buffer LanternArray
{
LanternIndirectEntry lanterns[];
}
lanterns;
void main()
{
// Global light pass is a full screen rectangle (lower corner 0,0), but
// lantern passes are only run within rectangles that may be offset.
ivec2 pixelOffset = ivec2(0);
if (pushC.lanternPassNumber >= 0)
if(pushC.lanternPassNumber >= 0)
{
pixelOffset.x = lanterns.lanterns[pushC.lanternPassNumber].offsetX;
pixelOffset.y = lanterns.lanterns[pushC.lanternPassNumber].offsetY;
}
const ivec2 pixelIntCoord = ivec2(gl_LaunchIDEXT.xy) + pixelOffset;
const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5);
const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY);
vec2 d = inUV * 2.0 - 1.0;
const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5);
const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY);
vec2 d = inUV * 2.0 - 1.0;
vec4 origin = cam.viewInverse * vec4(0, 0, 0, 1);
vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1);
@ -83,7 +87,8 @@ void main()
// Either add to or replace output image color based on prd.additiveBlending.
// Global pass always replaces color as it is the first pass.
vec3 oldColor = vec3(0);
if (prd.additiveBlending && pushC.lanternPassNumber >= 0) {
if(prd.additiveBlending && pushC.lanternPassNumber >= 0)
{
oldColor = imageLoad(image, pixelIntCoord).rgb;
}
imageStore(image, pixelIntCoord, vec4(prd.hitValue + oldColor, 1.0));

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_GOOGLE_include_directive : enable
@ -26,6 +26,6 @@ layout(location = 0) rayPayloadInEXT hitPayload prd;
void main()
{
prd.hitValue = pushC.clearColor.xyz * 0.8;
prd.hitValue = pushC.clearColor.xyz * 0.8;
prd.additiveBlending = false;
}

View file

@ -16,7 +16,7 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 460
#extension GL_EXT_ray_tracing : require

View file

@ -16,16 +16,18 @@
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_EXT_scalar_block_layout : enable
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
#include "wavefront.glsl"
// clang-format off
layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc;
layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc;
// clang-format on
layout(binding = 0) uniform UniformBufferObject
@ -65,8 +67,8 @@ out gl_PerVertex
void main()
{
mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo;
mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT;
mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo;
mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT;
vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1));

View file

@ -39,12 +39,16 @@ struct WaveFrontMaterial
int textureId;
};
struct sceneDesc
struct SceneDesc
{
int objId;
int txtOffset;
mat4 transfo;
mat4 transfoIT;
mat4 transfo;
mat4 transfoIT;
int objId;
int txtOffset;
uint64_t vertexAddress;
uint64_t indexAddress;
uint64_t materialAddress;
uint64_t materialIndexAddress;
};