Keyboard ALT + g to toggle grid overlay
Arnold 는 아무리 복잡한 장면도 처리할 수 있습니다. 대규모 데이터 세트도 문제 없이 처리하므로 중단 걱정 없이 렌더링할 수 있습니다.
이미지 제공: Heribert Raab
Houdini 용 Arnold 플러그인 (HtoA) 은 Houdini 아티스트들의 요구에 맞춰 특별히 설계되었습니다. 마치 원래 Houdini 의 일부인 것처럼 설계된 HtoA 는 많이 사용되는 모든 고유한 기능을 지원하므로 시간을 절약하고 보다 효율적으로 작업할 수 있습니다.
CPU 또는 GPU 렌더링 중에 선택할 수 있습니다. 에셋 작업을 빠르게 반복할 때는 GPU 렌더러를 사용하고, 복잡한 장면을 확대하고 렌더링해야 하는 경우에는 CPU 렌더링을 사용할 수 있습니다.
개방형 아키텍처의 확장성을 활용하여 Arnold 를 손쉽게 파이프라인에 통합하고 프로젝트 요구 사항에 맞게 조정할 수 있습니다. 커스텀 카메라, 조명 필터, 출력 드라이버 및 쉐이더를 생성할 수 있습니다.
이미지 제공: Serjan Burlak
HtoA 는 라이트, 쉐이더 및 기타 렌더 효과를 더 잘 제어할 수 있도록 빌드된 도구를 통해 Arnold 의 전체 기능을 지원합니다.
HtoA 는 라이트, 쉐이더 및 기타 렌더 효과를 더 잘 제어할 수 있도록 빌드된 도구를 통해 Arnold 의 전체 기능을 지원합니다.
이미지 제공: Yasin SINIK
Juraj Tomori
컴퓨터 아티스트
이 튜토리얼에서는 OSL(Open Shading Language) 을 사용하여 볼륨 프랙털 장면을 제작하는 방법을 보여 줍니다. 간단한 장면을 설정하고 OSL을 사용하여 쉐이더에서 프랙털 장면을 정의하고 렌더 설정을 최적화하는 과정을 안내합니다.
튜토리얼을 마칠 때쯤에는 비슷한 결과물을 생성할 수 있을 것입니다.
이 튜토리얼에서는 OSL(Open Shading Language) 을 사용하여 볼륨 프랙털 장면을 제작하는 방법을 보여 줍니다. 간단한 장면을 설정하고 OSL을 사용하여 쉐이더에서 프랙털 장면을 정의하고 렌더 설정을 최적화하는 과정을 안내합니다.
튜토리얼을 마칠 때쯤에는 비슷한 결과물을 생성할 수 있을 것입니다.
이제 OSL 로 모양을 정의하는 방법을 알았으니 좀 더 흥미로운 모양을 살펴보겠습니다. Mandelbrot 프랙털은 복잡한 2D 평면에서 정의되고 Mandelbulb 프랙털은 3D 공간에서 정의됩니다. Mandelbrot는 3D에서 정의되지 않지만 Mandelbulb의 결과도 좋으며 Mandelbrot를 통해 영감을 얻을 수 있습니다.
이제 OSL 로 모양을 정의하는 방법을 알았으니 좀 더 흥미로운 모양을 살펴보겠습니다. Mandelbrot 프랙털은 복잡한 2D 평면에서 정의되고 Mandelbulb 프랙털은 3D 공간에서 정의됩니다. Mandelbrot는 3D에서 정의되지 않지만 Mandelbulb의 결과도 좋으며 Mandelbrot를 통해 영감을 얻을 수 있습니다.
볼륨 장면 내 세부 정보의 양을 제어하는 두 가지 옵션이 있습니다. 경계 상자 객체의 볼륨 Step Size와 경계 형상의 크기 및 모양입니다. 또한 표준 Arnold ROP 품질 설정도 있습니다.
볼륨 장면 내 세부 정보의 양을 제어하는 두 가지 옵션이 있습니다. 경계 상자 객체의 볼륨 Step Size와 경계 형상의 크기 및 모양입니다. 또한 표준 Arnold ROP 품질 설정도 있습니다.
Mandelbulb 쉐이더를 기반으로 동일한 인덱스를 사용하여 값을 추출하고 쉐이딩에 사용할 수 있습니다. 창의적으로 값을 조정하고 조합하여 시각적으로 흥미로운 이미지를 만들어 보십시오. 다음 이미지에서는 두 가지 다른 색을 혼합하는 데 궤도 트랩이 사용되었으며 Standard Volume 노드에서 Scatter Color 매개변수를 유도하고 있습니다.
닫기
적용되는 기술을 살펴볼 수 있는 간단한 예시에서 시작하겠습니다. 이 예에서는 쉐이더에서 렌더링된 장면을 정의합니다(현재는 구, 나중에는 프랙털). 그러면 쉐이딩된 각 샘플의 밀도 값이 표시됩니다. 지정된 경계로 볼륨을 렌더링하기 위해 상자를 만든 후 볼륨으로 렌더링할 수 있습니다.
Render View 창에서 Render 버튼을 누릅니다. 렌더링되는 볼륨 큐브를 확인할 수 있습니다.
이제 표준 컨텐츠를 사용하여 쉐이더를 조정하여 모양을 정의할 수 있습니다. 현재 설정은 상자 경계 내, 즉 상자 내 어디서나 균일한 밀도를 출력합니다. 좀 더 흥미로운 구를 살펴보겠습니다. 여기서 구 볼륨은 중심까지의 거리가 구의 반지름보다 작거나 같은 모든 점으로 가득 찬 암시적 볼륨으로 정의할 수 있습니다. 나머지는 비어 있습니다. 이 정의는 다음 의사 코드로 다시 작성할 수 있습니다.
if (length(P_world) <= sphere_radius) density = 1 else density = 0
여기서 P_world 는 쉐이딩 샘플의 표준 공간 위치이며 length()는 벡터의 유클리드 길이를 반환합니다. 이 값은 다음 쉐이딩 네트워크로 변환할 수 있습니다. 상태 벡터는 표준 공간 P에서 쉐이딩 포인트를 출력하고 비교 노드는 구의 반지름보다 작거나 같게 설정됩니다.
쉐이딩 노드만 사용하여 모양을 정의하도록 했지만 의사 코드에서와 같이 프로그래밍 방식으로 모양을 정의할 수 있으면 더 잘 제어할 수 있습니다. 사실 이 작업은 OSL 을 사용하여 간단하게 수행할 수 있습니다. OSL 로 구를 다시 만들어 쉐이딩 네트워크가 어떻게 변경되는지 확인해 보겠습니다. 이 경우 구 쉐이더는 다음과 같습니다.
shader sphere_shader( float sphere_radius = 1.0, output float density = 0.0 ) { if (length(P) <= sphere_radius) density = 1.0; else density = 0.0; }
sphere_shader 는 쉐이더의 이름입니다. float sphere_radius 는 노드의 매개변수를 기본값으로 정의하고 output float 은 노드의 출력 유형을 정의하며 P 는 Arnold 에서 제공하는 전역 변수입니다. 여기서 볼 수 있듯이 OSL 코드는 위의 의사 코드와 거의 일치합니다.
sphere_shader.osl 을 저장하고 이 쉐이더가 있는 폴더를 가리키도록 ARNOLD_PLUGIN_PATH 환경 변수를 설정합니다. 예를 들어 houdini.env 파일에서 다음과 같이 지정합니다.
ARNOLD_PLUGIN_PATH = /path/to/folder/with/osl/shaders
쉐이더 경로를 설정한 후 Houdini 를 다시 시작하면 SHOP 에서 확인할 수 있습니다.
여기서 알 수 있듯이 네트워크가 이제 훨씬 단순해졌지만 동일한 결과를 제공합니다. 새 쉐이더를 만들거나 쉐이더의 출력 또는 입력 매개변수를 수정하는 경우에만 Houdini 를 다시 시작해야 합니다. OSL 코드 변경 시 Houdini 를 다시 시작할 필요 없이 다음에 Render 버튼을 누를 때 반영됩니다. 구의 반지름을 조정하는 경우 아래 그림과 같은 결과를 얻게 될 수 있습니다. 이 경우 구가 경계 객체보다 크다는 것을 의미하므로 구 또는 경계 객체 크기를 조정해야 합니다.
이제 OSL 로 모양을 정의하는 방법을 알았으니 좀 더 흥미로운 모양을 살펴보겠습니다. Mandelbrot 프랙털은 복잡한 2D 평면에서 정의되며 각 샘플은 무한 발사되는지 또는 경계를 유지하는지 반복적으로 평가되고 테스트됩니다. Mandelbulb 프랙털은 Daniel White 및 Paul Nylander 가 구성한 3D 공간에서 정의됩니다. Mandelbrot 는 3D 에서 정의되지 않지만 Mandelbulb 의 결과도 좋으며 Mandelbrot 를 통해 영감을 얻을 수 있습니다. 새로운 OSL 쉐이더를 생성하고 장면을 약간 수정하겠습니다.
shader mandelbulb_shader( float power = 8.0, int julia_enable = 0 [[ string widget = "boolean" ]], vector julia_coordinate = vector(0, 0, 0), int max_iterations = 150, float max_distance = 20.0, output float density = 0 ) { point P_in = P; point Z = P; int i; for (i = 0; i < max_iterations; i++) { float distance = length(Z); // convert to polar coordinates float theta = acos(Z[2] / distance); float phi = atan2(Z[1], Z[0]); // scale and rotate the point float zr = pow(distance, power); theta *= power; phi *= power; // convert back to cartesian coordinates point new_Z = zr * point( sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta) ); // update our point in normal or julia mode if (julia_enable == 0) { Z = new_Z + P_in; } else { Z = new_Z + julia_coordinate; } distance = length(Z); if (distance > max_distance) break; } // define density: 1 where point did not escape, 0 where point escaped to infinity if (i == max_iterations) density = 1.0; else density = 0.0; }
Houdini 장면을 다시 로드하고 새 Mandelbulb 쉐이더 노드를 쉐이딩 네트워크에 배치합니다. 경계 형상을 상자에서 구로 변경하면 모양이 더 잘 포함되고 보다 효과적으로 렌더링됩니다. 쉐이더가 1 또는 0만 출력하므로 Multiply 노드를 생성하여 밀도를 높입니다.
Power 매개변수를 조정하고 Julia 사용 및 다른 Julia 좌표 설정을 활성화하여 Julia 모드를 사용합니다. 매개변수를 애니메이션하여 흥미롭게 애니메이션된 모양을 생성할 수 있습니다.
지금까지 멋진 모양을 만들 수 있었지만 전부 회색입니다. 궤도 트랩이라는 기법을 사용하여 몇 가지 색을 추가해 보겠습니다. 다음 쉐이더에는 다섯 가지 궤도 트랩이 있습니다. 또한 두 가지 도우미 함수 (length2() 및 distPointPlane()) 도 포함됩니다.
// squared length float length2(vector vec) { return dot(vec, vec); } // point to plane distance float distPointPlane(vector pt, vector plane_n, vector plane_point) { float sb, sn, sd; vector point_proj; sn = -dot( plane_n, (pt - plane_point)); sd = dot(plane_n, plane_n); sb = sn / sd; point_proj = pt + sb * plane_n; return length(pt - point_proj); } shader mandelbulb_colors_shader( float power = 8.0, int julia_enable = 0 [[ string widget = "boolean" ]], vector julia_coordinate = vector(0, 0, 0), int max_iterations = 150, float max_distance = 20.0, output matrix out = 0 ) { point P_in = P; point Z = P; int i; // orbit traps float orbit_coord_dist = 100000; float orbit_sphere_dist = 100000; point orbit_plane_origin = point(0.0); vector orbit_plane_dist = vector(100000); for (i = 0; i < max_iterations; i++) { float distance = length(Z); // convert to polar coordinates float theta = acos(Z[2] / distance); float phi = atan2(Z[1], Z[0]); // scale and rotate the point float zr = pow(distance, power); theta *= power; phi *= power; // convert back to cartesian coordinates point new_Z = zr * point( sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta) ); // update our point in normal or julia mode if (julia_enable == 0) { Z = new_Z + P_in; } else { Z = new_Z + julia_coordinate; } distance = length(Z); if (distance > max_distance) break; // orbit traps orbit_coord_dist = min(orbit_coord_dist, fabs( length2(Z - P_in) )); orbit_sphere_dist = min( orbit_sphere_dist, fabs( length2(Z - point(0)) - 2.0) ); orbit_plane_dist[0] = min( orbit_plane_dist[0], distPointPlane(Z, vector(1.0, 0.0, 0.0), orbit_plane_origin) ); orbit_plane_dist[1] = min( orbit_plane_dist[1], distPointPlane(Z, vector(0.0, 1.0, 0.0), orbit_plane_origin) ); orbit_plane_dist[2] = min( orbit_plane_dist[2], distPointPlane(Z, vector(0.0, 0.0, 1.0), orbit_plane_origin) ); } // orbit traps orbit_coord_dist = sqrt(orbit_coord_dist); orbit_sphere_dist = sqrt(orbit_sphere_dist); // define density: 1 where point did not escape, 0 where point escaped to infinity float density; if (i == max_iterations) density = 1.0; else density = 0.0; // output values out[0][0] = density; out[0][1] = orbit_coord_dist; out[0][2] = orbit_sphere_dist; out[0][3] = orbit_plane_dist[0]; out[1][0] = orbit_plane_dist[1]; out[1][1] = orbit_plane_dist[2]; }
현재 OSL 노드에는 단일 출력만 포함할 수 있는 제한이 있습니다. 이 문제를 해결하기 위해 매트릭스 유형을 출력할 수 있습니다. 이 유형은 16 개의 부동 값으로 구성됩니다(4x4 변환 매트릭스). 단일 노드에서 여러 값을 출력하려면 다음 도우미 OSL 쉐이더로 매트릭스에서 값을 패킹하여 쉐이딩 네트워크에서 추출하면 됩니다.
shader vft_get_matrix_element( matrix mat = 1, int row = 0, int column = 0, output float element_out = 0.0 ) { element_out = mat[row][column]; }
Mandelbulb 쉐이더를 기반으로 동일한 인덱스를 사용하여 값을 추출하고 쉐이딩에 사용할 수 있습니다. 창의적으로 값을 조정하고 조합하여 시각적으로 흥미로운 이미지를 만들어 보십시오. 다음 이미지에서는 두 가지 다른 색을 혼합하는 데 궤도 트랩이 사용되었으며 Standard Volume 노드에서 Scatter Color 매개변수를 유도하고 있습니다.
다음 이미지에서는 궤도 트랩이 볼륨의 흑체 방사를 유도하는 데 사용되었습니다.
볼륨 장면에서 세부 정보의 양을 제어하는 첫 번째 옵션은 경계 상자 객체의 볼륨 Step Size입니다. 숫자가 작을수록 렌더링된 볼륨이 자세하게 표시됩니다. 차이를 확인할 수 없을 때까지 낮은 값으로 설정해 보십시오. 너무 낮게 설정하면 렌더 시간에 부정적인 영향을 미칩니다.
Step Size: 0.1
Step Size: 0.6
렌더 시간에 영향을 미치는 또 다른 요인은 경계 형상의 크기 및 모양입니다. 불필요하게 큰 경계 모양은 빈 공간에서 렌더링 기능을 낭비하므로 가능한 빽빽하게 설정합니다. 프랙털 조정에 영향을 미치는 또 다른 옵션은 OSL Mandelbulb 노드의 Max Iterations 매개변수입니다. 이 값을 시각적으로 필요한 만큼 높게 설정하되 너무 높으면 렌더 시간에 영향을 미칠 수 있습니다.
Iterations: 150
Iterations: 10
또한 표준 Arnold ROP 품질 설정도 있습니다. 방사 프랙털 렌더링 시에는 렌더를 두 개의 패스로 분할하는 것이 좋습니다(하나는 방사 조명용, 하나는 장면 조명용). 왜냐하면 두 경우 서로 다른 설정 조합이 필요하며 이 둘을 함께 렌더링하면 각각 렌더링하는 것보다 느려집니다.
닫기
도움이 필요하신가요? 고객을 위해 최선을 다하고 있는 개발팀과 지원 커뮤니티는 깊이 있는 자료를 통해 여러분의 질문에 답할 만반의 준비를 갖추었으므로 여러분은 놀라운 결과물을 내는 데만 집중하시면 됩니다.
도움이 필요하신가요? 고객을 위해 최선을 다하고 있는 개발팀과 지원 커뮤니티는 깊이 있는 자료를 통해 여러분의 질문에 답할 만반의 준비를 갖추었으므로 여러분은 놀라운 결과물을 내는 데만 집중하시면 됩니다.
최고의 3D 렌더러를 사용해 볼 준비가 되셨나요? 30 일 동안 무료로 HtoA 를 체험하세요.