[WIP] Use simple normal map for opengl water

This commit is contained in:
Michaël Lemaire 2014-01-05 21:52:09 +01:00
parent c52eeac71d
commit 49b7055655
5 changed files with 77 additions and 12 deletions

View file

@ -11,6 +11,8 @@
#include <cstring>
#include "Texture2D.h"
#include "Color.h"
#include "Geometry.h"
#include "Vector3.h"
typedef struct
{
@ -479,24 +481,58 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
}
static Texture2D *_sampleTexture = NULL;
static Texture2D *_valueTexture = NULL;
const Texture2D *NoiseFunctionSimplex::getSampleTexture()
const Texture2D *NoiseFunctionSimplex::getValueTexture()
{
const int width = 1024;
const int height = 1024;
if (!_sampleTexture)
if (!_valueTexture)
{
_sampleTexture = new Texture2D(width, height);
const int width = 1024;
const int height = 1024;
_valueTexture = new Texture2D(width, height);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
double val = noiseSimplexGet2DValue((double)x, (double)z);
_sampleTexture->setPixel(x, z, Color(val, val, val));
_valueTexture->setPixel(x, z, Color(val, val, val));
}
}
}
return _sampleTexture;
return _valueTexture;
}
static Texture2D *_normalTexture = NULL;
const Texture2D *NoiseFunctionSimplex::getNormalTexture()
{
if (!_normalTexture)
{
const int width = 1024;
const int height = 1024;
_normalTexture = new Texture2D(width, height);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
double vcenter = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z);
double vsouth = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z + 0.001);
double veast = noiseSimplexGet2DValue(0.01 * (double)x + 0.001, 0.01 * (double)z);
Vector3 normal = Geometry::getNormalFromTriangle(Vector3(0.0, vcenter, 0.0),
Vector3(0.0, vsouth, 0.01),
Vector3(0.01, veast, 0.0)
);
_normalTexture->setPixel(x, z, Color(normal.x, normal.y, normal.z));
}
}
}
return _normalTexture;
}

View file

@ -9,7 +9,8 @@ namespace basics {
class NoiseFunctionSimplex
{
public:
static const Texture2D *getSampleTexture();
static const Texture2D *getValueTexture();
static const Texture2D *getNormalTexture();
};
}

View file

@ -134,7 +134,7 @@ void OpenGLVariable::set(const Color &color)
assert(type == TYPE_NONE or type == TYPE_COLOR);
type = TYPE_COLOR;
value_color = QColor(color.r, color.g, color.b);
value_color = QColor::fromRgbF(color.r, color.g, color.b);
}
void OpenGLVariable::uploadTexture(OpenGLRenderer* renderer)

View file

@ -43,7 +43,7 @@ void OpenGLWater::update()
Color water_color = renderer->getScenery()->getWater()->material->_rgb;
renderer->getSharedState()->set("waterColor", water_color);
renderer->getSharedState()->set("simplexSampler", NoiseFunctionSimplex::getSampleTexture(), true, false);
renderer->getSharedState()->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
}
void OpenGLWater::render()

View file

@ -1,10 +1,38 @@
uniform vec4 waterColor;
uniform sampler2D simplexSampler;
vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess)
{
// TEMP phong lighting implementation for testing
vec3 N = normalize(normal);
vec3 L = sunDirection;
vec3 E = normalize(cameraLocation - location);
vec3 R = normalize(-reflect(L, N));
//calculate Ambient Term:
vec4 Iamb = vec4(0.1, 0.1, 0.1, 1.0);
//calculate Diffuse Term:
vec4 Idiff = vec4(3.0, 3.0, 3.0, 1.0) * color * max(dot(N, L), 0.0);
// calculate Specular Term:
vec4 Ispec = vec4(3.0, 3.0, 3.0, 1.0) * pow(max(dot(R,E),0.0),0.3*shininess);
// write Total Color:
return Iamb + Idiff + Ispec;
}
void main(void)
{
//gl_FragColor = waterColor;
gl_FragColor = texture2D(simplexSampler, unprojected.xz * 0.01);
//gl_FragColor = texture2D(simplexSampler, unprojected.xz * 0.01);
vec3 normal = vec3(0.0, 0.0, 0.0);
for (float scaling = 1.0; scaling < 50.0; scaling *= 1.5)
{
normal += texture2D(simplexSampler, unprojected.xz * 0.01 * scaling).xyz;
}
gl_FragColor = applyLighting(unprojected, normalize(normal), waterColor, 100.0);
gl_FragColor = applyAerialPerspective(gl_FragColor);