void GLShader::bindLights(LightList& lights, Renderer* renderer) { int locOffset = 0; if ((mShaderLocs[LIGHT_UBO_INDEX].size() == 0) || lights.isDirty()) { mShaderLocs[LIGHT_UBO_INDEX].resize(lights.getNumUniforms()); lights.forEachLight([this, renderer, locOffset](Light& light) mutable { UniformBlock& lightData = light.uniforms().uniforms(); findUniforms(light, locOffset); lightData.bindBuffer(this, renderer, locOffset); locOffset += lightData.getNumEntries(); }); } else { lights.forEachLight([this, renderer, locOffset](Light& light) mutable { UniformBlock& lightData = light.uniforms().uniforms(); lightData.bindBuffer(this, renderer, locOffset); locOffset += lightData.getNumEntries(); }); } }
void updateLights() { for(LightList::iterator light = Lights.begin(); light != Lights.end(); light++) { if(light->on) { if(fabsf(light->orient.Yaw += (kPi/180.0f) * light->origin.Yaw ) >= k2Pi) light->orient.Yaw -= k2Pi; if(fabsf(light->orient.Pitch += (kPi/180.0f) * light->origin.Pitch) >= k2Pi) light->orient.Pitch -= k2Pi; if(fabsf(light->orient.Roll += (kPi/180.0f) * light->origin.Roll ) >= k2Pi) light->orient.Roll -= k2Pi; } } }
//------------------------------------------------------------------------------ void SegmentedDynamicLightManager::regenerateActiveLightList(const LightList& i_LightList) { //add the buffers to the segmented lists LightList::const_iterator itLight = i_LightList.begin(), itLightEnd = i_LightList.end(); for(;itLight != itLightEnd ; ++itLight) { const Light* pLight = (*itLight); Light::LightTypes type = pLight->getType(); if (((type == Light::LT_SPOTLIGHT) || (type == Light::LT_POINT)) && (pLight->getAttenuationRange() > 0)) { MapLightData::iterator it = mActiveLights.insert( MapLightData::value_type(pLight,LightData())).first; LightData& lightData = it->second; calculateLightBounds(pLight, lightData); } } }
void DrawScene() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glEnable( GL_LIGHTING ); glEnable( GL_DEPTH_TEST ); glPushMatrix(); Point3 p = camera.pos; Point3 t = camera.pos + camera.dir; Point3 u = camera.up; gluLookAt( p.x, p.y, p.z, t.x, t.y, t.z, u.x, u.y, u.z ); glRotatef( viewAngle1, 1, 0, 0 ); glRotatef( viewAngle2, 0, 0, 1 ); if ( lights.size() > 0 ) { for ( unsigned int i=0; i<lights.size(); i++ ) { lights[i]->SetViewportLight(i); } } else { float white[] = {1,1,1,1}; float black[] = {0,0,0,0}; Point4 p(camera.pos, 1); glEnable ( GL_LIGHT0 ); glLightfv( GL_LIGHT0, GL_AMBIENT, black ); glLightfv( GL_LIGHT0, GL_DIFFUSE, white ); glLightfv( GL_LIGHT0, GL_SPECULAR, white ); glLightfv( GL_LIGHT0, GL_POSITION, &p.x ); } DrawNode(&rootNode); glPopMatrix(); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); }
void setupLights() { Obj.ambientIntensity = 1.0f; Obj.ambientColor = vec3(0.2,0.2,0.2); light3 l; l.on = true; l.orient = vecMath::Normalize(vec3(1.0f,0.0f,0.2f)); l.origin = vec3(0.0,1.0,0.0); l.color = vec3(1.0,0.0,0.0); Lights.push_back(l); l.on = true; l.orient = vecMath::Normalize(vec3(0.0f,1.0f,0.2f)); l.origin = vec3(0.0,-1.333,0.0); l.color = vec3(0.0,1.0,0.0); Lights.push_back(l); l.on = true; l.orient = vecMath::Normalize(vec3(1.0f,1.0f,0.2f)); l.origin = vec3(1.5,1.5,0.0); l.color = vec3(0.0,0.0,1.0); Lights.push_back(l); }
//----------------------------------------------------------------------- void SceneNode::findLights(LightList& destList, Real radius, uint32 lightMask) const { // No any optimisation here, hope inherits more smart for that. // // If a scene node is static and lights have moved, light list won't change // can't use a simple global boolean flag since this is only called for // visible nodes, so temporarily visible nodes will not be updated // Since this is only called for visible nodes, skip the check for now // if (mCreator) { // Use SceneManager to calculate mCreator->_populateLightList(this, radius, destList, lightMask); } else { destList.clear(); } }
void DrawScene() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); const TextureMap *bgMap = background.GetTexture(); if ( bgMap ) { glDepthMask(GL_FALSE); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); Color c = background.GetColor(); glColor3f(c.r,c.g,c.b); if ( bgMap->SetViewportTexture() ) { glEnable( GL_TEXTURE_2D ); glMatrixMode( GL_TEXTURE ); Matrix3 tm = bgMap->GetInverseTransform(); Point3 p = tm * bgMap->GetPosition(); float m[16] = { tm[0],tm[1],tm[2],0, tm[3],tm[4],tm[5],0, tm[6],tm[7],tm[8],0, -p.x,-p.y,-p.z,1 }; glLoadMatrixf( m ); glMatrixMode( GL_MODELVIEW ); } else { glDisable( GL_TEXTURE_2D ); } glBegin(GL_QUADS); glTexCoord2f(0,1); glVertex2f(-1,-1); glTexCoord2f(1,1); glVertex2f( 1,-1); glTexCoord2f(1,0); glVertex2f( 1, 1); glTexCoord2f(0,0); glVertex2f(-1, 1); glEnd(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glDepthMask(GL_TRUE); glDisable( GL_TEXTURE_2D ); } glEnable( GL_LIGHTING ); glEnable( GL_DEPTH_TEST ); glPushMatrix(); Point3 p = camera.pos; Point3 t = camera.pos + camera.dir*camera.focaldist; Point3 u = camera.up; if ( camera.dof > 0 ) { Point3 v = camera.dir ^ camera.up; float r = sqrtf(float(rand())/RAND_MAX)*camera.dof; float a = M_PI * 2.0f * float(rand())/RAND_MAX; p += r*cosf(a)*v + r*sinf(a)*u; } gluLookAt( p.x, p.y, p.z, t.x, t.y, t.z, u.x, u.y, u.z ); glRotatef( viewAngle1, 1, 0, 0 ); glRotatef( viewAngle2, 0, 0, 1 ); if ( lights.size() > 0 ) { for ( unsigned int i=0; i<lights.size(); i++ ) { lights[i]->SetViewportLight(i); } } else { float white[] = {1,1,1,1}; float black[] = {0,0,0,0}; Point4 p(camera.pos, 1); glEnable ( GL_LIGHT0 ); glLightfv( GL_LIGHT0, GL_AMBIENT, black ); glLightfv( GL_LIGHT0, GL_DIFFUSE, white ); glLightfv( GL_LIGHT0, GL_SPECULAR, white ); glLightfv( GL_LIGHT0, GL_POSITION, &p.x ); } DrawNode(&rootNode); glPopMatrix(); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); }
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int reflection_bounceCount, int gi_bounceCount) const { Color ambientComp, diffuseComp, specularComp, reflectiveComp, refractiveComp, reflectionTotal, refractionTotal, noColor, diffuseReflection; diffuseReflection = ambientComp = diffuseComp = specularComp = reflectiveComp = refractiveComp = noColor = reflectionTotal = refractionTotal = Color(0.0f, 0.0f, 0.0f); Color fromReflection = Color(0.0f, 0.0f, 0.0f); Color fromRefraction = Color(0.0f, 0.0f, 0.0f); Point3 viewDirection = -ray.dir; float schlicksConstant, ratioOfRefraction; Color kd = diffuse.Sample(hInfo.uvw); int hitside = HIT_FRONT; float n1 = 1; float n2 = ior; for (int i = 0; i < lights.size(); i++) { Color lightColor = lights[i]->Illuminate(hInfo.p, hInfo.N); /*if (lightColor != noColor) {*/ if (lights[i]->IsAmbient()) { ambientComp = ambientComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw)); } else { //lightColor.ClampMinMax(); Point3 rayDir = ray.dir; globalPhotonMap.EstimateIrradiance<50>(lightColor, rayDir, 2.0f, hInfo.p, &hInfo.N); diffuseComp = diffuseComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw)); specularComp = specularComponent(lights[i], lightColor, viewDirection, hInfo, specular.Sample(hInfo.uvw), glossiness); } //} } /************************Refraction************************************************************/ if(refraction.Sample(hInfo.uvw) != noColor && reflection_bounceCount > 0) { Ray refractionRay; HitInfo refractionRayHit; refractionRayHit.Init(); refractionRay.p = hInfo.p; if (hInfo.front == HIT_FRONT) { refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal(hInfo.N, hInfo.p, refractionGlossiness), n1, n2); } else { refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal( -hInfo.N, hInfo.p, refractionGlossiness), n2, n1); } if(TraceRay(&rootNode, refractionRay, refractionRayHit, hitside)) { Point3 refractionDir = refractionRay.dir; refractiveComp += refractionRayHit.node->GetMaterial()->Shade(refractionRay, refractionRayHit, lights, --reflection_bounceCount); refractiveComp *= refraction.Sample(hInfo.uvw); } else { refractiveComp = environment.SampleEnvironment(refractionRay.dir); } } /********************Schlick's Approximation - Fresnel Reflection***************************/ schlicksConstant = pow(((n1 - n2) / (n1 + n2)), 2); ratioOfRefraction = schlicksConstant + (1 - schlicksConstant) * pow((1 - viewDirection.Dot(hInfo.N)), 5); reflectionTotal = ratioOfRefraction*refraction.Sample(hInfo.uvw); refractionTotal = (1 - ratioOfRefraction)*refraction.Sample(hInfo.uvw); ///*******************************************************************************************/ //refractiv eComp *= refractionTotal; //It = (1-R) * KT' reflectionTotal += reflection.Sample(hInfo.uvw); //Doing outside in case refraction didn't occured at all /*********************************************************************************************/ /**********************Reflection*************************************************************/ if(reflectionTotal != noColor && reflection_bounceCount > 0) { Ray reflectionViewVector; reflectionViewVector.dir = getReflectionVector(viewDirection, getPerturbedNormal(hInfo.N, hInfo.p, reflectionGlossiness)); reflectionViewVector.p = hInfo.p; HitInfo reflectionRayHit; reflectionRayHit.Init(); //--reflection_bounceCount; if (TraceRay(&rootNode, reflectionViewVector, reflectionRayHit, HIT_FRONT)) { fromReflection += reflectionRayHit.node->GetMaterial()->Shade(reflectionViewVector, reflectionRayHit, lights, --reflection_bounceCount); reflectiveComp = reflectionTotal * fromReflection; } else { reflectiveComp = environment.SampleEnvironment(reflectionViewVector.dir); } } /****************************************************************************************************/ if(GI_ALGO) { if (kd != noColor && gi_bounceCount > 0) { HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1); giHemiSampler.generateSamples(); Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f); HitInfo diffuseReflectionHitInfo; Ray diffuseReflectionRay; for (int i = 0; i < giHemiSampler.getCurrentSampleCount(); ++i) { randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset(); diffuseReflectionRay.p = hInfo.p; Point3 u = Point3(0.0f, 0.0f, 0.0f); Point3 v = Point3(0.0f, 0.0f, 0.0f); Point3 w = Point3(0.0f, 0.0f, 0.0f); w = hInfo.N; getOrthoNormalBasisVector(w, u, v); diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u + randomDirectionAtHitPoint.y * v + randomDirectionAtHitPoint.z *w; diffuseReflectionHitInfo.Init(); if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT)) { diffuseReflection = diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay, diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1); } else { diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir); } giHemiSampler.setSampleColor(i, diffuseReflection); giHemiSampler.setIsSampleHit(i, true); } diffuseReflection = giHemiSampler.getAveragedSampleListColor() * diffuseReflection * kd * M_PI; } } else { if (kd != noColor && gi_bounceCount > 0) { HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1); giHemiSampler.generateSamples(); Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f); HitInfo diffuseReflectionHitInfo; Ray diffuseReflectionRay; randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset(); diffuseReflectionRay.p = hInfo.p; Point3 u = Point3(0.0f, 0.0f, 0.0f); Point3 v = Point3(0.0f, 0.0f, 0.0f); Point3 w = Point3(0.0f, 0.0f, 0.0f); w = hInfo.N; getOrthoNormalBasisVector(w, u, v); diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u + randomDirectionAtHitPoint.y * v + randomDirectionAtHitPoint.z *w; diffuseReflectionHitInfo.Init(); if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT)) { diffuseReflection += diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay, diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1); diffuseReflection = diffuseReflection * kd; } else { diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir); } } } return (ambientComp + diffuseComp + specularComp+ reflectiveComp + refractiveComp + diffuseReflection); }
Color MtlBlinn::Shade(const Cone &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{ float bias = BIAS_SHADING; Color shade; Color rShade = Color(0,0,0); Color tShade = Color(0,0,0); const Material *mat; mat = hInfo.node->GetMaterial(); const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat); // cout<<"HInfo front: "<<hInfo.front<<endl; /* local copy */ Point3 P; P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z); Cone iRay = ray; Color ambInt = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw); Color allOther = Color(0,0,0); Color diffuse = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw); Color ambComponent = Color(0,0,0); Point3 newN = hInfo.N; for ( unsigned int i=0; i<lights.size(); i++ ) { if(lights[i]->IsAmbient()){ // cout<<"ambient "<<endl; Color intensity = lights[i]->Illuminate(hInfo.p); ambComponent += (ambInt * intensity); continue; } else{ // cout<<"other lighting "<<endl; Point3 L = -lights[i]->Direction(P); L.Normalize(); Point3 V = ray.p - P; V.Normalize(); Point3 LplusV = L + V; Point3 H = (L+V)/LplusV.Length(); H.Normalize(); float alpha = mb->glossiness; // Point3 N = hInfo.N; Point3 N = newN; float S = H.Dot(N); S = pow(S,alpha); float costheta = L.Dot(N)/(L.Length() * N.Length()); Color intensity = lights[i]->Illuminate(P); // cout<<"costheta "<<endl; allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular.Sample(hInfo.uvw, hInfo.duvw))) ; } /* finally add inta*cola + intall*costheta*(cold + s* colS)*/ shade = ambComponent + allOther; } /* Calculate refraction */ if(refraction.GetColor().r>0 && bounceCount>0){ //compute new jittered normal float gloss = refractionGlossiness; if(gloss){ float random = rand()/(float)RAND_MAX; float rRadius = sqrtf(random) * gloss; random = rand()/(float)RAND_MAX; float rAngle = random * 2.0 * M_PI; float x = rRadius * cos(rAngle); float y = rRadius * sin(rAngle); Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir; normalDir = hInfo.N; // normalDir.Normalize(); if(normalDir.Dot(xAxis) > 0.7) v1 = normalDir.Cross(yAxis); else v1 = normalDir.Cross(xAxis); v2 = v1.Cross(normalDir); v1.Normalize(); v2.Normalize(); v1 *= x; v2 *= y; newN = hInfo.N + v1.Length() + v2.Length(); newN.Normalize(); } else{ newN = hInfo.N; } //------------------------------------- Color reflShade = Color(0,0,0); float R0, Refl = 0.0f, Trans = 0.0f; HitInfo temp; temp.Init(); // Point3 N = hInfo.N; Point3 N = newN; // Point3 V = Point3(iRay.p.x - hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z); Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z); V.Normalize(); float n1 = 1, n2 = 1; if(hInfo.front){ /* Hitting from outside */ // temp.front = false; n2 = ior; // cout<<"outside "<<endl; } else if(!hInfo.front){ /* Transmission from the inside */ // temp.front = true; n1 = ior; // cout<<"intside... "<<endl; // N = -hInfo.N; N *= -1; } float ratio_n = n1 / n2; float costheta_v = -V.Dot(N); /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */ float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v); Point3 T = ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ; // cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl; Cone tRay = Cone(hInfo.p,T); //tRay.dir.Normalize(); tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */ tRay.p.y = tRay.p.y + bias *tRay.dir.y; tRay.p.z = tRay.p.z + bias *tRay.dir.z; // cout<<"B temp front: "<< temp.front<<endl; temp.timeInstance = hInfo.timeInstance; if(sin2theta_t <= 1){ if(RayTrace_2(tRay, temp)){ /* ray tracing after refraction */ // bounceCount--; tShade = temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount); } else{ /* no hit after refraction */ tShade = environment.SampleEnvironment(tRay.dir); } /* Calculate Schlick's approximation */ R0 = (n1 - n2)/(n1 + n2); R0 *= R0; double X = 0.0; // if(n1 > n2){ // X = 1.0 - sqrtf(1.0 - sin2theta_t); // } // else{ X = 1.0 - costheta_v; } X = 1.0 - costheta_v; Refl = R0 + (1.0 - R0) * X * X * X * X * X; Trans = 1.0 - Refl; tShade.r *= exp(-absorption.r * temp.z); tShade.g *= exp(-absorption.g * temp.z); tShade.b *= exp(-absorption.b * temp.z); } else {/* Total internal reflection */ Refl = 1.0f; } /* Calculate reflection due to reflectance */ if(bounceCount >0){ // N = hInfo.N; N = newN; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); //V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; //VR.Normalize(); Cone rRay = Cone(P + BIAS_SHADING * VR, VR); rRay.dir.Normalize(); HitInfo temp1; temp1.Init(); temp.timeInstance = hInfo.timeInstance; if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp1)){ bounceCount --; reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount); } else{ reflShade = environment.SampleEnvironment(rRay.dir); // reflShade = Color(1,100,1); } } } // cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl; tShade = refraction.GetColor().r * (Trans * tShade + Refl * reflShade); } /* calculate reflection*/ if(reflection.GetColor().r>0 && bounceCount > 0){ //compute new jittered normal float gloss = reflectionGlossiness; if(gloss){ float random = rand()/(float)RAND_MAX; float rRadius = sqrtf(random) * gloss; random = rand()/(float)RAND_MAX; float rAngle = random * 2.0 * M_PI; float x = rRadius * cos(rAngle); float y = rRadius * sin(rAngle); Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir; normalDir = hInfo.N; // normalDir.Normalize(); if(normalDir.Dot(xAxis) > 0.7) v1 = normalDir.Cross(yAxis); else v1 = normalDir.Cross(xAxis); v2 = v1.Cross(normalDir); v1.Normalize(); v2.Normalize(); v1 *= x; v2 *= y; newN = hInfo.N + v1+ v2; newN.Normalize(); } else{ newN = hInfo.N; } //------------------------------------- Point3 N = newN;//hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); // V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; Cone rRay = Cone(P + BIAS_SHADING * VR, VR); rRay.dir.Normalize(); HitInfo temp; temp.Init(); temp.timeInstance=hInfo.timeInstance; if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp)){ bounceCount--; rShade = reflection.GetColor().r * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount); } else{ rShade = reflection.GetColor().r *environment.SampleEnvironment(rRay.dir); // rShade = Color(1,111,1); } } } /* Add shade with reflected and refracted colors */ shade += (rShade + tShade); return shade; };
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{ float bias = BIAS_SHADING; Color shade; Color rShade = Color(0,0,0); Color tShade = Color(0,0,0); const Material *mat; mat = hInfo.node->GetMaterial(); const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat); // cout<<"HInfo front: "<<hInfo.front<<endl; /* local copy */ Point3 P; P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z); Ray iRay = ray; Color ambInt = mb->diffuse; Color allOther = Color(0,0,0); Color diffuse = mb->diffuse;; Color ambComponent = Color(0,0,0); for ( unsigned int i=0; i<lights.size(); i++ ) { if(lights[i]->IsAmbient()){ // cout<<"ambient "<<endl; Color intensity = lights[i]->Illuminate(hInfo.p); ambComponent += (ambInt * intensity); continue; } else{ // cout<<"other lighting "<<endl; Point3 L = -lights[i]->Direction(P); L.Normalize(); Point3 V = ray.p - P; V.Normalize(); Point3 LplusV = L + V; Point3 H = (L+V)/LplusV.Length(); H.Normalize(); float alpha = mb->glossiness; Point3 N = hInfo.N; float S = H.Dot(N); S = pow(S,alpha); float costheta = L.Dot(N)/(L.Length() * N.Length()); Color intensity = lights[i]->Illuminate(P); // cout<<"costheta "<<endl; allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular)) ; } /* finally add inta*cola + intall*costheta*(cold + s* colS)*/ shade = ambComponent + allOther; } /* Calculate refraction */ if(refraction.Grey()>0 && bounceCount>0){ Color reflShade = Color(0,0,0); float R0, Refl = 0.0f, Trans = 0.0f; HitInfo temp; temp.Init(); Point3 N = hInfo.N; // Point3 V = Point3(iRay.p.x - hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z); Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z); V.Normalize(); float n1 = 1, n2 = 1; if(hInfo.front){ /* Hitting from outside */ // temp.front = false; n2 = ior; // cout<<"outside "<<endl; } else if(!hInfo.front){ /* Transmission from the inside */ // temp.front = true; n1 = ior; // cout<<"intside... "<<endl; N = -hInfo.N; } float ratio_n = n1 / n2; float costheta_v = -V.Dot(N); /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */ float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v); Point3 T = ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ; // cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl; Ray tRay = Ray(hInfo.p,T); //tRay.dir.Normalize(); tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */ tRay.p.y = tRay.p.y + bias *tRay.dir.y; tRay.p.z = tRay.p.z + bias *tRay.dir.z; // cout<<"B temp front: "<< temp.front<<endl; if(sin2theta_t <= 1){ if(RayTrace_2(tRay, temp)){ // bounceCount--; // cout<<"A temp front: "<< temp.front<<endl; tShade = temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount); tShade.r *= exp(-absorption.r * temp.z); tShade.g *= exp(-absorption.g * temp.z); tShade.b *= exp(-absorption.b * temp.z); // shade = tShade; /* remove later */ // return shade; /* Calculate Schlick's approximation */ R0 = (n1 - n2)/(n1 + n2); R0 *= R0; double X = 0.0; // if(n1 > n2){ // X = 1.0 - sqrtf(1.0 - sin2theta_t); // } // else{ X = 1.0 - costheta_v; } X = 1.0 - costheta_v; Refl = R0 + (1.0 - R0) * X * X * X * X * X; Trans = 1.0 - Refl; } } else {/* Total internal reflection */ Refl = 1.0f; } /* Calculate reflection due to reflectance */ if(bounceCount >0){ N = hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); //V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; //VR.Normalize(); Ray rRay = Ray(P, VR); //rRay.dir.Normalize(); rRay.p.x = rRay.p.x + bias *rRay.dir.x; rRay.p.y = rRay.p.y + bias *rRay.dir.y; rRay.p.z = rRay.p.z + bias *rRay.dir.z; HitInfo temp1; temp1.Init(); if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp1)){ bounceCount --; reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount); } } } // cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl; tShade = refraction * (Trans * tShade + Refl * reflShade); } /* calculate reflection*/ if(reflection.Grey()>0 && bounceCount > 0){ Point3 N = hInfo.N; Point3 V = Point3(iRay.p.x - P.x, iRay.p.y - P.y, iRay.p.z - P.z); // V.Normalize(); Point3 VR = 2 * V.Dot(N) * N - V; Ray rRay = Ray(hInfo.p, VR); //rRay.dir.Normalize(); rRay.p.x = rRay.p.x + bias *rRay.dir.x; rRay.p.y = rRay.p.y + bias *rRay.dir.y; rRay.p.z = rRay.p.z + bias *rRay.dir.z; HitInfo temp; temp.Init(); if(rootNode.GetNumChild()>0){ if(RayTrace_2(rRay, temp)){ bounceCount--; rShade = reflection * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount); } } } /* Add shade with reflected and refracted colors */ shade += (rShade + tShade); return shade; };
int LoadScene(const char *filename) { cout<<"Load......."; TiXmlDocument doc(filename); if ( ! doc.LoadFile() ) { printf("Failed to load the file \"%s\"\n", filename); return 0; } TiXmlElement *xml = doc.FirstChildElement("xml"); if ( ! xml ) { printf("No \"xml\" tag found.\n"); return 0; } TiXmlElement *scene = xml->FirstChildElement("scene"); if ( ! scene ) { printf("No \"scene\" tag found.\n"); return 0; } TiXmlElement *cam = xml->FirstChildElement("camera"); if ( ! cam ) { printf("No \"camera\" tag found.\n"); return 0; } nodeMtlList.clear(); rootNode.Init(); materials.DeleteAll(); lights.DeleteAll(); LoadScene( scene ); // Assign materials int numNodes = nodeMtlList.size(); for ( int i=0; i<numNodes; i++ ) { Material *mtl = materials.Find( nodeMtlList[i].mtlName ); if ( mtl ) nodeMtlList[i].node->SetMaterial(mtl); } nodeMtlList.clear(); // Load Camera camera.Init(); camera.dir += camera.pos; TiXmlElement *camChild = cam->FirstChildElement(); while ( camChild ) { if ( COMPARE( camChild->Value(), "position" ) ) ReadVector(camChild,camera.pos); else if ( COMPARE( camChild->Value(), "target" ) ) ReadVector(camChild,camera.dir); else if ( COMPARE( camChild->Value(), "up" ) ) ReadVector(camChild,camera.up); else if ( COMPARE( camChild->Value(), "fov" ) ) ReadFloat (camChild,camera.fov); else if ( COMPARE( camChild->Value(), "width" ) ) camChild->QueryIntAttribute("value", &camera.imgWidth); else if ( COMPARE( camChild->Value(), "height" ) ) camChild->QueryIntAttribute("value", &camera.imgHeight); camChild = camChild->NextSiblingElement(); } camera.dir -= camera.pos; camera.dir.Normalize(); Point3 x = camera.dir ^ camera.up; camera.up = (x ^ camera.dir).GetNormalized(); renderImage.Init( camera.imgWidth, camera.imgHeight ); return 1; }
void LoadLight(TiXmlElement *element) { Light *light = NULL; // name const char* name = element->Attribute("name"); printf("Light ["); if ( name ) printf("%s",name); printf("]"); // type const char* type = element->Attribute("type"); if ( type ) { if ( COMPARE(type,"ambient") ) { printf(" - Ambient\n"); AmbientLight *l = new AmbientLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } } } else if ( COMPARE(type,"direct") ) { printf(" - Direct\n"); DirectLight *l = new DirectLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } else if ( COMPARE( child->Value(), "direction" ) ) { Point3 v(1,1,1); ReadVector( child, v ); l->SetDirection(v); printf(" direction %f %f %f\n",v.x,v.y,v.z); } } } else if ( COMPARE(type,"point") ) { printf(" - Point\n"); PointLight *l = new PointLight(); light = l; for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "intensity" ) ) { Color c(1,1,1); ReadColor( child, c ); l->SetIntensity(c); printf(" intensity %f %f %f\n",c.r,c.g,c.b); } else if ( COMPARE( child->Value(), "position" ) ) { Point3 v(0,0,0); ReadVector( child, v ); l->SetPosition(v); printf(" position %f %f %f\n",v.x,v.y,v.z); } } } else { printf(" - UNKNOWN\n"); } } if ( light ) { light->SetName(name); lights.push_back(light); } }
void avtOpenGL3DTextureVolumeRenderer::Render( const avtVolumeRendererImplementation::RenderProperties &props, const avtVolumeRendererImplementation::VolumeData &volume) { static bool haveIssuedWarning = false; #ifdef HAVE_LIBGLEW if(!(avt::glew::supported("GL_VERSION_1_2") || avt::glew::supported("GL_EXT_texture3D"))) #endif { if(!haveIssuedWarning) { avtCallback::IssueWarning("Volume rendering based on 3D textures " "is not supported on your GPU."); haveIssuedWarning = true; } return; } // save state of what we will modify glPushAttrib(GL_COLOR_BUFFER_BIT|GL_TEXTURE_BIT| GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT); // Get the transfer function int ncolors=256; int nopacities=256; unsigned char rgba[256*4]; props.atts.GetTransferFunction(rgba); // Get the dimensions int dims[3]; vtkRectilinearGrid *grid = (vtkRectilinearGrid *)volume.grid; grid->GetDimensions(dims); int nx=dims[0]; int ny=dims[1]; int nz=dims[2]; // Find the smallest power of two in each dimension // that will accomodate this data set int newnx = MAX(int(pow(2.0,1+int(log(double(nx-1))/log(2.0)))),1); int newny = MAX(int(pow(2.0,1+int(log(double(ny-1))/log(2.0)))),1); int newnz = MAX(int(pow(2.0,1+int(log(double(nz-1))/log(2.0)))),1); // Get the new lighting parameters LightList lights = avtCallback::GetCurrentLightList(); // Determine if we need to invalidate the old texture if (volumetex && (props.atts != oldAtts || lights != oldLights)) { glDeleteTextures(1, (GLuint*)&volumetexId); volumetexId = 0; delete[] volumetex; volumetex = NULL; } oldAtts = props.atts; oldLights = lights; // // Extract the lighting information from the actual light list // float light[4] = {0,0,1, 0}; float ambient = 0.0; // Find an ambient light int i; for (i=0; i<lights.NumLights(); i++) { const LightAttributes &l = lights.GetLight(i); if (l.GetEnabledFlag() && l.GetType()==LightAttributes::Ambient) { // Take it's overall brightness double rgba[4]; l.GetColor().GetRgba(rgba); ambient = l.GetBrightness() * (rgba[0]+rgba[1]+rgba[2])/3.; break; } } // Find a directional (object or camera) light for (i=0; i<lights.NumLights(); i++) { const LightAttributes &l = lights.GetLight(i); if (l.GetEnabledFlag() && l.GetType()!=LightAttributes::Ambient) { // Take it's direction const double *dir = l.GetDirection(); light[0] = dir[0]; light[1] = dir[1]; light[2] = dir[2]; break; } } // If we want to transform the light so it is attached to the camera: //I->MultiplyPoint(light, light); // // Create the 3D texture if we need to // if (!volumetex) { int nels=newnx*newny*newnz; volumetex = new unsigned char[4*nels]; int outindex = -1; for (int k=0; k<newnz; k++) { for (int j=0; j<newny; j++) { for (int i=0; i<newnx; i++) { int ijk[3]={i,j,k}; outindex++; volumetex[outindex*4 + 0] = 0; volumetex[outindex*4 + 1] = 0; volumetex[outindex*4 + 2] = 0; volumetex[outindex*4 + 3] = 0; if (i>=nx || j>=ny || k>=nz) { // out of bounds data continue; } int index = grid->ComputePointId(ijk); float v = volume.data.data->GetTuple1(index); float o = volume.opacity.data->GetTuple1(index); // drop empty ones if (v < -1e+37) continue; // normalize the value v = (v < volume.data.min ? volume.data.min : v); v = (v > volume.data.max ? volume.data.max : v); v = (v-volume.data.min)/volume.data.size; o = (o < volume.opacity.min ? volume.opacity.min : o); o = (o > volume.opacity.max ? volume.opacity.max : o); o = (o-volume.opacity.min)/volume.opacity.size; // opactity map float opacity; opacity = float(rgba[int(o*(nopacities-1))*4 + 3])* props.atts.GetOpacityAttenuation()/256.; opacity = MAX(0,MIN(1,opacity)); // drop transparent splats //if (opacity < .0001) // continue; // do shading float brightness; const bool shading = props.atts.GetLightingFlag(); if (shading) { // Get the gradient float gi = volume.gx[index]; float gj = volume.gy[index]; float gk = volume.gz[index]; // Amount of shading should be somewhat proportional // to the magnitude of the gradient float gm = 1.0; if (props.atts.GetLowGradientLightingReduction() != VolumeAttributes::Off) { double lp = 1.0; switch (props.atts.GetLowGradientLightingReduction()) { case VolumeAttributes::Lowest: lp = 1./16.;break; case VolumeAttributes::Lower: lp = 1./8.; break; case VolumeAttributes::Low: lp = 1./4.; break; case VolumeAttributes::Medium: lp = 1./2.; break; case VolumeAttributes::High: lp = 1.; break; case VolumeAttributes::Higher: lp = 2.; break; case VolumeAttributes::Highest: lp = 4.; break; default: break; } if (props.atts.GetLowGradientLightingClampFlag()) { gm = volume.gm[index] / props.atts.GetLowGradientLightingClampValue(); } else { gm = volume.gmn[index]; } gm = pow((double)gm, lp); } if (gm < 0) gm = 0; if (gm > 1) gm = 1; // Get the base lit brightness based on the // light direction and the gradient float grad[3] = {gi,gj,gk}; float lightdir[3] = {light[0],light[1],light[2]}; brightness = vtkMath::Dot(grad,lightdir); if (brightness<0) brightness *= -1; // Modulate by the gradient magnitude brightness = (1.0 - gm)*1.0 + gm*brightness; // Modulate by the amount of ambient lighting brightness = (1.0 - ambient)*brightness + ambient; } else { // No shading ata ll brightness=1; } // Determine the actual color and opacity now int colorindex = int(ncolors * v); if (colorindex < 0) colorindex = 0; if (colorindex >= ncolors) colorindex = ncolors-1; int colorindex4 = colorindex*4; float scaledbrightness = brightness/255.; float r,g,b; r = float(rgba[colorindex4 + 0])*scaledbrightness; g = float(rgba[colorindex4 + 1])*scaledbrightness; b = float(rgba[colorindex4 + 2])*scaledbrightness; volumetex[outindex*4 + 0] = (unsigned char)(r*255); volumetex[outindex*4 + 1] = (unsigned char)(g*255); volumetex[outindex*4 + 2] = (unsigned char)(b*255); volumetex[outindex*4 + 3] = (unsigned char)(opacity*255); } } } // Create the texture //glPixelStorei(GL_UNPACK_ALIGNMENT,1); glGenTextures(1, (GLuint*)&volumetexId); glBindTexture(GL_TEXTURE_3D, volumetexId); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, newnx, newny, newnz, 0, GL_RGBA, GL_UNSIGNED_BYTE, volumetex); } // // We have the texture; now draw with it // // Set up OpenGL parameters glDisable(GL_LIGHTING); glBindTexture(GL_TEXTURE_3D, volumetexId); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_3D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glDepthMask(false); // Set up camera parameters vtkCamera *camera = vtkCamera::New(); props.view.SetCameraFromView(camera); vtkMatrix4x4 *cameraMatrix = camera->GetViewTransformMatrix(); // // Contour the bounding box at a user specified number of depths // BoundingBoxContourer bbox; // Extract the depth values at the corners of our bounding box int mapStructuredToUnstructured[8] = {0, 1, 3, 2, 4, 5, 7, 6}; int bbox_index = 0; float minz = FLT_MAX; float maxz = -FLT_MAX; for (int k=0; k<nz; k+=nz-1) { for (int j=0; j<ny; j+=ny-1) { for (int i=0; i<nx; i+=nx-1) { int ijk[] = {i,j,k}; double worldpt[4] = {0,0,0,1}; grid->GetPoint(grid->ComputePointId(ijk), worldpt); // Get the world space coordinates // The contourer expects an unstructured hex int pt_index = mapStructuredToUnstructured[bbox_index]; bbox.x[pt_index] = worldpt[0]; bbox.y[pt_index] = worldpt[1]; bbox.z[pt_index] = worldpt[2]; // Get the texture coordinates bbox.r[pt_index] = float(i) / float(newnx + 0) + (0.5 / float(newnx)); bbox.s[pt_index] = float(j) / float(newny + 0) + (0.5 / float(newny)); bbox.t[pt_index] = float(k) / float(newnz + 0) + (0.5 / float(newnz)); // Get the camera space coordinates double viewpt[4]; cameraMatrix->MultiplyPoint(worldpt, viewpt); float dist = viewpt[2]; bbox.v[pt_index] = dist; if (dist < minz) minz = dist; if (dist > maxz) maxz = dist; bbox_index++; if (nx == 1) break; } if (ny == 1) break; } if (nz == 1) break; } // Determine the depth values we need int pt0 = mapStructuredToUnstructured[0]; int ptn = mapStructuredToUnstructured[7]; float dx = bbox.x[pt0] - bbox.x[ptn]; float dy = bbox.y[pt0] - bbox.y[ptn]; float dz = bbox.z[pt0] - bbox.z[ptn]; float dist = sqrt(dx*dx + dy*dy + dz*dz); // Do the actual contouring glBegin(GL_TRIANGLES); glColor4f(1.,1.,1.,1.); int ns = props.atts.GetNum3DSlices(); if (ns < 1) ns = 1; if (ns > 1000) ns = 1000; float tr[15], ts[15], tt[15]; float vx[15], vy[15], vz[15]; int ntriangles; for (int z=0; z<ns; z++) { float value = (float(z)+0.5)/float(ns); bbox.ContourTriangles(minz + dist*value, ntriangles, tr, ts, tt, vx, vy, vz); for (int t=0; t<ntriangles*3; t++) { glTexCoord3f(tr[t], ts[t], tt[t]); glVertex3f(vx[t], vy[t], vz[t]); } } glEnd(); // Set some GL parameters back to their expected values // and free memory glPopAttrib(); camera->Delete(); }