📄 worleyshader.cpp
字号:
DefaultGenFactory<2, float> genFactory(useTexture); DistSqPropFactory<2, float> distSqPropFactory; Dist_1PropFactory<2, float> dist_1PropFactory; ShProgram worleysh = shWorley<4>(&genFactory, &dist_1PropFactory); worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); worleysh = (shDot<ShAttrib4f>() << coeff) << worleysh; ShProgram worleysh2 = shWorley<4>(&genFactory, &distSqPropFactory); worleysh2 = worleysh2 << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq2)); worleysh2 = (shDot<ShAttrib4f>() << coeff2) << worleysh2; worleysh = shSub<ShAttrib1f>() << namedCombine(worleysh, worleysh2); color1 = ShColor3f(0.0, 0.0, 1.0); color2 = ShColor3f(0.5, 0.0, 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); }};class GiraffeWorley: public WorleyShader {public: GiraffeWorley(bool useTexture): WorleyShader("Giraffe", useTexture) {} void initfsh() { param = ShConstAttrib1f(0.75); coeff = ShConstAttrib4f(-1, 1, 0, 0); ShAttrib4f SH_NAMEDECL(coeff2, "Worley coefficient 2") = ShConstAttrib4f(0, -1, 1, 0); DefaultGenFactory<2, float> genFactory(useTexture); Dist_1PropFactory<2, float> dist_1PropFactory; ShProgram worleysh = shWorley<4>(&genFactory, &dist_1PropFactory); worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); worleysh = (shDot<ShAttrib4f>() << coeff) << worleysh; ShProgram worleysh2 = shWorley<4>(&genFactory, &dist_1PropFactory); worleysh2 = worleysh2 << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); worleysh2 = (shDot<ShAttrib4f>() << coeff2) << worleysh2; // make patches out of the two ShProgram patcher = SH_BEGIN_PROGRAM() { ShInputAttrib1f SH_DECL(worleyScalar1); ShInputAttrib1f SH_DECL(worleyScalar2); ShOutputAttrib1f SH_DECL(result); worleyScalar1 = (1.0f - worleyScalar1 - param) * 30.0f; worleyScalar2 = (1.0f - worleyScalar2 - param) * 10.0f; result = clamp(worleyScalar1 + worleyScalar2, 0.0f, 1.0f); } SH_END; worleysh = patcher << namedCombine(worleysh, worleysh2); color1 = ShColor3f(1.0, 0.95, 0.8); color2 = ShColor3f(0.45, 0.3, 0.0); ShColor3f specularColor(0.2, 0.2, 0.2); 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); }};class CircuitWorley: public WorleyShader {public: CircuitWorley(bool useTexture): WorleyShader("Circuit", useTexture) {} void initfsh() { coeff = ShConstAttrib4f(0, 0, 0, 1); ShAttrib1f SH_NAMEDECL(freq2, "Worley frequency 2") = freq * 2.131313f; DefaultGenFactory<2, float> genFactory(useTexture); Dist_1PropFactory<2, float> dist_1PropFactory; ShProgram worleysh = shWorley<4>(&genFactory, &dist_1PropFactory); worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); worleysh = (shDot<ShAttrib4f>() << coeff) << worleysh; ShProgram worleysh2 = shWorley<4>(&genFactory, &dist_1PropFactory); worleysh2 = worleysh2 << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq2)); worleysh2 = (shDot<ShAttrib4f>() << coeff) << worleysh2; color1 = ShColor3f(0.0, 0.2, 0.8); color2 = ShColor3f(0.6, 0.6, 0.7); // make patches out of the two ShProgram colorizer = SH_BEGIN_PROGRAM() { ShInputAttrib1f SH_DECL(worleyScalar1); ShInputAttrib1f SH_DECL(worleyScalar2); ShOutputColor3f SH_DECL(kd); ShOutputColor3f SH_DECL(ks); worleyScalar1 = clamp((1.0f - worleyScalar1 + param) * 30.0f, 0.0f, 1.0f); worleyScalar2 = 1.0f - clamp((1.0f - worleyScalar2 + param) * 30.0f, 0.0f, 1.0f); kd = worleyScalar1 * color1 + worleyScalar2 * color2; ks = kd; } SH_END; worleysh = namedCombine(worleysh, worleysh2); worleysh = colorizer << worleysh; fsh = fsh << worleysh; vsh = namedAlign(vsh, fsh); }};class CrackedWorley: public WorleyShader {public: bool m_animate; ShAttrib1f m_old, m_enable, m_time, m_speed; CrackedWorley(bool useTexture, bool animate) : WorleyShader(std::string("Cracked") + (animate ? " Animating" : ""), useTexture), m_animate(animate) { m_old = m_enable = 1.0f; m_enable.name("Enable Animation"); m_speed = 0.1f; m_speed.name("Animation Speed"); m_speed.range(-2.0f, 2.0f); m_time = 0.0f; } void initfsh() { color1 = ShColor3f(3.0, 0.75, 0.0); color2 = ShColor3f(0.0f, 0.0f, 0.0f); ShColor3f specularColor(0.5, 0.5, 0.5); coeff = ShConstAttrib4f(2.5, -0.5f, -0.1f, 0); freq = ShConstAttrib1f(16.0f); ShProgram worleysh; DistSqPropFactory<2, float> propFactory; if (m_animate) { LerpGenFactory<2, float> genFactory(m_time, useTexture); worleysh = shWorley<4>(&genFactory, &propFactory); } else { DefaultGenFactory<2, float> genFactory(useTexture); worleysh = shWorley<4>(&genFactory, &propFactory); } worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); worleysh = (shDot<ShAttrib4f>() << coeff) << worleysh; ShProgram clamper = SH_BEGIN_PROGRAM() { ShInOutAttrib1f SH_DECL(scalar) = clamp(scalar, 0.0f, 1.0f); // TODO get rid of this hack... This makes m_speed and m_enable visible in the uniform panel scalar += 0.0f * (m_speed + m_enable); } SH_END; worleysh = clamper << worleysh; 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); } void render() { if((m_enable != m_old).getValue(0) > 0.5f) { m_time += m_speed; m_old = m_enable; } Shader::render(); }};class StoneWorley: public WorleyShader {public: StoneWorley(bool useTexture): WorleyShader("Stone Tile", useTexture) {} void initfsh() { color1 = ShColor3f(1.0, 0.5, 0.0); ShColor3f specularColor(0.1f, 0.1f, 0.1f); ShAttrib1f SH_NAMEDECL(groutThreshold, "Grout Threshold") = ShConstAttrib1f(0.05f); groutThreshold.range(-1.0f, 1.0f); ShAttrib1f SH_NAMEDECL(bevelThreshold, "Bump Threshold") = ShConstAttrib1f(0.2f); bevelThreshold.range(-1.0f, 1.0f); coeff = ShConstAttrib4f(-1.0f, 1.0f, 0.0f, 0.0f); ShAttrib4f noiseCoeff = ShConstAttrib4f(1.0f, 0.0f, 0.0f, 0.0f); freq = ShConstAttrib1f(16.0f); DefaultGenFactory<2, float> genFactory(useTexture); //NullGenFactory<2, float> genFactory; DistSqGradientPropFactory<2, float> distPropFactory; CellnoisePropFactory<1, 2, float> noisePropFactory(useTexture); PropertyFactory<4, 2, float> *propFactory = combine(&distPropFactory, &noisePropFactory); ShProgram worleysh = shWorley<4>(&genFactory, propFactory); // pass in coefficients worleysh = worleysh << (shMul<ShTexCoord2f>("texcoord", "freq", "texcoord") << fillcast<2>(freq)); ShAttrib1f SH_DECL(noiseScale) = ShConstAttrib1f(0.1f); noiseScale.range(0.0f, 1.0f); ShAttrib1f SH_DECL(noiseFreq) = ShConstAttrib1f(128.0f); noiseFreq.range(0.0f, 768.0f); ShAttrib3f SH_DECL(noiseAmps) = ShConstAttrib3f(1.0f, 0.5f, 0.25f); noiseAmps.range(0.0f, 1.0f); ShAttrib1f SH_DECL(bumpScale) = ShConstAttrib1f(3.0f); bumpScale.range(-10.0f, 10.0f); ShProgram worleyWeight = SH_BEGIN_PROGRAM() { // result[0] holds the 4-nearest distances, // result[1,2] holds the gradient for 4 nearest features // result[3] holds noise property for 4 nearest features ShInputAttrib4f result[4]; // change from squared euclidean to euclidean distances for(int i = 0; i < 4; ++i) result[0](i) = sqrt(result[0](i)); // calculate weighted sums of distances, gradients and noise property ShOutputAttrib1f SH_DECL(worleyDist) = dot(coeff, result[0]); ShOutputAttrib2f SH_DECL(worleyGrad); // TODO clean up this bump hack -coeff gives the right bumps, but // we should really be picking coeff correctly and fixing thresholds // below instead worleyGrad(0) = dot(-coeff, result[1]); worleyGrad(1) = dot(-coeff, result[2]); ShOutputAttrib1f SH_DECL(worleyNoise) = dot(noiseCoeff, result[3]); } SH_END; worleysh = worleyWeight << worleysh; ShProgram color = SH_BEGIN_PROGRAM() { ShInputTexCoord2f SH_DECL(texcoord); ShInputAttrib1f SH_DECL(worleyDist); ShInputAttrib2f SH_DECL(worleyGrad); ShInputAttrib1f SH_DECL(worleyNoise); ShInputVector3f SH_DECL(tangent) = normalize(tangent); ShInputVector3f SH_DECL(tangent2) = normalize(tangent2); ShInputVector3f SH_DECL(lightVec) = normalize(lightVec); ShInOutNormal3f SH_DECL(normal); ShOutputColor3f SH_DECL(kd); ShOutputColor3f SH_DECL(ks); ShOutputVector3f SH_DECL(halfVec); // decide whether we're in grout or in the bevel near the grout ShAttrib1f inGrout = worleyDist < groutThreshold; ShAttrib1f inBevel = (worleyDist < (groutThreshold + bevelThreshold)) - inGrout; // generate stone colors (one per tile) kd = lerp(inGrout, ShConstColor3f(1.0f, 1.0f, 1.0f), worleyNoise * color1); ks = specularColor; // apply bump mapping ShVector3f inBevelPerturb = (worleyGrad(0) * tangent + worleyGrad(1) * tangent2); ShVector3f insideTilePerturb = noiseScale * sperlin<3>(texcoord * noiseFreq, noiseAmps, useTexture); normal += bumpScale * ( lerp(inBevel, inBevelPerturb, ShConstVector3f(0.0f, 0.0f, 0.0f)) + lerp(inGrout, ShConstVector3f(0.0f, 0.0f, 0.0f), insideTilePerturb)); normal = normalize(normal); halfVec = 0.5f * (normal + lightVec); } SH_END; fsh = namedConnect(namedConnect(worleysh, color), fsh); vsh = namedAlign(vsh, fsh); delete propFactory; }};class TurbulentWorley: public WorleyShader {public: TurbulentWorley(bool useTexture): WorleyShader("Turbulence", useTexture) {} void initfsh() { ShAttrib4f SH_NAMEDECL(amps, "Octave_Amplitudes") = ShConstAttrib4f(1.0f, 0.5f, 0.25f, 0.125f); amps.range(0.0f, 1.0f); const int N = 4; // number of octaves color1 = ShColor3f(1.0f, 1.0f, 1.0f); color2 = ShColor3f(0.0f, 0.0f, 0.0f); ShColor3f specularColor(0.5, 0.5, 0.5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -