Skip to content

Commit 54c400d

Browse files
committed
Demo - add Transform motion blur demo
1 parent d401b56 commit 54c400d

File tree

12 files changed

+381
-103
lines changed

12 files changed

+381
-103
lines changed
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/*****************************************************************************\
2+
*
3+
* Module Name Transform Motion Demo
4+
* Project Radeon ProRender rendering tutorial
5+
*
6+
* Description Radeon ProRender SDK tutorials
7+
*
8+
* Copyright(C) 2011-2021 Advanced Micro Devices, Inc. All rights reserved.
9+
*
10+
\*****************************************************************************/
11+
#include "RadeonProRender.h"
12+
#include "Math/mathutils.h"
13+
#include "../common/common.h"
14+
#include <cassert>
15+
#include <iostream>
16+
17+
//
18+
// This demo covers shape and camera matrix transform changed over time for a blur effect.
19+
// Note that this is different compared to a Deformation motion blur ( illustrated in another Demo ) where we set each vertex individually over time.
20+
// Here it's simpler: we just change the transform matrix.
21+
// This demo also illustrates how we can export the blur with the RPR_AOV_VELOCITY AOV.
22+
//
23+
24+
25+
// convert a pos/lookat/up into a camera transform matrix
26+
RadeonProRender::matrix CameraLookAtToMatrix( RadeonProRender::float3 pos , RadeonProRender::float3 at, RadeonProRender::float3 up)
27+
{
28+
RadeonProRender::float3 directionVector = RadeonProRender::normalize(at - pos);
29+
RadeonProRender::float3 right = normalize(RadeonProRender::cross(directionVector,up));
30+
31+
// Warning: For rprCameraSetMotionTransform, we need to make sure to have both 'right' and 'up2' correctly orthogonal to 'directionVector'
32+
// otherwise it may result into bad blur rendering.
33+
RadeonProRender::float3 up2 = normalize(RadeonProRender::cross(right,directionVector));
34+
35+
RadeonProRender::matrix m(
36+
right.x, right.y, right.z, 0.0,
37+
up2.x, up2.y, up2.z, 0.0,
38+
-directionVector.x, -directionVector.y, -directionVector.z, 0.0,
39+
pos.x, pos.y, pos.z, 1.0
40+
);
41+
return m;
42+
}
43+
44+
45+
int main()
46+
{
47+
// enable Radeon ProRender API trace
48+
// set this before any rpr API calls
49+
// rprContextSetParameterByKey1u(0,RPR_CONTEXT_TRACING_ENABLED,1);
50+
51+
std::cout << "-- Radeon ProRender SDK Demo --" << std::endl;
52+
53+
// the RPR context object.
54+
rpr_context context = nullptr;
55+
56+
// Register the RPR DLL
57+
rpr_int tahoePluginID = rprRegisterPlugin(RPR_PLUGIN_FILE_NAME);
58+
CHECK_NE(tahoePluginID , -1);
59+
rpr_int plugins[] = { tahoePluginID };
60+
size_t pluginCount = sizeof(plugins) / sizeof(plugins[0]);
61+
62+
// Create context using a single GPU
63+
// note that multiple GPUs can be enabled for example with creation_flags = RPR_CREATION_FLAGS_ENABLE_GPU0 | RPR_CREATION_FLAGS_ENABLE_GPU1
64+
CHECK( rprCreateContext(RPR_API_VERSION, plugins, pluginCount, g_ContextCreationFlags, NULL, NULL, &context) );
65+
66+
// Set the active plugin.
67+
CHECK( rprContextSetActivePlugin(context, plugins[0]) );
68+
69+
std::cout << "RPR Context creation succeeded." << std::endl;
70+
71+
// create material system
72+
rpr_material_system matsys = nullptr;
73+
CHECK( rprContextCreateMaterialSystem(context, 0, &matsys) );
74+
75+
// Create the scene
76+
rpr_scene scene = nullptr;
77+
CHECK( rprContextCreateScene(context, &scene) );
78+
CHECK( rprContextSetScene(context, scene) );
79+
80+
// Create camera
81+
rpr_camera camera = nullptr;
82+
CHECK( rprContextCreateCamera(context, &camera) );
83+
CHECK( rprCameraLookAt(camera, 10, 10, 10, 0, 1, 0, 0, 1, 0) );
84+
CHECK( rprSceneSetCamera(scene, camera) );
85+
86+
87+
// Create framebuffer
88+
rpr_framebuffer_desc desc = { 800 , 600 };
89+
rpr_framebuffer_format fmt = {4, RPR_COMPONENT_TYPE_FLOAT32};
90+
rpr_framebuffer fb_color = nullptr;
91+
rpr_framebuffer fb_color_resolved = nullptr;
92+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &fb_color) );
93+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &fb_color_resolved) );
94+
CHECK( rprContextSetAOV(context, RPR_AOV_COLOR, fb_color) );
95+
96+
// Optional : add a Velocity AOV. this could be useful for debugging or post processing
97+
rpr_framebuffer fb_velocity = nullptr;
98+
rpr_framebuffer fb_velocity_resolved = nullptr;
99+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &fb_velocity) );
100+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &fb_velocity_resolved) );
101+
CHECK( rprContextSetAOV(context, RPR_AOV_VELOCITY, fb_velocity) );
102+
103+
104+
// create a teapot shape
105+
rpr_shape teapot01 = nullptr;
106+
{
107+
teapot01 = ImportOBJ("../../Resources/Meshes/teapot.obj",scene,context);
108+
109+
RadeonProRender::matrix m0 = RadeonProRender::rotation_x(MY_PI);
110+
CHECK(rprShapeSetTransform(teapot01, RPR_TRUE, &m0.m00));
111+
}
112+
113+
// Create plane mesh
114+
rpr_shape plane = nullptr;
115+
{
116+
CHECK(rprContextCreateMesh(context,
117+
(rpr_float const*)&plane_data[0], 4, sizeof(vertex),
118+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float) * 3), 4, sizeof(vertex),
119+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float) * 6), 4, sizeof(vertex),
120+
(rpr_int const*)indices, sizeof(rpr_int),
121+
(rpr_int const*)indices, sizeof(rpr_int),
122+
(rpr_int const*)indices, sizeof(rpr_int),
123+
num_face_vertices, 2, &plane));
124+
CHECK(rprSceneAttachShape(scene, plane));
125+
}
126+
127+
128+
// Create an Environment Light light
129+
rpr_light lightEnv = nullptr;
130+
rpr_image imgEnvLight = nullptr;
131+
{
132+
CHECK(rprContextCreateEnvironmentLight(context, &lightEnv));
133+
134+
const std::string pathImageFile = "../../Resources/Textures/envLightImage.exr";
135+
rpr_status status = rprContextCreateImageFromFile(context, pathImageFile.c_str(), &imgEnvLight); // import image use by the Env light
136+
if (status == RPR_ERROR_IO_ERROR)
137+
{
138+
std::cout << "Error : " << pathImageFile << " not found.\n";
139+
return -1;
140+
}
141+
CHECK(status);
142+
143+
CHECK(rprEnvironmentLightSetImage(lightEnv, imgEnvLight));
144+
CHECK(rprEnvironmentLightSetIntensityScale(lightEnv, 1.0f));
145+
CHECK(rprSceneAttachLight(scene, lightEnv));
146+
}
147+
148+
149+
// create a DIFFUSE material for the Teapot
150+
//
151+
rpr_material_node diffuse1=nullptr;
152+
rpr_image img=nullptr;
153+
rpr_material_node imgSampler = nullptr;
154+
{
155+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &diffuse1));
156+
CHECK(rprContextCreateImageFromFile(context, "../../Resources/Textures/textest.png",&img));
157+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_IMAGE_TEXTURE, &imgSampler));
158+
CHECK(rprMaterialNodeSetInputImageDataByKey(imgSampler, RPR_MATERIAL_INPUT_DATA, img)); // Set image data
159+
CHECK(rprMaterialNodeSetInputNByKey(diffuse1, RPR_MATERIAL_INPUT_COLOR, imgSampler));
160+
CHECK(rprShapeSetMaterial(teapot01, diffuse1));
161+
}
162+
163+
164+
165+
// create a DIFFUSE material for the Floor
166+
//
167+
rpr_material_node uv_scaled_node = NULL;
168+
rpr_material_node diffuse5 = nullptr;
169+
rpr_image image2 = nullptr;
170+
rpr_material_node materialImage2 = nullptr;
171+
rpr_material_node uv_node = NULL;
172+
{
173+
174+
175+
const std::string pathImageFileA = "../../Resources/Textures/amd.png";
176+
rpr_status status = rprContextCreateImageFromFile(context, pathImageFileA.c_str(), &image2);
177+
if (status == RPR_ERROR_IO_ERROR)
178+
{
179+
std::cout << "Error : " << pathImageFileA << " not found.\n";
180+
return -1;
181+
}
182+
CHECK(status);
183+
184+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_IMAGE_TEXTURE, &materialImage2));
185+
CHECK(rprMaterialNodeSetInputImageDataByKey(materialImage2, RPR_MATERIAL_INPUT_DATA, image2)); // Set image data
186+
187+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &diffuse5));
188+
CHECK(rprMaterialNodeSetInputNByKey(diffuse5, RPR_MATERIAL_INPUT_COLOR, materialImage2)); // set image sampler as the color input of diffuse material
189+
190+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_INPUT_LOOKUP, &uv_node));
191+
CHECK(rprMaterialNodeSetInputUByKey(uv_node, RPR_MATERIAL_INPUT_VALUE, RPR_MATERIAL_NODE_LOOKUP_UV));
192+
193+
CHECK(rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_ARITHMETIC, &uv_scaled_node));
194+
CHECK(rprMaterialNodeSetInputUByKey(uv_scaled_node, RPR_MATERIAL_INPUT_OP, RPR_MATERIAL_NODE_OP_MUL));
195+
CHECK(rprMaterialNodeSetInputNByKey(uv_scaled_node, RPR_MATERIAL_INPUT_COLOR0, uv_node));
196+
CHECK(rprMaterialNodeSetInputFByKey(uv_scaled_node, RPR_MATERIAL_INPUT_COLOR1, 2.0f, 4.0f, 0, 0));
197+
198+
CHECK(rprMaterialNodeSetInputNByKey(materialImage2, RPR_MATERIAL_INPUT_UV, uv_scaled_node));
199+
200+
CHECK(rprShapeSetMaterial(plane, diffuse5));
201+
}
202+
203+
204+
// First, Render scene without any motion
205+
CHECK( rprContextSetParameterByKey1f(context, RPR_CONTEXT_DISPLAY_GAMMA , 2.2f ) ); // set display gamma
206+
CHECK( rprContextSetParameterByKey1u(context,RPR_CONTEXT_ITERATIONS,NUM_ITERATIONS));
207+
CHECK( rprContextRender(context) );
208+
CHECK( rprContextResolveFrameBuffer(context,fb_color,fb_color_resolved,false));
209+
CHECK( rprContextResolveFrameBuffer(context,fb_velocity,fb_velocity_resolved,false));
210+
CHECK( rprFrameBufferSaveToFile(fb_color_resolved, "12_0.png") );
211+
std::cout << "Rendering 12_0 finished." << std::endl;
212+
213+
214+
// activate the motion by setting an exposure greater than 0.0
215+
CHECK(rprCameraSetExposure(camera,1.0));
216+
217+
218+
// Apply a rotation motion blur to the teapot
219+
// Note that rotation_x(MY_PI) is the transform at exposure=0 ( before motion blur ), and rotation_y(0.5f) is the real motion blur effect.
220+
{
221+
RadeonProRender::matrix m1 = RadeonProRender::rotation_y(0.1f) * RadeonProRender::rotation_x(MY_PI);
222+
CHECK( rprShapeSetMotionTransform(teapot01, RPR_TRUE, &m1.m00, 1)); // define the transform at exposure=1.0
223+
CHECK( rprShapeSetMotionTransformCount(teapot01, 1)); // specify that the matrix at 'timeIndex'=1 must be used
224+
}
225+
226+
// Render the scene
227+
CHECK( rprFrameBufferClear(fb_color) );
228+
CHECK( rprFrameBufferClear(fb_velocity) );
229+
CHECK( rprContextRender(context) );
230+
CHECK( rprContextResolveFrameBuffer(context,fb_color,fb_color_resolved,false));
231+
CHECK( rprContextResolveFrameBuffer(context,fb_velocity,fb_velocity_resolved,false));
232+
CHECK( rprFrameBufferSaveToFile(fb_color_resolved, "12_1.png") );
233+
CHECK( rprFrameBufferSaveToFile(fb_velocity_resolved, "12_1v.png") );
234+
std::cout << "Rendering 12_1 finished." << std::endl;
235+
236+
237+
// Same that previous rendering, but instead of a rotation we do a (0.0f,0.0f,-0.3f) blur translation of the teapot
238+
RadeonProRender::matrix m1 = RadeonProRender::translation(RadeonProRender::float3(0.0f,0.0f,-0.3f)) * RadeonProRender::rotation_x(MY_PI);
239+
CHECK( rprShapeSetMotionTransform(teapot01, RPR_TRUE, &m1.m00, 1));
240+
CHECK( rprShapeSetMotionTransformCount(teapot01, 1));
241+
CHECK( rprFrameBufferClear(fb_color) );
242+
CHECK( rprFrameBufferClear(fb_velocity) );
243+
CHECK( rprContextRender(context) );
244+
CHECK( rprContextResolveFrameBuffer(context,fb_color,fb_color_resolved,false));
245+
CHECK( rprContextResolveFrameBuffer(context,fb_velocity,fb_velocity_resolved,false));
246+
CHECK( rprFrameBufferSaveToFile(fb_color_resolved, "12_2.png") );
247+
CHECK( rprFrameBufferSaveToFile(fb_velocity_resolved, "12_2v.png") );
248+
std::cout << "Rendering 12_2 finished." << std::endl;
249+
250+
// Now, we do a movement of the camera instead of shape. This is pretty much the same API.
251+
RadeonProRender::matrix camMat1 = CameraLookAtToMatrix( RadeonProRender::float3(9, 9, 9) , RadeonProRender::float3(0,1,0) , RadeonProRender::float3(0,1,0) );
252+
CHECK( rprCameraSetMotionTransform(camera, false, &camMat1.m00 ,1 )); // define the camera transform at exposure=1.0
253+
CHECK( rprCameraSetMotionTransformCount(camera, 1)); // enable motion blur on camera
254+
CHECK( rprShapeSetMotionTransformCount(teapot01, 0)); // disable motion blur of teapot
255+
CHECK( rprFrameBufferClear(fb_color) );
256+
CHECK( rprFrameBufferClear(fb_velocity) );
257+
CHECK( rprContextRender(context) );
258+
CHECK( rprContextResolveFrameBuffer(context,fb_color,fb_color_resolved,false));
259+
CHECK( rprContextResolveFrameBuffer(context,fb_velocity,fb_velocity_resolved,false));
260+
CHECK( rprFrameBufferSaveToFile(fb_color_resolved, "12_3.png") );
261+
CHECK( rprFrameBufferSaveToFile(fb_velocity_resolved, "12_3v.png") );
262+
std::cout << "Rendering 12_3 finished." << std::endl;
263+
264+
265+
266+
// Release the stuff we created
267+
//
268+
CHECK(rprObjectDelete(img)); img=nullptr;
269+
CHECK(rprObjectDelete(imgSampler)); imgSampler=nullptr;
270+
CHECK(rprObjectDelete(uv_scaled_node)); uv_scaled_node=nullptr;
271+
CHECK(rprObjectDelete(diffuse5)); diffuse5=nullptr;
272+
CHECK(rprObjectDelete(image2)); image2=nullptr;
273+
CHECK(rprObjectDelete(materialImage2)); materialImage2=nullptr;
274+
CHECK(rprObjectDelete(uv_node)); uv_node=nullptr;
275+
CHECK(rprObjectDelete(diffuse1)); diffuse1=nullptr;
276+
CHECK(rprObjectDelete(lightEnv)); lightEnv=nullptr;
277+
CHECK(rprObjectDelete(imgEnvLight)); imgEnvLight=nullptr;
278+
CHECK(rprObjectDelete(camera)); camera=nullptr;
279+
CHECK(rprObjectDelete(fb_color)); fb_color=nullptr;
280+
CHECK(rprObjectDelete(fb_color_resolved)); fb_color_resolved=nullptr;
281+
CHECK(rprObjectDelete(fb_velocity)); fb_velocity=nullptr;
282+
CHECK(rprObjectDelete(fb_velocity_resolved)); fb_velocity_resolved=nullptr;
283+
CHECK(rprObjectDelete(scene)); scene=nullptr;
284+
CHECK(rprObjectDelete(teapot01)); teapot01=nullptr;
285+
CHECK(rprObjectDelete(plane)); plane=nullptr;
286+
CHECK(rprObjectDelete(matsys)); matsys=nullptr;
287+
CheckNoLeak(context);
288+
CHECK(rprObjectDelete(context));context=nullptr; // Always delete the RPR Context in last.
289+
return 0;
290+
}
291+
292+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
project "12_transform_motion_blur"
2+
kind "ConsoleApp"
3+
location "../build"
4+
files { "../12_transform_motion_blur/**.h", "../12_transform_motion_blur/**.cpp"}
5+
files { "../common/common.cpp","../common/common.h"}
6+
7+
-- remove filters for Visual Studio
8+
vpaths { [""] = { "../12_transform_motion_blur/**.h", "../12_transform_motion_blur/**.cpp","../common/common.cpp","../common/common.h"} }
9+
10+
11+
includedirs{ "../../RadeonProRender/inc" }
12+
13+
buildoptions "-std=c++11"
14+
15+
configuration {"x64"}
16+
links {"RadeonProRender64"}
17+
18+
configuration {"x64", "Debug"}
19+
targetdir "../Bin"
20+
configuration {"x64", "Release"}
21+
targetdir "../Bin"
22+
configuration {}
23+
Loading

tutorials/13_deformation_motion_blur/main.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,25 @@ int main()
2525
// rprContextSetParameterByKey1u(0,RPR_CONTEXT_TRACING_ENABLED,1);
2626

2727
std::cout << "-- Radeon ProRender SDK Demo --" << std::endl;
28-
// Indicates whether the last operation has suceeded or not
29-
rpr_int status = RPR_SUCCESS;
30-
// Create OpenCL context using a single GPU
31-
rpr_context context = NULL;
3228

33-
// Register Tahoe ray tracing plugin.
29+
// the RPR context object.
30+
rpr_context context = nullptr;
31+
32+
// Register the RPR DLL
3433
rpr_int tahoePluginID = rprRegisterPlugin(RPR_PLUGIN_FILE_NAME);
35-
CHECK_NE(tahoePluginID , -1)
34+
CHECK_NE(tahoePluginID , -1);
3635
rpr_int plugins[] = { tahoePluginID };
3736
size_t pluginCount = sizeof(plugins) / sizeof(plugins[0]);
3837

3938
// Create context using a single GPU
39+
// note that multiple GPUs can be enabled for example with creation_flags = RPR_CREATION_FLAGS_ENABLE_GPU0 | RPR_CREATION_FLAGS_ENABLE_GPU1
4040
CHECK( rprCreateContext(RPR_API_VERSION, plugins, pluginCount, g_ContextCreationFlags, NULL, NULL, &context) );
4141

42-
// Set active plugin.
42+
// Set the active plugin.
4343
CHECK( rprContextSetActivePlugin(context, plugins[0]) );
4444

45-
std::cout << "Context successfully created.\n";
45+
std::cout << "RPR Context creation succeeded." << std::endl;
46+
4647

4748
rpr_material_system matsys = nullptr;
4849
CHECK( rprContextCreateMaterialSystem(context, 0, &matsys) );

0 commit comments

Comments
 (0)