public double[] ColorReflection(IMaterial material, Vector3d normal, Vector3d input, Vector3d output, ReflectionComponent comp) { if (!(material is PhongMaterial)) { return(null); } PhongMaterial mat = (PhongMaterial)material; int bands = mat.Color.Length; double[] result = new double[bands]; bool viewOut = Vector3d.Dot(output, normal) > 0.0; double coef; if (input.Equals(Vector3d.Zero)) // ambient term only.. { // dim ambient light if viewer is inside coef = viewOut ? mat.Ka : (mat.Ka * mat.Kt); for (int i = 0; i < bands; i++) { result[i] = coef * mat.Color[i]; } return(result); } // directional light source: input.Normalize(); double cosAlpha = Vector3d.Dot(input, normal); bool lightOut = cosAlpha > 0.0; double ks = mat.Ks; double kd = mat.Kd; double kt = mat.Kt; Vector3d r = Vector3d.Zero; coef = 1.0; if (viewOut == lightOut) // viewer and source are on the same side.. { if ((comp & ReflectionComponent.SPECULAR_REFLECTION) != 0) { double cos2 = cosAlpha + cosAlpha; r = normal * cos2 - input; if (!lightOut && // total reflection check -cosAlpha <= mat.cosTotal) { if ((ks += kt) + kd > 1.0) { ks = 1.0 - kd; } } } } else // opposite sides => use specular refraction { if ((comp & ReflectionComponent.SPECULAR_REFRACTION) != 0) { r = Geometry.SpecularRefraction(normal, mat.n, input); } coef = kt; } double diffuse = (comp & ReflectionComponent.DIFFUSE) == 0 ? 0.0 : coef *kd *Math.Abs(cosAlpha); double specular = 0.0; if (r != Vector3d.Zero) { double cosBeta = Vector3d.Dot(r, output); if (cosBeta > 0.0) { specular = coef * ks * Arith.Pow(cosBeta, mat.H); } } for (int i = 0; i < bands; i++) { result[i] = diffuse * mat.Color[i] + specular; } return(result); }
public double[] ColorReflection( IMaterial material, Vector3d normal, Vector3d input, Vector3d output, ReflectionComponent comp ) { if ( !(material is PhongMaterial) ) return null; PhongMaterial mat = (PhongMaterial)material; int bands = mat.Color.Length; double[] result = new double[ bands ]; bool viewOut = Vector3d.Dot( output, normal ) > 0.0; double coef; if ( input.Equals( Vector3d.Zero ) ) // ambient term only.. { // dim ambient light if viewer is inside coef = viewOut ? mat.Ka : (mat.Ka * mat.Kt); for ( int i = 0; i < bands; i++ ) result[ i ] = coef * mat.Color[ i ]; return result; } // directional light source: input.Normalize(); double cosAlpha = Vector3d.Dot( input, normal ); bool lightOut = cosAlpha > 0.0; double ks = mat.Ks; double kd = mat.Kd; double kt = mat.Kt; Vector3d r = Vector3d.Zero; coef = 1.0; if ( viewOut == lightOut ) // viewer and source are on the same side.. { if ( (comp & ReflectionComponent.SPECULAR_REFLECTION) != 0 ) { double cos2 = cosAlpha + cosAlpha; r = normal * cos2 - input; if ( !lightOut && // total reflection check -cosAlpha <= mat.cosTotal ) if ( (ks += kt) + kd > 1.0 ) ks = 1.0 - kd; } } else // opposite sides => use specular refraction { if ( (comp & ReflectionComponent.SPECULAR_REFRACTION) != 0 ) r = Geometry.SpecularRefraction( normal, mat.n, input ); coef = kt; } double diffuse = (comp & ReflectionComponent.DIFFUSE) == 0 ? 0.0 : coef * kd * Math.Abs( cosAlpha ); double specular = 0.0; if ( r != Vector3d.Zero ) { double cosBeta = Vector3d.Dot( r, output ); if ( cosBeta > 0.0 ) specular = coef * ks * Arith.Pow( cosBeta, mat.H ); } for ( int i = 0; i < bands; i++ ) result[i] = diffuse * mat.Color[i] + specular; return result; }
public double[] ColorReflection(Intersection intersection, Vector3d input, Vector3d output, ReflectionComponent comp) { return(ColorReflection(intersection.Material, intersection.Normal, input, output, comp)); }
public double[] ColorReflection( Intersection intersection, Vector3d input, Vector3d output, ReflectionComponent comp ) { return ColorReflection( intersection.Material, intersection.Normal, input, output, comp ); }