Skip to content

Commit 0ca6284

Browse files
committed
Demo - add shadow catcher demo
1 parent 6063e29 commit 0ca6284

File tree

6 files changed

+232
-0
lines changed

6 files changed

+232
-0
lines changed

tutorials/36_shadow_catcher/main.cpp

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*****************************************************************************\
2+
*
3+
* Module Name Shadow Catcher Demo
4+
* Project Radeon ProRender rendering tutorial
5+
*
6+
* Description Radeon ProRender SDK tutorials
7+
*
8+
* Copyright(C) 2011-2022 Advanced Micro Devices, Inc. All rights reserved.
9+
*
10+
\*****************************************************************************/
11+
12+
#include "RadeonProRender.h"
13+
#include "Math/mathutils.h"
14+
#include "../common/common.h"
15+
#include <cassert>
16+
#include <iostream>
17+
18+
//
19+
// Demo of the Shadow Catcher. If a shape has this feature activated, it will "catch" the shadow. This shadow quantity can be rendered on a dedicated AOV.
20+
//
21+
22+
// simple garbage collector for RPR objects.
23+
RPRGarbageCollector g_gc;
24+
25+
int main()
26+
{
27+
// for Debugging you can enable Radeon ProRender API trace
28+
// set this before any RPR API calls
29+
// rprContextSetParameterByKey1u(0,RPR_CONTEXT_TRACING_ENABLED,1);
30+
31+
// the RPR context object.
32+
rpr_context context = nullptr;
33+
34+
// Register the RPR DLL
35+
rpr_int tahoePluginID = rprRegisterPlugin(RPR_PLUGIN_FILE_NAME);
36+
CHECK_NE(tahoePluginID , -1);
37+
rpr_int plugins[] = { tahoePluginID };
38+
size_t pluginCount = sizeof(plugins) / sizeof(plugins[0]);
39+
40+
// Create context using a single GPU
41+
// note that multiple GPUs can be enabled for example with creation_flags = RPR_CREATION_FLAGS_ENABLE_GPU0 | RPR_CREATION_FLAGS_ENABLE_GPU1
42+
CHECK( rprCreateContext(RPR_API_VERSION, plugins, pluginCount, g_ContextCreationFlags, NULL, NULL, &context) );
43+
44+
// Set the active plugin.
45+
CHECK( rprContextSetActivePlugin(context, plugins[0]) );
46+
47+
std::cout << "RPR Context creation succeeded." << std::endl;
48+
49+
// Create the scene.
50+
rpr_scene scene = nullptr;
51+
CHECK( rprContextCreateScene(context, &scene) ); // create the scene
52+
CHECK( rprContextSetScene(context, scene) ); // set this scene as the "active" scene used for rendering.
53+
54+
// Create the camera
55+
rpr_camera camera = nullptr;
56+
CHECK( rprContextCreateCamera(context, &camera) );
57+
g_gc.GCAdd(camera);
58+
CHECK( rprCameraLookAt(camera, 10, 10, 10, 0, -1, 0, 0, 1, 0) );
59+
CHECK( rprSceneSetCamera(scene, camera) );
60+
61+
// Create an environment light
62+
CHECK( CreateNatureEnvLight(context, scene, g_gc, 1.0f) );
63+
64+
65+
// create a teapot shape
66+
rpr_shape teapot01 = nullptr;
67+
{
68+
teapot01 = ImportOBJ("../../Resources/Meshes/teapot.obj",scene,context);
69+
g_gc.GCAdd(teapot01);
70+
RadeonProRender::matrix m = RadeonProRender::rotation_y(MY_PI/2.0f) * RadeonProRender::rotation_x(MY_PI);
71+
CHECK( rprShapeSetTransform(teapot01, RPR_TRUE, &m.m00));
72+
}
73+
74+
// create the material system
75+
rpr_material_system matsys = nullptr;
76+
CHECK( rprContextCreateMaterialSystem(context, 0, &matsys) );
77+
78+
79+
// create the shadow catcher plane shape.
80+
// This plane will be used to "catch" the shadow quantity.
81+
{
82+
rpr_shape plane = nullptr;
83+
rpr_material_node diffuse1=nullptr;
84+
85+
CHECK(rprContextCreateMesh(context,
86+
(rpr_float const*)&plane_data[0], 4, sizeof(vertex),
87+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float) * 3), 4, sizeof(vertex),
88+
(rpr_float const*)((char*)&plane_data[0] + sizeof(rpr_float) * 6), 4, sizeof(vertex),
89+
(rpr_int const*)indices, sizeof(rpr_int),
90+
(rpr_int const*)indices, sizeof(rpr_int),
91+
(rpr_int const*)indices, sizeof(rpr_int),
92+
num_face_vertices, 2, &plane));
93+
g_gc.GCAdd(plane);
94+
95+
RadeonProRender::matrix mat = RadeonProRender::scale(RadeonProRender::float3(0.5f, 1.0f, 0.5f));
96+
CHECK(rprShapeSetTransform(plane, RPR_TRUE, &mat.m00));
97+
98+
CHECK(rprSceneAttachShape(scene, plane));
99+
100+
// use a simple white diffuse material
101+
CHECK( rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &diffuse1));
102+
g_gc.GCAdd(diffuse1);
103+
CHECK( rprMaterialNodeSetInputFByKey(diffuse1, RPR_MATERIAL_INPUT_COLOR, 1.0, 1.0, 1.0, 1.0f));
104+
CHECK( rprShapeSetMaterial(plane, diffuse1));
105+
106+
// Enable the shadown catcher feature on this plane.
107+
CHECK( rprShapeSetShadowCatcher(plane,true) );
108+
}
109+
110+
111+
// create a DIFFUSE material for the Teapot
112+
//
113+
{
114+
rpr_material_node diffuse1=nullptr;
115+
rpr_image img=nullptr;
116+
rpr_material_node imgSampler = nullptr;
117+
118+
CHECK( rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_DIFFUSE, &diffuse1));
119+
g_gc.GCAdd(diffuse1);
120+
CHECK( rprContextCreateImageFromFile(context, "../../Resources/Textures/textest.png",&img));
121+
g_gc.GCAdd(img);
122+
123+
CHECK( rprMaterialSystemCreateNode(matsys, RPR_MATERIAL_NODE_IMAGE_TEXTURE, &imgSampler));
124+
g_gc.GCAdd(imgSampler);
125+
CHECK( rprMaterialNodeSetInputImageDataByKey(imgSampler, RPR_MATERIAL_INPUT_DATA, img)); // Set image data
126+
CHECK( rprMaterialNodeSetInputNByKey(diffuse1, RPR_MATERIAL_INPUT_COLOR, imgSampler));
127+
CHECK( rprShapeSetMaterial(teapot01, diffuse1));
128+
}
129+
130+
131+
// Create the Color framebuffers
132+
rpr_framebuffer_desc desc = { 800 , 600 };
133+
rpr_framebuffer_format fmt = {4, RPR_COMPONENT_TYPE_FLOAT32};
134+
rpr_framebuffer frame_buffer = nullptr;
135+
rpr_framebuffer frame_buffer_resolved = nullptr;
136+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer) );
137+
g_gc.GCAdd(frame_buffer);
138+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer_resolved) );
139+
g_gc.GCAdd(frame_buffer_resolved);
140+
CHECK( rprContextSetAOV(context, RPR_AOV_COLOR, frame_buffer) );
141+
142+
// Create the frambuffers dedicated to the shadow catching.
143+
rpr_framebuffer frame_buffer_shadowCatcher_unresolved = 0;
144+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer_shadowCatcher_unresolved) );
145+
g_gc.GCAdd(frame_buffer_shadowCatcher_unresolved);
146+
rpr_framebuffer frame_buffer_shadowCatcher_resolved = 0;
147+
CHECK( rprContextCreateFrameBuffer(context, fmt, &desc, &frame_buffer_shadowCatcher_resolved) );
148+
g_gc.GCAdd(frame_buffer_shadowCatcher_resolved);
149+
CHECK( rprContextSetAOV(context, RPR_AOV_SHADOW_CATCHER, frame_buffer_shadowCatcher_unresolved) );
150+
151+
152+
// set rendering gamma
153+
CHECK( rprContextSetParameterByKey1f(context, RPR_CONTEXT_DISPLAY_GAMMA , 2.2f ) );
154+
155+
// Render the scene
156+
CHECK( rprContextSetParameterByKey1u(context,RPR_CONTEXT_ITERATIONS, 200));
157+
CHECK( rprContextRender(context) );
158+
159+
// resolve and render the color framebuffer
160+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
161+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"36_0_c.png"));
162+
163+
// resolve and render the shadow-catcher framebuffer
164+
// Note that we use 'true' for the last argument of rprContextResolveFrameBuffer. This is because we don't want to apply gamma on the shadow catcher AOV.
165+
// That would not make sense as this AOV reprents a "shadow quantity", not a real color.
166+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer_shadowCatcher_unresolved,frame_buffer_shadowCatcher_resolved, true) );
167+
CHECK( rprFrameBufferSaveToFile(frame_buffer_shadowCatcher_resolved,"36_0_s.png"));
168+
169+
170+
/////////////////////
171+
//
172+
// demo of the RPR_CONTEXT_SHADOW_CATCHER_BAKING parameter.
173+
// If we turn it to 0, the shadow catcher plane will be invisible in the color framebuffer.
174+
// this parameter doesn't affect the Shadow Catcher AOV.
175+
//
176+
177+
CHECK( rprContextSetParameterByKey1u(context,RPR_CONTEXT_SHADOW_CATCHER_BAKING,0));
178+
179+
// always clear previous AOVs before starting a new rendering.
180+
CHECK( rprFrameBufferClear(frame_buffer));
181+
CHECK( rprFrameBufferClear(frame_buffer_shadowCatcher_unresolved));
182+
183+
CHECK( rprContextRender(context) );
184+
CHECK( rprContextResolveFrameBuffer(context,frame_buffer,frame_buffer_resolved,false));
185+
CHECK( rprFrameBufferSaveToFile(frame_buffer_resolved,"36_1_c.png"));
186+
187+
188+
/////////////////////
189+
//
190+
// Release the stuff we created
191+
192+
g_gc.GCClean();
193+
CHECK( rprObjectDelete(scene)); scene=nullptr;
194+
CHECK( rprObjectDelete(matsys)); matsys=nullptr;
195+
CheckNoLeak(context);
196+
CHECK( rprObjectDelete(context)); context=nullptr;
197+
return 0;
198+
}
199+
200+
201+
202+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
project "36_shadow_catcher"
2+
kind "ConsoleApp"
3+
location "../build"
4+
files { "../36_shadow_catcher/**.h", "../36_shadow_catcher/**.cpp"}
5+
files { "../common/common.cpp","../common/common.h"}
6+
7+
-- remove filters for Visual Studio
8+
vpaths { [""] = { "../36_shadow_catcher/**.h", "../36_shadow_catcher/**.cpp","../common/common.cpp","../common/common.h"} }
9+
10+
11+
includedirs{ "../../RadeonProRender/inc" }
12+
13+
buildoptions "-std=c++14"
14+
15+
configuration {"x64"}
16+
links {"RadeonProRender64"}
17+
18+
if os.istarget("linux") then
19+
links {"pthread"}
20+
end
21+
22+
configuration {"x64", "Debug"}
23+
targetdir "../Bin"
24+
configuration {"x64", "Release"}
25+
targetdir "../Bin"
26+
configuration {}
27+
11.9 KB
Loading

tutorials/make_vs22.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
..\premake5\win\premake5.exe vs2022

tutorials/premake5.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ solution "Tutorials"
9999
include "33_aov"
100100
include "34_material_per_face"
101101
include "35_advanced_texturing"
102+
include "36_shadow_catcher"
102103
include "50_curve"
103104
include "51_volume"
104105
include "60_mesh_export"

tutorials/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ List of tutorials in this SDK
2626
| [AOVs](33_aov) | ![](33_aov/screenshot.png) | This demo covers AOV (Arbitrary Output Variables), providing way to render different material component - mostly used for scene debugging. |
2727
| [Material Per Face](34_material_per_face) | ![](34_material_per_face/screenshot.png) | Demo of the rprShapeSetMaterialFaces API. This allows to set materials for specific faces of the shape. |
2828
| [Advanced Texturing](35_advanced_texturing) | ![](35_advanced_texturing/screenshot.png) | This demo shows different features related to texture manipulation: Manage the UV, create procedural textures, use arthmetics and custom materials, texture wrapping. |
29+
| [Shadow Catcher](36_shadow_catcher) | ![](36_shadow_catcher/screenshot.png) | Demo of the Shadow Catcher. If a shape has this feature activated, it will "catch" the shadow. This shadow quantity can be rendered on a dedicated AOV. |
2930
| [Curves](50_curve) | ![](50_curve/screenshot.png) | Demo covering Curves rendering. Curves are often used for hair rendering. |
3031
| [Volume](51_volume) | ![](51_volume/screenshot.png) | This demo demonstrates Volumes with RPR |
3132
| [RPR Scene Export](60_mesh_export) | ![](60_mesh_export/screenshot.png) | Shows how to export an RPR scene as RPRS files ( native RPR file format ) or GLTF ( Khronos Group ). |

0 commit comments

Comments
 (0)