LuciteShader
Refraction: Lucite — Sh shader source.
// Sh: A GPU metaprogramming language.
//
// Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
// Project administrator: Michael D. McCool
// Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
// Michael D. McCool
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must
// not claim that you wrote the original software. If you use this
// software in a product, an acknowledgment in the product documentation
// would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must
// not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include "Shader.hpp"
#include "Globals.hpp"
using namespace SH;
using namespace ShUtil;
#include "util.hpp"
class LuciteShader : public Shader {
public:
ShProgram vsh, fsh;
LuciteShader();
~LuciteShader();
bool init();
ShProgram vertex() { return vsh;}
ShProgram fragment() { return fsh;}
};
LuciteShader::LuciteShader()
: Shader("Refraction: Lucite")
{
}
LuciteShader::~LuciteShader()
{
}
bool LuciteShader::init()
{
std::cerr << "Initializing " << name() << std::endl;
std::string imageNames[6] = {"left", "right", "top", "bottom", "back", "front"};
ShImage test_image;
test_image.loadPng(std::string(SHMEDIA_DIR "/envmaps/aniroom/") + imageNames[0] + ".png");
ShTextureCube cubemap(test_image.width(), test_image.height());
{
for (int i = 0; i < 6; i++) {
ShImage image;
image.loadPng(std::string(SHMEDIA_DIR "/envmaps/aniroom/") + imageNames[i] + ".png");
cubemap.memory(image.memory(), static_cast(i));
}
}
ShAttrib3f theta = ShAttrib3f(1.32f,1.3f,1.28f);
theta.name("relative indices of refraction");
theta.range(0.0f,2.0f);
vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
ShInputPosition4f ipos;
ShInputNormal3f inorm;
ShOutputPosition4f opos; // Position in NDC
ShOutputNormal3f onorm; // view-space normal
ShOutputVector3f reflv; // reflection vector
ShOutputVector3f refrv[3]; // refraction vectors (per RGB channel)
ShOutputAttrib3f fres; // fresnel terms (per RGB channel)
opos = Globals::mvp | ipos; // Compute NDC position
onorm = Globals::mv | inorm; // Compute view-space normal
onorm = normalize(onorm);
ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
ShPoint3f viewv = -normalize(posv); // Compute view vector
reflv = reflect(viewv,onorm); // Compute reflection vector
// actually do reflection lookup in model space
reflv = Globals::mv_inverse | reflv;
for (int i=0; i<3; i++) {
refrv[i] = refract(viewv,onorm,theta[i]); // Compute refraction vectors
// actually do refraction lookup in model space
refrv[i] = Globals::mv_inverse | refrv[i];
fres[i] = fresnel(viewv,onorm,theta[i]); // Compute fresnel term
}
} SH_END;
fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
ShInputPosition4f posh;
ShInputNormal3f n; // normal
ShInputVector3f reflv; // reflection vector
ShInputVector3f refrv[3]; // refraction vectors (per RGB channel)
ShInputAttrib3f fres; // fresnel terms (per RGB channel)
ShOutputColor3f result;
result = fres*cubemap(reflv)(0,1,2);
for (int i=0; i<3; i++) {
result[i] += (1.0f-fres[i])*cubemap(refrv[i])(i);
}
} SH_END;
return true;
}
LuciteShader the_lucite_shader;
About the LuciteShader source
This page reproduces the Sh source for the Refraction: Lucite shader, a member of the glass shaders library. The shader is implemented as a Shader subclass named LuciteShader that exposes a vertex program (vsh) and a fragment program (fsh) through the vertex() and fragment() accessors.
Environment map
The init() method loads a six-face cube map from the aniroom environment map directory, reading the left, right, top, bottom, back, and front PNG images into a ShTextureCube<ShColor4f>.
Refraction parameters
A three-component attribute named relative indices of refraction (theta) supplies a per-RGB-channel index of refraction, with a declared range of 0.0 to 2.0. The vertex program computes reflection and refraction vectors plus Fresnel terms for each channel, and the fragment program combines the reflection and refraction cube-map lookups using those Fresnel terms.
Frequently Asked Questions
What does the LuciteShader do?
It implements a refraction shader named "Refraction: Lucite" using Sh, combining a reflection cube-map lookup with per-RGB-channel refraction lookups weighted by Fresnel terms.
What parameters does the shader expose?
The shader defines a three-component attribute called relative indices of refraction (variable theta) with a range of 0.0 to 2.0, providing a separate index of refraction for each color channel.
Where does the environment map come from?
The cube map is loaded in init() from PNG images in the envmaps/aniroom/ directory under SHMEDIA_DIR, using the six cube directions left, right, top, bottom, back, and front.
How is the final color computed?
The fragment program starts from the Fresnel-weighted reflection lookup and adds, for each channel, the refraction lookup scaled by one minus the Fresnel term.
What license applies to this source?
The source carries the zlib-style notice shown at the top of the listing, permitting use, alteration, and redistribution provided the origin is not misrepresented and the notice is retained.
