 
 	Context ctx;
 	{
-		ctx.geomnum = num;
+		ctx.geomnum = geomnum;
 		ctx.shapes = shapes;
 		ctx.mtrls = mtrls;
+		ctx.lightnum = lightnum;
+		ctx.lights = lights;
 	}
 
 	const auto idx = iy * camera->width + ix;

		cam.ptr(),
		spheres.ptr(), AT_COUNTOF(g_spheres),
		materials.ptr(),
		lightmem.ptr());

	checkCudaErrors(cudaDeviceSynchronize());


			if (m.attrib.isSingular || m.attrib.isTranslucent) {
			}
			else {
				for (int i = 0; i < lightnum; i++) {
					// TODO
					auto light = lights[i];
					auto* sphere = &ctx.shapes[light.object.idx];
					light.object.ptr = sphere;

					aten::LightSampleResult sampleres = sampleLight(light, rec.p, nullptr);

					aten::vec3 dirToLight = sampleres.dir;
					auto len = dirToLight.length();

					dirToLight.normalize();

					auto albedo = m.baseColor;

					aten::ray shadowRay(rec.p, dirToLight);

					aten::hitrecord tmpRec;

					auto funcHitTest = [&] AT_DEVICE_API(const aten::ray& _r, float t_min, float t_max, aten::hitrecord& _rec)
					{
						return intersect(&_r, &_rec, &ctx);
					};

					if (aten::scene::hitLight(funcHitTest, light, sampleres.pos, shadowRay, AT_MATH_EPSILON, AT_MATH_INF, tmpRec)) {
						auto lightColor = sampleres.finalColor;

						if (light.attrib.isInfinite) {
							len = 1.0f;
						}

						const auto c0 = max(0.0f, dot(orienting_normal, dirToLight));
						float c1 = 1.0f;

						if (!light.attrib.isSingular) {
							c1 = max(0.0f, dot(sampleres.nml, -dirToLight));
						}

						auto G = c0 * c1 / (len * len);

						contrib += throughput * (albedo * lightColor) * G;
					}
				}
				break;
			}
		}
		else {
