Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-14 23:48:14 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-04-14 23:48:14 +0400
commit0b8b4369c9dbfd9f0048b54a74bf3669919e7f0f (patch)
treee477c891228e01d40aba6dad160174f30f632e72 /source
parent7eb1b45281ad6b163ef8f2d67fb42f099260ec61 (diff)
Patch #8034: "soft" option for halos, which avoids ugly intersections
with geometry, and makes halos look more volumetric. Patch contributed by Markus Ilmola, thanks!
Diffstat (limited to 'source')
-rw-r--r--source/blender/makesdna/DNA_material_types.h1
-rw-r--r--source/blender/render/intern/include/pixelshading.h2
-rw-r--r--source/blender/render/intern/source/pixelshading.c88
-rw-r--r--source/blender/render/intern/source/rendercore.c69
-rw-r--r--source/blender/src/buttons_shading.c17
5 files changed, 113 insertions, 64 deletions
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index a4c6120374a..361b240eabf 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -161,6 +161,7 @@ typedef struct Material {
#define MA_SHLESS 4
#define MA_WIRE 8
#define MA_VERTEXCOL 16
+#define MA_HALO_SOFT 16
#define MA_HALO 32
#define MA_ZTRA 64
#define MA_VERTEXCOLP 128
diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
index d2235784a59..ee7199a4295 100644
--- a/source/blender/render/intern/include/pixelshading.h
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -45,7 +45,7 @@
* mask is pixel coverage in bits
* @return pointer to the object
*/
-void shadeHaloFloat(HaloRen *har,
+int shadeHaloFloat(HaloRen *har,
float *col, int zz,
float dist, float xn,
float yn, short flarec);
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 6871a066c4f..6128a4823a4 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -24,6 +24,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <float.h>
#include <math.h>
#include <string.h>
#include "BLI_arithb.h"
@@ -243,8 +244,36 @@ static void render_lighting_halo(HaloRen *har, float *colf)
}
+/**
+ * Converts a halo z-buffer value to distance from the camera's near plane
+ * @param z The z-buffer value to convert
+ * @return a distance from the camera's near plane in blender units
+ */
+static float haloZtoDist(int z)
+{
+ float zco = 0;
-void shadeHaloFloat(HaloRen *har, float *col, int zz,
+ if(z >= 0x7FFFFF)
+ return 10e10;
+ else {
+ zco = (float)z/(float)0x7FFFFF;
+ if(R.r.mode & R_ORTHO)
+ return (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]);
+ else
+ return (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco);
+ }
+}
+
+/**
+ * @param col (float[4]) Store the rgb color here (with alpha)
+ * The alpha is used to blend the color to the background
+ * color_new = (1-alpha)*color_background + color
+ * @param zz The current zbuffer value at the place of this pixel
+ * @param dist Distance of the pixel from the center of the halo squared. Given in pixels
+ * @param xn The x coordinate of the pixel relaticve to the center of the halo. given in pixels
+ * @param yn The y coordinate of the pixel relaticve to the center of the halo. given in pixels
+ */
+int shadeHaloFloat(HaloRen *har, float *col, int zz,
float dist, float xn, float yn, short flarec)
{
/* fill in col */
@@ -263,12 +292,40 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
}
else alpha= har->alfa;
- if(alpha==0.0) {
- col[0] = 0.0;
- col[1] = 0.0;
- col[2] = 0.0;
- col[3] = 0.0;
- return;
+ if(alpha==0.0)
+ return 0;
+
+ /* soften the halo if it intersects geometry */
+ if(har->mat->mode & MA_HALO_SOFT) {
+ float segment_length, halo_depth, distance_from_z, visible_depth, soften;
+
+ /* calculate halo depth */
+ segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad));
+ halo_depth= 2.0f*segment_length;
+
+ if(halo_depth < FLT_EPSILON)
+ return 0;
+
+ /* calculate how much of this depth is visible */
+ distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs);
+ visible_depth = halo_depth;
+ if(distance_from_z < segment_length) {
+ soften= (segment_length + distance_from_z)/halo_depth;
+
+ /* apply softening to alpha */
+ if(soften < 1.0f)
+ alpha *= soften;
+ if(alpha <= 0.0f)
+ return 0;
+ }
+ }
+ else {
+ /* not a soft halo. use the old softening code */
+ /* halo being intersected? */
+ if(har->zs> zz-har->zd) {
+ t= ((float)(zz-har->zs))/(float)har->zd;
+ alpha*= sqrt(sqrt(t));
+ }
}
radist= sqrt(dist);
@@ -366,21 +423,10 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
if(ster<1.0) dist*= sqrt(ster);
}
}
-
- /* halo being intersected? */
- if(har->zs> zz-har->zd) {
- t= ((float)(zz-har->zs))/(float)har->zd;
- alpha*= sqrt(sqrt(t));
- }
/* disputable optimize... (ton) */
- if(dist<=0.00001) {
- col[0] = 0.0;
- col[1] = 0.0;
- col[2] = 0.0;
- col[3] = 0.0;
- return;
- }
+ if(dist<=0.00001)
+ return 0;
dist*= alpha;
ringf*= dist;
@@ -441,6 +487,8 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz,
/* alpha requires clip, gives black dots */
if(col[3] > 1.0f)
col[3]= 1.0f;
+
+ return 1;
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index e36d8649036..15d41d45d88 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -165,9 +165,11 @@ static int calchalo_z(HaloRen *har, int zz)
return zz;
}
+
+
static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
{
- float col[4], accol[4];
+ float col[4], accol[4], fac;
int amount, amountm, zz, flarec, sample, fullsample, mask=0;
fullsample= (totsample > 1);
@@ -180,23 +182,22 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
amount+= amountm;
zz= calchalo_z(har, ps->z);
- if(zz> har->zs) {
- float fac;
-
- shadeHaloFloat(har, col, zz, dist, xn, yn, flarec);
- flarec= 0;
-
- if(fullsample) {
- for(sample=0; sample<totsample; sample++)
- if(ps->mask & (1 << sample))
- addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
- }
- else {
- fac= ((float)amountm)/(float)R.osa;
- accol[0]+= fac*col[0];
- accol[1]+= fac*col[1];
- accol[2]+= fac*col[2];
- accol[3]+= fac*col[3];
+ if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) {
+ if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
+ flarec= 0;
+
+ if(fullsample) {
+ for(sample=0; sample<totsample; sample++)
+ if(ps->mask & (1 << sample))
+ addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
+ }
+ else {
+ fac= ((float)amountm)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
+ }
}
}
@@ -207,16 +208,14 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
/* now do the sky sub-pixels */
amount= R.osa-amount;
if(amount) {
- float fac;
-
- shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec);
-
- if(!fullsample) {
- fac= ((float)amount)/(float)R.osa;
- accol[0]+= fac*col[0];
- accol[1]+= fac*col[1];
- accol[2]+= fac*col[2];
- accol[3]+= fac*col[3];
+ if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
+ if(!fullsample) {
+ fac= ((float)amount)/(float)R.osa;
+ accol[0]+= fac*col[0];
+ accol[1]+= fac*col[1];
+ accol[2]+= fac*col[2];
+ accol[3]+= fac*col[3];
+ }
}
}
@@ -301,11 +300,11 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl)
}
else {
zz= calchalo_z(har, *rz);
- if(zz> har->zs) {
- shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec);
-
- for(sample=0; sample<totsample; sample++)
- addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
+ if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) {
+ if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
+ for(sample=0; sample<totsample; sample++)
+ addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
+ }
}
}
}
@@ -1634,8 +1633,8 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos
dist= xsq+ysq;
if(dist<har->radsq) {
- shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec);
- addalphaAddfacFloat(rtf, colf, har->add);
+ if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
+ addalphaAddfacFloat(rtf, colf, har->add);
}
rtf+=4;
}
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index 880076de162..db531c7e6e3 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -3843,14 +3843,15 @@ static void material_panel_shading(Material *ma)
uiBlockSetCol(block, TH_BUT_SETTING1);
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV, "Flare",245,142,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare");
- uiDefButBitI(block, TOG, MA_HALO_RINGS, B_MATPRV, "Rings", 245,123,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders rings over halo");
- uiDefButBitI(block, TOG, MA_HALO_LINES, B_MATPRV, "Lines", 245,104,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders star shaped lines over halo");
- uiDefButBitI(block, TOG, MA_STAR, B_MATPRV, "Star", 245,85,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders halo as a star");
- uiDefButBitI(block, TOG, MA_HALOTEX, B_MATPRV, "HaloTex", 245,66,65, 18, &(ma->mode), 0, 0, 0, 0, "Gives halo a texture");
- uiDefButBitI(block, TOG, MA_HALOPUNO, B_MATPRV, "HaloPuno", 245,47,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses the vertex normal to specify the dimension of the halo");
- uiDefButBitI(block, TOG, MA_HALO_XALPHA, B_MATPRV, "X Alpha", 245,28,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses extreme alpha");
- uiDefButBitI(block, TOG, MA_HALO_SHADE, B_MATPRV, "Shaded", 245,9,65, 18, &(ma->mode), 0, 0, 0, 0, "Lets halo receive light and shadows");
+ uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV, "Flare", 245,161,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare");
+ uiDefButBitI(block, TOG, MA_HALO_RINGS, B_MATPRV, "Rings", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Renders rings over halo");
+ uiDefButBitI(block, TOG, MA_HALO_LINES, B_MATPRV, "Lines", 245,123,65,18, &(ma->mode), 0, 0, 0, 0, "Renders star shaped lines over halo");
+ uiDefButBitI(block, TOG, MA_STAR, B_MATPRV, "Star", 245,104,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders halo as a star");
+ uiDefButBitI(block, TOG, MA_HALOTEX, B_MATPRV, "HaloTex", 245,85,65, 18, &(ma->mode), 0, 0, 0, 0, "Gives halo a texture");
+ uiDefButBitI(block, TOG, MA_HALOPUNO, B_MATPRV, "HaloPuno", 245,66,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses the vertex normal to specify the dimension of the halo");
+ uiDefButBitI(block, TOG, MA_HALO_XALPHA, B_MATPRV, "X Alpha", 245,47,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses extreme alpha");
+ uiDefButBitI(block, TOG, MA_HALO_SHADE, B_MATPRV, "Shaded", 245,28,65, 18, &(ma->mode), 0, 0, 0, 0, "Lets halo receive light and shadows");
+ uiDefButBitI(block, TOG, MA_HALO_SOFT, B_MATPRV, "Soft", 245,9,65, 18, &(ma->mode), 0, 0, 0, 0, "Softens the halo");
uiBlockEndAlign(block);
}
else {