// File: /workspace/github_cpp_makefile_star2_O2/soybin[P]idyll/src/renderer.cpp
// Function: renderer::render(double, double)
math::vec3 renderer::render(double y, double x) {

	// get ray direction relative to the pixel being rendered
	// coordinates and rotate it
	math::vec3 dir = calculateRayDirection(x, y);
	math::vec3 color(0.0);

	//
	// render same pixel multiple times
	//
	for (int i = 0; i < SAMPLES; ++i) {

		//
		// data per sample
		//
		math::ray r(cameraPosition, dir);
		math::vec3 colorLeft(1.0);
		math::vec3 colorAccumulated(0.0);

		//
		// path tracing
		//
		double fdist = 0.0;
		for (int i = 0; i < BOUNCES; ++i) {

			//
			// get distance from fractal marching the ray's direction
			//
			double distance = march(r);
			if (distance == -1.0) {
				if (i == 0) {
					colorAccumulated = renderSky(y, x);
				}
				break;
			}

			//
			// record initial distance
			//
			if (i == 0) {
				fdist = distance;
			}

			//
			// get current position and normal
			//
			math::vec3 point = r.origin + r.direction * distance;
			math::vec3 normal = f->calculateNormal(point);	

			//
			// get fractal surface color
			//
			math::vec3 colorAtPoint = f->calculateColor(point);

			math::vec3 colorLighting(0.0);
			//
			// directional light
			//
			double dl = std::max(0.0, math::dot(lightDirection, normal));
			double dlShadow = 1.0;
			if (dl > 0.0) {
				dlShadow = f->calculateShadow({r.origin + r.direction * MIN_DIST, lightDirection});
			}
			colorLighting += lightColor * dl * dlShadow;

			//
			// sky light
			//
			double skyShadow = f->calculateShadow({r.origin + r.direction * MIN_DIST, brdf(r.direction, normal)});
			colorLighting += skyColor * skyShadow;

			//
			// add bounce color to sample color
			//
			colorLeft *= colorAtPoint;
			colorAccumulated += colorLeft * colorLighting;

			//
			// bounce ray
			//
			r.origin = point;
			r.direction = brdf(r.direction, normal);
		}

		//
		// scaling / grading
		//
		double ff = std::exp(-0.01 * fdist * fdist);
		colorAccumulated *= ff;
		colorAccumulated += math::vec3(0.9, 1.0, 1.0) * (1.0 - ff) *0.05;

		//
		// add clamped sample color to average color
		//
		color += math::clamp(colorAccumulated, 0.0, 1.0);
	}
	//get average of paths colors
	color /= (double)SAMPLES;

	// apply gamma correction
	color.x = pow(color.x, 0.45);
	color.y = pow(color.y, 0.45);
	color.z = pow(color.z, 0.45);

	return color * 255.0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x248, %rsp            # imm = 0x248
movaps %xmm0, %xmm2
movq %rsi, %r14
movq %rdi, -0x80(%rbp)
leaq -0x1f8(%rbp), %rdi
movaps %xmm1, %xmm0
movsd %xmm2, -0x88(%rbp)
movaps %xmm2, %xmm1
callq 0x664a
leaq -0x1e0(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0x5c32
leaq 0x30(%r14), %rax
movq %rax, -0x90(%rbp)
leaq -0xd8(%rbp), %r13
leaq 0x48(%r14), %rax
movq %rax, -0x48(%rbp)
leaq 0x60(%r14), %rax
movq %rax, -0xa0(%rbp)
leaq 0x78(%r14), %rax
movq %rax, -0x98(%rbp)
xorl %ecx, %ecx
movl 0xc(%r14), %eax
cmpl %eax, %ecx
jge 0x77b6
movl %ecx, -0x3c(%rbp)
movq -0x90(%rbp), %rcx
movq 0x10(%rcx), %rax
movq %rax, -0xe0(%rbp)
movups (%rcx), %xmm0
movaps %xmm0, -0xf0(%rbp)
movq -0x1e8(%rbp), %rax
movq %rax, 0x10(%r13)
movups -0x1f8(%rbp), %xmm0
movups %xmm0, (%r13)
leaq -0x228(%rbp), %rdi
movsd 0x5362(%rip), %xmm0     # 0xc678
callq 0x5c32
xorpd %xmm0, %xmm0
movsd %xmm0, -0x30(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x5c32
xorl %ebx, %ebx
cmpl 0x10(%r14), %ebx
jge 0x76e5
movapd -0xf0(%rbp), %xmm0
movaps -0xe0(%rbp), %xmm1
movaps -0xd0(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movupd %xmm0, (%rsp)
movq %r14, %rdi
callq 0x6f7e
ucomisd 0x54ff(%rip), %xmm0     # 0xc870
jne 0x7379
jnp 0x76bb
movapd %xmm0, %xmm1
testl %ebx, %ebx
je 0x7386
movsd -0x30(%rbp), %xmm1
movsd %xmm1, -0xa8(%rbp)
movl %ebx, -0x30(%rbp)
leaq -0x60(%rbp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x5cf6
leaq -0x78(%rbp), %rdi
leaq -0xf0(%rbp), %r12
movq %r12, %rsi
movq %r15, %rdx
callq 0x5c5a
movq 0xc0(%r14), %rsi
movq -0x68(%rbp), %rax
movq %rax, 0x10(%rsp)
movups -0x78(%rbp), %xmm0
movups %xmm0, (%rsp)
movq %r15, %rdi
callq 0x84e2
movq 0xc0(%r14), %rsi
movq -0x68(%rbp), %rax
movq %rax, 0x10(%rsp)
movups -0x78(%rbp), %xmm0
movups %xmm0, (%rsp)
leaq -0x1c8(%rbp), %rdi
callq 0x846a
xorps %xmm0, %xmm0
leaq -0x1b0(%rbp), %rdi
callq 0x5c32
movq -0x50(%rbp), %rax
movq %rax, 0x28(%rsp)
movups -0x60(%rbp), %xmm0
movups %xmm0, 0x18(%rsp)
movq -0x48(%rbp), %rcx
movq 0x10(%rcx), %rax
movq %rax, 0x10(%rsp)
movupd (%rcx), %xmm0
movupd %xmm0, (%rsp)
callq 0x5f5f
movapd %xmm0, %xmm1
ucomisd 0x54c6(%rip), %xmm0     # 0xc908
movsd 0x522e(%rip), %xmm0     # 0xc678
jbe 0x74ed
movq 0xc0(%r14), %r15
leaq -0x210(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
movsd 0x547c(%rip), %xmm0     # 0xc8e8
movsd %xmm1, -0x38(%rbp)
callq 0x5cf6
leaq -0x198(%rbp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x5c5a
movq -0x48(%rbp), %rcx
movq 0x10(%rcx), %rax
leaq -0x138(%rbp), %rdx
movq %rax, 0x10(%rdx)
movups (%rcx), %xmm0
movups %xmm0, (%rdx)
movq -0x188(%rbp), %rax
movq %rax, -0x140(%rbp)
movups -0x198(%rbp), %xmm0
movaps %xmm0, -0x150(%rbp)
movaps -0x150(%rbp), %xmm0
movaps -0x140(%rbp), %xmm1
movaps -0x130(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r15, %rdi
callq 0x8336
movsd -0x38(%rbp), %xmm1
movsd %xmm0, -0x38(%rbp)
maxsd 0x540e(%rip), %xmm1     # 0xc908
leaq -0x240(%rbp), %rbx
movq %rbx, %rdi
movq -0xa0(%rbp), %rsi
movapd %xmm1, %xmm0
callq 0x5cf6
movq %r12, %r15
movq %r14, %r12
leaq -0x210(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movsd -0x38(%rbp), %xmm0
callq 0x5cf6
leaq -0x1b0(%rbp), %rdi
movq %r14, %rsi
callq 0x5e1a
movq 0xc0(%r12), %rbx
movq %r14, %rdi
movq %r13, %rsi
movsd 0x5392(%rip), %xmm0     # 0xc8e8
callq 0x5cf6
leaq -0x180(%rbp), %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x5c5a
movq -0x50(%rbp), %rax
movq %rax, 0x28(%rsp)
movups -0x60(%rbp), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%r13), %rax
movq %rax, 0x10(%rsp)
movups (%r13), %xmm0
movups %xmm0, (%rsp)
leaq -0x168(%rbp), %rdi
movq %r12, %rsi
callq 0x7032
movq -0x158(%rbp), %rax
leaq -0x108(%rbp), %rcx
movq %rax, 0x10(%rcx)
movups -0x168(%rbp), %xmm0
movups %xmm0, (%rcx)
movups -0x180(%rbp), %xmm0
movaps %xmm0, -0x120(%rbp)
movq -0x170(%rbp), %rax
movq %rax, -0x110(%rbp)
movaps -0x120(%rbp), %xmm0
movaps -0x110(%rbp), %xmm1
movaps -0x100(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x8336
movq %r14, %rdi
movq -0x98(%rbp), %rsi
callq 0x5cf6
leaq -0x1b0(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x5e1a
leaq -0x228(%rbp), %r15
movq %r15, %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x5e7a
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x5cc2
leaq -0xc0(%rbp), %rdi
movq %r14, %rsi
callq 0x5e1a
leaq -0xf0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x5d8a
movq -0x50(%rbp), %rax
movq %rax, 0x28(%rsp)
movups -0x60(%rbp), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%r13), %rax
movq %rax, 0x10(%rsp)
movups (%r13), %xmm0
movups %xmm0, (%rsp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x7032
movq %r13, %rdi
movq %r14, %rsi
movq %r12, %r14
callq 0x5d8a
movl -0x30(%rbp), %ebx
incl %ebx
movsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
jmp 0x7332
testl %ebx, %ebx
jne 0x76e5
leaq -0x78(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
movsd -0x88(%rbp), %xmm0
callq 0x6814
leaq -0xc0(%rbp), %rdi
movq %rbx, %rsi
callq 0x5d8a
movsd -0x30(%rbp), %xmm1
movapd %xmm1, %xmm0
mulsd 0x522a(%rip), %xmm0     # 0xc920
mulsd %xmm1, %xmm0
callq 0x3470
movsd %xmm0, -0x30(%rbp)
leaq -0xc0(%rbp), %r12
movq %r12, %rdi
callq 0x5eaa
leaq -0x1c8(%rbp), %rbx
movq %rbx, %rdi
movsd 0x5203(%rip), %xmm0     # 0xc928
movsd 0x4f4b(%rip), %xmm1     # 0xc678
movaps %xmm1, %xmm2
callq 0x5c46
movsd 0x4f3b(%rip), %xmm0     # 0xc678
subsd -0x30(%rbp), %xmm0
leaq -0x60(%rbp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x5cf6
leaq -0x78(%rbp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movsd 0x51cd(%rip), %xmm0     # 0xc930
callq 0x5cf6
movq %r12, %rdi
movq %rbx, %rsi
callq 0x5e1a
movq -0xb0(%rbp), %rax
movq %rax, 0x10(%rsp)
movups -0xc0(%rbp), %xmm0
movups %xmm0, (%rsp)
xorps %xmm0, %xmm0
movq %rbx, %rdi
movsd 0x4ee0(%rip), %xmm1     # 0xc678
callq 0x6116
leaq -0x1e0(%rbp), %rdi
movq %rbx, %rsi
callq 0x5e1a
movl -0x3c(%rbp), %ecx
incl %ecx
jmp 0x72c5
cvtsi2sd %eax, %xmm0
leaq -0x1e0(%rbp), %rbx
movq %rbx, %rdi
callq 0x5f04
movsd (%rbx), %xmm0
movsd 0x513b(%rip), %xmm1     # 0xc910
callq 0x3450
movsd %xmm0, (%rbx)
movsd 0x8(%rbx), %xmm0
movsd 0x5125(%rip), %xmm1     # 0xc910
callq 0x3450
movsd %xmm0, 0x8(%rbx)
movsd 0x10(%rbx), %xmm0
movsd 0x510e(%rip), %xmm1     # 0xc910
callq 0x3450
movsd %xmm0, 0x10(%rbx)
movsd 0x5104(%rip), %xmm0     # 0xc918
movq -0x80(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x5cf6
movq %r14, %rax
addq $0x248, %rsp            # imm = 0x248
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq