OptiX - optix7course Example 05 분석

선비Sunbei·2023년 9월 2일
0

OptiX

목록 보기
19/25
post-thumbnail
post-custom-banner
https://github.com/ingowald/optix7course

마찬가지로 이전 Example에서 변경된 점만 설명한다.

// main.cpp
 /*! main entry point to this example - initially optix, print hello
    world, then exit */
  extern "C" int main(int ac, char **av)
  {
    try {
      TriangleMesh model;
      // 100x100 thin ground plane
      model.addCube(vec3f(0.f,-1.5f,0.f),vec3f(10.f,.1f,10.f));
      // a unit cube centered on top of that
      model.addCube(vec3f(0.f,0.f,0.f),vec3f(2.f,2.f,2.f));
      model.color = vec3f(.2f,.8f,.2f);
      
      Camera camera = { /*from*/vec3f(-10.f,2.f,-12.f),
                        /* at */vec3f(0.f,0.f,0.f),
                        /* 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 = 10.f;

      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;
      exit(1);
    }
    return 0;
  }

TriangleMesh에 color가 추가되었다.

// SampleRender.h
  struct TriangleMesh {
    /*! add a unit cube (subject to given xfm matrix) to the current
        triangleMesh */
    void addUnitCube(const affine3f &xfm);
    
    //! add aligned cube aith front-lower-left corner and size
    void addCube(const vec3f &center, const vec3f &size);
    
    std::vector<vec3f> vertex;
    std::vector<vec3i> index;
    vec3f              color;
  };
  
// SampleRenderer.cpp
  void SampleRenderer::buildSBT()
  {
    // ------------------------------------------------------------------
    // build raygen records
    // ------------------------------------------------------------------
    std::vector<RaygenRecord> raygenRecords;
    for (int i=0;i<raygenPGs.size();i++) {
      RaygenRecord rec;
      OPTIX_CHECK(optixSbtRecordPackHeader(raygenPGs[i],&rec));
      rec.data = nullptr; /* for now ... */
      raygenRecords.push_back(rec);
    }
    raygenRecordsBuffer.alloc_and_upload(raygenRecords);
    sbt.raygenRecord = raygenRecordsBuffer.d_pointer();

    // ------------------------------------------------------------------
    // build miss records
    // ------------------------------------------------------------------
    std::vector<MissRecord> missRecords;
    for (int i=0;i<missPGs.size();i++) {
      MissRecord rec;
      OPTIX_CHECK(optixSbtRecordPackHeader(missPGs[i],&rec));
      rec.data = nullptr; /* for now ... */
      missRecords.push_back(rec);
    }
    missRecordsBuffer.alloc_and_upload(missRecords);
    sbt.missRecordBase          = missRecordsBuffer.d_pointer();
    sbt.missRecordStrideInBytes = sizeof(MissRecord);
    sbt.missRecordCount         = (int)missRecords.size();

    // ------------------------------------------------------------------
    // build hitgroup records
    // ------------------------------------------------------------------
    int numObjects = 1;
    std::vector<HitgroupRecord> hitgroupRecords;
    for (int i=0;i<numObjects;i++) {
      // we only have a single object type so far
      int objectType = 0;
      HitgroupRecord rec;
      OPTIX_CHECK(optixSbtRecordPackHeader(hitgroupPGs[objectType],&rec));
      rec.data.vertex = (vec3f*)vertexBuffer.d_pointer();
      rec.data.index  = (vec3i*)indexBuffer.d_pointer();
      rec.data.color  = model.color;
      hitgroupRecords.push_back(rec);
    }
    hitgroupRecordsBuffer.alloc_and_upload(hitgroupRecords);
    sbt.hitgroupRecordBase          = hitgroupRecordsBuffer.d_pointer();
    sbt.hitgroupRecordStrideInBytes = sizeof(HitgroupRecord);
    sbt.hitgroupRecordCount         = (int)hitgroupRecords.size();
  }

ratgenRecords와 missRecords는 동일하고, hit group의 record만 변경되었다.

// SampleRenderer.cpp
  /*! SBT record for a hitgroup program */
  struct __align__( OPTIX_SBT_RECORD_ALIGNMENT ) HitgroupRecord
  {
    __align__( OPTIX_SBT_RECORD_ALIGNMENT ) char header[OPTIX_SBT_RECORD_HEADER_SIZE];
    TriangleMeshSBTData data;
  };

TriangleMeshSBTData를 Record에 저장한다.

// LaunchParams.h
#pragma once

#include "gdt/math/vec.h"
#include "optix7.h"

namespace osc {
  using namespace gdt;
  
  struct TriangleMeshSBTData {
    vec3f  color;
    vec3f *vertex;
    vec3i *index;
  };
  ...

} // ::osc

rec.data.vertex, rec.data.index의 값인 vertexBuffer, indexBuffer는 buildAccel()함수에서 alloc_and_upload된 값들이다.
color는 main 함수에서 설정한 color이다.

// devicePrograms.cu
  extern "C" __global__ void __closesthit__radiance()
  {
    const TriangleMeshSBTData &sbtData
      = *(const TriangleMeshSBTData*)optixGetSbtDataPointer();

    // compute normal:
    const int   primID = optixGetPrimitiveIndex();
    const vec3i index  = sbtData.index[primID];
    const vec3f &A     = sbtData.vertex[index.x];
    const vec3f &B     = sbtData.vertex[index.y];
    const vec3f &C     = sbtData.vertex[index.z];
    const vec3f Ng     = normalize(cross(B-A,C-A));

    const vec3f rayDir = optixGetWorldRayDirection();
    const float cosDN  = 0.2f + .8f*fabsf(dot(rayDir,Ng));
    vec3f &prd = *(vec3f*)getPRD<vec3f>();
    prd = cosDN * sbtData.color;
  }

optixGetSbtDataPointer() 함수는 현재 program에 해당하는 현재 활성 SBT record의 (헤더 만큼 stride한) 데이터 영역에 대한 pointer를 반환한다. (CUdeviceptr)

Ng는 해당 삼각형의 법선 벡터이다.
optixGetWorldRayDirection() 함수를 통해서 world space에서의 ray vector를 얻는다.

cosDN에서 0.2f는 ambient color를 의미하고, .8f*fabsf(dot(rayDir,Ng))는 diffuse color를 의미한다.
여기서는 camera 위치가 광원(light)가 된다.

post-custom-banner

0개의 댓글