9 #include "GrassShader.h" 31 float cutoff,
float intercept) :
32 m_lowThreshold(lowThreshold), m_highThreshold(highThreshold),
33 m_cutoff(cutoff), m_intercept(intercept)
44 auto Iend = params.end();
46 m_lowThreshold = I->second;
50 m_highThreshold = I->second;
58 m_intercept = I->second;
63 GrassShader::~GrassShader() =
default;
65 inline ColorT GrassShader::slopeToAlpha(
float height,
float slope)
const 67 if ((height < m_lowThreshold) ||
68 (height > m_highThreshold) ||
69 (slope > m_intercept)) {
71 }
else if (slope < m_cutoff) {
74 return (ColorT)(colorMax * ((slope - m_cutoff) / (m_intercept - m_cutoff)));
80 if ((s.
getMin() < m_highThreshold) &&
81 (s.
getMax() > m_lowThreshold)) {
92 unsigned int chanAlpha = channels - 1;
95 const float * height_data = seg.
getPoints();
96 if (height_data ==
nullptr) {
97 std::cerr <<
"WARNING: Mercator: Attempting to shade empty segment." 98 << std::endl << std::flush;
104 unsigned int data_count = size * size * channels;
105 for (
unsigned int i = 0; i < data_count; ++i) {
110 s(0, 0, chanAlpha) = slopeToAlpha(seg.
get(0,0), 0.f);
111 s(res, 0, chanAlpha) = slopeToAlpha(seg.
get(res,0), 0.f);
112 s(0, res, chanAlpha) = slopeToAlpha(seg.
get(0,res), 0.f);
113 s(res, res, chanAlpha) = slopeToAlpha(seg.
get(res,res), 0.f);
115 for (
int i = 1; i < res; ++i) {
116 float height = seg.
get(i, 0);
117 float avgSlope = (std::fabs(seg.
get(i - 1, 0) - height) +
118 std::fabs(seg.
get(i + 1, 0) - height)) / 2.f;
119 s(i, 0, chanAlpha) = slopeToAlpha(height, avgSlope);
121 height = seg.
get(i, res);
122 avgSlope = (std::fabs(seg.
get(i - 1, res) - height) +
123 std::fabs(seg.
get(i + 1, res) - height)) / 2.f;
124 s(i, res, chanAlpha) = slopeToAlpha(height, avgSlope);
126 height = seg.
get(0, i);
127 avgSlope = (std::fabs(seg.
get(0, i - 1) - height) +
128 std::fabs(seg.
get(0, i + 1) - height)) / 2.f;
129 s(0, i, chanAlpha) = slopeToAlpha(height, avgSlope);
131 height = seg.
get(res, i);
132 avgSlope = (std::fabs(seg.
get(res, i - 1) - height) +
133 std::fabs(seg.
get(res, i + 1) - height)) / 2.f;
134 s(res, i, chanAlpha) = slopeToAlpha(height, avgSlope);
135 for (
int j = 1; j < res; ++j) {
136 height = seg.
get(i, j);
137 avgSlope = (std::fabs(seg.
get(i + 1, j ) - height) +
138 std::fabs(seg.
get(i , j + 1) - height) +
139 std::fabs(seg.
get(i - 1, j ) - height) +
140 std::fabs(seg.
get(i , j - 1) - height)) / 4.f;
141 s(i, j, chanAlpha) = slopeToAlpha(height, avgSlope);
DataType * getData()
Accessor for a pointer to buffer containing data values.
float get(int x, int z) const
Get the height at a relative integer position in the Segment.
static const float default_highThreshold
Default level below which the shader renders.
bool checkIntersect(const Segment &) const override
Check whether this Shader has any effect on the given Segment.
static const std::string key_lowThreshold
Key string used when specifying the low threshold parameter.
Data store for terrain surface data.
int getSize() const
Accessor for array size of this segment.
std::map< std::string, float > Parameters
STL map of parameter values for a shader constructor.
static const float default_cutoff
Default slope below which grass is opaque.
static const std::string key_intercept
Key string used when specifying the intercept parameter.
Class storing heightfield and other data for a single fixed size square area of terrain defined by fo...
float getMax() const
Accessor for the maximum height value in this Segment.
float getMin() const
Accessor for the minimum height value in this Segment.
static const std::string key_cutoff
Key string used when specifying the cutoff parameter.
const float * getPoints() const
Accessor for buffer containing height points.
static const float default_lowThreshold
Default level above which the shader renders.
void shade(Surface &) const override
Populate a Surface with data.
int getResolution() const
Accessor for resolution of this segment.
static const float default_intercept
Default slope steeper than which no grass grows.
static const std::string key_highThreshold
Key string used when specifying the high threshold parameter.
unsigned int getChannels() const
Accessor for the number of data values per height point.
const Segment & getSegment() const
Accessor for the terrain height segment this surface is associated with.
GrassShader(float lowThreshold=default_lowThreshold, float highThreshold=default_highThreshold, float cutoff=default_cutoff, float intercept=default_intercept)
Constructor.