def Demarrer(): """ Démarre l'animation """ global Arret # # Preparation de la scene à rendre # # theScene.load("xmlfile") # pos = vec3(0,0,10) # theScene.insert( Sphere( pos, 1, "bouboule", Material( color(1,0,0) ) ) ) # pos = vec3(-1,0,8) # theScene.insert( Sphere( pos, 1, "bouboule2", Material( color(0,1,0) ) ) ) # pos = vec3(1,0,12) # theScene.insert( Sphere( pos, 1, "bouboule3", Material( color(0,0,1) ) ) ) # for p in range(0,10): # x = int(random.triangular()*RenderParam.width) # y = int(random.triangular()*RenderParam.height) # Img.put( "#FFF", (x, y) ) ############### pos = vec3(2,4,8) theScene.insert( Sphere( pos, 2, "light", Material( color(1,1,1), pEmissivity=8.0 ) ) ) pos = vec3(0,0.5,8) theScene.insert( Sphere( pos, 0.8, "bouboule2", Material( color(0,1,0) ) ) ) pos = vec3(0,-1.2,8) theScene.insert( Sphere( pos, 0.8, "bouboule3", Material( color(0,0,1) ) ) ) pos = vec3(0,0,0) up = vec3(0,1,0) direction = vec3(0,0,1) cam = Camera( pos, up, direction, "macam" ) theScene.insert( cam ) theScene.setActiveCamera( cam ) theRenderer.setScene( theScene ) theRenderer.reset() # print theScene.getObject("bouboule") # print theScene.getObject("macam") # print "activeCam: %r" % theScene.getObject("macam") if Arret == True: Arret = False RenderPixel()
def renderPixel(self, pX, pY): """ """ currColor = color(0,0,0) for dX in RenderParam.sampling: for dY in RenderParam.sampling: for samples in range(0, RenderParam.renderSampling): sx = random.triangular() sy = random.triangular() currColor += self.radiance( self.getCurrentRay( pX+dX+sx, pY+dY+sy), 0 ) # currColor += self.radiance( self.getCurrentRay( pX+dX, pY+dY), 0 ) res = currColor / (RenderParam.subSampling*RenderParam.subSampling*RenderParam.renderSampling) # Normalize color exposure res._r = 1.0 - math.exp(res._r * RenderParam.exposure); res._g = 1.0 - math.exp(res._g * RenderParam.exposure); res._b = 1.0 - math.exp(res._b * RenderParam.exposure); return (res*255).hexa()
def radiance(self, pRay, pDepth): """ """ pDepth += 1 self._stats['numCallRadiance'] += 1 if RenderParam.maxDepth < pDepth: return RenderParam.backgroundColor # if pDepth > 2: # print "pDepth:%d - ray: %s" % (pDepth, pRay) # # Find intersection # intersectionDict = {} for item in self._scene: # print "checking object %s with ray %r" % (item._name, pRay) intersectInfo = item.intersect(pRay) if intersectInfo is not None: intersectionDict[ intersectInfo['distance'] ] = intersectInfo if len(intersectionDict) is not 0: closest = intersectionDict[sorted(intersectionDict.keys())[0]] else: return RenderParam.backgroundColor currObj = closest['object'] intersectColor = copy(currObj._mat._color) # # Stop recursion # # maxTerm = currObj._mat._color.maxTerm() # if 5 < pDepth or maxTerm is not 0: # if RenderParam.maxDepth < pDepth: # # if russian roulette result < maxTerm: # # intersectColor /= maxTerm # # else: # resColor = currObj._mat._color * currObj._mat._emissivity # return resColor # # refract term # # # reflect term # # # diffuse term # r1 = 2*pi*random.uniform(0.0,1.0) r2 = random.uniform(0.0,1.0) r2s = math.sqrt(r2) w = closest['orientedNormal'] tmp = vec3(0,1,0) if (math.fabs(w.x)>0.1) else vec3(1,0,0) u = vec3.crossProduct(tmp,w).normalize() v = vec3.crossProduct(w,u) newDir = ( u*cos(r1)*r2s + v*sin(r1)*r2s + w*math.sqrt(1-r2)).normalize() newRay = Ray( closest['pos'], newDir ) # # print "sampleColor for %s at depth %d" % (newRay, pDepth) sampledColor = self.radiance( newRay, pDepth ) # sampledColor = color(0) # IS term: iterate over all lights importanceSamplingTerm = color(0.0,0.0,0.0) for light in self._scene: if (light._visible==True and hasattr(light,'_mat') \ and light._mat._emissivity > 0) \ and light is not currObj: # sw = light._pos - closest['pos'] # if 0.1 < math.fabs(sw.x): # su = vec3(0,1,0) # else: # su = vec3(1,0,0) # sv = vec3.crossProduct(sw, su) # tmp = (closest['pos']-light._pos) * (closest['pos']-light._pos) # cos_a_max = math.sqrt( 1 - (light._radius*light._radius) / tmp ) # eps1 = random.uniform(0,1) # eps2 = random.uniform(0,1) # cos_a = 1 - eps1 + eps1*cos_a_max # sin_a = math.sqrt( 1 - cos_a*cos_a ) # phi = 2*pi*eps2 # # # Create random direction # lightVec = su*math.cos(phi)*sin_a + \ # sv*math.sin(phi)*sin_a + \ # sw*cos_a # lightVec.normalize() # ou alors avec un vecteur direct intersection -> lum lightVec = light._pos - closest['pos'] lightVec.normalize() tmp = lightVec * closest['normal'] if 0<tmp: # importanceSamplingTerm = tmp*0.1 * currObj._mat._color * light._mat._emissivity # Shoot shadow ray shadowIntersectionDict = {} for item in self._scene: shadowIntersectInfo = item.intersect( Ray(closest['pos'], lightVec) ) if shadowIntersectInfo is not None: shadowIntersectionDict[ shadowIntersectInfo['distance'] ] = shadowIntersectInfo # print len(shadowIntersectionDict) if len(shadowIntersectionDict) != 0: closestLight = shadowIntersectionDict[sorted(shadowIntersectionDict.keys())[0]] print "closest %r, emit:%f" % (closestLight['object'], closestLight['object']._mat._emissivity) if closestLight['object']._mat._emissivity > 0: importanceSamplingTerm = tmp*0.1 * currObj._mat._color * light._mat._emissivity # else: # importanceSamplingTerm = color(0,1,0) # Shoot shadow ray # shadowIntersectionDict = {} # for item in self._scene: # shadowIntersectInfo = item.intersect(Ray(closest['pos'], lightVec)) # if shadowIntersectInfo is not None: # shadowIntersectionDict[ shadowIntersectInfo['distance'] ] = shadowIntersectInfo # if len(shadowIntersectionDict) is not 0: # closest = intersectionDict[sorted(intersectionDict.keys())[0]] # if closest['object'] is light: # omega = 2 * pi * (1 - cos_a_max) # importanceSamplingTerm = currObj._mat._color * light._mat._emissivity * (lightVec * closest['orientedNormal']) * (omega /pi) # else: # #pb ici!... # importanceSamplingTerm = color(1,0,0) # return EMISSIVE TERM + IS TERM + MIX INTERSECTION AND SAMPLES # return (currObj._mat._color*currObj._mat._emissivity + importanceSamplingTerm + intersectColor*sampledColor) # return (sampledColor) return ( importanceSamplingTerm )