1// Copyright 2009-2021 Intel Corporation 2// SPDX-License-Identifier: Apache-2.0 3 4#include "../common/tutorial/tutorial_device.isph" 5#include "../common/math/random_sampler.isph" 6 7struct Point 8{ 9 ALIGNED_STRUCT_(16) 10 Vec3f p; //!< position 11}; 12 13struct PointQueryResult 14{ 15 ALIGNED_STRUCT_(16) 16 unsigned int primID; 17}; 18 19struct PointQuery 20{ 21 Vec3f p; 22 float time; 23 float radius; 24}; 25 26/* scene data */ 27RTCScene g_scene = NULL; 28uniform Point* uniform g_points = NULL; 29const uniform int g_num_colors = 27; 30uniform Vec3fa g_colors[g_num_colors]; 31 32extern uniform int g_num_points; 33uniform int g_num_points_current; 34 35void renderTileStandardStream(uniform int taskIndex, 36 uniform int threadIndex, 37 uniform int* uniform pixels, 38 const uniform unsigned int width, 39 const uniform unsigned int height, 40 const uniform float time, 41 const uniform ISPCCamera& camera, 42 const uniform int numTilesX, 43 const uniform int numTilesY); 44 45// ======================================================================== // 46// User defined point geometry // 47// ======================================================================== // 48 49unmasked void pointBoundsFunc(const struct RTCBoundsFunctionArguments* uniform args) 50{ 51 const uniform Point* uniform points = (const uniform Point* uniform) args->geometryUserPtr; 52 uniform RTCBounds* uniform bounds_o = args->bounds_o; 53 const uniform Point& point = points[args->primID]; 54 bounds_o->lower_x = point.p.x; 55 bounds_o->lower_y = point.p.y; 56 bounds_o->lower_z = point.p.z; 57 bounds_o->upper_x = point.p.x; 58 bounds_o->upper_y = point.p.y; 59 bounds_o->upper_z = point.p.z; 60} 61 62unmasked bool pointQueryFunc(RTCPointQueryFunctionArguments* uniform args) 63{ 64 assert(args->userPtr); 65 66 RTCPointQuery* query = (RTCPointQuery*)args->query; 67 unsigned int primID = args->primID; 68 Vec3f q = make_Vec3f(query->x, query->y, query->z); 69 const Point point = g_points[primID]; 70 const float d = distance(point.p, q); 71 72 if(d < query->radius) 73 { 74 PointQueryResult* result = (PointQueryResult*)args->userPtr; 75 result->primID = primID; 76 query->radius = d; 77 return true; 78 } 79 return false; 80} 81 82uniform Point* uniform createPoints (RTCScene scene, uniform unsigned int N) 83{ 84 RTCGeometry geom = rtcNewGeometry(g_device, RTC_GEOMETRY_TYPE_USER); 85 g_points = uniform new uniform Point[N]; 86 uniform unsigned int geomID = rtcAttachGeometry(scene, geom); 87 rtcSetGeometryUserPrimitiveCount(geom, N); 88 rtcSetGeometryUserData(geom, g_points); 89 rtcSetGeometryBoundsFunction(geom, pointBoundsFunc, NULL); 90 rtcCommitGeometry(geom); 91 rtcReleaseGeometry(geom); 92 93 RandomSampler rs; 94 RandomSampler_init(rs, 42); 95 for (unsigned int i = 0; i < N; ++i) 96 { 97 float xi1 = RandomSampler_getFloat(rs); 98 float xi2 = RandomSampler_getFloat(rs); 99 g_points[i].p = make_Vec3f(xi1, 0.f, xi2); 100 } 101 102 g_num_points_current = N; 103 return g_points; 104} 105 106/* called by the C++ code for initialization */ 107export void device_init (uniform int8* uniform cfg) 108{ 109 /* create scene */ 110 g_scene = rtcNewScene(g_device); 111 g_points = createPoints(g_scene, g_num_points); 112 rtcCommitScene(g_scene); 113 114 /* set all colors */ 115 for (uniform int r = 0; r < 3; ++r) 116 for (uniform int g = 0; g < 3; ++g) 117 for (uniform int b = 0; b < 3; ++b) 118 g_colors[r * 9 + g * 3 + b] = make_Vec3fa(0.2f + 0.3f * r, 0.2f + 0.3f * g, 0.2f + 0.3f * b); 119 120} 121 122/* renders a single screen tile */ 123void renderTileStandard(uniform int taskIndex, 124 uniform int threadIndex, 125 uniform int* uniform pixels, 126 const uniform unsigned int width, 127 const uniform unsigned int height, 128 const uniform float time, 129 const uniform ISPCCamera& camera, 130 const uniform int numTilesX, 131 const uniform int numTilesY) 132{ 133 const uniform unsigned int tileY = taskIndex / numTilesX; 134 const uniform unsigned int tileX = taskIndex - tileY * numTilesX; 135 const uniform unsigned int x0 = tileX * TILE_SIZE_X; 136 const uniform unsigned int x1 = min(x0+TILE_SIZE_X,width); 137 const uniform unsigned int y0 = tileY * TILE_SIZE_Y; 138 const uniform unsigned int y1 = min(y0+TILE_SIZE_Y,height); 139 140 foreach_tiled (y = y0 ... y1, x = x0 ... x1) 141 { 142 if (all(__mask == 0)) continue; 143 144 /* calculate pixel color */ 145 Vec3fa color = make_Vec3fa(0.f); 146 Vec3f q = make_Vec3f(((float)x + 0.5f) / width, 0.f, ((float)y + 0.5f) / height); 147 148 PointQuery query; 149 query.p = q; 150 query.time = 0.f; 151 query.radius = inf; 152 153 uniform PointQueryResult result[programCount]; 154 result[programIndex].primID = RTC_INVALID_GEOMETRY_ID; 155 void* userPtr = (void*)&result[programIndex]; 156 157 uniform RTCPointQueryContext context; 158 rtcInitPointQueryContext(&context); 159 rtcPointQueryV(g_scene, 160 (varying RTCPointQuery* uniform)&query, 161 &context, 162 pointQueryFunc, 163 &userPtr); 164 165 unsigned int primID = result[programIndex].primID; 166 167 if (primID != RTC_INVALID_GEOMETRY_ID) 168 color = g_colors[primID % 27]; 169 170 /* write color to framebuffer */ 171 unsigned int r = (unsigned int) (255.0f * clamp(color.x,0.0f,1.0f)); 172 unsigned int g = (unsigned int) (255.0f * clamp(color.y,0.0f,1.0f)); 173 unsigned int b = (unsigned int) (255.0f * clamp(color.z,0.0f,1.0f)); 174 pixels[y*width+x] = (b << 16) + (g << 8) + r; 175 } 176} 177 178/* task that renders a single screen tile */ 179task void renderTileTask(uniform int* uniform pixels, 180 const uniform unsigned int width, 181 const uniform unsigned int height, 182 const uniform float time, 183 const uniform ISPCCamera& camera, 184 const uniform int numTilesX, 185 const uniform int numTilesY) 186{ 187 renderTileStandard(taskIndex,threadIndex,pixels,width,height,time,camera,numTilesX,numTilesY); 188} 189 190void splat_color(uniform int* pixels, 191 const uniform unsigned int width, 192 const uniform unsigned int height, 193 const uniform int kernel_size, 194 float x, float y, Vec3fa const& color) 195{ 196 for (int dy = -kernel_size; dy <= kernel_size; ++dy) 197 for (int dx = -kernel_size; dx <= kernel_size; ++dx) 198 { 199 unsigned int r = (unsigned int)(255.0f * clamp(color.x, 0.0f, 1.0f)); 200 unsigned int g = (unsigned int)(255.0f * clamp(color.y, 0.0f, 1.0f)); 201 unsigned int b = (unsigned int)(255.0f * clamp(color.z, 0.0f, 1.0f)); 202 const unsigned int px = (unsigned int)min(width - 1.f, max(0.f, x * width + dx)); 203 const unsigned int py = (unsigned int)min(height - 1.f, max(0.f, y * height + dy)); 204 pixels[py*width + px] = (b << 16) + (g << 8) + r; 205 } 206} 207 208 209task void drawPoints(uniform int* uniform pixels, 210 const uniform unsigned int width, 211 const uniform unsigned int height) 212{ 213 Point p = g_points[taskIndex]; 214 Vec3fa color = g_colors[taskIndex % g_num_colors] / 0.8f; 215 splat_color(pixels, width, height, 2, p.p.x, p.p.z, color); 216} 217 218export void renderFrameStandard (uniform int* uniform pixels, 219 const uniform unsigned int width, 220 const uniform unsigned int height, 221 const uniform float time, 222 const uniform ISPCCamera& camera) 223{ 224 /* render all pixels */ 225 const uniform int numTilesX = (width +TILE_SIZE_X-1)/TILE_SIZE_X; 226 const uniform int numTilesY = (height+TILE_SIZE_Y-1)/TILE_SIZE_Y; 227 launch[numTilesX*numTilesY] renderTileTask(pixels,width,height,time,camera,numTilesX,numTilesY); sync; 228 229 launch[g_num_points] drawPoints(pixels, width, height); sync; 230} 231 232/* called by the C++ code to render */ 233export void device_render (uniform int* uniform pixels, 234 const uniform unsigned int width, 235 const uniform unsigned int height, 236 const uniform float time, 237 const uniform ISPCCamera& camera) 238{ 239 if (g_num_points != g_num_points_current) 240 { 241 rtcReleaseScene (g_scene); 242 g_scene = rtcNewScene(g_device); 243 delete[] g_points; g_points = NULL; 244 g_points = createPoints(g_scene, g_num_points); 245 rtcCommitScene(g_scene); 246 } 247} 248 249/* called by the C++ code for cleanup */ 250export void device_cleanup () 251{ 252 rtcReleaseScene (g_scene); g_scene = NULL; 253 rtcReleaseDevice(g_device); g_device = NULL; 254 delete[] g_points; g_points = NULL; 255} 256