Project

General

Profile

« Previous | Next » 

Revision 353f7580

Added by Leszek Koltunski over 5 years ago

Make Distort truly 3D.

View differences:

src/main/res/raw/main_vertex_shader.glsl
59 59
// We still have to avoid division by 0 when p.x = +- u_objD.x or p.y = +- u_objD.y (i.e on the edge of the Object)
60 60
// We do that by first multiplying the above 'float d' with sign(denominator1*denominator2)^2.
61 61
//
62
// 2019-01-09: make this 3D. The trick: we want only the EDGES of the cuboid to stay constant.
63
// the interiors of the Faces move! Thus, we want the MIDDLE of the PS/(sign(PS)*u_objD+S) !
62 64
//////////////////////////////////////////////////////////////////////////////////////////////
63
// return degree of the point as defined by the bitmap rectangle
65
// return degree of the point as defined by the object cuboid (u_objD.x X u_objD.y X u_objD.z)
64 66

  
65
float degree_bitmap(in vec3 S, in vec3 PS)
67
float degree_object(in vec3 S, in vec3 PS)
66 68
  {
69
  vec3 ONE = vec3(1.0,1.0,1.0);
67 70
  vec3 A = sign(PS)*u_objD + S;
68 71

  
69
  vec3 signA = sign(A);                                    //
70
  vec3 signA_SQ = signA*signA;                             // div = PS/A if A!=0, 0 otherwise.
71
  vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ)); //
72
  vec3 signA = sign(A);                      //
73
  vec3 signA_SQ = signA*signA;               // div = PS/A if A!=0, 0 otherwise.
74
  vec3 div = signA_SQ*PS/(A-(ONE-signA_SQ)); //
72 75

  
73
  return 1.0-max(div.x,div.y);
76
  float d1= div.x-div.y;
77
  float d2= div.y-div.z;
78
  float d3= div.x-div.z;
79

  
80
  if( d1*d2>0.0 ) return 1.0-div.y;          //
81
  if( d1*d3>0.0 ) return 1.0-div.z;          // return 1-middle(div.x,div.y,div.z)
82
  return 1.0-div.x;                          //
74 83
  }
75 84

  
76 85
//////////////////////////////////////////////////////////////////////////////////////////////
77
// Return degree of the point as defined by the Region. Currently only supports circular regions.
86
// Return degree of the point as defined by the Region. Currently only supports spherical regions.
78 87
//
79
// Let us first introduce some notation.
80 88
// Let 'PS' be the vector from point P (the current vertex) to point S (the center of the effect).
81
// Let region.xy be the vector from point S to point O (the center point of the region circle)
82
// Let region.z be the radius of the region circle.
83
// (This all should work regardless if S is inside or outside of the circle).
89
// Let region.xyz be the vector from point S to point O (the center point of the region sphere)
90
// Let region.w be the radius of the region sphere.
91
// (This all should work regardless if S is inside or outside of the sphere).
84 92
//
85
// Then, the degree of a point with respect to a given (circular!) Region is defined by:
93
// Then, the degree of a point with respect to a given (spherical!) Region is defined by:
86 94
//
87
// If P is outside the circle, return 0.
88
// Otherwise, let X be the point where the halfline SP meets the region circle - then return |PX|/||SX|,
95
// If P is outside the sphere, return 0.
96
// Otherwise, let X be the point where the halfline SP meets the sphere - then return |PX|/||SX|,
89 97
// aka the 'degree' of point P.
90 98
//
91 99
// We solve the triangle OPX.
......
117 125
  }
118 126

  
119 127
//////////////////////////////////////////////////////////////////////////////////////////////
120
// return min(degree_bitmap,degree_region). Just like degree_region, currently only supports circles.
128
// return min(degree_object,degree_region). Just like degree_region, currently only supports spheres.
121 129

  
122 130
float degree(in vec4 region, in vec3 S, in vec3 PS)
123 131
  {
......
130 138
  vec3 signA = sign(A);
131 139
  vec3 signA_SQ = signA*signA;
132 140
  vec3 div = signA_SQ*PS/(A-(vec3(1.0,1.0,1.0)-signA_SQ));
133
  float E = 1.0-max(div.x,div.y);
141

  
142
  float d1= div.x-div.y;
143
  float d2= div.y-div.z;
144
  float d3= div.x-div.z;
145
  float E;
146

  
147
       if( d1*d2>0.0 ) E= 1.0-div.y;
148
  else if( d1*d3>0.0 ) E= 1.0-div.z;
149
  else                 E= 1.0-div.x;
134 150

  
135 151
  float ps_sq = dot(PS,PS);
136 152
  float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0));  // return 1.0 if ps_sq = 0.0

Also available in: Unified diff