📄 worleyshader.cpp
字号:
coeff = ShConstAttrib4f(0.0f, 0.5f, 0.5f, 0.0f); freq = ShConstAttrib1f(16.0f); ShProgram worleysh[N]; for(int i = N - 1; i >= 0; --i) { DefaultGenFactory<2, float> genFactory(useTexture); Dist_1PropFactory<2, float> distFactory; worleysh[i] = shWorley<4>(&genFactory, &distFactory); ShProgram multiplier = SH_BEGIN_PROGRAM() { ShInOutTexCoord2f SH_DECL(texcoord); texcoord *= freq * (float)(1 << i); } SH_END; worleysh[i] = worleysh[i] << multiplier; } ShProgram comboWorley = worleysh[0]; for(int i = 1; i < N; ++i) { comboWorley = namedCombine(comboWorley, worleysh[i]); } ShProgram colorizer = SH_BEGIN_PROGRAM() { ShInputAttrib4f SH_DECL(result[N]); ShOutputColor3f SH_DECL(kd); ShOutputColor3f SH_DECL(ks); ShAttrib1f weightedResult(0.0f); for(int i = 0; i < N; ++i) weightedResult = mad(dot(result[i], coeff), amps(i), weightedResult); kd = lerp(weightedResult, color1, color2); ks = kd; } SH_END; fsh = fsh << colorizer << comboWorley; vsh = namedAlign(vsh, fsh); }};class MosaicWorley: public WorleyShader {public: MosaicWorley(bool useTexture): WorleyShader("Mosaic", useTexture) {} void initfsh() { ShColor3f specularColor(0.5, 0.5, 0.5); ShImage image; load_PNG(image, normalize_path(SHMEDIA_DIR "/textures/kd.png")); ShTable2D<ShColor3fub> mosaicTex(image.width(), image.height()); mosaicTex.name("Mosaic Texture"); mosaicTex.memory(image.memory()); std::string imageNames[6] = {"left", "right", "top", "bottom", "back", "front"}; ShImage test_image; load_PNG(test_image, normalize_path(std::string(SHMEDIA_DIR "/envmaps/aniroom/") + imageNames[0] + ".png")); ShTableCube<ShColor4fub> cubemap(test_image.width(), test_image.height()); { for (int i = 0; i < 6; i++) { ShImage image2; load_PNG(image2, normalize_path(std::string(SHMEDIA_DIR "/envmaps/aniroom/") + imageNames[i] + ".png")); cubemap.memory(image2.memory(), static_cast<ShCubeDirection>(i)); } } ShAttrib1f SH_DECL(texScale) = ShConstAttrib1f(32.0); texScale.range(0.0f, image.width() / 16.0f); DefaultGenFactory<2, float> genFactory(useTexture); //NullGenFactory<2, float> genFactory; DistSqPropFactory<2, float> distFactory; Tex2DPropFactory<ShColor3fub, float> tex2dFactory(mosaicTex, texScale); coeff = ShConstAttrib4f(-1.0f, 1.0f, 0.0f, 0.0f); ShAttrib4f SH_DECL(colorCoeff) = ShConstAttrib4f(3.0f, 0.0f, 0.0f, 0.0f); colorCoeff.range(-4.0f, 4.0f); ShProgram worleysh = shWorley<4>(&genFactory, combine(&distFactory, &tex2dFactory)); ShProgram texcoordScaler = SH_BEGIN_PROGRAM() { ShInOutTexCoord2f SH_DECL(texcoord) = texcoord * (image.width() / texScale); } SH_END; worleysh = worleysh << texcoordScaler; ShAttrib1f theta = ShAttrib1f(1.3f); theta.name("relative indices of refraction"); theta.range(0.0f,2.0f); ShAttrib1f SH_NAMEDECL(threshold, "Lattice threshold") = ShAttrib1f(0.1f); threshold.range(-1.0f, 1.0f); // TODO actually get the glass shader instead of rewriting it here ShProgram vshAddon = SH_BEGIN_PROGRAM("gpu:vertex") { ShInOutNormal3f SH_DECL(normal); ShInOutVector3f SH_DECL(viewVec); ShOutputVector3f SH_DECL(reflv); ShOutputVector3f SH_DECL(refrv); ShOutputAttrib1f SH_DECL(fres); reflv = reflect(viewVec,normal); // Compute reflection vector refrv = refract(viewVec,normal,theta); // Compute refraction vector fres = fresnel(viewVec,normal,theta); // Compute fresnel term // actually do reflection and refraction lookup in model space reflv = Globals::mv_inverse | reflv; refrv = Globals::mv_inverse | refrv; } SH_END; vsh = namedConnect(vsh, vshAddon, true); ShAttrib1f SH_DECL(killThreshold) = -0.1f; killThreshold.range(-16.0f, 16.0f); ShProgram perturber = SH_BEGIN_PROGRAM("gpu:fragment") { ShInputAttrib4f result[4]; // worley result - result[0] = distance and result[1-3] = RGB color ShOutputColor3f SH_DECL(color); ShInOutAttrib1f SH_DECL(fres); // take square roots to get real euclidean distance for(int i = 0; i < 4; ++i) result[0](i) = sqrt(result[0](i)); // stain colours inside mosaic tiles and at tile edges, // make it opaque and black ShAttrib1f dist = dot(result[0], coeff); ShAttrib1f inEdge = dist < threshold; for(int i = 0; i < 3; ++i) color(i) = dot(result[i+1], colorCoeff); discard((color|ShConstAttrib3f(1.0f, 1.0f, 1.0f)) < killThreshold); color = lerp(inEdge, ShConstColor3f(0.0f, 0.0f, 0.0f), color); fres = lerp(inEdge, ShConstAttrib1f(1.0f), fres); } SH_END; fsh = SH_BEGIN_PROGRAM("gpu:fragment") { ShInputPosition4f SH_DECL(posh); ShInputColor3f SH_DECL(color); // stain color on glass ShInputNormal3f SH_DECL(normal); // normal ShInputVector3f SH_DECL(reflv); // Compute reflection vector ShInputVector3f SH_DECL(refrv); // Compute refraction vector ShInputAttrib1f SH_DECL(fres); // Compute fresnel term ShOutputColor3f result; result = color * lerp(fres, cubemap(reflv)(0,1,2), cubemap(refrv)(0,1,2)); } SH_END; fsh = namedConnect(perturber << worleysh, fsh); vsh = namedAlign(vsh, fsh); }}; class Worley3D: public WorleyShader {public: Worley3D(bool useTexture): WorleyShader("3D", useTexture) {} void initfsh() { ShProgram worleysh = shWorley<1, 3, float>(useTexture); // only keep closest neighbour worleysh = worleysh << (shMul<ShTexCoord3f>("texcoord", "freq", "posv") << fillcast<3>(freq)); // make polkadots by clamping the scalar result from worley color1 = ShColor3f(0.27, 0.35, 0.45); color2 = ShColor3f(1.0, 0.7, 0.0); ShColor3f specularColor(0.5, 0.5, 0.5); ShProgram colorsh = shLerp<ShColor3f, ShAttrib1f>("kd") << color1 << color2; // kd is a lerp based on the worley scalar colorsh = colorsh & ( keep<ShColor3f>("ks") << specularColor); fsh = fsh << colorsh << worleysh; vsh = namedAlign(vsh, fsh); }};// replace these with inline nibbles later onclass Worley2D: public WorleyShader {public: Worley2D(bool useTexture, ShConstAttrib4f c, PropertyFactory<1, 2, float> *distFactory, std::string name) : WorleyShader(std::string("2D: ") + name, useTexture), m_distFactory(distFactory), m_coeff(c) { m_time.name("time"); m_time.range(0.0f, 2.0f); } ~Worley2D() { delete m_distFactory; } // Lerp factory that starts with a fixed grid at time = 0 (good to see how // grid jittering works) struct FixedLerpFactory: GridGenFactory<2, float> { FixedLerpFactory(const ShGeneric<1, float> &time, bool useTexture) : m_time(time), m_useTexture(useTexture){} private: const ShGeneric<1, float> &m_time; bool m_useTexture; void makePos(Generator<2, float> &g) const { ShAttrib1f lastTime = floor(m_time); ShAttrib1f timeOffset = frac(m_time); ShAttrib3f offsetCell; offsetCell = fillcast<3>(g.cell); offsetCell(2) = lastTime; ShAttrib2f p1 = cellnoise<2>(offsetCell, m_useTexture); p1 = lerp(lastTime < 0.5f, ShConstAttrib2f(0.0f, 0.0f), p1); offsetCell(2) += 1; ShAttrib2f p2 = cellnoise<2>(offsetCell, m_useTexture); g.pos = g.cell + lerp(timeOffset, p2, p1); } }; void initfsh() { coeff = m_coeff; FixedLerpFactory genFactory(m_time, useTexture); DistSqPropFactory<2, float> euclideanDistFactory; PropertyFactory<2, 2, float> *propFactory = combine(m_distFactory, &euclideanDistFactory); ShProgram worleysh = shWorley<4>(&genFactory, propFactory); worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); // make polkadots by clamping the scalar result from worley color1 = ShColor3f(1.0, 1.0f, 1.0f); color2 = ShColor3f(0.0f, 0.0f, 0.0f); ShAttrib1f SH_DECL(threshold) = 0.01f; threshold.range(-1.0f, 1.0f); ShColor3f SH_DECL(featureColor) = ShConstColor3f(1.0f, 0.0f, 1.0f); ShProgram colorsh = SH_BEGIN_PROGRAM("gpu:fragment") { ShInputAttrib4f dists; // 4-nearest worley distances ShInputAttrib4f euclideanDists; // 4-nearest euclidean distances ShInputPosition4f SH_DECL(posh); ShOutputColor3f SH_DECL(result); result = lerp(coeff | dists, color1, color2); result = cond(euclideanDists(0) < threshold, featureColor, result); } SH_END; colorsh = colorsh; fsh = colorsh << worleysh; vsh = namedAlign(vsh, fsh); } static ShAttrib1f m_time; PropertyFactory<1, 2, float> *m_distFactory; ShConstAttrib4f m_coeff;};ShAttrib1f Worley2D::m_time = 1.0f;// Basic Examples:Worley2D worley2dNothing(true, ShConstAttrib4f(0.0f, 0.0f, 0.0f, 0.0f), new DistSqPropFactory<2, float>(), "Points Only");Worley2D worley2dF1(true, ShConstAttrib4f(1.0f, 0.0f, 0.0f, 0.0f), new DistSqPropFactory<2, float>(), "Euclidean Distance Squared: F1");Worley2D worley2dF2(true, ShConstAttrib4f(0.0f, 1.0f, 0.0f, 0.0f), new DistSqPropFactory<2, float>(), "Euclidean Distance Squared: F2");Worley2D worley2dF3(true, ShConstAttrib4f(0.0f, 0.0f, 1.0f, 0.0f), new DistSqPropFactory<2, float>(), "Euclidean Distance Squared: F3");Worley2D worley2dF4(true, ShConstAttrib4f(0.0f, 0.0f, 0.0f, 1.0f), new DistSqPropFactory<2, float>(), "Euclidean Distance Squared: F4");Worley2D worley2dL1F1(true, ShConstAttrib4f(1.0f, 0.0f, 0.0f, 0.0f), new Dist_1PropFactory<2, float>(), "Manhattan(L1) Distance: F1");Worley2D worley2dL1F2(true, ShConstAttrib4f(0.0f, 1.0f, 0.0f, 0.0f), new Dist_1PropFactory<2, float>(), "Manhattan(L1) Distance: F2");Worley2D worley2dL1F3(true, ShConstAttrib4f(0.0f, 0.0f, 1.0f, 0.0f), new Dist_1PropFactory<2, float>(), "Manhattan(L1) Distance: F3");Worley2D worley2dL1F4(true, ShConstAttrib4f(0.0f, 0.0f, 0.0f, 1.0f), new Dist_1PropFactory<2, float>(), "Manhattan(L1) Distance: F4");Worley2D worley2dInfF1(true, ShConstAttrib4f(1.0f, 0.0f, 0.0f, 0.0f), new Dist_InfPropFactory<2, float>(), "L Infinity Distance: F1");Worley2D worley2dInfF2(true, ShConstAttrib4f(0.0f, 1.0f, 0.0f, 0.0f), new Dist_InfPropFactory<2, float>(), "L Infinity Distance: F2");Worley2D worley2dInfF3(true, ShConstAttrib4f(0.0f, 0.0f, 1.0f, 0.0f), new Dist_InfPropFactory<2, float>(), "L Infinity Distance: F3");Worley2D worley2dInfF4(true, ShConstAttrib4f(0.0f, 0.0f, 0.0f, 1.0f), new Dist_InfPropFactory<2, float>(), "L Infinity Distance: F4");Worley3D worley3d(true);// Thresholding Examples // (Euclidean and L1 metrics)PolkaDotWorley polka(false);GiraffeWorley giraffe(false);CircuitWorley circuit(false);// Fractal examplesLavaWorley lava(false);TurbulentWorley turb(true);// Bump Mapping examplesOrganicWorley organic(true);BlueOrbWorley borg(true);//GradientWorley gradworley(true);// Animated ExamplesCrackedWorley crackedAnim(true, true);CrackedWorley crackedProceduralAnim(false, true);//CrackedWorley cracked(true, false);//CrackedWorley crackedProcedural(false, false);// Cell-colouring examples (attaching random and texture-lookup// cell colours to feature points)StoneWorley stone(true);MosaicWorley mosaic(true);MosaicWorley mosaic2(false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -