You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2005/11/07 21:34:10 UTC
svn commit: r331595 - in
/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image:
SpotLight.java rendered/SpecularLightingRed.java
Author: deweese
Date: Mon Nov 7 12:34:04 2005
New Revision: 331595
URL: http://svn.apache.org/viewcvs?rev=331595&view=rev
Log:
Fixes a problem with feSpotLight and feSpecular lighting,
PR: 36745
Modified:
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/SpotLight.java
xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/rendered/SpecularLightingRed.java
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/SpotLight.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/SpotLight.java?rev=331595&r1=331594&r2=331595&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/SpotLight.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/SpotLight.java Mon Nov 7 12:34:04 2005
@@ -107,10 +107,10 @@
return limitingConeAngle;
}
- public SpotLight(final double lightX, final double lightY, final double lightZ,
- final double pointAtX, final double pointAtY, final double pointAtZ,
- final double specularExponent, final double limitingConeAngle,
- final Color lightColor){
+ public SpotLight(double lightX, double lightY, double lightZ,
+ double pointAtX, double pointAtY, double pointAtZ,
+ double specularExponent, double limitingConeAngle,
+ Color lightColor){
super(lightColor);
this.lightX = lightX;
@@ -127,13 +127,11 @@
S[1] = pointAtY - lightY;
S[2] = pointAtZ - lightZ;
- double norm = Math.sqrt(S[0]*S[0]
- + S[1]*S[1]
- + S[2]*S[2]);
-
- S[0] /= norm;
- S[1] /= norm;
- S[2] /= norm;
+ double invNorm = 1/Math.sqrt(S[0]*S[0] + S[1]*S[1] + S[2]*S[2]);
+
+ S[0] *= invNorm;
+ S[1] *= invNorm;
+ S[2] *= invNorm;
}
/**
@@ -150,25 +148,29 @@
* @param y y-axis coordinate where the light should be computed
* @param z z-axis coordinate where the light should be computed
* @param L array of length 3 where the result is stored
+ * @return the intensity factor for this light vector.
*/
- public final void getLight(final double x, final double y, final double z,
- final double L[]){
+ public final double getLightBase(final double x, final double y,
+ final double z,
+ final double L[]){
// Light Vector, L
L[0] = lightX - x;
L[1] = lightY - y;
L[2] = lightZ - z;
- final double norm = Math.sqrt(L[0]*L[0] +
- L[1]*L[1] +
- L[2]*L[2]);
-
- L[0] /= norm;
- L[1] /= norm;
- L[2] /= norm;
+ final double invNorm = 1/Math.sqrt(L[0]*L[0] +
+ L[1]*L[1] +
+ L[2]*L[2]);
+
+ L[0] *= invNorm;
+ L[1] *= invNorm;
+ L[2] *= invNorm;
double LS = -(L[0]*S[0] + L[1]*S[1] + L[2]*S[2]);
- if(LS > limitingCos){
+ if(LS <= limitingCos){
+ return 0;
+ } else {
double Iatt = limitingCos/LS;
Iatt *= Iatt;
Iatt *= Iatt;
@@ -178,17 +180,58 @@
Iatt *= Iatt; // akin Math.pow(Iatt, 64)
Iatt = 1 - Iatt;
- LS = Iatt*Math.pow(LS, specularExponent);
-
- L[0] *= LS;
- L[1] *= LS;
- L[2] *= LS;
+ return Iatt*Math.pow(LS, specularExponent);
}
- else{
- L[0] = 0;
- L[1] = 0;
- L[2] = 0;
+ }
+
+ /**
+ * Computes the light vector in (x, y, z)
+ *
+ * @param x x-axis coordinate where the light should be computed
+ * @param y y-axis coordinate where the light should be computed
+ * @param z z-axis coordinate where the light should be computed
+ * @param L array of length 3 where the result is stored,
+ * x,y,z are scaled by light intensity.
+ */
+ public final void getLight(final double x, final double y,
+ final double z,
+ final double L[]){
+ final double s = getLightBase(x, y, z, L);
+ L[0] *= s;
+ L[1] *= s;
+ L[2] *= s;
+ }
+
+ /**
+ * computes light vector in (x, y, z).
+ *
+ * @param x x-axis coordinate where the light should be computed
+ * @param y y-axis coordinate where the light should be computed
+ * @param z z-axis coordinate where the light should be computed
+ * @param L array of length 4 where result is stored.
+ * 0,1,2 are x,y,z respectively of light vector (normalized).
+ * 3 is the intensity of the light at this point.
+ */
+ public final void getLight4(final double x, final double y, final double z,
+ final double L[]){
+ L[3] = getLightBase(x, y, z, L);
+ }
+
+ public double[][] getLightRow4(double x, double y,
+ final double dx, final int width,
+ final double[][] z,
+ final double[][] lightRow) {
+ double [][] ret = lightRow;
+ if (ret == null)
+ ret = new double[width][4];
+
+ for(int i=0; i<width; i++){
+ getLight4(x, y, z[i][3], ret[i]);
+ x += dx;
}
+
+ return ret;
}
+
}
Modified: xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/rendered/SpecularLightingRed.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/rendered/SpecularLightingRed.java?rev=331595&r1=331594&r2=331595&view=diff
==============================================================================
--- xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/rendered/SpecularLightingRed.java (original)
+++ xmlgraphics/batik/branches/svg11/sources/org/apache/batik/ext/awt/image/rendered/SpecularLightingRed.java Mon Nov 7 12:34:04 2005
@@ -26,6 +26,7 @@
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.ext.awt.image.Light;
+import org.apache.batik.ext.awt.image.SpotLight;
/**
*
@@ -160,32 +161,57 @@
final double[][][] NA = bumpMap.getNormalArray(minX, minY, w, h);
// System.out.println("Entering Specular Lighting");
- if(!light.isConstant()){
- final double[][] LA = new double[w][3];
+ if (light instanceof SpotLight) {
+ SpotLight slight = (SpotLight)light;
+ final double[][] LA = new double[w][4];
for(i=0; i<h; i++){
// System.out.println("Row: " + i);
final double [][] NR = NA[i];
- light.getLightRow(x, y+i*scaleY, scaleX, w, NR, LA);
+ slight.getLightRow4(x, y+i*scaleY, scaleX, w, NR, LA);
for (j=0; j<w; j++){
// Get Normal
final double [] N = NR[j];
// Get Light Vector
final double [] L = LA[j];
-
- // Compute Half-way vector
- L[2] += 1;
- norm = L[0]*L[0] + L[1]*L[1] + L[2]*L[2];
- if(norm == 0)
- a = (int)(mult+0.5);
- else {
+ double vs = L[3];
+ if (vs == 0) {
+ a = 0;
+ } else {
+ L[2] += 1;
+ norm = L[0]*L[0] + L[1]*L[1] + L[2]*L[2];
norm = Math.sqrt(norm);
- a = (int)(mult*Math.pow((N[0]*L[0] +
- N[1]*L[1] + N[2]*L[2])/norm,
- specularExponent) + 0.5);
+ double dot = N[0]*L[0] + N[1]*L[1] + N[2]*L[2];
+ vs = vs*Math.pow(dot/norm, specularExponent);
+ a = (int)(mult*vs + 0.5);
if ((a & 0xFFFFFF00) != 0)
a = ((a & 0x80000000) != 0)?0:255;
}
+ pixels[p++] = (a << 24 | pixel);
+ }
+ p += adjust;
+ }
+ } else if(!light.isConstant()){
+ final double[][] LA = new double[w][4];
+ for(i=0; i<h; i++){
+ // System.out.println("Row: " + i);
+ final double [][] NR = NA[i];
+ light.getLightRow(x, y+i*scaleY, scaleX, w, NR, LA);
+ for (j=0; j<w; j++){
+ // Get Normal
+ final double [] N = NR[j];
+
+ // Get Light Vector
+ final double [] L = LA[j];
+ L[2] += 1;
+ norm = L[0]*L[0] + L[1]*L[1] + L[2]*L[2];
+ norm = Math.sqrt(norm);
+ double dot = N[0]*L[0] + N[1]*L[1] + N[2]*L[2];
+ // vs = vs/norm;
+ norm = Math.pow(dot/norm, specularExponent);
+ a = (int)(mult*norm + 0.5);
+ if ((a & 0xFFFFFF00) != 0)
+ a = ((a & 0x80000000) != 0)?0:255;
pixels[p++] = (a << 24 | pixel);
}
p += adjust;