extern "C" int main(int ac, char** av)
{
try {
Model* model = loadOBJ("../../models/sponza.obj");
Camera camera = { /*from*/vec3f(-1293.07f, 154.681f, -0.7304f),
/* at */model->bounds.center() - vec3f(0,400,0),
/* up */vec3f(0.f,1.f,0.f) };
// something approximating the scale of the world, so the
// camera knows how much to move for any given user interaction:
const float worldScale = length(model->bounds.span());
SampleWindow* window = new SampleWindow("Optix 7 Course Example",
model, camera, worldScale);
window->run();
}
catch (std::runtime_error& e) {
std::cout << GDT_TERMINAL_RED << "FATAL ERROR: " << e.what()
<< GDT_TERMINAL_DEFAULT << std::endl;
std::cout << "Did you forget to copy sponza.obj and sponza.mtl into your optix7course/models directory?" << std::endl;
exit(1);
}
return 0;
}
extern "C" __global__ void __closesthit__shadow()
{
/* not going to be used ... */
}
extern "C" __global__ void __closesthit__radiance()
{
const TriangleMeshSBTData &sbtData
= *(const TriangleMeshSBTData*)optixGetSbtDataPointer();
PRD &prd = *getPRD<PRD>();
// ------------------------------------------------------------------
// gather some basic hit information
// ------------------------------------------------------------------
const int primID = optixGetPrimitiveIndex();
const vec3i index = sbtData.index[primID];
const float u = optixGetTriangleBarycentrics().x;
const float v = optixGetTriangleBarycentrics().y;
// ------------------------------------------------------------------
// compute normal, using either shading normal (if avail), or
// geometry normal (fallback)
// ------------------------------------------------------------------
const vec3f &A = sbtData.vertex[index.x];
const vec3f &B = sbtData.vertex[index.y];
const vec3f &C = sbtData.vertex[index.z];
vec3f Ng = cross(B-A,C-A);
vec3f Ns = (sbtData.normal)
? ((1.f-u-v) * sbtData.normal[index.x]
+ u * sbtData.normal[index.y]
+ v * sbtData.normal[index.z])
: Ng;
// ------------------------------------------------------------------
// face-forward and normalize normals
// ------------------------------------------------------------------
const vec3f rayDir = optixGetWorldRayDirection();
if (dot(rayDir,Ng) > 0.f) Ng = -Ng;
Ng = normalize(Ng);
if (dot(Ng,Ns) < 0.f)
Ns -= 2.f*dot(Ng,Ns)*Ng;
Ns = normalize(Ns);
// ------------------------------------------------------------------
// compute diffuse material color, including diffuse texture, if
// available
// ------------------------------------------------------------------
vec3f diffuseColor = sbtData.color;
if (sbtData.hasTexture && sbtData.texcoord) {
const vec2f tc
= (1.f-u-v) * sbtData.texcoord[index.x]
+ u * sbtData.texcoord[index.y]
+ v * sbtData.texcoord[index.z];
vec4f fromTexture = tex2D<float4>(sbtData.texture,tc.x,tc.y);
diffuseColor *= (vec3f)fromTexture;
}
// start with some ambient term
vec3f pixelColor = (0.1f + 0.2f*fabsf(dot(Ns,rayDir)))*diffuseColor;
// ------------------------------------------------------------------
// compute shadow
// ------------------------------------------------------------------
const vec3f surfPos
= (1.f-u-v) * sbtData.vertex[index.x]
+ u * sbtData.vertex[index.y]
+ v * sbtData.vertex[index.z];
const int numLightSamples = NUM_LIGHT_SAMPLES;
for (int lightSampleID=0;lightSampleID<numLightSamples;lightSampleID++) {
// produce random light sample
const vec3f lightPos
= optixLaunchParams.light.origin
+ prd.random() * optixLaunchParams.light.du
+ prd.random() * optixLaunchParams.light.dv;
vec3f lightDir = lightPos - surfPos;
float lightDist = gdt::length(lightDir);
lightDir = normalize(lightDir);
// trace shadow ray:
const float NdotL = dot(lightDir,Ns);
if (NdotL >= 0.f) {
vec3f lightVisibility = 0.f;
// the values we store the PRD pointer in:
uint32_t u0, u1;
packPointer( &lightVisibility, u0, u1 );
optixTrace(optixLaunchParams.traversable,
surfPos + 1e-3f * Ng,
lightDir,
1e-3f, // tmin
lightDist * (1.f-1e-3f), // tmax
0.0f, // rayTime
OptixVisibilityMask( 255 ),
// For shadow rays: skip any/closest hit shaders and terminate on first
// intersection with anything. The miss shader is used to mark if the
// light was visible.
OPTIX_RAY_FLAG_DISABLE_ANYHIT
| OPTIX_RAY_FLAG_TERMINATE_ON_FIRST_HIT
| OPTIX_RAY_FLAG_DISABLE_CLOSESTHIT,
SHADOW_RAY_TYPE, // SBT offset
RAY_TYPE_COUNT, // SBT stride
SHADOW_RAY_TYPE, // missSBTIndex
u0, u1 );
pixelColor
+= lightVisibility
* optixLaunchParams.light.power
* diffuseColor
* (NdotL / (lightDist*lightDist*numLightSamples));
}
}
prd.pixelColor = pixelColor;
}
extern "C" __global__ void __anyhit__radiance()
{ /*! for this simple example, this will remain empty */ }
extern "C" __global__ void __anyhit__shadow()
{ /*! not going to be used */ }
//------------------------------------------------------------------------------
// miss program that gets called for any ray that did not have a
// valid intersection
//
// as with the anyhit/closest hit programs, in this example we only
// need to have _some_ dummy function to set up a valid SBT
// ------------------------------------------------------------------------------
extern "C" __global__ void __miss__radiance()
{
PRD &prd = *getPRD<PRD>();
// set to constant white as background color
prd.pixelColor = vec3f(1.f);
}
extern "C" __global__ void __miss__shadow()
{
// we didn't hit anything, so the light is visible
vec3f &prd = *(vec3f*)getPRD<vec3f>();
prd = vec3f(1.f);
}
Comments | NOTHING