📄 algebrashader.cpp
字号:
// Normalize (theoretically not needed if compiler smart enough) lightVect = normalize(lightVect); viewVect = normalize(viewVect); halfVect = normalize(halfVect); // Incorporate diffuse scale, correction factor, and irradiance result = diffuse * alpha * pos(lightVect(2)); // Theoretically not needed if use common subexpression elimination... ShTexCoord2f hu = parabolic_norm(halfVect); ShTexCoord2f lu = parabolic_norm(lightVect); ShTexCoord2f vu = parabolic_norm(viewVect); // TODO: SHOULD use automatic projective normalization in texture lookup... // and/or parabolic texture type instead. result *= ptex(lu); result *= qtex(hu); result *= ptex(vu); // Add in specular term (also represented using parabolic map) result += specular * stex(hu) * pos(lightVect(2)); // Take into account lightVect power and colour result *= light_power * irrad; } SH_END; return fsh;}namespace {/* Ashikhmin Surface Atom from Stefanus' demo... * Move some of this into the utils library later */template<int N>ShGeneric<N, float> pow5(const ShGeneric<N, float>& f){ ShAttrib<N, SH_TEMP, float> t = f * f; return t * t * f;}ShColor3f schlick(ShColor3f refl, ShAttrib1f kh){ return refl + (ShColor3f(1.0, 1.0, 1.0) - refl)*pow5(1.0f - kh);}ShColor3f ashikhmin_specular(ShAttrib1f nu, ShAttrib1f nv, ShNormal3f n, ShVector3f h, ShVector3f light, ShVector3f viewer, ShVector3f u, ShVector3f v, ShColor3f refl){ ShVector3f k = viewer; // either light or viewer works here#define CLAMP(x) max(x, 0.01) ShAttrib1f hn = CLAMP(h|n); ShAttrib1f kn = CLAMP(k|n); ShAttrib1f ln = CLAMP(light|n); ShAttrib1f vn = CLAMP(viewer|n); ShAttrib1f kh = CLAMP(k|h); ShAttrib1f hu = (h|u); ShAttrib1f hv = (h|v); ShAttrib1f scale = sqrt((nu + 1.0f) * (nv + 1.0f))/(8.0*M_PI); ShAttrib1f exponent = (nu*hu*hu + nv*hv*hv)/(1.0f - hn*hn); ShAttrib1f geom = pow(hn, exponent)/(kn*SH::max(ln, vn)); return scale * geom * schlick(refl, kh);}ShColor3f ashikhmin_diffuse(ShNormal3f normal, ShVector3f light, ShVector3f viewer, ShColor3f spec, ShColor3f diffuse){ ShColor3f scale = (28.0/(23.0*M_PI))*diffuse*(ShColor3f(1.0, 1.0, 1.0) - spec); ShAttrib1f v = 1.0f - pow5(1.0f - max(normal|light, 0.0)/2.0f); ShAttrib1f l = 1.0f - pow5(1.0f - max(normal|viewer, 0.0)/2.0f); return scale * v * l;}ShColor3f ashikhmin(ShAttrib1f nu, ShAttrib1f nv, ShNormal3f n, ShVector3f h, ShVector3f light, ShVector3f viewer, ShVector3f u, ShVector3f v, ShColor3f spec, ShColor3f diffuse){ return ashikhmin_specular(nu, nv, n, h, light, viewer, u, v, spec) + ashikhmin_diffuse(n, light, viewer, spec, diffuse);}}ShProgram ashikhminSurface() { ShColor3f SH_DECL(diffuse) = ShColor3f(0.0, 1.0, 0.5); ShColor3f SH_DECL(specular) = ShColor3f(1.0, .5, 0.8)/20.0f; ShColor3f SH_DECL(ambient) = ShColor3f(0.0, 0.1, 0.05); ShAttrib1f SH_DECL(nu) = 1000.0f; ShAttrib1f SH_DECL(nv) = 10.0f; specular.range(0.0f, 0.05f); nu.range(10.0f, 10000.0f); nv.range(10.0f, 10000.0f); ShProgram fsh = SH_BEGIN_FRAGMENT_PROGRAM { ShInputColor3f SH_DECL(irrad); ShInputNormal3f SH_DECL(normal); ShInputVector3f SH_DECL(viewVec); ShInputVector3f SH_DECL(halfVec); ShInputVector3f SH_DECL(lightVec); ShInputVector3f SH_DECL(tangent); ShInputPosition4f SH_DECL(posh); ShOutputColor3f SH_DECL(result); ShVector3f tangent2 = cross(normal, tangent); result = ashikhmin(nu, nv, normalize(normal), normalize(halfVec), normalize(lightVec), normalize(viewVec), tangent, tangent2, specular, diffuse) * irrad + ambient; } SH_END_PROGRAM; return fsh;}bool AlgebraShaders::init_all(){ if( doneInit ) return true; int i; doneInit = true; ShImage image; // useful globals ShColor3f SH_NAMEDECL(lightColor, "Light Colour") = ShConstColor3f(1.0f, 1.0f, 1.0f); ShAttrib1f SH_NAMEDECL(falloff, "Light falloff angle") = ShConstAttrib1f(0.35f); falloff.range(0.0f, M_PI); ShAttrib1f SH_NAMEDECL(lightAngle, "Light cutoff angle") = ShConstAttrib1f(0.5f); lightAngle.range(0.0f, M_PI); // TODO handle lightDirection and light up properly ShColor3f SH_NAMEDECL(kd, "Diffuse Color") = ShConstColor3f(1.0f, 0.5f, 0.7f); ShColor3f SH_NAMEDECL(ks, "Specular Color") = ShConstColor3f(0.7f, 0.7f, 0.7f); ShColor3f SH_NAMEDECL(cool, "Cool Color") = ShConstColor3f(0.4f, 0.4f, 1.0f); ShColor3f SH_NAMEDECL(warm, "Warm Color") = ShConstColor3f(1.0f, 0.4f, 0.4f); ShAttrib1f SH_NAMEDECL(specExp, "Specular Exponent") = ShConstAttrib1f(48.13f); specExp.range(0.0f, 256.0f); // ****************** Make light shaders i = 0; lightsh[i++] = ShKernelLight::pointLight<ShColor3f>() << lightColor; lightsh[i++] = ShKernelLight::spotLight<ShColor3f>() << lightColor << falloff << lightAngle << lightDir; ShAttrib1f SH_NAMEDECL(texLightScale, "Mask Scaling Factor") = ShConstAttrib1f(5.0f); texLightScale.range(1.0f, 10.0f); load_PNG(image, normalize_path(SHMEDIA_DIR "/mats/inv_oriental038.png")); ShTable2D<ShColor3fub> lighttex(image.width(), image.height()); lighttex.memory(image.memory()); lightsh[i++] = ShKernelLight::texLight2D(lighttex) << texLightScale << lightAngle << lightDir << lightUp; //lightsh[1] = ShKernelLight::spotLight(ShColor3f>() << lightColor << falloff << lightAngle << lightDir; //lightName[1] = "Spot Light"; // ****************** Make bump/frame mapping shaders i = 0; surfmapsh[i++] = keep<ShNormal3f>("normal"); load_PNG(image, normalize_path(SHMEDIA_DIR "/bumpmaps/bumps_normals.png")); ShTable2D<ShColor3fub> normaltex(image.width(), image.height()); normaltex.name("Bumpmap Normals"); normaltex.memory(image.memory()); ShAttrib1f SH_NAMEDECL(bumpScale, "Bump Scaling Factor") = ShConstAttrib1f(1.0f); bumpScale.range(0.0f, 10.0f); // make a VCS bump mapper by reading in normal map and extracting gradients surfmapsh[i] = SH_BEGIN_PROGRAM() { ShInputTexCoord2f SH_DECL(texcoord); ShOutputAttrib2f SH_DECL(gradient); ShColor3f norm = normaltex(texcoord) - ShConstAttrib3f(0.5, 0.5, 0.0); gradient = norm(0,1) * bumpScale; } SH_END; surfmapsh[i] = ShKernelSurfMap::vcsBump() << surfmapsh[i]; i++; // ****************** Make surface shaders i = 0; surfsh[i++] = ShKernelSurface::null<ShColor3f>(); surfsh[i++] = ShKernelSurface::diffuse<ShColor3f>() << kd; //surfsh[i++] = ShKernelSurface::specular<ShColor3f>() << ks << specExp; //surfsh[i++] = ShKernelSurface::phong<ShColor3f>() << kd << ks << specExp; load_PNG(image, normalize_path(SHMEDIA_DIR "/textures/rustkd.png")); ShTable2D<ShColor3fub> difftex(image.width(), image.height()); difftex.name("Diffuse texture"); difftex.memory(image.memory()); load_PNG(image, normalize_path(SHMEDIA_DIR "/textures/rustks.png")); ShTable2D<ShColor3fub> spectex(image.width(), image.height()); spectex.name("Specular texture"); spectex.memory(image.memory()); surfsh[i] = ShKernelSurface::phong<ShColor3f>() << ( shAccess(difftex) & shAccess(spectex) ); surfsh[i] = surfsh[i] << shExtract("specExp") << specExp; i++; surfsh[i] = worleySurface() << shExtract("ks") << ks; surfsh[i] = surfsh[i] << shExtract("specExp") << specExp; i++; surfsh[i++] = ShKernelSurface::gooch<ShColor3f>() << kd << cool << warm; surfsh[i++] = satinSurface(); surfsh[i++] = ashikhminSurface(); // ******************* Make postprocessing shaders i = 0; load_PNG(image, normalize_path(SHMEDIA_DIR "/textures/halftone.png")); ShTable2D<ShColor3fub> halftoneTex(image.width(), image.height()); halftoneTex.name("Halftoning texture"); halftoneTex.memory(image.memory()); postsh[i++] = keep<ShColor3f>("result"); ShAttrib1f SH_NAMEDECL(htscale, "Scaling Factor") = ShConstAttrib1f(10.0f); htscale.range(1.0f, 400.0f); ShProgram scaler = SH_BEGIN_PROGRAM() { ShInputPosition4f SH_DECL(posh); ShOutputTexCoord2f SH_DECL(texcoord) = posh(0,1) * invheight * htscale; //ShInOutTexCoord2f SH_DECL(texcoord) *= htscale; } SH_END; postsh[i++] = namedConnect(scaler, shHalftone<ShColor3fub>(halftoneTex)); ShAttrib1f SH_NAMEDECL(nscale, "Scaling Factor") = ShConstAttrib1f(50.0f); nscale.range(1.0f, 400.0f); ShAttrib1f SH_NAMEDECL(noiseScale, "Noise Amount") = ShConstAttrib1f(0.2f); noiseScale.range(0.0f, 1.0f); scaler = SH_BEGIN_PROGRAM() { ShInputPosition4f SH_DECL(posh); ShOutputTexCoord2f SH_DECL(texcoord) = posh(0,1) * invheight * nscale; } SH_END; // replace texcoord with scaled posh ShProgram noisifier = shNoisify<2, ShColor3f>(false) & lose<ShTexCoord2f>("texcoord"); noisifier = noisifier << noiseScale; postsh[i++] = namedConnect(scaler, noisifier); return true;}AlgebraShaders the_algebra_shader;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -