Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

ShWorleyImpl.hpp

00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory 00004 // Project administrator: Michael D. McCool 00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa, 00006 // Bryan Chan, Michael D. McCool 00007 // 00008 // This software is provided 'as-is', without any express or implied 00009 // warranty. In no event will the authors be held liable for any damages 00010 // arising from the use of this software. 00011 // 00012 // Permission is granted to anyone to use this software for any purpose, 00013 // including commercial applications, and to alter it and redistribute it 00014 // freely, subject to the following restrictions: 00015 // 00016 // 1. The origin of this software must not be misrepresented; you must 00017 // not claim that you wrote the original software. If you use this 00018 // software in a product, an acknowledgment in the product documentation 00019 // would be appreciated but is not required. 00020 // 00021 // 2. Altered source versions must be plainly marked as such, and must 00022 // not be misrepresented as being the original software. 00023 // 00024 // 3. This notice may not be removed or altered from any source 00025 // distribution. 00027 00028 #ifndef SHUTIL_WORLEYIMPL_HPP 00029 #define SHUTIL_WORLEYIMPL_HPP 00030 00031 #include <cstdlib> 00032 #include "ShSyntax.hpp" 00033 #include "ShWorley.hpp" 00034 #include "ShNoise.hpp" 00035 #include "ShFunc.hpp" 00036 #include "ShImage.hpp" 00037 #include "ShTexCoord.hpp" 00038 00039 namespace ShUtil { 00040 00041 using namespace SH; 00042 00043 template<int D, typename T> 00044 void GridGenFactory<D, T>::operator()(const ShGeneric<D, T> &p, Generator<D, T> result[]) const { 00045 ShAttrib<D, SH_TEMP, T> pCell = floor(p); 00046 00047 // each set of two bits represents offset along one dimension 00048 // if the bit value = 0, offset by -1, 1 = no offset, 2 = offset by 1 00049 int i, j, offsetBits; 00050 ShConstAttrib3f offsets(-1, 0, 1); 00051 int offsetSwiz[D]; 00052 j = 0; 00053 for(offsetBits = 0; offsetBits < (1 << (D * 2)); ++offsetBits) { 00054 for(i = 0; i < D; ++i) { 00055 offsetSwiz[i] = ((offsetBits >> (i * 2)) & 3); 00056 if(offsetSwiz[i] == 3) break; 00057 } 00058 if(i < D) continue; 00059 00060 Generator<D, T> gen; 00061 result[j].offset = offsets.template swiz<D>(offsetSwiz); 00062 SH_DEBUG_PRINT("Offset:" << result[j].offset); 00063 result[j].cell = pCell + result[j].offset; 00064 makePos(result[j]); 00065 ++j; 00066 } 00067 } 00068 00069 00070 template<int D, typename T> 00071 void DefaultGenFactory<D, T>::makePos(Generator<D, T> &g) const { 00072 g.pos = g.cell + cellnoise<D>(g.cell, m_useTexture); 00073 } 00074 00075 template<int D, typename T> 00076 void NullGenFactory<D, T>::makePos(Generator<D, T> &g) const { 00077 g.pos = g.cell + fillcast<D>(ShAttrib<1, SH_CONST, T>(0.5f)); 00078 } 00079 00080 template<int D, typename T> 00081 LerpGenFactory<D, T>::LerpGenFactory(const ShGeneric<1, T> &time, bool useTexture) 00082 : m_time(time), m_useTexture(useTexture) {} 00083 00084 template<int D, typename T> 00085 void LerpGenFactory<D, T>::makePos(Generator<D, T> &g) const { 00086 ShAttrib<1, SH_TEMP, T> lastTime = floor(m_time); 00087 ShAttrib<1, SH_TEMP, T> timeOffset = frac(m_time); 00088 ShAttrib<D + 1, SH_TEMP, T> offsetCell; 00089 00090 offsetCell = fillcast<D+1>(g.cell); 00091 offsetCell(D) = lastTime; 00092 ShAttrib<D, SH_TEMP, T> p1 = cellnoise<D>(offsetCell, m_useTexture); 00093 00094 offsetCell(D) += 1; 00095 ShAttrib<D, SH_TEMP, T> p2 = cellnoise<D>(offsetCell, m_useTexture); 00096 00097 g.pos = g.cell + lerp(timeOffset, p2, p1); 00098 } 00099 00100 template<int N, int D, typename T, typename P1, typename P2> 00101 CombinedPropFactory<N, D, T, P1, P2>::CombinedPropFactory(const P1 *propFactory1, const P2 *propFactory2) 00102 : m_propFactory1(propFactory1), m_propFactory2(propFactory2) {} 00103 00104 template<int N, int D, typename T, typename P1, typename P2> 00105 ShGeneric<N, T> CombinedPropFactory<N, D, T, P1, P2>::operator()( 00106 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00107 return join((*m_propFactory1)(p, g), (*m_propFactory2)(p, g)); 00108 } 00109 00110 template<typename P1, typename P2> 00111 PropertyFactory<P1::NUM_PROPS + P2::NUM_PROPS, P1::DIM, typename P1::PropType>* 00112 combine(const P1 *propFactory1, const P2 *propFactory2) { 00113 const int N = P1::NUM_PROPS + P2::NUM_PROPS; 00114 return new CombinedPropFactory<N, P1::DIM, typename P1::PropType, P1, P2>(propFactory1, propFactory2); 00115 } 00116 00117 template<int D, typename T> 00118 ShGeneric<1, T> DistSqPropFactory<D, T>::operator()( 00119 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00120 ShAttrib<D, SH_TEMP, T> delta = p - g.pos; 00121 return delta | delta; 00122 } 00123 00124 template<int D, typename T> 00125 ShGeneric<1, T> Dist_1PropFactory<D, T>::operator() ( 00126 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00127 ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos); 00128 return delta | fillcast<D>(ShConstAttrib1f(1.0f)); 00129 } 00130 00131 template<int D, typename T> 00132 ShGeneric<1, T> Dist_InfPropFactory<D, T>::operator() ( 00133 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00134 ShAttrib<D, SH_TEMP, T> delta = abs(p - g.pos); 00135 00136 // TODO replace with tuple max function when implemented 00137 ShAttrib<1, SH_TEMP, T> result = 0; 00138 for(int i = 0; i < D; ++i) result = max(result, delta(i)); 00139 return result; 00140 } 00141 00142 template<int D, typename T> 00143 ShGeneric<D + 1, T> DistSqGradientPropFactory<D, T>::operator() ( 00144 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00145 ShAttrib<D + 1, SH_TEMP, T> result; 00146 ShAttrib<D, SH_TEMP, T> delta = p - g.pos; 00147 00148 result(0) = delta | delta; 00149 for(int i = 1; i < D + 1; ++i) { 00150 result(i) = delta(i-1) * result(0); 00151 } 00152 return result; 00153 }; 00154 00155 template<int D, typename T> 00156 ShGeneric<D + 1, T> Dist_1GradientPropFactory<D, T>::operator() ( 00157 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00158 00159 ShAttrib<D + 1, SH_TEMP, T> result; 00160 ShAttrib<D, SH_TEMP, T> delta = p - g.pos; 00161 00162 ShAttrib<1, SH_CONST, T> ONE(1); 00163 result(0) = abs(delta) | fillcast<D>(ONE); 00164 for(int i = 1; i < D + 1; ++i) { // TODO switch to a swizzled version 00165 result(i) = cond(delta(i-1), ONE, -ONE); 00166 } 00167 return result; 00168 }; 00169 00170 template<int D, typename T> 00171 ShGeneric<D + 1, T> Dist_InfGradientPropFactory<D, T>::operator() ( 00172 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00173 ShAttrib<D + 1, SH_TEMP, T> result; 00174 ShAttrib<D, SH_TEMP, T> delta = p - g.pos; 00175 ShAttrib<D, SH_TEMP, T> absDelta = abs(delta); 00176 00177 result(0) = 0; 00178 for(int i = 0; i < D; ++i) result(0) = max(result(0), absDelta(i)); 00179 00180 // TODO remove this when constant folding is available 00181 ShAttrib<1, SH_CONST, T> ONE(1); 00182 for(int i = 1; i < D + 1; ++i) { // TODO switch to a swizzled version 00183 result(i) = (absDelta(i-1) >= result(0)) * cond(delta(i-1), ONE, -ONE); 00184 } 00185 return result; 00186 }; 00187 00188 template<int N, int D, typename T> 00189 ShGeneric<N, T> CellnoisePropFactory<N, D, T>::operator() ( 00190 const ShGeneric<D, T> &p, const Generator<D, T> &g) const { 00191 // TODO remove frac once Issue58 fixed 00192 return frac(cellnoise<N>(g.cell, m_useTexture)); 00193 }; 00194 00195 template<typename TexType, typename T> 00196 Tex2DPropFactory<TexType, T>::Tex2DPropFactory( 00197 const ShBaseTexture2D<TexType> &tex, const ShGeneric<1, T> &scale) 00198 : m_tex(tex), m_scale(scale), invScale(ShConstAttrib2f(1.0f, 1.0f) / tex.size()) {} 00199 00200 /* Moved to ShWorley.hpp 00201 template<typename TexType, typename T> 00202 ShGeneric<TexType::typesize, T> Tex2DPropFactory<TexType, T>::operator()( 00203 const ShGeneric<2, T> &p, const Generator<2, T> &g) const { 00204 } 00205 */ 00206 00207 template<int N, int K, int P, typename T> 00208 void kSelect(const ShGeneric<P, T> vals[N], ShGeneric<K, T> result[N], float LARGE = 1e10) { 00209 result[0] = fillcast<K>(ShConstAttrib1f(LARGE)); 00210 00211 int i, j, k, l; 00212 int shiftswiz[K]; 00213 ShAttrib1f c; 00214 for(i = 0; i < K; ++i) shiftswiz[i] = (i == 0 ? 0 : i - 1); 00215 00216 // insert into result one by one 00217 for(i = 0; i < P; ++i) { 00218 // check if smaller than the first one 00219 c = vals[0](i) < result[0](0); 00220 for(j = 0; j < N; ++j) { 00221 result[0] = lerp(c, result[0].template swiz<K>(shiftswiz), result[0]); 00222 result[0](0) = lerp(c, vals[0](i), result[0](0)); 00223 } 00224 00225 // check for the other ones 00226 for(j = 1; j < K; ++j) { 00227 c = (result[0](j-1) < vals[0](i)) * (vals[0](i) < result[0](j)); 00228 for(k = 0; k < N; ++k) { 00229 for(l = 0; l < K; ++l) shiftswiz[l] = l + ( l >= j ? -1 : 0); 00230 result[k] = lerp(c, result[k].template swiz<K>(shiftswiz), result[k]); 00231 result[k](j) = lerp(c, vals[k](i), result[k](j)); 00232 } 00233 } 00234 } 00235 } 00236 00237 template<int K, int L, int P, int D, typename T> 00238 void worley(ShGeneric<K, T> result[], const ShGeneric<D, T> &p, 00239 const GeneratorFactory<P, D, T> *genFactory, 00240 const PropertyFactory<L, D, T> *propFactory) { 00241 00242 int i, j; 00243 Generator<D, T> generators[P]; 00244 ShAttrib<P, SH_TEMP, T> props[L]; 00245 ShAttrib<L, SH_TEMP, T> propTemp; 00246 00247 (*genFactory)(p, generators); // make generators 00248 for(i = 0; i < P; ++i) { 00249 propTemp = (*propFactory)(p, generators[i]); 00250 for(j = 0; j < L; ++j) props[j](i) = propTemp(j); 00251 } 00252 00253 // sort points & gradients by distance 00254 groupEvenOddSort<L>(props); 00255 00256 // weighted sum of basis function values to get final result 00257 for(j = 0; j < L; ++j) result[j] = cast<K>(props[j]); 00258 } 00259 00260 template<int K, int D, typename T> 00261 ShGeneric<K, T> worley(const ShGeneric<D, T> &p, bool useTexture) { 00262 DefaultGenFactory<D, T> genFactory(useTexture); 00263 DistSqPropFactory<D, T> propFactory; 00264 ShAttrib<K, SH_TEMP, T> result; 00265 worley(&result, p, &genFactory, &propFactory); 00266 return result; 00267 } 00268 00269 template<int K, int D, typename T> 00270 ShProgram shWorley(bool useTexture) { 00271 DefaultGenFactory<D, T> genFactory(useTexture); 00272 DistSqPropFactory<D, T> propFactory; 00273 return shWorley<K>(&genFactory, &propFactory); 00274 } 00275 00276 template<int K, int L, int P, int D, typename T> 00277 ShProgram shWorley(const GeneratorFactory<P, D, T> *genFactory, 00278 const PropertyFactory<L, D, T> *propFactory) { 00279 ShProgram program = SH_BEGIN_PROGRAM() { 00280 ShTexCoord<D, SH_INPUT, T> SH_DECL(texcoord); 00281 00282 ShAttrib<K, SH_OUTPUT, T> result[L]; 00283 worley(&result[0], texcoord, genFactory, propFactory); 00284 } SH_END_PROGRAM; 00285 return program; 00286 } 00287 00288 } 00289 00290 #endif

Generated on Mon Oct 18 14:17:40 2004 for Sh by doxygen 1.3.7