[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20468] branches/soc-2009-yukishiro/source /blender: start integrating SH computation in render part

Jingyuan Huang jingyuan.huang at gmail.com
Thu May 28 08:10:48 CEST 2009


Revision: 20468
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20468
Author:   yukishiro
Date:     2009-05-28 08:10:48 +0200 (Thu, 28 May 2009)

Log Message:
-----------
start integrating SH computation in render part

Modified Paths:
--------------
    branches/soc-2009-yukishiro/source/blender/render/SConscript
    branches/soc-2009-yukishiro/source/blender/render/intern/source/occlusion.c
    branches/soc-2009-yukishiro/source/blender/sh/SH_api.h
    branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c

Modified: branches/soc-2009-yukishiro/source/blender/render/SConscript
===================================================================
--- branches/soc-2009-yukishiro/source/blender/render/SConscript	2009-05-28 05:09:25 UTC (rev 20467)
+++ branches/soc-2009-yukishiro/source/blender/render/SConscript	2009-05-28 06:10:48 UTC (rev 20468)
@@ -6,7 +6,7 @@
 
 incs = 'intern/include #/intern/guardedalloc ../blenlib ../makesdna'
 incs += ' extern/include ../blenkernel ../radiosity/extern/include ../imbuf'
-incs += ' ../include ../blenloader'
+incs += ' ../include ../blenloader ../sh'
 
 defs = []
 

Modified: branches/soc-2009-yukishiro/source/blender/render/intern/source/occlusion.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/render/intern/source/occlusion.c	2009-05-28 05:09:25 UTC (rev 20467)
+++ branches/soc-2009-yukishiro/source/blender/render/intern/source/occlusion.c	2009-05-28 06:10:48 UTC (rev 20468)
@@ -47,6 +47,8 @@
 
 #include "RE_shader_ext.h"
 
+#include "SH_api.h"
+
 /* local includes */
 #include "occlusion.h"
 #include "render_types.h"
@@ -224,16 +226,6 @@
 
 /* ------------------------- Spherical Harmonics --------------------------- */
 
-/* Use 2nd order SH => 9 coefficients, stored in this order:
-   0 = (0,0),
-   1 = (1,-1), 2 = (1,0), 3 = (1,1),
-   4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */
-
-static void sh_copy(float *shresult, float *sh)
-{
-	memcpy(shresult, sh, sizeof(float)*9);
-}
-
 static void sh_mul(float *sh, float f)
 {
 	int i;
@@ -250,54 +242,6 @@
 		shresult[i]= sh1[i] + sh2[i];
 }
 
-static void sh_from_disc(float *n, float area, float *shresult)
-{
-	/* See formula (3) in:
-	   "An Efficient Representation for Irradiance Environment Maps" */
-	float sh[9], x, y, z;
-
-	x= n[0];
-	y= n[1];
-	z= n[2];
-
-	sh[0]= 0.282095f;
-
-	sh[1]= 0.488603f*y;
-	sh[2]= 0.488603f*z;
-	sh[3]= 0.488603f*x;
-	
-	sh[4]= 1.092548f*x*y;
-	sh[5]= 1.092548f*y*z;
-	sh[6]= 0.315392f*(3.0f*z*z - 1.0f);
-	sh[7]= 1.092548f*x*z;
-	sh[8]= 0.546274f*(x*x - y*y);
-
-	sh_mul(sh, area);
-	sh_copy(shresult, sh);
-}
-
-static float sh_eval(float *sh, float *v)
-{
-	/* See formula (13) in:
-	   "An Efficient Representation for Irradiance Environment Maps" */
-	static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
-	static const float c4 = 0.886227f, c5 = 0.247708f;
-	float x, y, z, sum;
-
-	x= v[0];
-	y= v[1];
-	z= v[2];
-
-	sum= c1*sh[8]*(x*x - y*y);
-	sum += c3*sh[6]*z*z;
-	sum += c4*sh[0];
-	sum += -c5*sh[6];
-	sum += 2.0f*c1*(sh[4]*x*y + sh[7]*x*z + sh[5]*y*z);
-	sum += 2.0f*c2*(sh[3]*x + sh[1]*y + sh[2]*z);
-
-	return sum;
-}
-
 /* ------------------------------ Building --------------------------------- */
 
 static void occ_face(const OccFace *face, float *co, float *normal, float *area)
@@ -408,7 +352,7 @@
 
 	occ_face(face, node->co, n, &node->area);
 	node->dco= 0.0f;
-	sh_from_disc(n, node->area, node->sh);
+	SH_from_disc(2, n, node->area, node->sh); // sh degree = 2
 }
 
 static void occ_build_dco(OcclusionTree *tree, OccNode *node, float *co, float *dco)
@@ -726,7 +670,7 @@
 	ev[0]= -v[0]*invd2;
 	ev[1]= -v[1]*invd2;
 	ev[2]= -v[2]*invd2;
-	dotemit= sh_eval(node->sh, ev);
+	dotemit= SH_eval(node->sh, ev);
 	dotreceive= INPR(receivenormal, v)*invd2;
 
 	CLAMP(dotemit, 0.0f, 1.0f);

Modified: branches/soc-2009-yukishiro/source/blender/sh/SH_api.h
===================================================================
--- branches/soc-2009-yukishiro/source/blender/sh/SH_api.h	2009-05-28 05:09:25 UTC (rev 20467)
+++ branches/soc-2009-yukishiro/source/blender/sh/SH_api.h	2009-05-28 06:10:48 UTC (rev 20468)
@@ -33,8 +33,12 @@
 struct LightEnv;
 
 void SH_init();
+void SH_exit();
+
 void SH_ComputeSceneCoefficients(struct Scene *scene);
 void SH_ComputeLightCoefficients(struct LightEnv *env);
-void SH_exit();
 
+void SH_from_disc(int L, float *n, float area, float *shresult);
+float SH_eval(float *sh, float *v);
+
 #endif //_SH_API_H

Modified: branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c
===================================================================
--- branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c	2009-05-28 05:09:25 UTC (rev 20467)
+++ branches/soc-2009-yukishiro/source/blender/sh/intern/compute.c	2009-05-28 06:10:48 UTC (rev 20468)
@@ -135,32 +135,33 @@
 }
 
 /* compute SH values for a vector in (x, y, z) */
-static void compute_Y(Vec3 u, ShCoeffs *Y)
+static void compute_Y(Vec3 u, ShCoeffs Y)
 {
         int l, m;
         
-        (*Y)[0][0] = aan[0][0];
+        Y[0][0] = aan[0][0];
         
         // work out the degree 1 case immediately
-        (*Y)[1][0]  = aan[1][0] * u[2];
-        (*Y)[1][-1] = aan[1][1] * u[1];
-        (*Y)[1][1]  = aan[1][1] * u[0];
+        Y[1][0]  = aan[1][0] * u[2];
+        Y[1][-1] = aan[1][1] * u[1];
+        Y[1][1]  = aan[1][1] * u[0];
         
         // And then do DEGREES 2..L via the recurrences
         for (l = 2; l <= L; l++) {
-                (*Y)[l][l]    = aan[l][l] * (u[0] * (*Y)[l-1][l-1] - u[1] * (*Y)[l-1][-l+1]);
-                (*Y)[l][-l]   = aan[l][l] * (u[1] * (*Y)[l-1][l-1] + u[0] * (*Y)[l-1][-l+1]);
-                (*Y)[l][l-1]  = aan[l][l-1] * u[2] * (*Y)[l-1][l-1];
-                (*Y)[l][-l+1] = aan[l][l-1] * u[2] * (*Y)[l-1][-l+1];
-                (*Y)[l][0]    = aan[l][0]   * u[2] * (*Y)[l-1][0] + bbn[l][0] * (*Y)[l-2][0]; 
+                Y[l][l]    = aan[l][l] * (u[0] * Y[l-1][l-1] - u[1] * Y[l-1][-l+1]);
+                Y[l][-l]   = aan[l][l] * (u[1] * Y[l-1][l-1] + u[0] * Y[l-1][-l+1]);
+                Y[l][l-1]  = aan[l][l-1] * u[2] * Y[l-1][l-1];
+                Y[l][-l+1] = aan[l][l-1] * u[2] * Y[l-1][-l+1];
+                Y[l][0]    = aan[l][0]   * u[2] * Y[l-1][0] + bbn[l][0] * Y[l-2][0]; 
 
                 for (m = 1; m <= l-2; m++) {
-                        (*Y)[l][m]  = aan[l][m] * u[2] * (*Y)[l-1][m]  + bbn[l][m] * (*Y)[l-2][m] ;
-                        (*Y)[l][-m] = aan[l][m] * u[2] * (*Y)[l-1][-m] + bbn[l][m] * (*Y)[l-2][-m];
+                        Y[l][m]  = aan[l][m] * u[2] * Y[l-1][m]  + bbn[l][m] * Y[l-2][m] ;
+                        Y[l][-m] = aan[l][m] * u[2] * Y[l-1][-m] + bbn[l][m] * Y[l-2][-m];
                 }
         }
 }
 
+//float SH_eval(float *sh, float *v)
 static void init_aan_bbn()
 {
         int l, m;
@@ -169,11 +170,11 @@
         bbn = allocate_ShCoeffs();
 
         aan[0][0] = 1.0/sqrt(4.0*M_PI);
-        aan[1][0] = aan[0][0] *sqrt(3.0);
+        aan[1][0] = aan[0][0] * sqrt(3.0);
         aan[1][1] = -aan[1][0];
 
         for (l=2; l <= L; l++) {
-                aan[l][l] =  -sqrt((2.0*l+1)/(2.0*l));
+                aan[l][l]   =  -sqrt((2.0*l+1)/(2.0*l));
                 aan[l][l-1] = sqrt(2.0*l+1.0);
                 aan[l][0]   = sqrt(4*l*l-1.0) / l;
                 bbn[l][0]   = (1.0/l - 1.0) * sqrt( (float)(2*l+1)/(float)(2*l-3));
@@ -211,7 +212,7 @@
         }
         
         for (i = 0; i < NUM_SAMPLES; i++) {
-            compute_Y(samples[i], &(samples_Y[i]));        
+            compute_Y(samples[i], samples_Y[i]);        
         }
 }
 
@@ -307,12 +308,54 @@
                         env->shcoeffs[m][2] += l_val[2] * y_val[m];
                 }
         }
+}
 
-        for (m = 0; m < num_sh; m++) {
-                printf("%f %f %f\n", 
-                        env->shcoeffs[m][0],
-                        env->shcoeffs[m][1],
-                        env->shcoeffs[m][2]
-                      );
+// size of shresult = (L + 1) * (L + 1)
+/* Use 2nd order SH => 9 coefficients, stored in this order:
+   0 = (0,0),
+   1 = (1,-1), 2 = (1,0), 3 = (1,1),
+   4 = (2,-2), 5 = (2,-1), 6 = (2,0), 7 = (2,1), 8 = (2,2) */
+void SH_from_disc(int degree, float *n, float area, float *shresult)
+{
+        int l, m, c;
+        Vec3 u;
+        ShCoeffs coeffs = allocate_ShCoeffs();
+
+        u[0] = n[0];
+        u[1] = n[1];
+        u[2] = n[2];
+        compute_Y(u, coeffs);
+
+        for (l = 0; l <= degree; l++) {
+                c = l * l + l;
+                for (m = -l; m <= l; m++) {
+                        shresult[c+m] = area * coeffs[l][m];
+                }
         }
+
+        free_ShCoeffs(coeffs);
 }
+
+// TODO: remove constants...
+float SH_eval(float *sh, float *v)
+{
+	/* See formula (13) in:
+	   "An Efficient Representation for Irradiance Environment Maps" */
+	static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
+	static const float c4 = 0.886227f, c5 = 0.247708f;
+	float x, y, z, sum;
+
+	x= v[0];
+	y= v[1];
+	z= v[2];
+
+	sum= c1*sh[8]*(x*x - y*y);
+	sum += c3*sh[6]*z*z;
+	sum += c4*sh[0];
+	sum += -c5*sh[6];
+	sum += 2.0f*c1*(sh[4]*x*y + sh[7]*x*z + sh[5]*y*z);
+	sum += 2.0f*c2*(sh[3]*x + sh[1]*y + sh[2]*z);
+
+	return sum;
+}
+





More information about the Bf-blender-cvs mailing list