📄 algebrashader.cpp
字号:
// 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 <list>#include "Shader.hpp"#include "Globals.hpp"#include "ShrikeCanvas.hpp"using namespace SH;using namespace ShUtil;#include "util.hpp"// VCS direction and upShVector3f lightDir;ShVector3f lightUp;ShAttrib1f width;ShAttrib1f invwidth;ShAttrib1f height;ShAttrib1f invheight;class AlgebraWrapper: public Shader {public: AlgebraWrapper(std::string name, int lightidx, int surfmapidx, int surfidx, int postidx) : Shader(name), lightidx(lightidx), surfmapidx(surfmapidx), surfidx(surfidx), postidx(postidx) {} bool init(); void render(); ShProgram vertex() { return vsh;} ShProgram fragment() { return fsh;}private: int lightidx, surfmapidx, surfidx, postidx; ShProgram vsh, fsh;};class AlgebraShaders {public: AlgebraShaders(); ~AlgebraShaders(); static bool init_all();private: friend class AlgebraWrapper; static const int LIGHT = 3; static const int SURFMAP = 2; static const int SURFACE = 7; static const int POST = 3; static ShProgram lightsh[LIGHT]; static const char* lightName[LIGHT]; static ShProgram surfmapsh[SURFMAP]; static const char* surfmapName[SURFMAP]; static ShProgram surfsh[SURFACE]; static const char* surfName[SURFACE]; static ShProgram postsh[POST]; static const char* postName[POST]; typedef std::list<Shader*> ShaderList; static std::list<Shader*> shaders; static bool doneInit;};AlgebraShaders::ShaderList AlgebraShaders::shaders;ShProgram AlgebraShaders::lightsh[AlgebraShaders::LIGHT];ShProgram AlgebraShaders::surfmapsh[AlgebraShaders::SURFMAP];ShProgram AlgebraShaders::surfsh[AlgebraShaders::SURFACE];ShProgram AlgebraShaders::postsh[AlgebraShaders::POST];bool AlgebraShaders::doneInit = false;const char* AlgebraShaders::lightName[] = { "Point Light", "Spot Light", "Textured Light"};const char* AlgebraShaders::surfmapName[] = { 0, "Bump Map"};const char* AlgebraShaders::surfName[] = { 0, "Diffuse", // "Specular Surface", // "Phong Surface", "Textured Phong", "Procedural Worley Phong", "Gooch", "Satin Homomorphic BRDF", "Ashikhmin"};const char* AlgebraShaders::postName[] = { 0, "Halftone PostOp", "Noisify PostOp"};bool AlgebraWrapper::init() { AlgebraShaders::init_all(); ShProgram lightsh = AlgebraShaders::lightsh[lightidx]; ShProgram surfmapsh = AlgebraShaders::surfmapsh[surfmapidx]; ShProgram surfsh = AlgebraShaders::surfsh[surfidx]; ShProgram postsh = AlgebraShaders::postsh[postidx]; fsh = namedCombine(lightsh, surfmapsh); fsh = namedConnect(fsh, surfsh); fsh = namedConnect(fsh, postsh); vsh = ShKernelLib::shVsh( Globals::mv, Globals::mvp, 1); vsh = vsh << shExtract("lightPos") << Globals::lightPos; vsh = namedAlign(vsh, fsh); return true;}void AlgebraWrapper::render() { lightDir = -normalize(Globals::mv | Globals::lightDirW); ShVector3f horiz = cross(lightDir, ShConstVector3f(0.0f, 1.0f, 0.0f)); lightUp = cross(horiz, lightDir); const ShrikeCanvas *canvas = ShrikeCanvas::instance(); width = canvas->GetClientSize().GetWidth(); invwidth = 1.0f / width; height = canvas->GetClientSize().GetHeight(); invheight = 1.0f / height; // set up lighting crap Shader::render();}AlgebraShaders::AlgebraShaders(){ for(int i = 0; i < LIGHT; ++i) { for(int j = 0; j < SURFMAP; ++j) { for(int k = 0; k < SURFACE; ++k) { for(int l = 0; l < POST; ++l) { std::string name = std::string("Algebra"); if (lightName[i]) {name += ": "; name += lightName[i];} if (surfmapName[j]) {name += ": "; name += surfmapName[j];} if (surfName[k]) {name += ": "; name += surfName[k];} if (postName[l]) {name += ": "; name += postName[l];} shaders.push_back(new AlgebraWrapper(name, i, j, k, l)); } } } }}AlgebraShaders::~AlgebraShaders(){ for(ShaderList::iterator I = shaders.begin(); I != shaders.end(); ++I) { delete *I; }}// returns a KernelSurface::phong shader with kd filled in by a worley shaderShProgram worleySurface() { ShAttrib3f SH_NAMEDECL(color1, "Worley Color1") = ShColor3f(3.0, 0.75, 0.0); color1.range(-3.0f, 3.0f); ShAttrib3f SH_NAMEDECL(color2, "Worley Color2") = ShColor3f(0.0f, 0.0f, 0.0f); color2.range(-3.0f, 3.0f); ShAttrib4f SH_NAMEDECL(coeff, "Worley Coefficients") = ShConstAttrib4f(2.5, -0.5f, -0.1f, 0); coeff.range(-3.0f, 3.0f); ShAttrib1f SH_NAMEDECL(freq, "Worley Frequency") = ShConstAttrib1f(16.0f); freq.range(0.1f, 64.0f); ShProgram worleysh = shWorley<4, 2, float>(false); // pass in coefficient worleysh = (shDot<ShAttrib4f>() << coeff) << worleysh; ShProgram scaler = SH_BEGIN_PROGRAM() { ShInOutTexCoord2f SH_DECL(texcoord) = freq * texcoord; } SH_END; worleysh = worleysh << scaler; ShProgram clamper = SH_BEGIN_PROGRAM() { ShInOutAttrib1f SH_DECL(scalar) = clamp(scalar, 0.0f, 1.0f); } SH_END; worleysh = clamper << worleysh; ShProgram colorsh = shLerp<ShColor3f, ShAttrib1f>("kd") << color1 << color2; // kd is a lerp based on the worley scalar return ShKernelSurface::phong<ShColor3f>() << colorsh << worleysh;}ShProgram satinSurface() { ShImage image; // TODO: should have array of available BRDFs with correction // factor for each, hidden uniforms (don't want user to play with // alpha, really), pulldown menu to select BRDFs from list, // settings for extra specularities, etc. etc. load_PNG(image, normalize_path(SHMEDIA_DIR "/brdfs/satin/satinp.png")); ShTable2D<ShColor3fub> ptex(image.width(), image.height()); ptex.internal(true); ptex.memory(image.memory()); load_PNG(image, normalize_path(SHMEDIA_DIR "/brdfs/satin/satinq.png")); ShTable2D<ShColor3fub> qtex(image.width(), image.height()); qtex.internal(true); qtex.memory(image.memory()); // HACK, satin doesn't have specular part, turned off by default load_PNG(image, normalize_path(SHMEDIA_DIR "/textures/ks.png")); ShTable2D<ShColor3fub> stex(image.width(), image.height()); stex.name("Satin Texture"); stex.memory(image.memory()); // these scale factors are specific to satin ShColor3f SH_DECL(alpha) = ShColor3f(0.762367,0.762367,0.762367); ShAttrib1f SH_DECL(diffuse) = ShAttrib1f(1.0); diffuse.range(0.0,5.0); ShAttrib1f SH_DECL(specular) = ShAttrib1f(0.0); specular.range(0.0,1.0); ShAttrib1f SH_DECL(light_power) = ShAttrib1f(1.0); light_power.range(0.0,100.0); ShProgram fsh = SH_BEGIN_PROGRAM("gpu:fragment") { ShInputColor3f SH_DECL(irrad); ShInputVector3f SH_DECL(lightVect); ShInputVector3f SH_DECL(halfVect); ShInputVector3f SH_DECL(viewVect); ShInputPosition4f SH_DECL(posh); ShOutputColor3f SH_DECL(result);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -