brickwall.cpp

来自「shrike is a utility application that act」· C++ 代码 · 共 197 行

CPP
197
字号
// Sh: A GPU metaprogramming language.//// Copyright 2003-2005 Serious Hack Inc.// // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA  02110-1301, USA//////////////////////////////////////////////////////////////////////////////#include <sh/sh.hpp>#include <sh/shutil.hpp>#include <iostream>#include <math.h>#include "Shader.hpp"#include "Globals.hpp"using namespace SH;using namespace ShUtil;/* hyperbolic tangent function * created because tanh in not yet implemented in Sh */ShAttrib1f tanh( ShAttrib1f x) {  return (pow(M_E, 2*x) - 1) / (pow(M_E, 2*x) + 1);}class BrickWall : public Shader {public:  BrickWall();  ~BrickWall();  bool init();  ShProgram vertex() { return vsh;}  ShProgram fragment() { return fsh;}  ShProgram vsh, fsh;  static BrickWall instance;};BrickWall::BrickWall()  : Shader("Brick Wall: Brick Wall"){}BrickWall::~BrickWall(){}bool BrickWall::init(){  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {    ShInputPosition4f ipos;    ShInputNormal3f inorm;        ShOutputPosition4f opos; // Position in NDC    ShOutputNormal3f onorm;    ShInOutTexCoord2f tc; // pass through tex coords    ShOutputVector3f halfv;    ShOutputVector3f lightv; // direction to light    opos = Globals::mvp | ipos; // Compute NDC position    onorm = Globals::mv | inorm; // Compute view-space normal    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position    lightv = normalize(Globals::lightPos - posv); // Compute light direction    ShPoint3f viewv = -normalize(posv); // Compute view vector    halfv = normalize(viewv + lightv); // Compute half vector  } SH_END;  ShColor3f SH_DECL(brick) = ShColor3f(0.7, 0.1, 0.1);  ShColor3f SH_DECL(mortar) = ShColor3f(0.3, 0.3, 0.3);  ShAttrib2f SH_DECL(scale) = ShAttrib2f(3.0, 5.0);  scale.name("brick size");  scale.range(1.0, 100.0);  ShAttrib2f SH_DECL(mortarsize) = ShAttrib2f(0.03, 0.03);  mortarsize.name("mortar size");  mortarsize.range(0.0, 0.1);  ShAttrib1f SH_DECL(offset) = ShAttrib1f(0.5);  offset.range(0.0, 1.0);   ShAttrib3f SH_DECL(colorVariations) = ShAttrib3f(0.2, 0.1, 0.1);  colorVariations.range(0.0, 1.0);  ShAttrib1f SH_DECL(noiseScale) = ShConstAttrib1f(0.1f);  noiseScale.range(0.0f, 1.0f);  ShAttrib1f SH_DECL(noiseFreq) = ShConstAttrib1f(25.0f);  noiseFreq.range(0.0f, 100.0f);  ShAttrib3f SH_DECL(noiseAmps) = ShConstAttrib3f(1.0f, 0.5f, 0.25f);	  noiseAmps.range(0.0f, 1.0f);   /* Create the bricks and the mortar between them   */  ShProgram brickID = SH_BEGIN_PROGRAM("gpu:fragment") {    ShInputPosition4f pos;    ShInOutTexCoord2f tc;    ShOutputAttrib1f changeColor; // change the color between 2 consecutive bricks    ShInOutNormal3f norm;    ShOutputAttrib1f id; // define if the current point belongs to a brick or to the mortar    tc *= scale;    tc(0) -= floor(tc(1))*offset; // change the horizontal position of a line    changeColor = abs(floor(tc(1))) * abs(floor(tc(0)+0.5));    tc(1) -= floor(tc(1)+0.5);    tc(0) -= floor(tc(0)+0.5);    id = SH::min(abs(tc(0)) < 0.5-mortarsize(0), abs(tc(1)) > mortarsize(1)); // limits of a brick  } SH_END;    /* Add bump-mapping to the wall   * edges are bumpmapped with a tanh function   * bricks and mortar are bumpmapped with some noise   */  ShProgram bumpmap = SH_BEGIN_PROGRAM("gpu:fragment") {    ShInOutTexCoord2f tc;    ShInOutAttrib1f changeColor;    ShInOutNormal3f norm;     ShVector3f TilePerturb = noiseScale * sperlin<3>(tc * noiseFreq, noiseAmps, true);    norm = mad(0.35, TilePerturb, norm);    // set the limits of edges    ShAttrib1f verticalLimits = SH::min(abs(tc(0)) < 0.5-mortarsize(0)+0.01, abs(tc(0)) > 0.5-mortarsize(0)-0.01);    ShAttrib1f horizontalLimits = SH::min(abs(tc(1)) > mortarsize(1)-0.01, abs(tc(1)) < mortarsize(1)+0.01);    // change the normals with a tanh function    ShVector3f normDeformation = ShVector3f(tc(0)/abs(tc(0)) * 0.5 * (tanh(10*abs(tc(0))-0.5-mortarsize(0))+1), ShAttrib1f(0.0), ShAttrib1f(0.0));    norm = cond( min(verticalLimits, abs(tc(1))>mortarsize(1)), norm + normDeformation, norm);    normDeformation = ShVector3f(ShAttrib1f(0.0),tc(1)/abs(tc(1)) * 0.5 * (tanh(10*abs(tc(1)-mortarsize(1)))+1), ShAttrib1f(0.0));    norm = cond( min(horizontalLimits, abs(tc(0))<0.5-mortarsize(0)), norm + normDeformation, norm);           norm = normalize(norm); // normalize the new normal      } SH_END;    /* Change the color of a brick   * a noise function is used to add variations to the initial color   */  ShProgram brickModifier = SH_BEGIN_PROGRAM("gpu:fragment") {    ShInputTexCoord2f tc;    ShInputAttrib1f changeColor;    ShOutputColor3f brickVariations;     brickVariations = noiseScale * perlin<3>(tc * noiseFreq, noiseAmps, true);    brickVariations = mad(cellnoise<1>(changeColor, false), colorVariations, brickVariations);    brickVariations = mad(0.35, brickVariations, brick);  } SH_END;    /* Select the color to render in function of the id   * id = 1.0 is a brick   * id = 0.0 is the mortar   */  ShProgram select = SH_BEGIN_PROGRAM("gpu:fragment") {    ShInputColor3f brickVariations;    ShInputNormal3f normal;    ShInputAttrib1f id;    ShInputVector3f half;    ShInputVector3f light;     ShOutputColor3f result;      result= cond(id<0.5, mortar, brickVariations);    // add Phong lighting    normal = normalize(normal);    half = normalize(half);    light = normalize(light);    result = result * pos(normal | light);           } SH_END;   fsh = select << (((brickModifier & keep<ShNormal3f>() & keep<ShAttrib1f>()) << (bumpmap & keep<ShAttrib1f>()) << brickID) & keep<ShVector3f>() & keep<ShVector3f>());    return true;}BrickWall BrickWall::instance = BrickWall();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?