# 조명(Lighting)과 카메라(Camera) 설정

Isaac Sim에서 로봇 시뮬레이션을 효과적으로 구현하기 위해서는 조명과 카메라의 설정이 매우 중요하다. 이들 요소는 시뮬레이션의 사실성을 높이며, 로봇의 환경을 정확하게 인식하고 상호작용할 수 있도록 한다. 이 섹션에서는 조명과 카메라의 기본 개념부터 고급 설정까지 다양한 부분을 다룰 것이다.

#### 조명(Lighting) 설정

조명은 시뮬레이션에서 물체의 외형을 인식할 수 있도록 해주는 중요한 요소이다. Isaac Sim에서는 다양한 조명 설정을 통해 환경을 세밀하게 조정할 수 있다. 기본적으로 사용되는 조명 유형은 다음과 같다:

1. **포인트 라이트(Point Light)**: 모든 방향으로 균일하게 빛을 방출하는 조명이다. 주로 로봇이나 특정 객체 주변을 비추는 데 사용된다.
2. **스포트라이트(Spotlight)**: 특정 방향으로 집중적으로 빛을 방출하는 조명이다. 로봇의 이동 경로를 강조하거나 특정 영역을 강조하는 데 유용하다.
3. **디렉셔널 라이트(Directional Light)**: 무한히 멀리 있는 빛의 원천에서 일정한 방향으로 빛을 방출하는 조명이다. 일반적으로 태양광을 시뮬레이션하는 데 사용된다.
4. **앰비언트 라이트(Ambient Light)**: 모든 방향에서 동일한 강도로 비추는 빛이다. 환경의 기본적인 밝기를 설정하는 데 사용된다.

이 외에도 다양한 조명 설정을 통해 물체의 그림자나 반사 등 세부적인 사항까지 제어할 수 있다.

**조명 설정을 위한 코드 예시 (C++)**

```cpp
#include <gazebo/gazebo.hh>
#include <gazebo/physics/World.hh>
#include <gazebo/rendering/Lighting.hh>

void setupLighting()
{
    gazebo::rendering::LightingPtr lighting = gazebo::rendering::get_scene()->GetLighting();
    
    // Ambient light 설정
    lighting->SetAmbientColor(0.3, 0.3, 0.3, 1.0);
    
    // Directional light 설정
    gazebo::rendering::LightPtr dirLight = gazebo::rendering::get_scene()->CreateLight("directionalLight");
    dirLight->SetType(gazebo::rendering::Light::LIGHT_DIRECTIONAL);
    dirLight->SetDiffuseColor(1.0, 1.0, 1.0, 1.0);
    dirLight->SetDirection(0, -1, -1);
    
    // Spot light 설정
    gazebo::rendering::LightPtr spotLight = gazebo::rendering::get_scene()->CreateLight("spotLight");
    spotLight->SetType(gazebo::rendering::Light::LIGHT_SPOT);
    spotLight->SetDiffuseColor(1.0, 0.0, 0.0, 1.0);
    spotLight->SetDirection(1, 0, -1);
    spotLight->SetPosition(2, 2, 5);
    spotLight->SetSpotOuterAngle(0.6);
}
```

위 코드는 Gazebo의 `rendering::Lighting` API를 사용하여 시뮬레이션의 조명을 설정하는 예시이다. `ambient` 조명, `directional` 라이트, 그리고 `spot` 라이트를 각각 설정하는 방법을 보여준다.

#### 카메라(Camera) 설정

Isaac Sim에서 카메라는 로봇의 시각적 정보를 얻는 데 중요한 역할을 한다. 카메라는 기본적으로 로봇의 센서 역할을 하며, 환경을 인식하고 이를 처리할 수 있도록 한다. 카메라는 시뮬레이션 내에서 다양한 시점으로 설정할 수 있다.

**카메라의 기본 설정**

1. **카메라 위치(Camera Position)**: 카메라의 위치는 로봇의 동작 및 환경 인식에 중요한 영향을 미친다. 카메라는 고정된 위치에서만 작동하는 것이 아니라, 움직이는 로봇에 맞춰 실시간으로 이동하거나 회전할 수 있다.
2. **카메라 뷰(Camera View)**: 카메라의 시점은 로봇의 목적에 맞게 조정할 수 있다. 예를 들어, 로봇의 앞, 뒤, 좌, 우 등을 바라보는 카메라 뷰를 설정할 수 있다.
3. **카메라 해상도(Camera Resolution)**: 카메라의 해상도는 로봇이 처리할 수 있는 시각적 정보를 얼마나 세밀하게 받을 수 있는지를 결정한다. 해상도가 높을수록 더 많은 데이터를 생성하지만, 더 많은 처리 능력이 필요하다.
4. **카메라의 렌더링 방식(Rendering Mode)**: Isaac Sim에서는 카메라가 수집할 수 있는 정보의 종류를 선택할 수 있다. 예를 들어, 일반적인 RGB 이미지를 획득할 수도 있고, 깊이 정보(Depth), 텍스처(Texture) 등을 획득할 수도 있다.

**카메라 설정을 위한 코드 예시 (C++)**

```cpp
#include <gazebo/gazebo.hh>
#include <gazebo/physics/World.hh>
#include <gazebo/rendering/Camera.hh>

void setupCamera()
{
    gazebo::rendering::CameraPtr camera = gazebo::rendering::get_scene()->CreateCamera("camera");
    
    // 카메라 위치 설정
    camera->SetPosition(2, 3, 5);
    camera->SetRotation(0, 0, 0);
    
    // 카메라의 해상도 설정
    camera->SetImageWidth(1920);
    camera->SetImageHeight(1080);
    
    // 카메라 렌더링 모드 설정 (RGB, Depth, etc.)
    camera->SetCaptureDepth(true);
    camera->SetCaptureColor(true);
    
    // 카메라 뷰 설정
    camera->SetViewDirection(1, 0, 0);  // 카메라가 바라보는 방향 설정
}
```

위 코드는 Gazebo에서 카메라의 기본 설정을 구성하는 예시이다. 카메라 위치, 해상도, 캡처할 정보(색상 및 깊이) 등을 설정할 수 있다.

조명 설정에서는 물리 기반 렌더링(Physically Based Rendering, PBR)을 고려할 수 있다. 물리 기반 렌더링은 실제 광학 현상을 모델링하여 더욱 사실적인 시각 효과를 제공한다. 이를 통해 재질(Material)과 표면 특성에 따라 빛이 반사되는 양상을 세밀하게 표현할 수 있다. 반사 계수나 굴절률 등의 물리적 성질을 기반으로 광선이 표면에서 어떻게 상호작용하는지를 계산하기 때문에, 자연스러운 광원과 그림자를 생성할 수 있다.

조명 환경을 더욱 정교하게 만들기 위해서는 환경 맵(Environment Map) 또는 HDR(High Dynamic Range) 이미지 기반 조명을 사용할 수도 있다. HDR 이미지를 사용하면 넓은 범위의 광도와 색상 정보를 담을 수 있어, 장면의 디테일이 보다 뚜렷해진다. Isaac Sim에서는 이러한 배경 조명 또는 스카이돔(Skydome) 기능을 활용하여 원하는 시간대나 날씨 조건에 맞는 조명 환경을 생성할 수 있다.

조명과 관련하여 궁극적인 목표는 렌더링 방정식(Rendering Equation)을 보다 정확하게 구현하는 것이다. 렌더링 방정식은 장면 내에서 빛이 상호작용하는 과정을 적분 형태로 표현하며, 물리 기반 렌더링의 근간이 된다. 한 점 $x$에서 방향 $\omega$로 방출되는 복사휘도 $\mathbf{L}(x \rightarrow \omega)$를 표현하면 다음과 같다.

$$
\begin{align} \mathbf{L}(x \rightarrow \omega) &= \mathbf{L\_e}(x \rightarrow \omega) \\
&+ \int\_{\Omega} \mathbf{f\_r}(x, \omega', \omega) ,\mathbf{L}(x \rightarrow \omega') (\mathbf{n}\cdot \omega') , d\omega' \end{align}
$$

위 식에서 ${L\_e}(x \rightarrow \omega)$는 방출 복사휘도(Emission)를 나타내고, $\mathbf{f\_r}(x, \omega', \omega)$는 재질(Material)의 BRDF(Bidirectional Reflectance Distribution Function)에 해당한다. $\mathbf{n}$은 표면의 법선 벡터이며, $\omega'$는 적분 영역 $\Omega$에 포함되는 모든 입사 방향 벡터를 의미한다.

카메라 모델에서는 시뮬레이션의 광학 시스템을 단순화하거나 실제 물리적 현상을 반영하는 방식을 택할 수 있다. 단순한 카메라 모델은 이상적인 핀홀 카메라(Pinhole Camera) 방식을 적용하지만, 고급 시뮬레이션에서는 실제 렌즈의 초점 거리(Focal Length), 조리개(Aperture), 왜곡(Distortion) 파라미터 등을 반영하는 물리 기반 카메라(Physical Camera) 모델을 사용할 수 있다. 실제로 로봇 비전에서 요구하는 왜곡 보정(Distortion Correction) 알고리즘의 효과를 확인하고자 한다면, 시뮬레이션 환경에서 광학적 왜곡 요소를 포함하는 카메라 모델을 적용하여 테스트할 수 있다.

조명과 카메라 설정을 종합적으로 다룰 때 주의해야 할 점은 성능 상의 고려다. 높은 해상도의 카메라를 여러 대 구동하거나 복잡한 조명 효과를 구현하면 시뮬레이션에 필요한 연산량이 크게 증가한다. Isaac Sim에서는 GPU 가속을 통한 병렬 처리가 가능하지만, 실시간 시뮬레이션 성능을 유지해야 한다면 무작정 해상도나 조명 품질을 끌어올리는 것은 바람직하지 않을 수 있다. 시뮬레이션 목적에 맞는 적절한 성능 타협점을 찾는 것이 중요하다.

고급 카메라 사용 예시로 물체 인식 테스트 시나리오를 생각해볼 수 있다. 카메라 여러 대를 장면에 배치하여 객체를 다양한 시점에서 관측하고, 동적으로 조명의 색온도나 강도를 변화시키면서 로봇의 인식 알고리즘이 얼마나 견고하게 작동하는지 측정할 수 있다. 이를 도메인 랜덤화(Domain Randomization) 기법과 결합하면, 로봇 비전에 필요한 학습 데이터를 다양하게 확보하고 실제 환경에서의 불확실성을 줄이는 데 도움이 된다.

고급 조명과 카메라를 설정하는 코드 예시(Isaac Sim의 C++ API 가정)는 다음과 같이 확장할 수 있다.

```cpp
#include <isaac_sim/isaac_sim.hh>

using namespace isaac_sim;

void advancedLightingAndCameraSetup()
{
    // 환경 맵 기반 조명 설정
    EnvironmentLightingPtr envLighting = get_scene()->GetEnvironmentLighting();
    envLighting->LoadHDR("path/to/HDR_image.hdr");
    envLighting->SetIntensity(1.5);

    // 물리 기반 카메라 생성
    CameraPtr physicalCamera = get_scene()->CreateCamera("PhysicalCamera");
    physicalCamera->EnablePhysicalProperties(true);
    physicalCamera->SetFocalLength(35.0f);       // mm 단위 가정
    physicalCamera->SetAperture(2.8f);          // f-stop 값
    physicalCamera->SetDistortionParameters(0.1f, -0.05f, 0.001f, 0.0f);

    // 카메라 초기 위치 및 방향
    physicalCamera->SetPosition(0.0, 1.0, 2.0);
    physicalCamera->LookAt(0.0, 0.0, 0.0);

    // 고화질 렌더링 모드
    physicalCamera->SetResolution(2560, 1440);
    physicalCamera->SetCaptureColor(true);
    physicalCamera->SetCaptureDepth(true);
    physicalCamera->SetCaptureSegmentation(false);
    
    // 조명 - 고급 스포트라이트
    LightPtr advancedSpotLight = get_scene()->CreateLight("AdvancedSpot");
    advancedSpotLight->SetType(Light::LIGHT_SPOT);
    advancedSpotLight->SetDiffuseColor(1.0, 0.9, 0.8, 1.0);
    advancedSpotLight->SetSpecularColor(1.0, 1.0, 1.0, 1.0);
    advancedSpotLight->SetPosition(2.0, 3.0, 5.0);
    advancedSpotLight->SetDirection(-0.5, -0.5, -1.0);
    advancedSpotLight->SetSpotInnerAngle(0.3f);
    advancedSpotLight->SetSpotOuterAngle(0.7f);
    advancedSpotLight->EnableShadows(true);
}
```

위 코드는 가상의 API를 예시로 한 것이며, 실제 Isaac Sim 버전에 따라 함수명이나 클래스명이 달라질 수 있다. HDR 이미지를 로드하여 환경 조명을 설정하고, 왜곡 파라미터를 포함한 물리 기반 카메라를 구성한다. 고급 스포트라이트를 생성하여 그림자를 활성화하고 내부·외부 각도를 세밀하게 조절함으로써 자연스러운 음영 효과를 구현한다.

조명과 카메라를 보다 현실적으로 다루기 위해서는 물리 기반 시뮬레이션 이외에도 후처리(포스트 프로세싱) 효과나 노이즈 모델 등을 고려할 수 있다. 예를 들어, 현실의 카메라는 센서에서 전자 신호를 증폭하는 과정에서 열적 잡음(Thermal Noise)이나 감도 차이(Gain Variation) 등이 발생한다. Isaac Sim 내에서 이를 재현하기 위해서는 카메라 센서 모델에 노이즈 파라미터를 적용하여 시뮬레이션 이미지에 무작위 잡음을 추가할 수 있다. 노이즈가 추가되면 물체 인식이나 경로 추정 알고리즘이 실제 환경에서 요구되는 정확도에 어느 정도 근접하게 작동하는지를 확인할 수 있다.

카메라 투영(Projection) 모델에서는 이상적인 핀홀 모델뿐 아니라 렌즈 왜곡을 반영할 수 있다. 실제 카메라에서 발생하는 왜곡으로는 방사왜곡(Radial Distortion)과 접선왜곡(Tangential Distortion)이 대표적이다. 방사왜곡은 화상의 중심으로부터 멀어질수록 픽셀이 바깥쪽 또는 안쪽으로 치우치게 되는 현상이며, 접선왜곡은 카메라 조립 시 센서가 렌즈 축에 대해 약간 기울어져 생긴다. Isaac Sim에서는 이러한 왜곡 계수를 지정하여 시뮬레이션 이미지가 실제 촬영 결과와 유사하게 나타나도록 할 수 있다.

왜곡 계수를 다루는 대표적인 수학적 표현은 다음과 같다.

$$
\begin{align} x'\_d &= x'\bigl(1 + k\_1 r^2 + k\_2 r^4 + k\_3 r^6\bigr)  \\
&+ 2p\_1 x'y' + p\_2\bigl(r^2 + 2x'^2\bigr),  \\
y'\_d &= y'\bigl(1 + k\_1 r^2 + k\_2 r^4 + k\_3 r^6\bigr)  \\
&+ p\_1\bigl(r^2 + 2y'^2\bigr) + 2p\_2 x'y', \end{align}
$$

여기서 $x', y'$는 카메라 내부 파라미터(초점 거리 $f\_x, f\_y$와 주점 좌표 $c\_x, c\_y$)를 적용해 정규화된 좌표를 나타내고, $x'\_d, y'\_d$는 왜곡이 적용된 최종 좌표를 의미한다. $k3k\_1, k\_2, k\_3$는 방사왜곡 계수들이고 $p\_1, p\_2$는 접선왜곡 계수다. $r = \sqrt{x'^2 + y'^2}$는 이미지 평면 상에서 광축 중심으로부터의 거리다.

이러한 모델을 활용해 시뮬레이션 카메라에 왜곡을 부여하고, 로봇 비전 알고리즘에서 왜곡 보정(Distortion Correction) 과정을 테스트할 수 있다. 실제 환경에서 카메라 교정(Camera Calibration) 절차를 거쳐 얻은 왜곡 파라미터를 Isaac Sim에 그대로 적용하면, 시뮬레이션 환경에서 실제 환경에 가까운 영상 처리를 수행할 수 있게 된다.

조명의 후처리 효과로는 블룸(Bloom), SSR(Screen Space Reflection), SSAO(Screen Space Ambient Occlusion) 등이 있다. 블룸 효과는 밝은 빛이 센서에 과도하게 노출되어 번지는 것처럼 보이게 하며, SSR은 장면에서 반사 표면에 비친 환경을 스크린 공간에서 재현한다. SSAO는 물체 표면에 직접적으로 조명이 닿지 않는 미세한 음영 영역을 계산한다. Isaac Sim 내의 렌더링 파이프라인에서 이를 활성화하면 사실적인 실내·실외 환경을 구성할 수 있다.

카메라 노출(Exposure)도 중요한 요인이다. 노출은 실제 카메라에서 ISO, 조리개 크기, 셔터 스피드 등으로 결정되며, 시뮬레이션에서도 이와 유사한 파라미터를 조정할 수 있다. 예를 들어 셔터 스피드가 짧으면 노이즈는 줄어드나 밝기가 낮아지고, 셔터 스피드가 길면 움직임이 많은 장면에서 모션 블러(Motion Blur)가 발생할 수 있다. 이를 시뮬레이션에서도 재현할 수 있으며, 로봇 비전 알고리즘의 성능에 어떠한 영향을 미치는지 분석할 수 있다.

초점 심도(Depth of Field) 설정을 통해 특정 거리의 물체만 선명하게 보이게 만들고 그 앞뒤를 흐릿하게 만드는 효과도 가능하다. 이는 실제 카메라에서 조리개 값에 따라 심도가 달라지는 원리를 반영한 것이다. Isaac Sim에서 심도를 조절하면 시뮬레이션 결과물에 보다 전문적인 시네마틱 표현이 가능하며, 로봇의 시야가 특정 물체에만 집중하도록 시각화할 수 있다.

이처럼 조명과 카메라 설정은 단순히 시각적 품질을 향상하는 데 그치지 않고, 로봇 비전과 인식 알고리즘, 그리고 시뮬레이션 성능에 직접적인 영향을 미친다. 목표로 하는 시나리오가 무엇이냐에 따라 고품질의 렌더링이 필요할 수도 있고, 실시간성을 우선해야 할 수도 있다. 이러한 요소들을 종합적으로 고려하여 조명과 카메라 파라미터를 조정하는 것이 Isaac Sim 시뮬레이션의 핵심이다.

조명과 카메라를 Isaac Sim에서 동적으로 변화시키는 것은 시뮬레이션 환경의 사실성을 한층 끌어올린다. 예를 들어 이동형 로봇이 어두운 창고와 밝은 실외를 오갈 때, 조명의 밝기와 색온도를 실시간으로 변경할 수 있다. 이를 통해 센서가 급작스럽게 바뀌는 광량에 어떻게 반응하는지를 시뮬레이션하고, 카메라의 자동 노출 또는 자동 화이트밸런스 알고리즘이 정상적으로 작동하는지 점검할 수 있다. 이러한 방식으로 환경의 다양한 시나리오를 재현하여 로봇이 예기치 않은 조명 변화를 얼마나 잘 대처하는지를 측정할 수 있다.

실시간 레이트레이싱(Ray Tracing)을 활용하면 광선 추적을 통해 물리적으로 정확한 그림자, 반사, 굴절 등을 시뮬레이션할 수 있다. Isaac Sim의 최신 버전은 RTX GPU 같은 하드웨어 가속 기능을 사용해 레이트레이싱을 지원하므로, 고급 렌더링을 수행할 때도 비교적 빠른 프레임레이트를 확보할 수 있다. 레이트레이싱 기반 조명은 화면에서 잘 드러나지 않던 미세한 반사와 간접 조명(Indirect Lighting)까지 재현하여, 로봇이 반사나 반투명 물체를 어떻게 감지하는지에 대한 연구에 유용하다. 다만 레이트레이싱은 일반적인 래스터화 렌더링보다 계산량이 많으므로, 매우 큰 장면이나 복잡한 객체가 많을 경우 성능 저하가 발생할 수 있다.

카메라를 여러 대 운영하는 시나리오에서는 시점마다 다른 노이즈나 화질 특성을 적용해볼 수 있다. 어떤 카메라는 저해상도이면서 근적외선(NIR) 이미지 센싱을, 또 다른 카메라는 RGB-D 센서로 깊이 정보를, 그리고 고해상도 카메라는 고정밀 물체 인식을 담당하게 구성할 수도 있다. 이러한 멀티 센서 구성은 실제 로봇 시스템에서 빈번하게 사용된다. Isaac Sim에서 각각의 카메라 센서로부터 얻은 정보를 ROS2 토픽으로 발행하고, ROS2 노드에서 받아서 처리하는 과정을 시뮬레이션해볼 수도 있다. 이때 카메라에서 발생하는 동기화 이슈나 데이터 레이트 차이를 고려해야 하며, Isaac Sim의 내부 시간 축과 ROS2의 시간을 어떻게 맞출지 결정해야 한다.

카메라 이미지를 로봇에게 전달하는 과정에서 Isaac Sim 내부 API를 통해 직접 픽셀 데이터를 획득하거나, 노이즈 파라미터를 거친 후에 ROS2 메시 형식으로 인코딩하여 퍼블리시할 수 있다. 고해상도 영상 데이터는 대역폭이 크므로, 네트워크 트래픽이나 CPU/GPU 사용량을 점검해야 한다. 가능한 한 효율적인 인코딩 방식을 사용하거나, 필요한 경우 프레임 레이트를 낮춰서 보낼 수 있다. 이러한 설정은 실제 물리 환경에서도 네트워크 대역폭 제약과 긴밀히 관련되므로, 시뮬레이션 초기 단계부터 트레이드오프를 모사하는 것이 중요하다.

조명과 카메라가 로봇 제어에 미치는 영향을 연구하기 위해서는 모델 기반 제어나 딥러닝 비전 알고리즘을 함께 실험하는 방법이 있다. 예를 들어 다음 코드는 카메라 데이터를 구독하여 이미지 처리를 수행하는 ROS2 C++ 노드를 Isaac Sim과 연동하는 단편적인 예시다.

```cpp
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>

class ImageSubscriber : public rclcpp::Node
{
public:
    ImageSubscriber() : Node("image_subscriber")
    {
        sub_ = this->create_subscription<sensor_msgs::msg::Image>(
            "/isaac_sim/camera0/image_raw",
            10,
            std::bind(&ImageSubscriber::imageCallback, this, std::placeholders::_1));
    }

private:
    void imageCallback(const sensor_msgs::msg::Image::SharedPtr msg)
    {
        // 이미지 데이터 처리 로직
        // 노이즈나 조명 변화를 고려한 영상 처리
    }

    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_;
};

int main(int argc, char** argv)
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ImageSubscriber>());
    rclcpp::shutdown();
    return 0;
}
```

이 노드는 Isaac Sim에서 퍼블리시하는 카메라 데이터를 구독하고, 콜백 함수에서 이미지 처리를 수행한다. 조명 변화로 인한 명암비(Contrast) 차이, 물체 반사도(Reflectivity)에 따른 인식 성능, 또는 노이즈 유발 상황 등이 충분히 시뮬레이션에 반영된다면, 실제 로봇 제어 시스템의 강인성을 높이는데 도움이 된다.

조명과 카메라를 구성하는 과정을 자동화하려면 스크립트를 통해 Isaac Sim의 장면(Scene)을 동적으로 제어해야 한다. 예를 들어 실험 시나리오가 매 반복마다 서로 다른 조명 상태나 카메라 구도를 갖도록 설정하려는 경우, Isaac Sim의 스크립트 API나 Python 인터페이스를 사용하여 루프 내에서 라이트 파라미터를 조정하고 카메라 위치나 해상도를 바꿀 수 있다. 이렇게 생성된 각 장면에서 로봇의 센서가 수집하는 데이터를 자동으로 저장하면, 후처리에 필요한 대규모 학습 데이터셋을 구축할 수 있다. 이는 일종의 가상 데이터 증강(Virtual Data Augmentation) 기법으로, 로봇 비전 알고리즘을 실제 환경에서 발생할 수 있는 다양한 변동 요소에 빠르게 적응시키는 데 효과적이다.

조명을 더욱 세밀하게 제어하기 위해서는 광학 특성뿐만 아니라 색온도(Temperature), 밝기(Intensity), 방향(Direction) 등을 시간에 따라 또는 이벤트에 따라 변경하는 시나리오를 고려할 수 있다. 예를 들어 일정 시간이 지난 뒤에 태양의 위치를 시뮬레이션하여 디렉셔널 라이트의 각도를 이동시키거나, 특정 이벤트가 발생하면 스포트라이트가 켜지고 꺼지도록 한다. 이러한 동적 변화는 물리 기반의 재질이나 반사 모델과 결합하면 매우 풍부한 시각적 효과를 낳으며, 로봇이 실제 세계에서 맞닥뜨릴 수 있는 조명 변화에 대한 대응 전략을 사전에 마련할 수 있게 해준다.

여러 카메라를 하나의 시뮬레이션에서 다룰 때는 각 카메라의 뷰포트(Viewport)나 관측 범위를 적절히 설정해야 한다. 예를 들어 전방 카메라와 후방 카메라가 서로 겹치는 영역을 어느 정도 가질지, 또는 측면 카메라가 충돌 가능성이 높은 장애물을 모두 포착하도록 배치할 것인지 같은 부분이 중요하다. 어떤 경우에는 전방 카메라와 측면 카메라 사이에서 공통 영역이 생기면 스테레오 매칭이나 3D 재구성 알고리즘을 실험할 수도 있다. 이때 장면 내 조명 조건이 변화하면 스테레오 매칭 알고리즘이 에지(Edge)나 텍스처를 어떻게 인식하는지에 영향을 끼친다.

카메라가 수집한 이미지가 단순히 시각 정보를 제공하는 것을 넘어, 물체 파편이나 레이저 반사 같은 특수 효과를 구현하고자 할 때는 파티클 시스템이나 볼륨 렌더링 기법을 고려할 수 있다. Isaac Sim은 안개(Fog)나 스모그, 연기(Smoke) 같은 볼류메트릭(Volumetric) 효과도 지원할 수 있으며, 이러한 환경에서 조명의 산란(Scattering)과 반사(Reflection)를 시뮬레이션하면 로봇 센서가 어려운 환경에서 어떤 성능을 내는지 확인할 수 있다. 심한 안개가 낀 환경을 재현하고, 라이더(LiDAR)나 레이다(Radar) 센서와의 결합 실험을 진행하면 실제 악천후에서의 로봇 주행에 필요한 성능 요구사항을 검토할 수 있다.

시뮬레이션 성능 측면에서, 장면에 많은 광원을 배치하고 고급 렌더링 옵션을 활성화하면 GPU와 CPU 사용률이 크게 오르므로 프레임레이트가 떨어질 수 있다. 대규모 시뮬레이션 실험에서는 핵심 장면의 시각적 품질은 유지하되, 배경 요소나 꼭 필요하지 않은 광원을 줄이는 방식으로 최적화해야 할 때도 있다. 목표로 하는 물리적 현상 또는 인식 알고리즘의 검증 포인트에 맞추어, 불필요한 시각 효과를 끄고 성능을 확보하는 편이 더 합리적인 경우도 흔하다.

이와 함께 Isaac Sim에서 제공하는 포스트 프로세싱 파이프라인을 적절히 활용하면, 화이트밸런스(White Balance) 보정이나 감마(Gamma) 보정을 시뮬레이션 단계에서 수행할 수 있다. 실제 카메라에서 이루어지는 이미지 보정 프로세스를 Isaac Sim에서 미리 적용하거나, 반대로 실제 환경에서 발생하는 모든 잡음과 노출 변동을 온전히 데이터로 받아들인 뒤 별도의 ROS2 노드에서 후처리하도록 시나리오를 구성할 수도 있다. 이는 어떤 파이프라인이 더 효과적인지 비교 분석하고, 최종적으로 실제 로봇 시스템에 이식할 때 참고할 근거가 된다.

아래는 Isaac Sim의 후처리와 노이즈 모델 파라미터를 활성화하는 가상의 C++ 예시이다.

```cpp
#include <isaac_sim/isaac_sim.hh>

using namespace isaac_sim;

void applyPostProcessingAndNoise()
{
    CameraPtr cam = get_scene()->GetCamera("MainCamera");
    if (!cam)
        return;
    
    // 노이즈 파라미터 적용
    cam->EnableNoiseModel(true);
    cam->SetNoiseMean(0.0f);
    cam->SetNoiseStdDev(0.02f);
    
    // 포스트 프로세싱 설정
    cam->SetPostProcessEnabled(true);
    cam->SetExposureCompensation(0.5f);
    cam->SetWhiteBalanceTemperature(5500.0f);
    cam->SetVignetteIntensity(0.2f);
    cam->SetMotionBlurIntensity(0.1f);
}
```

노이즈 모델은 평균값과 표준편차 등으로 단순화된 가우시안 노이즈를 적용하는 예시이며, 여기서는 카메라 후처리에 노출 보정, 화이트밸런스, 비네팅(Vignette), 모션블러 효과를 모두 간단히 활성화한다. 실제 Isaac Sim 버전에 따라 함수명이나 인터페이스가 달라질 수 있다. 이처럼 후처리와 노이즈를 시뮬레이션 단계에서 포함하면, 로봇의 인식 알고리즘이 이미지 품질이 저하된 환경에서도 제대로 작동할 수 있는지 검증할 수 있다.

Isaac Sim은 HDR 렌더링 파이프라인에서 톤 매핑(Tone Mapping)을 적용할 수 있다. 톤 매핑은 고휘도 범위를 가지는 씬의 픽셀 데이터를 인간이 인지할 수 있는 범위로 매핑하는 과정이다. 실제 카메라 촬영에서 하이라이트가 날아가거나 그림자 부위가 까맣게 뭉개지는 현상을 최소화하기 위해서도 필요하다. 톤 매핑 알고리즘은 관능적으로 자연스럽게 보이는 이미지, 또는 컴퓨터 비전 알고리즘이 선호하는 중립적인 밝기 분포를 조절할 수 있다. 대표적인 방식으로 Reinhard 톤 매핑과 ACES(Academy Color Encoding System)가 있으며, Isaac Sim의 설정 메뉴나 API를 통해 이를 활성화할 수 있다.

조명 면에서 볼류메트릭 라이팅(Volumetric Lighting)은 안개, 먼지, 연기 같은 매질(Medium)을 시뮬레이션하여 빛이 매질 속에서 산란되고 흡수되는 현상을 표현한다. 레이트레이싱이 없더라도 스크린 공간 혹은 볼류메트릭 버퍼를 활용해 근사적으로 구현할 수 있다. 매질의 밀도나 산란 계수를 증가시키면 빛기둥(God Rays)처럼 특정 영역만 강조되는 연출이 가능하며, 이를 카메라로 관측하면 실제 풍경에서 보이는 극적인 효과를 재현할 수 있다. 로봇 비전 측면에서는 실외 환경에서 발생하는 안개나 먼지, 또는 지하 시설의 연기 등을 대비한 인식 알고리즘을 시험하기에 유리하다.

추가적으로 렌즈 플레어(Lens Flare)나 글레어(Glare) 같은 시각 효과를 시뮬레이션할 수 있다. 이는 광선이 렌즈 내에서 내부 반사를 일으키며 발생하는 현상으로, 실제 촬영에서는 역광 상황에서 두드러진다. Isaac Sim에서 렌즈 플레어를 적절히 활성화하면, 밝은 광원이 카메라 시야에 들어왔을 때 화면에 렌즈 반사 무늬가 보이게 된다. 이는 실제 영상과 같은 시각적 일관성을 확보하는 동시에, 너무 강한 빛으로 인해 비전 알고리즘이 교란을 받을 수 있는 상황을 재현하는 방법이 된다.

렌즈 쉐이더(Lens Shader)를 활용하면 보다 정교한 초점 심도나 광학 수차(Abberation)를 재현할 수도 있다. 초점 심도는 피사계 심도(Depth of Field)와 관련되어, 조리개 크기나 초점 거리 설정에 따라 특정 거리 밖에 있는 물체는 흐릿하게 표현된다. 이 효과는 로봇이 멀리 있는 물체보다는 가까운 물체에만 시야를 집중하게 만들거나, 인간에게 전달되는 영상을 보다 사실적으로 보여주는 시나리오에 사용된다. 광학 수차는 단순한 왜곡보다 복합적인 렌즈 결함을 포함하며, 실제 렌즈가 모든 파장에 대해 완벽하게 초점을 맞추지 못하는 현상을 뜻한다. 이를 시뮬레이션에 반영하면 로봇 비전 알고리즘이 흐릿하거나 색수차(Chromatic Aberration)가 발생하는 이미지에서 얼마나 견고하게 동작하는지를 점검할 수 있다.

멀티패스 렌더링(Multi-pass Rendering)을 통해 색, 깊이, 노멀(Normal) 등 다양한 G-Buffer를 동시에 생성할 수 있다. G-Buffer는 화면의 각 픽셀이 가지는 공간상 정보(예: 법선 벡터, 반사도, 금속성 등)를 저장해두고, 후처리 단계에서 이를 조합하여 복잡한 조명 효과나 컴퓨터 비전 알고리즘을 구현할 때 활용한다. Isaac Sim은 카메라별로 멀티패스 렌더링을 지원하므로, 동일한 장면에서 여러 종류의 데이터를 동시 획득하고 후처리 알고리즘을 개발하기에 용이하다.

로봇이 카메라를 자세 제어(Orientation Control)를 통해 회전시키거나 줌(Zoom)을 변경할 수도 있다. 이를 시뮬레이션에서 자동화하기 위해서는 Isaac Sim의 카메라 컨트롤 API를 사용하여 짧은 간격으로 회전각이나 초점 길이를 업데이트한다. 카메라 자체를 링크(Link) 형태로 로봇 모델에 연결하고 조인트(Joint)로 회전 범위를 정의하면, 물리 시뮬레이션과 연동된 조인트 움직임을 통해 카메라 방향이 바뀌는 효과를 낼 수 있다. 실제 로봇에서 사용되는 팬틸트(Pan-Tilt) 장치나 짐벌(Gimbal)을 Isaac Sim에 맞게 모델링하면, 동적 환경에서 시야를 추적하는 기법을 평가할 수 있다.

고급 시뮬레이션 사례 중 하나로, 동적인 라이트를 이용해 주야 변환(Day-Night Cycle)을 장시간에 걸쳐 시뮬레이션하는 방법이 있다. 로봇이 하루 종일 다른 조도 조건에서 어떻게 동작하고 인식 성능이 떨어지는 시점을 어떤 식으로 보완하는지 검증할 수 있다. 예를 들어 일정 간격마다 디렉셔널 라이트의 각도와 색온도를 변경하여 아침, 정오, 저녁, 밤을 재현하고, 로봇이 스스로 조도 센서를 참고해 헤드라이트를 켜도록 하는 시나리오도 구성할 수 있다. 이 경우 장면의 파라미터를 키프레임(Keyframe) 방식으로 시간에 따라 변조할 수 있으며, Isaac Sim의 시뮬레이션 API나 타임라인(Timeline) 기능을 사용해 자동화한다.

아래 코드는 Isaac Sim의 타임라인으로 조명을 시간에 따라 변화시키는 가상의 예시다.

```cpp
#include <isaac_sim/isaac_sim.hh>

using namespace isaac_sim;

void animateLighting(float elapsedTime)
{
    float cycle = fmod(elapsedTime, 60.0f);
    LightPtr sun = get_scene()->GetLight("SunLight");
    if (!sun)
        return;

    float angle = (cycle / 60.0f) * 360.0f;
    float radians = angle * 3.1415926535f / 180.0f;
    float yDir = cos(radians);
    float zDir = sin(radians);

    sun->SetDirection(0.0, yDir, zDir);
    sun->SetDiffuseColor(1.0, 1.0 - 0.5f * fabs(zDir), 1.0 - 0.5f * fabs(zDir), 1.0);
}
```

elapsedTime에 따라 주기적으로 빛의 각도와 색온도(또는 색조)를 바꾸고 있다. cycle을 60초로 설정했다면, 시뮬레이션 내부에서 60초가 지날 때마다 태양이 한 바퀴 도는 식으로 구현할 수 있다. 실제 주야 변환은 더 긴 시간을 주거나, 색온도 변화를 더욱 세밀하게 반영할 수 있다.

이처럼 Isaac Sim의 조명과 카메라 설정은 물리 기반 렌더링, 노이즈 모델, 멀티패스 렌더링, 동적 라이트 변화 등 다양한 요소를 종합적으로 다루면서, 실제 환경에 근접하는 로봇 시뮬레이션을 구축하게 해준다. 시나리오에 따라 비전 알고리즘을 검증하는 방법, 성능 튜닝, 그리고 데이터셋 확보 전략을 세울 수 있으며, 궁극적으로 로봇의 견고성과 적응력을 높이는 데 기여한다.
