#include "EnvironmentShader.hpp" #include #include #include "Globals.hpp" #ifdef HAVE_CONFIG_H #include "config.h" #endif using namespace SH; EnvironmentShader::EnvironmentShader() { } EnvironmentShader::~EnvironmentShader() { } void EnvironmentShader::init() { ShTextureCube cubemap; std::string imageNames[6] = {"left", "right", "top", "bottom", "back", "front"}; { ShImage image; for (int i = 0; i < 6; i++) { image.loadPng(std::string(SHMEDIA_DIR "/envmaps/aniroom/") + imageNames[i] + ".png"); ShTexture2D face(image.width(), image.height()); face.load(image); cubemap.set(static_cast(i), face); } } vsh = SH_BEGIN_VERTEX_PROGRAM { ShInputNormal3f normal; ShInputTexCoord2f texture; ShInputPosition4f pos; ShOutputNormal3f out_normal; ShOutputPoint3f out_posEye; ShOutputPosition4f out_posDevice; out_posEye = (Globals::mv | pos)(0,1,2); out_posDevice = Globals::mvp | pos; out_normal = Globals::mv | normal; } SH_END_PROGRAM; ShAttrib1f Ks(1.0); ShAttrib1f roughness(0.1); ShColor3f lightColor(1, 1, 1); fsh = SH_BEGIN_FRAGMENT_PROGRAM { ShInputNormal3f normal; ShInputPoint3f posEye; ShInputPosition4f p; ShOutputColor4f out_color; out_color = cubemap(normalize(reflect(normalize(normal), normalize(-posEye)))); } SH_END_PROGRAM; } void EnvironmentShader::apply() { shBindShader(vsh); shBindShader(fsh); } void EnvironmentShader::vertex(const SH::ShPoint4f& n, // normal const SH::ShPoint4f& t, // tangent const SH::ShPoint4f& tex, // texture // coordinates const SH::ShPoint4f& t2, // secondary // tangent const SH::ShPoint4f& v // vertex ) { pushSmAttrib(n); pushSmAttrib(tex); pushSmVertex(v); }

About the Environment Shader Source

This page contains the C++ source for EnvironmentShader, one of the shader implementations built with the Sh metaprogramming language. The shader loads a six-face cubemap and uses it to shade geometry by reflecting the view direction off the surface normal, producing a mirror-like environment reflection.

How the shader is structured

The class follows the usual Sh shader pattern: an init() method that builds the vertex and fragment programs, an apply() method that binds them, and a vertex() method that pushes per-vertex attributes. The vertex program transforms normals and positions into eye space, while the fragment program samples the cubemap.

Cubemap loading

Six PNG images named left, right, top, bottom, back, and front are loaded from the envmaps/aniroom/ media directory and assembled into a ShTextureCube.

Reflection calculation

The fragment program computes reflect(normalize(normal), normalize(-posEye)) and uses the resulting direction to look up a color in the cubemap. The vertex program supplies the interpolated normal and eye-space position needed for that lookup.

Frequently Asked Questions

What does the Environment shader do?

It renders reflections of a surrounding cubemap environment onto a surface. The fragment program reflects the view direction about the surface normal and samples the cubemap with the result.

What images does the shader need?

It loads six PNG faces — left, right, top, bottom, back, and front — from the envmaps/aniroom/ media directory and combines them into a cubemap texture.

Which Sh APIs does the source use?

The source uses ShTextureCube, ShTexture2D, ShImage, and the SH_BEGIN_VERTEX_PROGRAM / SH_BEGIN_FRAGMENT_PROGRAM blocks, along with shBindShader and pushSmAttrib / pushSmVertex.

How is the shader applied to geometry?

Calling apply() binds the vertex and fragment programs, and vertex() pushes the normal, texture coordinates, and vertex position for each vertex.

Can I reuse this shader in my own project?

The class is self-contained: it declares its programs in init(), binds them in apply(), and feeds attributes in vertex(), so it can be adapted by changing the cubemap source or the reflection expression.

// Instantiate the shader EnvironmentShader environmentShader;