cleanup and refactoring
This commit is contained in:
parent
2302158928
commit
76f6bf62a4
1285 changed files with 757994 additions and 8 deletions
63
raytracer/nvpro_core/nvvkhl/shaders/README.md
Normal file
63
raytracer/nvpro_core/nvvkhl/shaders/README.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
## Table of Contents
|
||||
- [bsdf_functions.h](#bsdf_functionsh)
|
||||
- [bsdf_structs.h](#bsdf_structsh)
|
||||
- [dh_comp.h](#dh_comph)
|
||||
- [dh_inspector.h](#dh_inspectorh)
|
||||
- [dh_sky.h](#dh_skyh)
|
||||
- [dh_tonemap.h](#dh_tonemaph)
|
||||
|
||||
## bsdf_functions.h
|
||||
### Function absorptionCoefficient
|
||||
|
||||
> Compute the absorption coefficient of the material
|
||||
### Function bsdfEvaluate
|
||||
|
||||
> Evaluate the BSDF for the given material
|
||||
### Function bsdfSample
|
||||
|
||||
> Sample the BSDF for the given material
|
||||
|
||||
## bsdf_structs.h
|
||||
### struct BsdfEvaluateData
|
||||
|
||||
> Data structure for evaluating a BSDF
|
||||
### struct BsdfSampleData
|
||||
|
||||
> Data structure for sampling a BSDF
|
||||
|
||||
## dh_comp.h
|
||||
### Function getGroupCounts
|
||||
|
||||
> Returns the number of workgroups needed to cover the size
|
||||
|
||||
This function is used to calculate the number of workgroups needed to cover a given size. It is used in the compute shader to calculate the number of workgroups needed to cover the size of the image.
|
||||
|
||||
## dh_inspector.h
|
||||
### Function inspect32BitValue
|
||||
|
||||
> Inspect a 32-bit value at a given index
|
||||
### Function inspectCustom32BitValue
|
||||
|
||||
> Inspect a 32-bit value at a given index
|
||||
|
||||
## dh_sky.h
|
||||
### Function initSkyShaderParameters
|
||||
|
||||
> Initializes the sky shader parameters with default values
|
||||
### Function proceduralSky
|
||||
|
||||
> Return the color of the procedural sky shader
|
||||
|
||||
## dh_tonemap.h
|
||||
### Function tonemapFilmic
|
||||
|
||||
> Filmic tonemapping operator
|
||||
http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
### Function gammaCorrection
|
||||
|
||||
> Gamma correction
|
||||
see https://www.teamten.com/lawrence/graphics/gamma/
|
||||
### Function tonemapUncharted
|
||||
|
||||
> Uncharted tone map
|
||||
see: http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
283
raytracer/nvpro_core/nvvkhl/shaders/bsdf_functions.h
Normal file
283
raytracer/nvpro_core/nvvkhl/shaders/bsdf_functions.h
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "func.glsl" // cosineSampleHemisphere
|
||||
#include "ggx.glsl" // brdfLambertian, ..
|
||||
#include "bsdf_structs.h" // Bsdf*,
|
||||
#include "pbr_mat_struct.h" // PbrMaterial
|
||||
|
||||
/** @DOC_START
|
||||
# Function absorptionCoefficient
|
||||
> Compute the absorption coefficient of the material
|
||||
@DOC_END */
|
||||
vec3 absorptionCoefficient(in PbrMaterial mat)
|
||||
{
|
||||
float tmp1 = mat.attenuationDistance;
|
||||
return tmp1 <= 0.0F ? vec3(0.0F, 0.0F, 0.0F) :
|
||||
-vec3(log(mat.attenuationColor.x), log(mat.attenuationColor.y), log(mat.attenuationColor.z)) / tmp1;
|
||||
}
|
||||
|
||||
struct EvalData
|
||||
{
|
||||
float pdf;
|
||||
vec3 bsdf;
|
||||
};
|
||||
|
||||
void evalDiffuse(in BsdfEvaluateData data, in PbrMaterial mat, out EvalData eval)
|
||||
{
|
||||
// Diffuse reflection
|
||||
float NdotL = clampedDot(mat.normal, data.k2);
|
||||
eval.bsdf = brdfLambertian(mat.albedo.rgb, mat.metallic) * NdotL;
|
||||
eval.pdf = M_1_OVER_PI;
|
||||
}
|
||||
|
||||
void evalSpecular(in BsdfEvaluateData data, in PbrMaterial mat, out EvalData eval)
|
||||
{
|
||||
// Specular reflection
|
||||
vec3 H = normalize(data.k1 + data.k2);
|
||||
|
||||
float alphaRoughness = mat.roughness * mat.roughness;
|
||||
float NdotV = clampedDot(mat.normal, data.k1);
|
||||
float NdotL = clampedDot(mat.normal, data.k2);
|
||||
float VdotH = clampedDot(data.k1, H);
|
||||
float NdotH = clampedDot(mat.normal, H);
|
||||
float LdotH = clampedDot(data.k2, H);
|
||||
|
||||
vec3 f_specular = brdfSpecularGGX(mat.f0, mat.f90, alphaRoughness, VdotH, NdotL, NdotV, NdotH);
|
||||
eval.bsdf = f_specular * NdotL;
|
||||
eval.pdf = distributionGGX(NdotH, alphaRoughness) * NdotH / (4.0F * LdotH);
|
||||
}
|
||||
|
||||
void evalTransmission(in BsdfEvaluateData data, in PbrMaterial mat, out EvalData eval)
|
||||
{
|
||||
eval.pdf = 0;
|
||||
eval.bsdf = vec3(0.0F, 0.0F, 0.0F);
|
||||
|
||||
if(mat.transmissionFactor <= 0.0F)
|
||||
return;
|
||||
|
||||
vec3 refractedDir;
|
||||
bool totalInternalRefraction = refract(data.k2, mat.normal, mat.eta, refractedDir);
|
||||
|
||||
if(!totalInternalRefraction)
|
||||
{
|
||||
//eval.bsdf = mat.albedo.rgb * mat.transmissionFactor;
|
||||
eval.pdf = abs(dot(refractedDir, mat.normal));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @DOC_START
|
||||
# Function bsdfEvaluate
|
||||
> Evaluate the BSDF for the given material.
|
||||
@DOC_END */
|
||||
void bsdfEvaluate(inout BsdfEvaluateData data, in PbrMaterial mat)
|
||||
{
|
||||
// Initialization
|
||||
float diffuseRatio = 0.5F * (1.0F - mat.metallic);
|
||||
float specularRatio = 1.0F - diffuseRatio;
|
||||
float transmissionRatio = (1.0F - mat.metallic) * mat.transmissionFactor;
|
||||
|
||||
// Contribution
|
||||
EvalData f_diffuse;
|
||||
EvalData f_specular;
|
||||
EvalData f_transmission;
|
||||
|
||||
evalDiffuse(data, mat, f_diffuse);
|
||||
evalSpecular(data, mat, f_specular);
|
||||
evalTransmission(data, mat, f_transmission);
|
||||
|
||||
// Combine the results
|
||||
float brdfPdf = 0;
|
||||
brdfPdf += f_diffuse.pdf * diffuseRatio;
|
||||
brdfPdf += f_specular.pdf * specularRatio;
|
||||
brdfPdf = mix(brdfPdf, f_transmission.pdf, transmissionRatio);
|
||||
|
||||
vec3 bsdfDiffuse = mix(f_diffuse.bsdf, f_transmission.bsdf, transmissionRatio);
|
||||
vec3 bsdfGlossy = mix(f_specular.bsdf, f_transmission.bsdf, transmissionRatio);
|
||||
|
||||
// Return results
|
||||
data.bsdf_diffuse = bsdfDiffuse;
|
||||
data.bsdf_glossy = bsdfGlossy;
|
||||
data.pdf = brdfPdf;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
vec3 sampleDiffuse(inout BsdfSampleData data, in PbrMaterial mat)
|
||||
{
|
||||
vec3 surfaceNormal = mat.normal;
|
||||
vec3 tangent, bitangent;
|
||||
orthonormalBasis(surfaceNormal, tangent, bitangent);
|
||||
float r1 = data.xi.x;
|
||||
float r2 = data.xi.y;
|
||||
vec3 sampleDirection = cosineSampleHemisphere(r1, r2); // Diffuse
|
||||
sampleDirection = tangent * sampleDirection.x + bitangent * sampleDirection.y + surfaceNormal * sampleDirection.z;
|
||||
data.event_type = BSDF_EVENT_DIFFUSE;
|
||||
return sampleDirection;
|
||||
}
|
||||
|
||||
vec3 sampleSpecular(inout BsdfSampleData data, in PbrMaterial mat)
|
||||
{
|
||||
vec3 surfaceNormal = mat.normal;
|
||||
vec3 tangent, bitangent;
|
||||
orthonormalBasis(surfaceNormal, tangent, bitangent);
|
||||
float alphaRoughness = mat.roughness * mat.roughness;
|
||||
float r1 = data.xi.x;
|
||||
float r2 = data.xi.y;
|
||||
vec3 halfVector = ggxSampling(alphaRoughness, r1, r2); // Glossy
|
||||
halfVector = tangent * halfVector.x + bitangent * halfVector.y + surfaceNormal * halfVector.z;
|
||||
vec3 sampleDirection = reflect(-data.k1, halfVector);
|
||||
data.event_type = BSDF_EVENT_SPECULAR;
|
||||
|
||||
return sampleDirection;
|
||||
}
|
||||
|
||||
vec3 sampleThinTransmission(in BsdfSampleData data, in PbrMaterial mat)
|
||||
{
|
||||
vec3 incomingDir = data.k1;
|
||||
float r1 = data.xi.x;
|
||||
float r2 = data.xi.y;
|
||||
float alphaRoughness = mat.roughness * mat.roughness;
|
||||
vec3 halfVector = ggxSampling(alphaRoughness, r1, r2);
|
||||
vec3 tangent, bitangent;
|
||||
orthonormalBasis(incomingDir, tangent, bitangent);
|
||||
vec3 transformedHalfVector = tangent * halfVector.x + bitangent * halfVector.y + incomingDir * halfVector.z;
|
||||
vec3 refractedDir = -transformedHalfVector;
|
||||
|
||||
return refractedDir;
|
||||
}
|
||||
|
||||
vec3 sampleSolidTransmission(inout BsdfSampleData data, in PbrMaterial mat, out bool refracted)
|
||||
{
|
||||
vec3 surfaceNormal = mat.normal;
|
||||
if(mat.roughness > 0.0F)
|
||||
{
|
||||
vec3 tangent, bitangent;
|
||||
orthonormalBasis(surfaceNormal, tangent, bitangent);
|
||||
float alphaRoughness = mat.roughness * mat.roughness;
|
||||
float r1 = data.xi.x;
|
||||
float r2 = data.xi.y;
|
||||
vec3 halfVector = ggxSampling(alphaRoughness, r1, r2); // Glossy
|
||||
halfVector = tangent * halfVector.x + bitangent * halfVector.y + surfaceNormal * halfVector.z;
|
||||
surfaceNormal = halfVector;
|
||||
}
|
||||
|
||||
vec3 refractedDir;
|
||||
refracted = refract(-data.k1, surfaceNormal, mat.eta, refractedDir);
|
||||
|
||||
return refractedDir;
|
||||
}
|
||||
|
||||
void sampleTransmission(inout BsdfSampleData data, in PbrMaterial mat)
|
||||
{
|
||||
// Calculate transmission direction using Snell's law
|
||||
vec3 refractedDir;
|
||||
vec3 sampleDirection;
|
||||
bool refracted = true;
|
||||
float r4 = data.xi.w;
|
||||
|
||||
// Thin film approximation
|
||||
if(mat.thicknessFactor == 0.0F && mat.roughness > 0.0F)
|
||||
{
|
||||
refractedDir = sampleThinTransmission(data, mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
refractedDir = sampleSolidTransmission(data, mat, refracted);
|
||||
}
|
||||
|
||||
// Fresnel term
|
||||
float VdotH = dot(data.k1, mat.normal);
|
||||
vec3 reflectance = fresnelSchlick(mat.f0, mat.f90, VdotH);
|
||||
vec3 surfaceNormal = mat.normal;
|
||||
|
||||
if(!refracted || r4 < luminance(reflectance))
|
||||
{
|
||||
// Total internal reflection or reflection based on Fresnel term
|
||||
sampleDirection = reflect(-data.k1, surfaceNormal); // Reflective direction
|
||||
data.event_type = BSDF_EVENT_SPECULAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transmission
|
||||
sampleDirection = refractedDir;
|
||||
data.event_type = BSDF_EVENT_TRANSMISSION;
|
||||
}
|
||||
|
||||
// Attenuate albedo for transmission
|
||||
vec3 bsdf = mat.albedo.rgb; // * mat.transmissionFactor;
|
||||
|
||||
// Result
|
||||
data.bsdf_over_pdf = bsdf;
|
||||
data.pdf = abs(dot(surfaceNormal, sampleDirection)); //transmissionRatio;
|
||||
data.k2 = sampleDirection;
|
||||
}
|
||||
|
||||
|
||||
/** @DOC_START
|
||||
# Function bsdfSample
|
||||
> Sample the BSDF for the given material
|
||||
@DOC_END */
|
||||
void bsdfSample(inout BsdfSampleData data, in PbrMaterial mat)
|
||||
{
|
||||
// Random numbers for importance sampling
|
||||
float r3 = data.xi.z;
|
||||
|
||||
// Initialization
|
||||
float diffuseRatio = 0.5F * (1.0F - mat.metallic);
|
||||
float specularRatio = 1.0F - diffuseRatio;
|
||||
float transmissionRatio = (1.0F - mat.metallic) * mat.transmissionFactor;
|
||||
|
||||
// Calculate if the ray goes through
|
||||
if(r3 < transmissionRatio)
|
||||
{
|
||||
sampleTransmission(data, mat);
|
||||
return;
|
||||
}
|
||||
|
||||
// Choose between diffuse and glossy reflection
|
||||
vec3 sampleDirection = vec3(0.0F, 0.0F, 0.0F);
|
||||
if(r3 < diffuseRatio)
|
||||
{
|
||||
sampleDirection = sampleDiffuse(data, mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Specular roughness
|
||||
sampleDirection = sampleSpecular(data, mat);
|
||||
}
|
||||
|
||||
// Evaluate the reflection coefficient with the new ray direction
|
||||
BsdfEvaluateData evalData;
|
||||
evalData.k1 = data.k1;
|
||||
evalData.k2 = sampleDirection;
|
||||
bsdfEvaluate(evalData, mat);
|
||||
|
||||
// Return values
|
||||
data.pdf = evalData.pdf;
|
||||
data.bsdf_over_pdf = (evalData.bsdf_diffuse + evalData.bsdf_glossy) / data.pdf;
|
||||
data.k2 = sampleDirection;
|
||||
|
||||
// Avoid internal reflection
|
||||
if(data.pdf <= 0.00001F || any(isnan(data.bsdf_over_pdf)))
|
||||
data.event_type = BSDF_EVENT_ABSORB;
|
||||
|
||||
return;
|
||||
}
|
||||
67
raytracer/nvpro_core/nvvkhl/shaders/bsdf_structs.h
Normal file
67
raytracer/nvpro_core/nvvkhl/shaders/bsdf_structs.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef BSDF_STRUCTS_H
|
||||
#define BSDF_STRUCTS_H 1
|
||||
|
||||
#define BSDF_EVENT_ABSORB 0 // 0
|
||||
#define BSDF_EVENT_DIFFUSE 1 // 1
|
||||
#define BSDF_EVENT_GLOSSY (1 << 1) // 2
|
||||
#define BSDF_EVENT_SPECULAR (1 << 2) // 4
|
||||
#define BSDF_EVENT_REFLECTION (1 << 3) // 8
|
||||
#define BSDF_EVENT_TRANSMISSION (1 << 4) // 16
|
||||
|
||||
#define BSDF_EVENT_DIFFUSE_REFLECTION (BSDF_EVENT_DIFFUSE | BSDF_EVENT_REFLECTION) // 9
|
||||
#define BSDF_EVENT_DIFFUSE_TRANSMISSION (BSDF_EVENT_DIFFUSE | BSDF_EVENT_TRANSMISSION) // 17
|
||||
#define BSDF_EVENT_GLOSSY_REFLECTION (BSDF_EVENT_GLOSSY | BSDF_EVENT_REFLECTION) // 10
|
||||
#define BSDF_EVENT_GLOSSY_TRANSMISSION (BSDF_EVENT_GLOSSY | BSDF_EVENT_TRANSMISSION) // 18
|
||||
#define BSDF_EVENT_SPECULAR_REFLECTION (BSDF_EVENT_SPECULAR | BSDF_EVENT_REFLECTION) // 12
|
||||
#define BSDF_EVENT_SPECULAR_TRANSMISSION (BSDF_EVENT_SPECULAR | BSDF_EVENT_TRANSMISSION) // 20
|
||||
|
||||
#define BSDF_USE_MATERIAL_IOR (-1.0)
|
||||
|
||||
/** @DOC_START
|
||||
# struct BsdfEvaluateData
|
||||
> Data structure for evaluating a BSDF
|
||||
@DOC_END */
|
||||
struct BsdfEvaluateData
|
||||
{
|
||||
vec3 k1; // [in] Toward the incoming ray
|
||||
vec3 k2; // [in] Toward the sampled light
|
||||
vec3 bsdf_diffuse; // [out] Diffuse contribution
|
||||
vec3 bsdf_glossy; // [out] Specular contribution
|
||||
float pdf; // [out] PDF
|
||||
};
|
||||
|
||||
/** @DOC_START
|
||||
# struct BsdfSampleData
|
||||
> Data structure for sampling a BSDF
|
||||
@DOC_END */
|
||||
struct BsdfSampleData
|
||||
{
|
||||
vec3 k1; // [in] Toward the incoming ray
|
||||
vec3 k2; // [in] Toward the sampled light
|
||||
vec4 xi; // [in] 4 random [0..1]
|
||||
float pdf; // [out] PDF
|
||||
vec3 bsdf_over_pdf; // [out] contribution / PDF
|
||||
int event_type; // [out] one of the event above
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
36
raytracer/nvpro_core/nvvkhl/shaders/constants.glsl
Normal file
36
raytracer/nvpro_core/nvvkhl/shaders/constants.glsl
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CONSTANTS_GLSL
|
||||
#define CONSTANTS_GLSL
|
||||
|
||||
|
||||
precision highp float;
|
||||
|
||||
const float M_PI = 3.1415926535897F; // PI
|
||||
const float M_TWO_PI = 6.2831853071795F; // 2*PI
|
||||
const float M_PI_2 = 1.5707963267948F; // PI/2
|
||||
const float M_PI_4 = 0.7853981633974F; // PI/4
|
||||
const float M_1_OVER_PI = 0.3183098861837F; // 1/PI
|
||||
const float M_2_OVER_PI = 0.6366197723675F; // 2/PI
|
||||
|
||||
const float INFINITE = 1e32F;
|
||||
|
||||
#endif // CONSTANTS_GLSL
|
||||
40
raytracer/nvpro_core/nvvkhl/shaders/dh_comp.h
Normal file
40
raytracer/nvpro_core/nvvkhl/shaders/dh_comp.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DH_COMP_H
|
||||
#define DH_COMP_H 1
|
||||
|
||||
#define WORKGROUP_SIZE 16 // Grid size used by compute shaders
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/** @DOC_START
|
||||
# Function getGroupCounts
|
||||
> Returns the number of workgroups needed to cover the size
|
||||
|
||||
This function is used to calculate the number of workgroups needed to cover a given size. It is used in the compute shader to calculate the number of workgroups needed to cover the size of the image.
|
||||
@DOC_END */
|
||||
inline VkExtent2D getGroupCounts(const VkExtent2D& size, int workgroupSize = WORKGROUP_SIZE)
|
||||
{
|
||||
return VkExtent2D{(size.width + (workgroupSize - 1)) / workgroupSize, (size.height + (workgroupSize - 1)) / workgroupSize};
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // DH_COMP_H
|
||||
95
raytracer/nvpro_core/nvvkhl/shaders/dh_hdr.h
Normal file
95
raytracer/nvpro_core/nvvkhl/shaders/dh_hdr.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/// @DOC_SKIP
|
||||
|
||||
#ifndef DH_HDR_H
|
||||
#define DH_HDR_H 1
|
||||
|
||||
#ifndef WORKGROUP_SIZE
|
||||
#define WORKGROUP_SIZE 16 // Grid size used by compute shaders
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <glm/glm.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace nvvkhl_shaders {
|
||||
using uint = uint32_t;
|
||||
using mat4 = glm::mat4;
|
||||
using vec4 = glm::vec4;
|
||||
using vec2 = glm::vec2;
|
||||
#endif
|
||||
|
||||
// Environment acceleration structure - computed in hdr_env
|
||||
struct EnvAccel
|
||||
{
|
||||
uint alias;
|
||||
float q;
|
||||
};
|
||||
|
||||
struct HdrPushBlock
|
||||
{
|
||||
mat4 mvp;
|
||||
vec2 size;
|
||||
float roughness;
|
||||
uint numSamples;
|
||||
};
|
||||
|
||||
|
||||
struct HdrDomePushConstant
|
||||
{
|
||||
mat4 mvp;
|
||||
vec4 multColor;
|
||||
float rotation;
|
||||
};
|
||||
|
||||
|
||||
// clang-format off
|
||||
#ifdef __cplusplus // Descriptor binding helper for C++ and GLSL
|
||||
#define START_BINDING(a) enum a {
|
||||
#define END_BINDING() }
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define START_BINDING(a) const uint
|
||||
#define END_BINDING()
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
START_BINDING(EnvBindings)
|
||||
eHdr = 0,
|
||||
eImpSamples = 1
|
||||
END_BINDING();
|
||||
|
||||
START_BINDING(EnvDomeBindings)
|
||||
eHdrBrdf = 0,
|
||||
eHdrDiffuse = 1,
|
||||
eHdrSpecular = 2
|
||||
END_BINDING();
|
||||
|
||||
START_BINDING(EnvDomeDraw)
|
||||
eHdrImage = 0
|
||||
END_BINDING();
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif // DH_HDR_H
|
||||
240
raytracer/nvpro_core/nvvkhl/shaders/dh_inspector.h
Normal file
240
raytracer/nvpro_core/nvvkhl/shaders/dh_inspector.h
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
// Shader header for inspection shader variables
|
||||
// Prior to including this header the following macros need to be defined
|
||||
// Either INSPECTOR_MODE_COMPUTE or INSPECTOR_MODE_FRAGMENT
|
||||
// If INSPECTOR_MODE_COMPUTE is defined the shader must expose invocation information (e.g. gl_LocalInvocationID).
|
||||
// This typically applies to compute, task and mesh shaders
|
||||
// If INSPECTOR_MODE_FRAGMENT is defined the shader must expose fragment information (e.g. gl_FragCoord).
|
||||
// This applies to fragment shaders
|
||||
//
|
||||
// INSPECTOR_DESCRIPTOR_SET: the index of the descriptor set containing the Inspector buffers
|
||||
// INSPECTOR_INSPECTION_DATA_BINDING: the binding index of the buffer containing the inspection information, as provided by ElementInspector::getComputeInspectionBuffer()
|
||||
// INSPECTOR_METADATA_BINDING: the binding index of the buffer containing the inspection metadata, as provided by ElementInspector::getComputeMetadataBuffer()
|
||||
|
||||
#ifndef DH_INSPECTOR_H
|
||||
#define DH_INSPECTOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
namespace nvvkhl_shaders {
|
||||
using uvec3 = glm::uvec3;
|
||||
using uvec2 = glm::uvec2;
|
||||
#else
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
#extension GL_EXT_shader_atomic_int64 : require
|
||||
#extension GL_KHR_shader_subgroup_basic : require
|
||||
#endif
|
||||
|
||||
#define WARP_SIZE 32
|
||||
|
||||
#define WARP_2D_SIZE_X 8
|
||||
#define WARP_2D_SIZE_Y 4
|
||||
#define WARP_2D_SIZE_Z 1
|
||||
|
||||
struct InspectorComputeMetadata
|
||||
{
|
||||
uvec3 minBlock;
|
||||
uint32_t u32PerThread;
|
||||
uvec3 maxBlock;
|
||||
uint32_t minWarpInBlock;
|
||||
uint32_t maxWarpInBlock;
|
||||
};
|
||||
|
||||
struct InspectorFragmentMetadata
|
||||
{
|
||||
uvec2 minFragment;
|
||||
uvec2 maxFragment;
|
||||
uvec2 renderSize;
|
||||
uint32_t u32PerThread;
|
||||
};
|
||||
|
||||
struct InspectorCustomMetadata
|
||||
{
|
||||
uvec3 minCoord;
|
||||
uint32_t pad0;
|
||||
uvec3 maxCoord;
|
||||
uint32_t pad1;
|
||||
uvec3 extent;
|
||||
uint32_t u32PerThread;
|
||||
};
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#if !(defined INSPECTOR_MODE_COMPUTE) && !(defined INSPECTOR_MODE_FRAGMENT) && !(defined INSPECTOR_MODE_CUSTOM)
|
||||
#error At least one inspector mode (INSPECTOR_MODE_COMPUTE, INSPECTOR_MODE_FRAGMENT, INSPECTOR_MODE_CUSTOM) must be defined before including this file
|
||||
#endif
|
||||
|
||||
#if(defined INSPECTOR_MODE_COMPUTE) && (defined INSPECTOR_MODE_FRAGMENT)
|
||||
#error Only one of inspector modes INSPECTOR_MODE_COMPUTE, INSPECTOR_MODE_FRAGMENT can be chosen
|
||||
#endif
|
||||
|
||||
#ifndef INSPECTOR_DESCRIPTOR_SET
|
||||
#error The descriptor set containing thread inspection data must be provided before including this file
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef INSPECTOR_MODE_CUSTOM
|
||||
#ifndef INSPECTOR_CUSTOM_INSPECTION_DATA_BINDING
|
||||
#error The descriptor binding containing custom thread inspection data must be provided before including this file
|
||||
#endif
|
||||
#ifndef INSPECTOR_CUSTOM_METADATA_BINDING
|
||||
#error The descriptor binding containing custom thread inspection metadata must be provided before including this file
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if(defined INSPECTOR_MODE_COMPUTE) || (defined INSPECTOR_MODE_FRAGMENT)
|
||||
#ifndef INSPECTOR_INSPECTION_DATA_BINDING
|
||||
#error The descriptor binding containing thread inspection data must be provided before including this file
|
||||
#endif
|
||||
|
||||
#ifndef INSPECTOR_METADATA_BINDING
|
||||
#error The descriptor binding containing thread inspection metadata must be provided before including this file
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef INSPECTOR_MODE_COMPUTE
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_INSPECTION_DATA_BINDING) buffer InspectorInspectionData
|
||||
{
|
||||
uint32_t inspectorInspectionData[];
|
||||
};
|
||||
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_METADATA_BINDING) readonly buffer InspectorComputeInspectionMetadata
|
||||
{
|
||||
InspectorComputeMetadata inspectorMetadata;
|
||||
};
|
||||
|
||||
/** @DOC_START
|
||||
# Function inspect32BitValue
|
||||
> Inspect a 32-bit value at a given index
|
||||
@DOC_END */
|
||||
void inspect32BitValue(uint32_t index, uint32_t v)
|
||||
{
|
||||
|
||||
if(clamp(gl_WorkGroupID, inspectorMetadata.minBlock, inspectorMetadata.maxBlock) != gl_WorkGroupID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t warpIndex = gl_SubgroupID;
|
||||
|
||||
if(warpIndex < inspectorMetadata.minWarpInBlock || warpIndex > inspectorMetadata.maxWarpInBlock)
|
||||
return;
|
||||
uint32_t inspectedThreadsPerBlock = (inspectorMetadata.maxWarpInBlock - inspectorMetadata.minWarpInBlock + 1) * gl_SubgroupSize;
|
||||
;
|
||||
|
||||
uint32_t blockIndex = gl_WorkGroupID.x + gl_NumWorkGroups.x * (gl_WorkGroupID.y + gl_NumWorkGroups.y * gl_WorkGroupID.z);
|
||||
uint32_t minBlockIndex =
|
||||
inspectorMetadata.minBlock.x
|
||||
+ gl_NumWorkGroups.x * (inspectorMetadata.minBlock.y + gl_NumWorkGroups.y * inspectorMetadata.minBlock.z);
|
||||
|
||||
uint32_t blockStart = inspectedThreadsPerBlock * (blockIndex - minBlockIndex) * inspectorMetadata.u32PerThread;
|
||||
uint32_t warpStart = (warpIndex - inspectorMetadata.minWarpInBlock) * inspectorMetadata.u32PerThread * gl_SubgroupSize;
|
||||
uint32_t threadInWarpStart = gl_SubgroupInvocationID * inspectorMetadata.u32PerThread;
|
||||
|
||||
inspectorInspectionData[blockStart + warpStart + threadInWarpStart + index] = v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INSPECTOR_MODE_FRAGMENT
|
||||
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_INSPECTION_DATA_BINDING) buffer InspectorInspectionData
|
||||
{
|
||||
uint64_t inspectorInspectionData[];
|
||||
};
|
||||
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_METADATA_BINDING) readonly buffer InspectorFragmentInspectionMetadata
|
||||
{
|
||||
InspectorFragmentMetadata inspectorMetadata;
|
||||
};
|
||||
|
||||
void inspect32BitValue(uint32_t index, uint32_t v)
|
||||
{
|
||||
|
||||
uvec2 fragment = uvec2(floor(gl_FragCoord.xy));
|
||||
|
||||
|
||||
if(clamp(fragment, inspectorMetadata.minFragment, inspectorMetadata.maxFragment) != fragment)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uvec2 localFragment = fragment - inspectorMetadata.minFragment;
|
||||
uint32_t inspectionWidth = inspectorMetadata.maxFragment.x - inspectorMetadata.minFragment.x + 1;
|
||||
uint32_t fragmentIndex = localFragment.x + inspectionWidth * localFragment.y;
|
||||
|
||||
// Atomically store the fragment depth along with the value so we always keep the fragment value
|
||||
// with the lowest depth
|
||||
float z = 1.f - clamp(gl_FragCoord.z, 0.f, 1.f);
|
||||
uint64_t zUint = floatBitsToUint(z);
|
||||
uint64_t value = (zUint << 32) | uint64_t(v);
|
||||
atomicMax(inspectorInspectionData[fragmentIndex * inspectorMetadata.u32PerThread / 2 + index], value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef INSPECTOR_MODE_CUSTOM
|
||||
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_CUSTOM_INSPECTION_DATA_BINDING) buffer InspectorCustomInspections
|
||||
{
|
||||
uint32_t inspectorCustomInspection[];
|
||||
};
|
||||
|
||||
layout(set = INSPECTOR_DESCRIPTOR_SET, binding = INSPECTOR_CUSTOM_METADATA_BINDING) readonly buffer InspectorCustomInspectionMetadata
|
||||
{
|
||||
InspectorCustomMetadata inspectorCustomMetadata;
|
||||
};
|
||||
|
||||
/** @DOC_START
|
||||
# Function inspectCustom32BitValue
|
||||
> Inspect a 32-bit value at a given index
|
||||
@DOC_END */
|
||||
void inspectCustom32BitValue(uint32_t index, uvec3 location, uint32_t v)
|
||||
{
|
||||
if(clamp(location, inspectorCustomMetadata.minCoord, inspectorCustomMetadata.maxCoord) != location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uvec3 localCoord = location - inspectorCustomMetadata.minCoord;
|
||||
uint32_t inspectionWidth = inspectorCustomMetadata.maxCoord.x - inspectorCustomMetadata.minCoord.x + 1;
|
||||
uint32_t inspectionHeight = inspectorCustomMetadata.maxCoord.y - inspectorCustomMetadata.minCoord.y + 1;
|
||||
uint32_t coordIndex = localCoord.x + inspectionWidth * (localCoord.y + inspectionHeight * localCoord.z);
|
||||
|
||||
inspectorCustomInspection[coordIndex * inspectorCustomMetadata.u32PerThread + index] = v;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif // DH_INSPECTOR_H
|
||||
91
raytracer/nvpro_core/nvvkhl/shaders/dh_lighting.h
Normal file
91
raytracer/nvpro_core/nvvkhl/shaders/dh_lighting.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/// @DOC_SKIP
|
||||
#ifndef DH_LIGHTING_H
|
||||
#define DH_LIGHTING_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace nvvkhl_shaders {
|
||||
|
||||
using vec3 = glm::vec3;
|
||||
#endif // __cplusplus
|
||||
|
||||
const int eLightTypeNone = 0;
|
||||
const int eLightTypeDirectional = 1;
|
||||
const int eLightTypeSpot = 2;
|
||||
const int eLightTypePoint = 3;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Use for light/env contribution
|
||||
struct VisibilityContribution
|
||||
{
|
||||
vec3 radiance; // Radiance at the point if light is visible
|
||||
vec3 lightDir; // Direction to the light, to shoot shadow ray
|
||||
float lightDist; // Distance to the light (1e32 for infinite or sky)
|
||||
bool visible; // true if in front of the face and should shoot shadow ray
|
||||
};
|
||||
|
||||
struct LightContrib
|
||||
{
|
||||
vec3 incidentVector;
|
||||
float halfAngularSize;
|
||||
vec3 intensity;
|
||||
};
|
||||
|
||||
struct Light
|
||||
{
|
||||
vec3 direction;
|
||||
int type;
|
||||
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float intensity; // illuminance (lm/m2) for directional lights, luminous intensity (lm/sr) for positional lights
|
||||
|
||||
float angularSizeOrInvRange; // angular size for directional lights, 1/range for spot and point lights
|
||||
float innerAngle;
|
||||
float outerAngle;
|
||||
float outOfBoundsShadow;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline Light defaultLight()
|
||||
{
|
||||
Light l;
|
||||
l.position = vec3{5.0F, 5.F, 5.F};
|
||||
l.direction = glm::normalize(vec3{0.0F, -.7F, -.7F});
|
||||
l.type = eLightTypeDirectional;
|
||||
l.angularSizeOrInvRange = glm::radians(0.53F);
|
||||
l.color = {1.0F, 1.0F, 1.0F};
|
||||
l.intensity = 0.F; // Dark
|
||||
l.innerAngle = glm::radians(10.F);
|
||||
l.outerAngle = glm::radians(30.F);
|
||||
l.radius = 1.0F;
|
||||
|
||||
return l;
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif // DH_LIGHTING_H
|
||||
118
raytracer/nvpro_core/nvvkhl/shaders/dh_scn_desc.h
Normal file
118
raytracer/nvpro_core/nvvkhl/shaders/dh_scn_desc.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/// @DOC_SKIP
|
||||
|
||||
#ifndef DH_SCN_DESC_H
|
||||
#define DH_SCN_DESC_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace nvvkhl_shaders {
|
||||
|
||||
using mat4 = glm::mat4;
|
||||
using mat3 = glm::mat3;
|
||||
using vec4 = glm::vec4;
|
||||
using vec3 = glm::vec3;
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
struct InstanceInfo
|
||||
{
|
||||
mat4 objectToWorld;
|
||||
mat4 worldToObject;
|
||||
int materialID;
|
||||
};
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
vec4 position; // POS.xyz + UV.x
|
||||
vec4 normal; // NRM.xyz + UV.y
|
||||
vec4 tangent; // TNG.xyz + sign: 1, -1
|
||||
};
|
||||
|
||||
struct PrimMeshInfo
|
||||
{
|
||||
uint64_t vertexAddress;
|
||||
uint64_t indexAddress;
|
||||
int materialIndex;
|
||||
};
|
||||
|
||||
struct SceneDescription
|
||||
{
|
||||
uint64_t materialAddress;
|
||||
uint64_t instInfoAddress;
|
||||
uint64_t primInfoAddress;
|
||||
};
|
||||
|
||||
// alphaMode
|
||||
#define ALPHA_OPAQUE 0
|
||||
#define ALPHA_MASK 1
|
||||
#define ALPHA_BLEND 2
|
||||
|
||||
struct GltfShadeMaterial
|
||||
{
|
||||
// Core
|
||||
vec4 pbrBaseColorFactor;
|
||||
vec3 emissiveFactor;
|
||||
int pbrBaseColorTexture;
|
||||
|
||||
int normalTexture;
|
||||
float normalTextureScale;
|
||||
int _pad0;
|
||||
float pbrRoughnessFactor;
|
||||
|
||||
float pbrMetallicFactor;
|
||||
int pbrMetallicRoughnessTexture;
|
||||
|
||||
int emissiveTexture;
|
||||
int alphaMode;
|
||||
float alphaCutoff;
|
||||
|
||||
// KHR_materials_transmission
|
||||
float transmissionFactor;
|
||||
int transmissionTexture;
|
||||
// KHR_materials_ior
|
||||
float ior;
|
||||
// KHR_materials_volume
|
||||
vec3 attenuationColor;
|
||||
float thicknessFactor;
|
||||
int thicknessTexture;
|
||||
bool thinWalled;
|
||||
float attenuationDistance;
|
||||
// KHR_materials_clearcoat
|
||||
float clearcoatFactor;
|
||||
float clearcoatRoughness;
|
||||
int clearcoatTexture;
|
||||
int clearcoatRoughnessTexture;
|
||||
int clearcoatNormalTexture;
|
||||
// KHR_materials_specular
|
||||
float specularFactor;
|
||||
int specularTexture;
|
||||
vec3 specularColorFactor;
|
||||
int specularColorTexture;
|
||||
// KHR_texture_transform
|
||||
mat3 uvTransform;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif
|
||||
135
raytracer/nvpro_core/nvvkhl/shaders/dh_sky.h
Normal file
135
raytracer/nvpro_core/nvvkhl/shaders/dh_sky.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DH_SKY_H
|
||||
#define DH_SKY_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define inout // Not used
|
||||
namespace nvvkhl_shaders {
|
||||
using mat4 = glm::mat4;
|
||||
using vec2 = glm::vec2;
|
||||
using vec3 = glm::vec3;
|
||||
#else
|
||||
#define static
|
||||
#define inline
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef WORKGROUP_SIZE
|
||||
#define WORKGROUP_SIZE 16 // Grid size used by compute shaders
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#ifdef __cplusplus // Descriptor binding helper for C++ and GLSL
|
||||
#define START_BINDING(a) enum a {
|
||||
#define END_BINDING() }
|
||||
#else
|
||||
#define START_BINDING(a) const uint
|
||||
#define END_BINDING()
|
||||
#endif
|
||||
|
||||
START_BINDING(SkyBindings)
|
||||
eSkyOutImage = 0,
|
||||
eSkyParam = 1
|
||||
END_BINDING();
|
||||
// clang-format on
|
||||
|
||||
|
||||
struct ProceduralSkyShaderParameters
|
||||
{
|
||||
vec3 directionToLight;
|
||||
float angularSizeOfLight;
|
||||
|
||||
vec3 lightColor;
|
||||
float glowSize;
|
||||
|
||||
vec3 skyColor;
|
||||
float glowIntensity;
|
||||
|
||||
vec3 horizonColor;
|
||||
float horizonSize;
|
||||
|
||||
vec3 groundColor;
|
||||
float glowSharpness;
|
||||
|
||||
vec3 directionUp;
|
||||
float pad1;
|
||||
};
|
||||
|
||||
struct SkyPushConstant
|
||||
{
|
||||
mat4 mvp;
|
||||
};
|
||||
|
||||
/** @DOC_START
|
||||
# Function initSkyShaderParameters
|
||||
> Initializes the sky shader parameters with default values
|
||||
@DOC_END */
|
||||
inline ProceduralSkyShaderParameters initSkyShaderParameters()
|
||||
{
|
||||
ProceduralSkyShaderParameters p;
|
||||
p.directionToLight = vec3(0.0F, 0.707F, 0.707F);
|
||||
p.angularSizeOfLight = 0.059F;
|
||||
p.lightColor = vec3(1.0F, 1.0F, 1.0F);
|
||||
p.skyColor = vec3(0.17F, 0.37F, 0.65F);
|
||||
p.horizonColor = vec3(0.50F, 0.70F, 0.92F);
|
||||
p.groundColor = vec3(0.62F, 0.59F, 0.55F);
|
||||
p.directionUp = vec3(0.F, 1.F, 0.F);
|
||||
p.horizonSize = 0.5F; // +/- degrees
|
||||
p.glowSize = 0.091F; // degrees, starting from the edge of the light disk
|
||||
p.glowIntensity = 0.9F; // [0-1] relative to light intensity
|
||||
p.glowSharpness = 4.F; // [1-10] is the glow power exponent
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifndef __cplusplus
|
||||
/** @DOC_START
|
||||
# Function proceduralSky
|
||||
> Return the color of the procedural sky shader
|
||||
@DOC_END */
|
||||
inline vec3 proceduralSky(ProceduralSkyShaderParameters params, vec3 direction, float angularSizeOfPixel)
|
||||
{
|
||||
float elevation = asin(clamp(dot(direction, params.directionUp), -1.0F, 1.0F));
|
||||
float top = smoothstep(0.F, params.horizonSize, elevation);
|
||||
float bottom = smoothstep(0.F, params.horizonSize, -elevation);
|
||||
vec3 environment = mix(mix(params.horizonColor, params.groundColor, bottom), params.skyColor, top);
|
||||
|
||||
float angle_to_light = acos(clamp(dot(direction, params.directionToLight), 0.0F, 1.0F));
|
||||
float half_angular_size = params.angularSizeOfLight * 0.5F;
|
||||
float light_intensity =
|
||||
clamp(1.0F - smoothstep(half_angular_size - angularSizeOfPixel * 2.0F, half_angular_size + angularSizeOfPixel * 2.0F, angle_to_light),
|
||||
0.0F, 1.0F);
|
||||
light_intensity = pow(light_intensity, 4.0F);
|
||||
float glow_input =
|
||||
clamp(2.0F * (1.0F - smoothstep(half_angular_size - params.glowSize, half_angular_size + params.glowSize, angle_to_light)),
|
||||
0.0F, 1.0F);
|
||||
float glow_intensity = params.glowIntensity * pow(glow_input, params.glowSharpness);
|
||||
vec3 light = max(light_intensity, glow_intensity) * params.lightColor;
|
||||
|
||||
return environment + light;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif // DH_SKY_H
|
||||
169
raytracer/nvpro_core/nvvkhl/shaders/dh_tonemap.h
Normal file
169
raytracer/nvpro_core/nvvkhl/shaders/dh_tonemap.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DH_TONEMAMP_H
|
||||
#define DH_TONEMAMP_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace nvvkhl_shaders {
|
||||
using vec3 = glm::vec3;
|
||||
using vec2 = glm::vec2;
|
||||
using uint = uint32_t;
|
||||
#define INLINE inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
|
||||
const int eTonemapFilmic = 0;
|
||||
const int eTonemapUncharted = 1;
|
||||
const int eTonemapGamma = 2;
|
||||
|
||||
|
||||
// Tonemapper settings
|
||||
struct Tonemapper
|
||||
{
|
||||
int method;
|
||||
int isActive;
|
||||
float exposure;
|
||||
float brightness;
|
||||
float contrast;
|
||||
float saturation;
|
||||
float vignette;
|
||||
float gamma;
|
||||
};
|
||||
|
||||
INLINE Tonemapper defaultTonemapper()
|
||||
{
|
||||
Tonemapper t;
|
||||
t.method = 0;
|
||||
t.isActive = 1;
|
||||
t.exposure = 1.0F;
|
||||
t.brightness = 1.0F;
|
||||
t.contrast = 1.0F;
|
||||
t.saturation = 1.0F;
|
||||
t.vignette = 0.0F;
|
||||
t.gamma = 2.2F;
|
||||
return t;
|
||||
}
|
||||
|
||||
// Bindings
|
||||
const int eTonemapperInput = 0;
|
||||
const int eTonemapperOutput = 1;
|
||||
|
||||
/** @DOC_START
|
||||
# Function tonemapFilmic
|
||||
> Filmic tonemapping operator
|
||||
http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
@DOC_END */
|
||||
INLINE vec3 tonemapFilmic(vec3 color)
|
||||
{
|
||||
vec3 temp = max(vec3(0.0F), color - vec3(0.004F));
|
||||
vec3 result = (temp * (vec3(6.2F) * temp + vec3(0.5F))) / (temp * (vec3(6.2F) * temp + vec3(1.7F)) + vec3(0.06F));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @DOC_START
|
||||
# Function gammaCorrection
|
||||
> Gamma correction
|
||||
see https://www.teamten.com/lawrence/graphics/gamma/
|
||||
@DOC_END */
|
||||
INLINE vec3 gammaCorrection(vec3 color, float gamma)
|
||||
{
|
||||
return pow(color, vec3(1.0F / gamma));
|
||||
}
|
||||
|
||||
/** @DOC_START
|
||||
# Function tonemapUncharted
|
||||
> Uncharted tone map
|
||||
see: http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
@DOC_END */
|
||||
|
||||
INLINE vec3 tonemapUncharted2Impl(vec3 color)
|
||||
{
|
||||
const float a = 0.15F;
|
||||
const float b = 0.50F;
|
||||
const float c = 0.10F;
|
||||
const float d = 0.20F;
|
||||
const float e = 0.02F;
|
||||
const float f = 0.30F;
|
||||
return ((color * (a * color + c * b) + d * e) / (color * (a * color + b) + d * f)) - e / f;
|
||||
}
|
||||
|
||||
INLINE vec3 tonemapUncharted(vec3 color, float gamma)
|
||||
{
|
||||
const float W = 11.2F;
|
||||
const float exposure_bias = 2.0F;
|
||||
color = tonemapUncharted2Impl(color * exposure_bias);
|
||||
vec3 white_scale = vec3(1.0F) / tonemapUncharted2Impl(vec3(W));
|
||||
return gammaCorrection(color * white_scale, gamma);
|
||||
}
|
||||
|
||||
INLINE vec3 applyTonemap(Tonemapper tm, vec3 color, vec2 uv)
|
||||
{
|
||||
// Exposure
|
||||
color *= tm.exposure;
|
||||
vec3 c;
|
||||
// Tonemap
|
||||
switch(tm.method)
|
||||
{
|
||||
case eTonemapFilmic:
|
||||
c = tonemapFilmic(color);
|
||||
break;
|
||||
case eTonemapUncharted:
|
||||
c = tonemapUncharted(color, tm.gamma);
|
||||
break;
|
||||
default:
|
||||
c = gammaCorrection(color, tm.gamma);
|
||||
break;
|
||||
}
|
||||
//contrast
|
||||
c = clamp(mix(vec3(0.5F), c, vec3(tm.contrast)), vec3(0.F), vec3(1.F));
|
||||
// brighness
|
||||
c = pow(c, vec3(1.0F / tm.brightness));
|
||||
// saturation
|
||||
vec3 i = vec3(dot(c, vec3(0.299F, 0.587F, 0.114F)));
|
||||
c = mix(i, c, tm.saturation);
|
||||
// vignette
|
||||
vec2 center_uv = ((uv)-vec2(0.5F)) * vec2(2.0F);
|
||||
c *= 1.0F - dot(center_uv, center_uv) * tm.vignette;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
// http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
|
||||
INLINE vec3 toSrgb(vec3 rgb)
|
||||
{
|
||||
vec3 s1 = sqrt(rgb);
|
||||
vec3 s2 = sqrt(s1);
|
||||
vec3 s3 = sqrt(s2);
|
||||
return vec3(0.662002687F) * s1 + vec3(0.684122060F) * s2 - vec3(0.323583601F) * s3 - vec3(0.0225411470F) * rgb;
|
||||
}
|
||||
|
||||
INLINE vec3 toLinear(vec3 srgb)
|
||||
{
|
||||
return srgb * (srgb * (srgb * vec3(0.305306011F) + vec3(0.682171111F)) + vec3(0.012522878F));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace nvvkhl_shaders
|
||||
#endif
|
||||
|
||||
#endif // DH_TONEMAMP_H
|
||||
141
raytracer/nvpro_core/nvvkhl/shaders/func.glsl
Normal file
141
raytracer/nvpro_core/nvvkhl/shaders/func.glsl
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef FUNC_GLSL
|
||||
#define FUNC_GLSL 1
|
||||
|
||||
#include "constants.glsl"
|
||||
|
||||
precision highp float;
|
||||
|
||||
float square(float x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
float saturate(float x)
|
||||
{
|
||||
return clamp(x, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
vec3 saturate(vec3 x)
|
||||
{
|
||||
return clamp(x, vec3(0.0F), vec3(1.0F));
|
||||
}
|
||||
|
||||
// Return the luminance of a color
|
||||
float luminance(in vec3 color)
|
||||
{
|
||||
return color.x * 0.2126F + color.y * 0.7152F + color.z * 0.0722F;
|
||||
}
|
||||
|
||||
vec3 slerp(vec3 a, vec3 b, float angle, float t)
|
||||
{
|
||||
t = saturate(t);
|
||||
float sin1 = sin(angle * t);
|
||||
float sin2 = sin(angle * (1.0F - t));
|
||||
float ta = sin1 / (sin1 + sin2);
|
||||
vec3 result = mix(a, b, ta);
|
||||
return normalize(result);
|
||||
}
|
||||
|
||||
float clampedDot(vec3 x, vec3 y)
|
||||
{
|
||||
return clamp(dot(x, y), 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
// Return the tangent and binormal from the incoming normal
|
||||
void createCoordinateSystem(in vec3 normal, out vec3 tangent, out vec3 bitangent)
|
||||
{
|
||||
if(abs(normal.x) > abs(normal.y))
|
||||
tangent = vec3(normal.z, 0.0F, -normal.x) / sqrt(normal.x * normal.x + normal.z * normal.z);
|
||||
else
|
||||
tangent = vec3(0.0F, -normal.z, normal.y) / sqrt(normal.y * normal.y + normal.z * normal.z);
|
||||
bitangent = cross(normal, tangent);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Building an Orthonormal Basis, Revisited
|
||||
// by Tom Duff, James Burgess, Per Christensen, Christophe Hery, Andrew Kensler, Max Liani, Ryusuke Villemin
|
||||
// https://graphics.pixar.com/library/OrthonormalB/
|
||||
//-----------------------------------------------------------------------
|
||||
void orthonormalBasis(in vec3 normal, out vec3 tangent, out vec3 bitangent)
|
||||
{
|
||||
float sgn = normal.z > 0.0F ? 1.0F : -1.0F;
|
||||
float a = -1.0F / (sgn + normal.z);
|
||||
float b = normal.x * normal.y * a;
|
||||
|
||||
tangent = vec3(1.0f + sgn * normal.x * normal.x * a, sgn * b, -sgn * normal.x);
|
||||
bitangent = vec3(b, sgn + normal.y * normal.y * a, -normal.y);
|
||||
}
|
||||
|
||||
vec3 rotate(vec3 v, vec3 k, float theta)
|
||||
{
|
||||
float cos_theta = cos(theta);
|
||||
float sin_theta = sin(theta);
|
||||
|
||||
return (v * cos_theta) + (cross(k, v) * sin_theta) + (k * dot(k, v)) * (1.0F - cos_theta);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Return the UV in a lat-long HDR map
|
||||
//-----------------------------------------------------------------------
|
||||
vec2 getSphericalUv(vec3 v)
|
||||
{
|
||||
float gamma = asin(-v.y);
|
||||
float theta = atan(v.z, v.x);
|
||||
|
||||
vec2 uv = vec2(theta * M_1_OVER_PI * 0.5F, gamma * M_1_OVER_PI) + 0.5F;
|
||||
return uv;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Return the interpolated value between 3 values and the barycentrics
|
||||
//-----------------------------------------------------------------------
|
||||
vec2 mixBary(vec2 a, vec2 b, vec2 c, vec3 bary)
|
||||
{
|
||||
return a * bary.x + b * bary.y + c * bary.z;
|
||||
}
|
||||
|
||||
vec3 mixBary(vec3 a, vec3 b, vec3 c, vec3 bary)
|
||||
{
|
||||
return a * bary.x + b * bary.y + c * bary.z;
|
||||
}
|
||||
|
||||
vec4 mixBary(vec4 a, vec4 b, vec4 c, vec3 bary)
|
||||
{
|
||||
return a * bary.x + b * bary.y + c * bary.z;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// https://www.realtimerendering.com/raytracinggems/unofficial_RayTracingGems_v1.4.pdf
|
||||
// 16.6.1 COSINE-WEIGHTED HEMISPHERE ORIENTED TO THE Z-AXIS
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 cosineSampleHemisphere(float r1, float r2)
|
||||
{
|
||||
float r = sqrt(r1);
|
||||
float phi = M_TWO_PI * r2;
|
||||
vec3 dir;
|
||||
dir.x = r * cos(phi);
|
||||
dir.y = r * sin(phi);
|
||||
dir.z = sqrt(max(0.0, 1.0 - dir.x * dir.x - dir.y * dir.y));
|
||||
return dir;
|
||||
}
|
||||
#endif // FUNC_GLSL
|
||||
135
raytracer/nvpro_core/nvvkhl/shaders/ggx.glsl
Normal file
135
raytracer/nvpro_core/nvvkhl/shaders/ggx.glsl
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GGX_GLSL
|
||||
#define GGX_GLSL 1
|
||||
|
||||
|
||||
#include "constants.glsl"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// The following equation models the Fresnel reflectance term of the spec equation (aka F())
|
||||
// Implementation of fresnel from [4], Equation 15
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 fresnelSchlick(vec3 f0, vec3 f90, float VdotH)
|
||||
{
|
||||
return f0 + (f90 - f0) * pow(clamp(vec3(1.0F) - VdotH, vec3(0.0F), vec3(1.0F)), vec3(5.0F));
|
||||
}
|
||||
|
||||
float fresnelSchlick(float f0, float f90, float VdotH)
|
||||
{
|
||||
return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0F, 1.0F), 5.0F);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Smith Joint GGX
|
||||
// Note: Vis = G / (4 * NdotL * NdotV)
|
||||
// see Eric Heitz. 2014. Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs. Journal of Computer Graphics Techniques, 3
|
||||
// see Real-Time Rendering. Page 331 to 336.
|
||||
// see https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg)
|
||||
//-----------------------------------------------------------------------
|
||||
float smithJointGGX(float NdotL, float NdotV, float alphaRoughness)
|
||||
{
|
||||
float alphaRoughnessSq = max(alphaRoughness * alphaRoughness, 1e-07);
|
||||
|
||||
float ggxV = NdotL * sqrt(NdotV * NdotV * (1.0F - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
float ggxL = NdotV * sqrt(NdotL * NdotL * (1.0F - alphaRoughnessSq) + alphaRoughnessSq);
|
||||
|
||||
float ggx = ggxV + ggxL;
|
||||
if(ggx > 0.0F)
|
||||
{
|
||||
return 0.5F / ggx;
|
||||
}
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
|
||||
// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
|
||||
// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
|
||||
//-----------------------------------------------------------------------
|
||||
float distributionGGX(float NdotH, float alphaRoughness) // alphaRoughness = roughness * roughness;
|
||||
{
|
||||
float alphaSqr = max(alphaRoughness * alphaRoughness, 1e-07);
|
||||
|
||||
float NdotHSqr = NdotH * NdotH;
|
||||
float denom = NdotHSqr * (alphaSqr - 1.0) + 1.0;
|
||||
|
||||
return alphaSqr / (M_PI * denom * denom);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 brdfLambertian(vec3 diffuseColor, float metallic)
|
||||
{
|
||||
return (1.0F - metallic) * (diffuseColor / M_PI);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 brdfSpecularGGX(vec3 f0, vec3 f90, float alphaRoughness, float VdotH, float NdotL, float NdotV, float NdotH)
|
||||
{
|
||||
vec3 f = fresnelSchlick(f0, f90, VdotH);
|
||||
float vis = smithJointGGX(NdotL, NdotV, alphaRoughness); // Vis = G / (4 * NdotL * NdotV)
|
||||
float d = distributionGGX(NdotH, alphaRoughness);
|
||||
|
||||
return f * vis * d;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Sample the GGX distribution
|
||||
// - Return the half vector
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 ggxSampling(float alphaRoughness, float r1, float r2)
|
||||
{
|
||||
float alphaSqr = max(alphaRoughness * alphaRoughness, 1e-07);
|
||||
|
||||
float phi = 2.0 * M_PI * r1;
|
||||
float cosTheta = sqrt((1.0 - r2) / (1.0 + (alphaSqr - 1.0) * r2));
|
||||
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
|
||||
|
||||
return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
|
||||
}
|
||||
|
||||
// Return false if it produce a total internal reflection
|
||||
bool refract(vec3 incident, vec3 normal, float eta, out vec3 transmitted)
|
||||
{
|
||||
float cosTheta = dot(incident, normal);
|
||||
float k = 1.0F - eta * eta * (1.0F - cosTheta * cosTheta);
|
||||
|
||||
if(k < 0.0F)
|
||||
{
|
||||
// Total internal reflection
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
transmitted = eta * incident - (eta * cosTheta + sqrt(k)) * normal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // GGX_H
|
||||
67
raytracer/nvpro_core/nvvkhl/shaders/hdr_dome.comp
Normal file
67
raytracer/nvpro_core/nvvkhl/shaders/hdr_dome.comp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "dh_hdr.h"
|
||||
#include "constants.glsl"
|
||||
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
layout(set = 0, binding = eHdrBrdf) writeonly uniform image2D gOutHdr;
|
||||
layout(set = 1, binding = eHdr) uniform sampler2D gInHdr;
|
||||
|
||||
|
||||
layout(push_constant) uniform SkyDomePushConstant_
|
||||
{
|
||||
HdrDomePushConstant pc;
|
||||
};
|
||||
|
||||
|
||||
vec2 getSphericalUv(vec3 v)
|
||||
{
|
||||
float gamma = asin(-v.y);
|
||||
float theta = atan(v.z, v.x);
|
||||
return vec2(theta * M_1_OVER_PI * 0.5, gamma * M_1_OVER_PI) + 0.5F;
|
||||
}
|
||||
|
||||
vec3 rotate(vec3 v, vec3 k, float theta)
|
||||
{
|
||||
float cos_theta = cos(theta);
|
||||
float sin_theta = sin(theta);
|
||||
|
||||
return (v * cos_theta) + (cross(k, v) * sin_theta) + (k * dot(k, v)) * (1.0F - cos_theta);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
const vec2 pixel_center = vec2(gl_GlobalInvocationID.xy) + vec2(0.5);
|
||||
const vec2 in_uv = pixel_center / vec2(imageSize(gOutHdr));
|
||||
const vec2 d = in_uv * 2.0F - 1.0F;
|
||||
vec3 direction = vec3(pc.mvp * vec4(d.x, d.y, 1.0F, 1.0F));
|
||||
|
||||
direction = rotate(direction, vec3(0.0F, 1.0F, 0.0F), -pc.rotation);
|
||||
|
||||
const vec2 uv = getSphericalUv(normalize(direction.xyz));
|
||||
const vec3 color = texture(gInHdr, uv).rgb * pc.multColor.rgb;
|
||||
imageStore(gOutHdr, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1.0));
|
||||
}
|
||||
106
raytracer/nvpro_core/nvvkhl/shaders/hdr_env_sampling.glsl
Normal file
106
raytracer/nvpro_core/nvvkhl/shaders/hdr_env_sampling.glsl
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// This file has the functions to sample the environment
|
||||
|
||||
|
||||
#ifndef HDR_ENV_SAMPLING_GLSL
|
||||
#define HDR_ENV_SAMPLING_GLSL 1
|
||||
|
||||
|
||||
precision highp float;
|
||||
|
||||
#include "dh_hdr.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Environment Sampling (HDR)
|
||||
// See: https://arxiv.org/pdf/1901.05423.pdf
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
vec4 environmentSample(in sampler2D hdrTexture, in vec3 randVal, out vec3 toLight)
|
||||
{
|
||||
|
||||
// Uniformly pick a texel index idx in the environment map
|
||||
vec3 xi = randVal;
|
||||
uvec2 tsize = uvec2(textureSize(hdrTexture, 0));
|
||||
uint width = tsize.x;
|
||||
uint height = tsize.y;
|
||||
|
||||
uint size = width * height;
|
||||
uint idx = min(uint(xi.x * float(size)), size - 1U);
|
||||
|
||||
// Fetch the sampling data for that texel, containing the ratio q between its
|
||||
// emitted radiance and the average of the environment map, the texel alias,
|
||||
// the probability distribution function (PDF) values for that texel and its
|
||||
// alias
|
||||
EnvAccel sample_data = envSamplingData[idx];
|
||||
|
||||
uint env_idx;
|
||||
|
||||
if(xi.y < sample_data.q)
|
||||
{
|
||||
// If the random variable is lower than the intensity ratio q, we directly pick
|
||||
// this texel, and renormalize the random variable for later use. The PDF is the
|
||||
// one of the texel itself
|
||||
env_idx = idx;
|
||||
xi.y /= sample_data.q;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise we pick the alias of the texel, renormalize the random variable and use
|
||||
// the PDF of the alias
|
||||
env_idx = sample_data.alias;
|
||||
xi.y = (xi.y - sample_data.q) / (1.0f - sample_data.q);
|
||||
}
|
||||
|
||||
// Compute the 2D integer coordinates of the texel
|
||||
const uint px = env_idx % width;
|
||||
uint py = env_idx / width;
|
||||
|
||||
// Uniformly sample the solid angle subtended by the pixel.
|
||||
// Generate both the UV for texture lookup and a direction in spherical coordinates
|
||||
const float u = float(px + xi.y) / float(width);
|
||||
const float phi = u * (2.0f * M_PI) - M_PI;
|
||||
float sin_phi = sin(phi);
|
||||
float cos_phi = cos(phi);
|
||||
|
||||
const float step_theta = M_PI / float(height);
|
||||
const float theta0 = float(py) * step_theta;
|
||||
const float cos_theta = cos(theta0) * (1.0f - xi.z) + cos(theta0 + step_theta) * xi.z;
|
||||
const float theta = acos(cos_theta);
|
||||
const float sin_theta = sin(theta);
|
||||
const float v = theta * M_1_OVER_PI;
|
||||
|
||||
// Convert to a light direction vector in Cartesian coordinates
|
||||
toLight = vec3(cos_phi * sin_theta, cos_theta, sin_phi * sin_theta);
|
||||
|
||||
// Lookup the environment value using bilinear filtering
|
||||
return texture(hdrTexture, vec2(u, v));
|
||||
}
|
||||
|
||||
|
||||
float powerHeuristic(float a, float b)
|
||||
{
|
||||
const float t = a * a;
|
||||
return t / (b * b + t);
|
||||
}
|
||||
|
||||
|
||||
#endif // ENV_SAMPLING_GLSL
|
||||
138
raytracer/nvpro_core/nvvkhl/shaders/hdr_integrate_brdf.comp
Normal file
138
raytracer/nvpro_core/nvvkhl/shaders/hdr_integrate_brdf.comp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
|
||||
// This shader computes a glossy BRDF map to be used with the Unreal 4 PBR shading model as
|
||||
// described in
|
||||
//
|
||||
// "Real Shading in Unreal Engine 4" by Brian Karis
|
||||
// http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
//
|
||||
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "dh_hdr.h"
|
||||
|
||||
layout(set = 0, binding = eHdrImage) writeonly uniform image2D gOutColor;
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
|
||||
const float M_PI = 3.14159265359F;
|
||||
|
||||
// See http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
float radinv(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
|
||||
vec2 hammersley2D(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i) / float(N), radinv(i));
|
||||
}
|
||||
|
||||
vec3 ggxSample(vec2 xi, vec3 normal, float alpha)
|
||||
{
|
||||
// compute half-vector in spherical coordinates
|
||||
float phi = 2.0F * M_PI * xi.x;
|
||||
float cos_theta = sqrt((1.0F - xi.y) / (1.0F + (alpha * alpha - 1.0F) * xi.y));
|
||||
float sin_theta = sqrt(1.0F - cos_theta * cos_theta);
|
||||
|
||||
return vec3(cos(phi) * sin_theta, sin(phi) * sin_theta, cos_theta);
|
||||
}
|
||||
|
||||
float geometrySchlickGgx(float ndotv, float roughness)
|
||||
{
|
||||
// note that we use a different k for IBL
|
||||
float a = roughness;
|
||||
float k = (a * a) / 2.0F;
|
||||
|
||||
float nom = ndotv;
|
||||
float denom = ndotv * (1.0F - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float geometrySmith(vec3 normal, vec3 view, vec3 light, float roughness)
|
||||
{
|
||||
float ndotv = max(dot(normal, view), 0.0F);
|
||||
float ndotl = max(dot(normal, light), 0.0F);
|
||||
float g1 = geometrySchlickGgx(ndotv, roughness);
|
||||
float g2 = geometrySchlickGgx(ndotl, roughness);
|
||||
|
||||
return g1 * g2;
|
||||
}
|
||||
|
||||
vec2 integrateBrdf(float ndotv, float roughness)
|
||||
{
|
||||
vec3 view;
|
||||
view.x = sqrt(1.0F - ndotv * ndotv); // sin
|
||||
view.y = 0.0;
|
||||
view.z = ndotv;
|
||||
|
||||
float A = 0.0F;
|
||||
float B = 0.0F;
|
||||
|
||||
const vec3 normal = vec3(0.0F, 0.0F, 1.0F);
|
||||
|
||||
const uint nsamples = 1024u;
|
||||
float alpha = roughness * roughness;
|
||||
|
||||
for(uint i = 0u; i < nsamples; ++i)
|
||||
{
|
||||
vec2 xi = hammersley2D(i, nsamples);
|
||||
vec3 h0 = ggxSample(xi, normal, alpha);
|
||||
vec3 h = vec3(h0.y, -h0.x, h0.z);
|
||||
|
||||
vec3 light = normalize(2.0F * dot(view, h) * h - view);
|
||||
|
||||
float ndotl = max(light.z, 0.0F);
|
||||
float ndoth = max(h.z, 0.0F);
|
||||
float vdoth = max(dot(view, h), 0.0F);
|
||||
|
||||
if(ndotl > 0.0)
|
||||
{
|
||||
float G = geometrySmith(normal, view, light, roughness);
|
||||
float G_Vis = (G * vdoth) / (ndoth * ndotv);
|
||||
float Fc = pow(1.0 - vdoth, 5.0F);
|
||||
|
||||
A += (1.0 - Fc) * G_Vis;
|
||||
B += Fc * G_Vis;
|
||||
}
|
||||
}
|
||||
A /= float(nsamples);
|
||||
B /= float(nsamples);
|
||||
return vec2(A, B);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
const vec2 pixel_center = vec2(gl_GlobalInvocationID.xy) + vec2(0.5F);
|
||||
const vec2 in_uv = pixel_center / vec2(imageSize(gOutColor));
|
||||
vec2 brdf = integrateBrdf(in_uv.s, 1.0F - in_uv.t);
|
||||
imageStore(gOutColor, ivec2(gl_GlobalInvocationID.xy), vec4(brdf, 0.0F, 0.0F));
|
||||
}
|
||||
120
raytracer/nvpro_core/nvvkhl/shaders/hdr_prefilter_diffuse.comp
Normal file
120
raytracer/nvpro_core/nvvkhl/shaders/hdr_prefilter_diffuse.comp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
|
||||
// This shader computes a diffuse irradiance IBL map using multiple importance sampling weighted
|
||||
// hemisphere sampling and environment map importance sampling.
|
||||
|
||||
// varying inputs
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
||||
#include "dh_hdr.h"
|
||||
|
||||
#include "constants.glsl"
|
||||
#include "func.glsl"
|
||||
#include "random.glsl"
|
||||
|
||||
|
||||
// clang-format off
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
layout(set = 0, binding = eHdrImage) writeonly uniform image2D gOutColor;
|
||||
layout(set = 1, binding = eImpSamples, scalar) buffer _EnvAccel { EnvAccel envSamplingData[]; };
|
||||
layout(set = 1, binding = eHdr) uniform sampler2D hdrTexture;
|
||||
|
||||
layout(push_constant) uniform HdrPushBlock_ { HdrPushBlock pc; };
|
||||
// clang-format on
|
||||
|
||||
|
||||
#include "hdr_env_sampling.glsl"
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// Finding the world direction
|
||||
const vec2 pixelCenter = vec2(gl_GlobalInvocationID.xy) + vec2(0.5F);
|
||||
const vec2 inUV = pixelCenter / pc.size;
|
||||
const vec2 d = inUV * 2.0F - 1.0F;
|
||||
vec3 direction = vec3(pc.mvp * vec4(d.x, d.y, 1.0F, 1.0F));
|
||||
|
||||
// Getting axis
|
||||
vec3 tangent, bitangent;
|
||||
vec3 normal = normalize(vec3(direction.x, -direction.y, direction.z)); // Flipping Y
|
||||
orthonormalBasis(normal, tangent, bitangent);
|
||||
|
||||
// Random seed
|
||||
uint seed = xxhash32(uvec3(gl_GlobalInvocationID.xyz));
|
||||
|
||||
|
||||
vec3 result = vec3(0.0f);
|
||||
uint nsamples = 512u;
|
||||
float inv_samples = 1.0f / float(nsamples);
|
||||
for(uint i = 0u; i < nsamples; ++i)
|
||||
{
|
||||
// Importance sample diffuse BRDF.
|
||||
{
|
||||
float xi0 = (float(i) + 0.5f) * inv_samples;
|
||||
float xi1 = rand(seed);
|
||||
|
||||
float phi = 2.0f * M_PI * xi0;
|
||||
float sin_phi = sin(phi);
|
||||
float cos_phi = cos(phi);
|
||||
|
||||
float sin_theta = sqrt(1.0f - xi1);
|
||||
float cos_theta = sqrt(xi1);
|
||||
|
||||
vec3 d = vec3(sin_theta * cos_phi, sin_theta * sin_phi, cos_theta);
|
||||
|
||||
vec3 direction = d.x * tangent + d.y * bitangent + d.z * normal;
|
||||
vec2 uv = getSphericalUv(direction);
|
||||
|
||||
float p_brdf_sqr = cos_theta * cos_theta * (M_1_OVER_PI * M_1_OVER_PI);
|
||||
|
||||
vec4 rad_pdf = texture(hdrTexture, uv);
|
||||
float p_env = rad_pdf.a;
|
||||
float w = p_brdf_sqr / (p_brdf_sqr + p_env * p_env);
|
||||
result += rad_pdf.rgb * w * M_PI;
|
||||
}
|
||||
|
||||
// Importance sample environment.
|
||||
{
|
||||
vec3 dir;
|
||||
vec3 rand_val = vec3(rand(seed), rand(seed), rand(seed));
|
||||
vec4 rad_pdf = environmentSample(hdrTexture, rand_val, dir);
|
||||
float pdf = rad_pdf.a;
|
||||
vec3 value = rad_pdf.rgb / pdf;
|
||||
|
||||
float cosine = dot(dir, normal);
|
||||
float p_brdf_sqr = cosine * cosine * (M_1_OVER_PI * M_1_OVER_PI);
|
||||
float p_env_sqr = pdf * pdf;
|
||||
if(cosine > 0.0f)
|
||||
{
|
||||
float w = p_env_sqr / (p_env_sqr + p_brdf_sqr);
|
||||
result += w * value * cosine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec4 frag_color = vec4(result * (1.0f / float(nsamples)) / M_PI, 1.0f);
|
||||
imageStore(gOutColor, ivec2(gl_GlobalInvocationID.xy), frag_color);
|
||||
}
|
||||
166
raytracer/nvpro_core/nvvkhl/shaders/hdr_prefilter_glossy.comp
Normal file
166
raytracer/nvpro_core/nvvkhl/shaders/hdr_prefilter_glossy.comp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
|
||||
// This shader computes a glossy IBL map to be used with the Unreal 4 PBR shading model as
|
||||
// described in
|
||||
//
|
||||
// "Real Shading in Unreal Engine 4" by Brian Karis
|
||||
// http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
|
||||
//
|
||||
// As an extension to the original it uses multiple importance sampling weighted BRDF importance
|
||||
// sampling and environment map importance sampling to yield good results for high dynamic range
|
||||
// lighting.
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
#extension GL_EXT_scalar_block_layout : enable
|
||||
|
||||
#include "dh_hdr.h"
|
||||
|
||||
|
||||
// clang-format off
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
|
||||
layout(set = 0, binding = eHdrImage) writeonly uniform image2D g_outColor;
|
||||
layout(set = 1, binding = eImpSamples, scalar) buffer _EnvAccel { EnvAccel envSamplingData[]; };
|
||||
layout(set = 1, binding = eHdr) uniform sampler2D hdrTexture;
|
||||
|
||||
layout(push_constant) uniform HdrPushBlock_ { HdrPushBlock pc; };
|
||||
// clang-format on
|
||||
|
||||
#include "constants.glsl"
|
||||
#include "func.glsl"
|
||||
#include "random.glsl"
|
||||
#include "hdr_env_sampling.glsl"
|
||||
|
||||
|
||||
// Importance sample a GGX microfacet distribution.
|
||||
vec3 ggxSample(vec2 xi, float alpha)
|
||||
{
|
||||
float phi = 2.0F * M_PI * xi.x;
|
||||
float cos_theta = sqrt((1.0F - xi.y) / (1.0F + (alpha * alpha - 1.0F) * xi.y));
|
||||
float sin_theta = sqrt(1.0F - cos_theta * cos_theta);
|
||||
|
||||
return vec3(cos(phi) * sin_theta, sin(phi) * sin_theta, cos_theta);
|
||||
}
|
||||
|
||||
// Evaluate a GGX microfacet distribution.
|
||||
float ggxEval(float alpha, float nh)
|
||||
{
|
||||
float a2 = alpha * alpha;
|
||||
float nh2 = nh * nh;
|
||||
float tan2 = (1.0f - nh2) / nh2;
|
||||
float f = a2 + tan2;
|
||||
return a2 / (f * f * M_PI * nh2 * nh);
|
||||
}
|
||||
|
||||
|
||||
struct EnvmapSampleValue
|
||||
{
|
||||
vec3 dir;
|
||||
vec3 value;
|
||||
float pdf;
|
||||
};
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
const vec2 pixel_center = vec2(gl_GlobalInvocationID.xy) + vec2(0.5F);
|
||||
const vec2 in_uv = pixel_center / vec2(pc.size);
|
||||
const vec2 d = in_uv * 2.0F - 1.0F;
|
||||
vec3 direction = vec3(pc.mvp * vec4(d.x, d.y, 1.0F, 1.0F));
|
||||
|
||||
vec3 tangent, bitangent;
|
||||
vec3 normal = normalize(vec3(direction.x, -direction.y, direction.z)); // Flipping Y
|
||||
orthonormalBasis(normal, tangent, bitangent);
|
||||
|
||||
float alpha = pc.roughness;
|
||||
uint nsamples = alpha > 0.0F ? 512u : 1u;
|
||||
|
||||
|
||||
uint state = xxhash32(uvec3(gl_GlobalInvocationID.xy, pc.roughness * 10.0F));
|
||||
|
||||
// The integrals are additionally weighted by the cosine and normalized using the average cosine of
|
||||
// the importance sampled BRDF directions (as in the Unreal publication).
|
||||
float weight_sum = 0.0f;
|
||||
|
||||
vec3 result = vec3(0.0F);
|
||||
float inv_nsamples = 1.0F / float(nsamples);
|
||||
for(uint i = 0u; i < nsamples; ++i)
|
||||
{
|
||||
// Importance sample BRDF.
|
||||
{
|
||||
float xi0 = (float(i) + 0.5F) * inv_nsamples;
|
||||
float xi1 = rand(state);
|
||||
|
||||
vec3 h0 = alpha > 0.0f ? ggxSample(vec2(xi0, xi1), alpha) : vec3(0.0F, 0.0F, 1.0F);
|
||||
vec3 h = tangent * h0.x + bitangent * h0.y + normal * h0.z;
|
||||
|
||||
vec3 direction = normalize(2.0 * dot(normal, h) * h - normal);
|
||||
|
||||
float cos_theta = dot(normal, direction);
|
||||
if(cos_theta > 0.0F)
|
||||
{
|
||||
vec2 uv = getSphericalUv(direction);
|
||||
float w = 1.0F;
|
||||
if(alpha > 0.0F)
|
||||
{
|
||||
float pdf_brdf_sqr = ggxEval(alpha, h0.z) * 0.25F / dot(direction, h);
|
||||
pdf_brdf_sqr *= pdf_brdf_sqr;
|
||||
float pdf_env = texture(hdrTexture, uv).a;
|
||||
w = pdf_brdf_sqr / (pdf_brdf_sqr + pdf_env * pdf_env);
|
||||
}
|
||||
result += w * texture(hdrTexture, uv).rgb * cos_theta;
|
||||
weight_sum += cos_theta;
|
||||
}
|
||||
}
|
||||
|
||||
// Importance sample environment.
|
||||
if(alpha > 0.0f)
|
||||
{
|
||||
vec3 randVal = vec3(rand(state), rand(state), rand(state));
|
||||
|
||||
EnvmapSampleValue val;
|
||||
vec4 radPdf = environmentSample(hdrTexture, randVal, val.dir);
|
||||
val.pdf = radPdf.a;
|
||||
val.value = radPdf.rgb / val.pdf;
|
||||
|
||||
|
||||
vec3 h = normalize(normal + val.dir);
|
||||
float nh = dot(h, normal);
|
||||
float kh = dot(val.dir, h);
|
||||
float nk = dot(val.dir, normal);
|
||||
if(kh > 0.0F && nh > 0.0F && nk > 0.0F)
|
||||
{
|
||||
float pdf_env_sqr = val.pdf * val.pdf;
|
||||
float pdf_brdf = ggxEval(alpha, nh) * 0.25F / kh;
|
||||
|
||||
float w = pdf_env_sqr / (pdf_env_sqr + pdf_brdf * pdf_brdf);
|
||||
result += w * val.value * pdf_brdf * nk * nk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec4 result_color = vec4(result / float(weight_sum), 1.0F);
|
||||
imageStore(g_outColor, ivec2(gl_GlobalInvocationID.xy), result_color);
|
||||
}
|
||||
118
raytracer/nvpro_core/nvvkhl/shaders/light_contrib.glsl
Normal file
118
raytracer/nvpro_core/nvvkhl/shaders/light_contrib.glsl
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef LIGHT_CONTRIB_H
|
||||
#define LIGHT_CONTRIB_H 1
|
||||
|
||||
#include "func.glsl"
|
||||
#include "dh_lighting.h"
|
||||
|
||||
LightContrib singleLightContribution(in Light light, in vec3 surfacePos, in vec3 surfaceNormal, in vec3 viewIncident, in vec2 randVal)
|
||||
{
|
||||
LightContrib contrib;
|
||||
contrib.incidentVector = vec3(0.0F);
|
||||
contrib.halfAngularSize = 0.0F;
|
||||
contrib.intensity = vec3(0.0F);
|
||||
float irradiance = 0.0F;
|
||||
|
||||
if(light.type == eLightTypeDirectional)
|
||||
{
|
||||
contrib.incidentVector = light.direction;
|
||||
contrib.halfAngularSize = light.angularSizeOrInvRange * 0.5F;
|
||||
irradiance = light.intensity;
|
||||
}
|
||||
else if(light.type == eLightTypeSpot || light.type == eLightTypePoint)
|
||||
{
|
||||
vec3 light_to_surface = surfacePos - light.position;
|
||||
float distance = sqrt(dot(light_to_surface, light_to_surface));
|
||||
float r_distance = 1.0F / distance;
|
||||
contrib.incidentVector = light_to_surface * r_distance;
|
||||
|
||||
float attenuation = 1.F;
|
||||
if(light.angularSizeOrInvRange > 0.0F)
|
||||
{
|
||||
attenuation = square(saturate(1.0F - square(square(distance * light.angularSizeOrInvRange))));
|
||||
|
||||
if(attenuation == 0.0F)
|
||||
return contrib;
|
||||
}
|
||||
|
||||
float spotlight = 1.0F;
|
||||
if(light.type == eLightTypeSpot)
|
||||
{
|
||||
float lDotD = dot(contrib.incidentVector, light.direction);
|
||||
float direction_angle = acos(lDotD);
|
||||
spotlight = 1.0F - smoothstep(light.innerAngle, light.outerAngle, direction_angle);
|
||||
|
||||
if(spotlight == 0.0F)
|
||||
return contrib;
|
||||
}
|
||||
|
||||
if(light.radius > 0.0F)
|
||||
{
|
||||
contrib.halfAngularSize = atan(min(light.radius * r_distance, 1.0F));
|
||||
|
||||
// A good enough approximation for 2 * (1 - cos(halfAngularSize)), numerically more accurate for small angular sizes
|
||||
float solidAngleOverPi = square(contrib.halfAngularSize);
|
||||
|
||||
float radianceTimesPi = light.intensity / square(light.radius);
|
||||
|
||||
irradiance = radianceTimesPi * solidAngleOverPi;
|
||||
}
|
||||
else
|
||||
{
|
||||
irradiance = light.intensity * square(r_distance);
|
||||
}
|
||||
|
||||
irradiance *= spotlight * attenuation;
|
||||
}
|
||||
|
||||
contrib.intensity = irradiance * light.color;
|
||||
|
||||
|
||||
if(contrib.halfAngularSize > 0.0F)
|
||||
{ // <----- Sampling area lights
|
||||
float angular_size = contrib.halfAngularSize;
|
||||
|
||||
// section 34 https://people.cs.kuleuven.be/~philip.dutre/GI/TotalCompendium.pdf
|
||||
vec3 dir;
|
||||
float tmp = (1.0F - randVal.y * (1.0F - cos(angular_size)));
|
||||
float tmp2 = tmp * tmp;
|
||||
float tetha = sqrt(1.0F - tmp2);
|
||||
dir.x = cos(M_TWO_PI * randVal.x) * tetha;
|
||||
dir.y = sin(M_TWO_PI * randVal.x) * tetha;
|
||||
dir.z = tmp;
|
||||
vec3 light_dir = -contrib.incidentVector;
|
||||
vec3 tangent, binormal;
|
||||
orthonormalBasis(light_dir, tangent, binormal);
|
||||
mat3 tbn = mat3(tangent, binormal, light_dir);
|
||||
light_dir = normalize(tbn * dir);
|
||||
|
||||
contrib.incidentVector = -light_dir;
|
||||
}
|
||||
|
||||
return contrib;
|
||||
}
|
||||
|
||||
// Version without random values
|
||||
LightContrib singleLightContribution(in Light light, in vec3 surfacePos, in vec3 surfaceNormal, in vec3 viewIncident)
|
||||
{
|
||||
return singleLightContribution(light, surfacePos, surfaceNormal, viewIncident, vec2(0.0F));
|
||||
}
|
||||
#endif
|
||||
35
raytracer/nvpro_core/nvvkhl/shaders/passthrough.vert
Normal file
35
raytracer/nvpro_core/nvvkhl/shaders/passthrough.vert
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
layout(location = 0) out vec2 outUv;
|
||||
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
outUv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUv * 2.0f - 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
195
raytracer/nvpro_core/nvvkhl/shaders/pbr_mat_eval.glsl
Normal file
195
raytracer/nvpro_core/nvvkhl/shaders/pbr_mat_eval.glsl
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// This file takes the incoming GltfShadeMaterial (material uploaded in a buffer) and
|
||||
// evaluates it, basically sample the textures and return the struct PbrMaterial
|
||||
// which is used by the Bsdf functions to evaluate and sample the material
|
||||
//
|
||||
|
||||
#ifndef MAT_EVAL_H
|
||||
#define MAT_EVAL_H 1
|
||||
|
||||
#include "pbr_mat_struct.h"
|
||||
|
||||
// This is the list of all textures
|
||||
#ifndef MAT_EVAL_TEXTURE_ARRAY
|
||||
#define MAT_EVAL_TEXTURE_ARRAY texturesMap
|
||||
#endif
|
||||
|
||||
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// MATERIAL FOR EVALUATION
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
const float g_min_reflectance = 0.04F;
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
// sRGB to linear approximation, see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html
|
||||
vec4 srgbToLinear(in vec4 sRgb)
|
||||
{
|
||||
//return vec4(pow(sRgb.xyz, vec3(2.2f)), sRgb.w);
|
||||
vec3 rgb = sRgb.xyz * (sRgb.xyz * (sRgb.xyz * 0.305306011F + 0.682171111F) + 0.012522878F);
|
||||
return vec4(rgb, sRgb.a);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// From the incoming material return the material for evaluating PBR
|
||||
//-----------------------------------------------------------------------
|
||||
PbrMaterial evaluateMaterial(in GltfShadeMaterial material, in vec3 normal, in vec3 tangent, in vec3 bitangent, in vec2 texCoord, in bool isInside)
|
||||
{
|
||||
float perceptual_roughness = 0.0F;
|
||||
float metallic = 0.0F;
|
||||
vec3 f0 = vec3(0.0F);
|
||||
vec3 f90 = vec3(1.0F);
|
||||
vec4 baseColor = vec4(0.0F, 0.0F, 0.0F, 1.0F);
|
||||
|
||||
// KHR_texture_transform
|
||||
texCoord = vec2(vec3(texCoord, 1) * material.uvTransform);
|
||||
|
||||
// Normal Map
|
||||
if(material.normalTexture > -1)
|
||||
{
|
||||
mat3 tbn = mat3(tangent, bitangent, normal);
|
||||
vec3 normal_vector = texture(MAT_EVAL_TEXTURE_ARRAY[nonuniformEXT(material.normalTexture)], texCoord).xyz;
|
||||
normal_vector = normal_vector * 2.0F - 1.0F;
|
||||
normal_vector *= vec3(material.normalTextureScale, material.normalTextureScale, 1.0F);
|
||||
normal = normalize(tbn * normal_vector);
|
||||
}
|
||||
|
||||
// Metallic-Roughness
|
||||
{
|
||||
perceptual_roughness = material.pbrRoughnessFactor;
|
||||
metallic = material.pbrMetallicFactor;
|
||||
if(material.pbrMetallicRoughnessTexture > -1.0F)
|
||||
{
|
||||
// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
|
||||
vec4 mr_sample = texture(MAT_EVAL_TEXTURE_ARRAY[nonuniformEXT(material.pbrMetallicRoughnessTexture)], texCoord);
|
||||
perceptual_roughness *= mr_sample.g;
|
||||
metallic *= mr_sample.b;
|
||||
}
|
||||
|
||||
// The albedo may be defined from a base texture or a flat color
|
||||
baseColor = material.pbrBaseColorFactor;
|
||||
if(material.pbrBaseColorTexture > -1.0F)
|
||||
{
|
||||
baseColor *= texture(MAT_EVAL_TEXTURE_ARRAY[nonuniformEXT(material.pbrBaseColorTexture)], texCoord);
|
||||
}
|
||||
vec3 specular_color = mix(vec3(g_min_reflectance), vec3(baseColor), float(metallic));
|
||||
f0 = specular_color;
|
||||
}
|
||||
|
||||
// Protection
|
||||
metallic = clamp(metallic, 0.0F, 1.0F);
|
||||
|
||||
|
||||
// Emissive term
|
||||
vec3 emissive = material.emissiveFactor;
|
||||
if(material.emissiveTexture > -1.0F)
|
||||
{
|
||||
emissive *= vec3(texture(MAT_EVAL_TEXTURE_ARRAY[material.emissiveTexture], texCoord));
|
||||
}
|
||||
|
||||
// KHR_materials_specular
|
||||
// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_specular
|
||||
vec4 specularColorTexture = vec4(1.0F);
|
||||
if(material.specularColorTexture > -1)
|
||||
{
|
||||
specularColorTexture = textureLod(texturesMap[nonuniformEXT(material.specularColorTexture)], texCoord, 0);
|
||||
}
|
||||
float specularTexture = 1.0F;
|
||||
if(material.specularTexture > -1)
|
||||
{
|
||||
specularTexture = textureLod(texturesMap[nonuniformEXT(material.specularTexture)], texCoord, 0).a;
|
||||
}
|
||||
|
||||
|
||||
// Dielectric Specular
|
||||
float ior1 = 1.0F;
|
||||
float ior2 = material.ior;
|
||||
if(isInside)
|
||||
{
|
||||
ior1 = material.ior;
|
||||
ior2 = 1.0F;
|
||||
}
|
||||
float iorRatio = ((ior1 - ior2) / (ior1 + ior2));
|
||||
float iorRatioSqr = iorRatio * iorRatio;
|
||||
|
||||
vec3 dielectricSpecularF0 = material.specularColorFactor * specularColorTexture.rgb;
|
||||
float dielectricSpecularF90 = material.specularFactor * specularTexture;
|
||||
|
||||
f0 = mix(min(iorRatioSqr * dielectricSpecularF0, vec3(1.0F)) * dielectricSpecularF0, baseColor.rgb, metallic);
|
||||
f90 = vec3(mix(dielectricSpecularF90, 1.0F, metallic));
|
||||
|
||||
|
||||
// Material Evaluated
|
||||
PbrMaterial pbrMat;
|
||||
pbrMat.albedo = baseColor;
|
||||
pbrMat.f0 = f0;
|
||||
pbrMat.f90 = f90;
|
||||
pbrMat.roughness = perceptual_roughness;
|
||||
pbrMat.metallic = metallic;
|
||||
pbrMat.emissive = max(vec3(0.0F), emissive);
|
||||
pbrMat.normal = normal;
|
||||
pbrMat.eta = (material.thicknessFactor == 0.0F) ? 1.0F : ior1 / ior2;
|
||||
|
||||
// KHR_materials_transmission
|
||||
pbrMat.transmissionFactor = material.transmissionFactor;
|
||||
if(material.transmissionTexture > -1)
|
||||
{
|
||||
pbrMat.transmissionFactor *= textureLod(texturesMap[nonuniformEXT(material.transmissionTexture)], texCoord, 0).r;
|
||||
}
|
||||
|
||||
// KHR_materials_ior
|
||||
pbrMat.ior = material.ior;
|
||||
|
||||
// KHR_materials_volume
|
||||
pbrMat.attenuationColor = material.attenuationColor;
|
||||
pbrMat.attenuationDistance = material.attenuationDistance;
|
||||
pbrMat.thicknessFactor = material.thicknessFactor;
|
||||
|
||||
// KHR_materials_clearcoat
|
||||
pbrMat.clearcoatFactor = material.clearcoatFactor;
|
||||
pbrMat.clearcoatRoughness = material.clearcoatRoughness;
|
||||
if(material.clearcoatTexture > -1)
|
||||
{
|
||||
pbrMat.clearcoatFactor *= textureLod(texturesMap[nonuniformEXT(material.clearcoatTexture)], texCoord, 0).r;
|
||||
}
|
||||
if(material.clearcoatRoughnessTexture > -1)
|
||||
{
|
||||
pbrMat.clearcoatRoughness *= textureLod(texturesMap[nonuniformEXT(material.clearcoatRoughnessTexture)], texCoord, 0).g;
|
||||
}
|
||||
pbrMat.clearcoatRoughness = max(pbrMat.clearcoatRoughness, 0.001F);
|
||||
|
||||
return pbrMat;
|
||||
}
|
||||
|
||||
PbrMaterial evaluateMaterial(in GltfShadeMaterial material, in vec3 normal, in vec3 tangent, in vec3 bitangent, in vec2 texCoord)
|
||||
{
|
||||
return evaluateMaterial(material, normal, tangent, bitangent, texCoord, false);
|
||||
}
|
||||
|
||||
#endif // MAT_EVAL_H
|
||||
46
raytracer/nvpro_core/nvvkhl/shaders/pbr_mat_struct.h
Normal file
46
raytracer/nvpro_core/nvvkhl/shaders/pbr_mat_struct.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/// @DOC_SKIP
|
||||
|
||||
#ifndef PBR_MAT_STRUCT_H
|
||||
#define PBR_MAT_STRUCT_H 1
|
||||
|
||||
struct PbrMaterial
|
||||
{
|
||||
vec4 albedo; // base color
|
||||
float roughness; // 0 = smooth, 1 = rough
|
||||
float metallic; // 0 = dielectric, 1 = metallic
|
||||
vec3 normal; // shading normal
|
||||
vec3 emissive; // emissive color
|
||||
vec3 f0; // full reflectance color (n incidence angle)
|
||||
vec3 f90; // reflectance color at grazing angle
|
||||
float eta; // index of refraction
|
||||
float specularWeight; // product of specularFactor and specularTexture.a
|
||||
float transmissionFactor; // KHR_materials_transmission
|
||||
float ior; // KHR_materials_ior
|
||||
vec3 attenuationColor; // KHR_materials_volume
|
||||
float attenuationDistance; // KHR_materials_volume
|
||||
float thicknessFactor; // KHR_materials_volume
|
||||
float clearcoatFactor; // KHR_materials_clearcoat
|
||||
float clearcoatRoughness; // KHR_materials_clearcoat
|
||||
vec3 clearcoatNormal; // KHR_materials_clearcoat
|
||||
};
|
||||
|
||||
#endif
|
||||
62
raytracer/nvpro_core/nvvkhl/shaders/random.glsl
Normal file
62
raytracer/nvpro_core/nvvkhl/shaders/random.glsl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_GLSL
|
||||
#define RANDOM_GLSL 1
|
||||
|
||||
precision highp float;
|
||||
|
||||
// Generate a seed for the random generator.
|
||||
// Input - pixel.x, pixel.y, frame_nb
|
||||
// From https://github.com/Cyan4973/xxHash, https://www.shadertoy.com/view/XlGcRh
|
||||
uint xxhash32(uvec3 p)
|
||||
{
|
||||
const uvec4 primes = uvec4(2246822519U, 3266489917U, 668265263U, 374761393U);
|
||||
uint h32;
|
||||
h32 = p.z + primes.w + p.x * primes.y;
|
||||
h32 = primes.z * ((h32 << 17) | (h32 >> (32 - 17)));
|
||||
h32 += p.y * primes.y;
|
||||
h32 = primes.z * ((h32 << 17) | (h32 >> (32 - 17)));
|
||||
h32 = primes.x * (h32 ^ (h32 >> 15));
|
||||
h32 = primes.y * (h32 ^ (h32 >> 13));
|
||||
return h32 ^ (h32 >> 16);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// https://www.pcg-random.org/
|
||||
//-----------------------------------------------------------------------
|
||||
uint pcg(inout uint state)
|
||||
{
|
||||
uint prev = state * 747796405u + 2891336453u;
|
||||
uint word = ((prev >> ((prev >> 28u) + 4u)) ^ prev) * 277803737u;
|
||||
state = prev;
|
||||
return (word >> 22u) ^ word;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Generate a random float in [0, 1) given the previous RNG state
|
||||
//-----------------------------------------------------------------------
|
||||
float rand(inout uint seed)
|
||||
{
|
||||
uint r = pcg(seed);
|
||||
return float(r) * (1.F / float(0xffffffffu));
|
||||
}
|
||||
|
||||
|
||||
#endif // RANDOM_GLSL
|
||||
70
raytracer/nvpro_core/nvvkhl/shaders/ray_util.glsl
Normal file
70
raytracer/nvpro_core/nvvkhl/shaders/ray_util.glsl
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef RAY_UTIL_H
|
||||
#define RAY_UTIL_H 1
|
||||
|
||||
precision highp float;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Avoiding self intersections
|
||||
//-----------------------------------------------------------------------
|
||||
vec3 offsetRay(in vec3 p, in vec3 n)
|
||||
{
|
||||
// Smallest epsilon that can be added without losing precision is 1.19209e-07, but we play safe
|
||||
const float epsilon = 1.0f / 65536.0f; // Safe epsilon
|
||||
|
||||
float magnitude = length(p);
|
||||
float offset = epsilon * magnitude;
|
||||
// multiply the direction vector by the smallest offset
|
||||
vec3 offsetVector = n * offset;
|
||||
// add the offset vector to the starting point
|
||||
vec3 offsetPoint = p + offsetVector;
|
||||
|
||||
return offsetPoint;
|
||||
}
|
||||
|
||||
// Hacking the shadow terminator
|
||||
// https://jo.dreggn.org/home/2021_terminator.pdf
|
||||
// p : point of intersection
|
||||
// p[a..c]: position of the triangle
|
||||
// n[a..c]: normal of the triangle
|
||||
// bary: barycentric coordinate of the hit position
|
||||
// return the offset position
|
||||
vec3 pointOffset(vec3 p, vec3 pa, vec3 pb, vec3 pc, vec3 na, vec3 nb, vec3 nc, vec3 bary)
|
||||
{
|
||||
vec3 tmpu = p - pa;
|
||||
vec3 tmpv = p - pb;
|
||||
vec3 tmpw = p - pc;
|
||||
|
||||
float dotu = min(0.0F, dot(tmpu, na));
|
||||
float dotv = min(0.0F, dot(tmpv, nb));
|
||||
float dotw = min(0.0F, dot(tmpw, nc));
|
||||
|
||||
tmpu -= dotu * na;
|
||||
tmpv -= dotv * nb;
|
||||
tmpw -= dotw * nc;
|
||||
|
||||
vec3 pP = p + tmpu * bary.x + tmpv * bary.y + tmpw * bary.z;
|
||||
|
||||
return pP;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
53
raytracer/nvpro_core/nvvkhl/shaders/sky.comp
Normal file
53
raytracer/nvpro_core/nvvkhl/shaders/sky.comp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2022 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int8 : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
|
||||
#include "dh_sky.h"
|
||||
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
layout(set = 0, binding = eSkyOutImage) writeonly uniform image2D g_out_hdr;
|
||||
layout(set = 0, binding = eSkyParam) uniform SkyInfo_
|
||||
{
|
||||
ProceduralSkyShaderParameters skyInfo;
|
||||
};
|
||||
|
||||
|
||||
layout(push_constant) uniform SkyDomePushConstant_
|
||||
{
|
||||
SkyPushConstant pc;
|
||||
};
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
const vec2 pixel_center = vec2(gl_GlobalInvocationID.xy) + vec2(0.5F);
|
||||
const vec2 in_uv = pixel_center / vec2(imageSize(g_out_hdr));
|
||||
const vec2 d = in_uv * 2.0 - 1.0;
|
||||
vec3 direction = normalize(vec3(pc.mvp * vec4(d.x, d.y, 1.0F, 1.0F)));
|
||||
|
||||
vec3 color = proceduralSky(skyInfo, direction, 0.0F);
|
||||
|
||||
imageStore(g_out_hdr, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1.0F));
|
||||
}
|
||||
55
raytracer/nvpro_core/nvvkhl/shaders/tonemapper.comp
Normal file
55
raytracer/nvpro_core/nvvkhl/shaders/tonemapper.comp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "dh_tonemap.h"
|
||||
#include "dh_comp.h"
|
||||
|
||||
|
||||
layout(set = 0, binding = eTonemapperInput) uniform sampler2D g_image;
|
||||
layout(set = 0, binding = eTonemapperOutput) writeonly uniform image2D g_out_image;
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
{
|
||||
Tonemapper tm;
|
||||
};
|
||||
|
||||
layout(local_size_x = WORKGROUP_SIZE, local_size_y = WORKGROUP_SIZE, local_size_z = 1) in;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
if(gl_GlobalInvocationID.xy != clamp(gl_GlobalInvocationID.xy, vec2(0.0F), imageSize(g_out_image)))
|
||||
return;
|
||||
|
||||
const vec2 pixel_center = vec2(gl_GlobalInvocationID.xy) + vec2(0.5F);
|
||||
const vec2 i_uv = pixel_center / vec2(imageSize(g_out_image));
|
||||
|
||||
vec4 R = texture(g_image, i_uv);
|
||||
|
||||
if(tm.isActive == 1)
|
||||
R.xyz = applyTonemap(tm, R.xyz, i_uv);
|
||||
R.a = 1.0F; // No alpha, or it will blend with ImGui black viewport
|
||||
|
||||
imageStore(g_out_image, ivec2(gl_GlobalInvocationID.xy), R);
|
||||
}
|
||||
47
raytracer/nvpro_core/nvvkhl/shaders/tonemapper.frag
Normal file
47
raytracer/nvpro_core/nvvkhl/shaders/tonemapper.frag
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#version 450
|
||||
|
||||
#extension GL_GOOGLE_include_directive : enable
|
||||
|
||||
#include "dh_tonemap.h"
|
||||
|
||||
layout(location = 0) in vec2 i_uv;
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
layout(set = 0, binding = eTonemapperInput) uniform sampler2D g_image;
|
||||
|
||||
|
||||
layout(push_constant) uniform shaderInformation
|
||||
{
|
||||
Tonemapper tm;
|
||||
};
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 R = texture(g_image, i_uv);
|
||||
|
||||
if(tm.isActive == 1)
|
||||
R.xyz = applyTonemap(tm, R.xyz, i_uv);
|
||||
|
||||
o_color = R;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue