mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 16:38:27 +02:00
More work on atmosphere rendering; rendering now working.
This commit is contained in:
parent
a44cb3fcb6
commit
7faa9e4318
7 changed files with 246 additions and 12 deletions
24
interface/resources/shaders/SkyFromAtmosphere.frag
Normal file
24
interface/resources/shaders/SkyFromAtmosphere.frag
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// Atmospheric scattering fragment shader
|
||||||
|
//
|
||||||
|
// Author: Sean O'Neil
|
||||||
|
//
|
||||||
|
// Copyright (c) 2004 Sean O'Neil
|
||||||
|
//
|
||||||
|
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform vec3 v3LightPos;
|
||||||
|
uniform float g;
|
||||||
|
uniform float g2;
|
||||||
|
|
||||||
|
varying vec3 v3Direction;
|
||||||
|
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
float fCos = dot(v3LightPos, v3Direction) / length(v3Direction);
|
||||||
|
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5);
|
||||||
|
gl_FragColor = gl_Color + fMiePhase * gl_SecondaryColor;
|
||||||
|
gl_FragColor.a = 1.0; // gl_FragColor.b;
|
||||||
|
}
|
76
interface/resources/shaders/SkyFromAtmosphere.vert
Normal file
76
interface/resources/shaders/SkyFromAtmosphere.vert
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
//
|
||||||
|
// Atmospheric scattering vertex shader
|
||||||
|
//
|
||||||
|
// Author: Sean O'Neil
|
||||||
|
//
|
||||||
|
// Copyright (c) 2004 Sean O'Neil
|
||||||
|
//
|
||||||
|
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform vec3 v3CameraPos; // The camera's current position
|
||||||
|
uniform vec3 v3LightPos; // The direction vector to the light source
|
||||||
|
uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels
|
||||||
|
uniform float fInnerRadius; // The inner (planetary) radius
|
||||||
|
uniform float fKrESun; // Kr * ESun
|
||||||
|
uniform float fKmESun; // Km * ESun
|
||||||
|
uniform float fKr4PI; // Kr * 4 * PI
|
||||||
|
uniform float fKm4PI; // Km * 4 * PI
|
||||||
|
uniform float fScale; // 1 / (fOuterRadius - fInnerRadius)
|
||||||
|
uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found)
|
||||||
|
uniform float fScaleOverScaleDepth; // fScale / fScaleDepth
|
||||||
|
|
||||||
|
const int nSamples = 2;
|
||||||
|
const float fSamples = 2.0;
|
||||||
|
|
||||||
|
varying vec3 v3Direction;
|
||||||
|
|
||||||
|
|
||||||
|
float scale(float fCos)
|
||||||
|
{
|
||||||
|
float x = 1.0 - fCos;
|
||||||
|
return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
// Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere)
|
||||||
|
vec3 v3Pos = gl_Vertex.xyz;
|
||||||
|
vec3 v3Ray = v3Pos - v3CameraPos;
|
||||||
|
float fFar = length(v3Ray);
|
||||||
|
v3Ray /= fFar;
|
||||||
|
|
||||||
|
// Calculate the ray's starting position, then calculate its scattering offset
|
||||||
|
vec3 v3Start = v3CameraPos;
|
||||||
|
float fHeight = length(v3Start);
|
||||||
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
|
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
|
||||||
|
float fStartOffset = fDepth*scale(fStartAngle);
|
||||||
|
|
||||||
|
// Initialize the scattering loop variables
|
||||||
|
//gl_FrontColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
float fSampleLength = fFar / fSamples;
|
||||||
|
float fScaledLength = fSampleLength * fScale;
|
||||||
|
vec3 v3SampleRay = v3Ray * fSampleLength;
|
||||||
|
vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
|
||||||
|
|
||||||
|
// Now loop through the sample rays
|
||||||
|
vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
|
||||||
|
for(int i=0; i<nSamples; i++)
|
||||||
|
{
|
||||||
|
float fHeight = length(v3SamplePoint);
|
||||||
|
float fDepth = exp(fScaleOverScaleDepth * (fInnerRadius - fHeight));
|
||||||
|
float fLightAngle = dot(v3LightPos, v3SamplePoint) / fHeight;
|
||||||
|
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
|
||||||
|
float fScatter = (fStartOffset + fDepth*(scale(fLightAngle) - scale(fCameraAngle)));
|
||||||
|
vec3 v3Attenuate = exp(-fScatter * (v3InvWavelength * fKr4PI + fKm4PI));
|
||||||
|
v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
|
||||||
|
v3SamplePoint += v3SampleRay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader
|
||||||
|
gl_FrontSecondaryColor.rgb = v3FrontColor * fKmESun;
|
||||||
|
gl_FrontColor.rgb = v3FrontColor * (v3InvWavelength * fKrESun);
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
v3Direction = v3CameraPos - v3Pos;
|
||||||
|
}
|
|
@ -5,8 +5,98 @@
|
||||||
// Created by Andrzej Kapolka on 5/6/13.
|
// Created by Andrzej Kapolka on 5/6/13.
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
#include "Environment.h"
|
#include <QFile>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
void Environment::render() {
|
#include "Camera.h"
|
||||||
|
#include "Environment.h"
|
||||||
|
#include "world.h"
|
||||||
|
|
||||||
|
// checks for an error, printing the info log if one is deteced
|
||||||
|
static void errorCheck(GLhandleARB obj) {
|
||||||
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
QByteArray log(1024, 0);
|
||||||
|
glGetInfoLogARB(obj, log.size(), 0, log.data());
|
||||||
|
qDebug() << log;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLhandleARB compileShader(int type, const QString& filename) {
|
||||||
|
QFile file(filename);
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
qWarning() << "Couldn't find file." << filename;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
GLhandleARB shaderID = glCreateShaderObjectARB(type);
|
||||||
|
QByteArray source = file.readAll();
|
||||||
|
const char* sdata = source.constData();
|
||||||
|
glShaderSource(shaderID, 1, &sdata, 0);
|
||||||
|
glCompileShaderARB(shaderID);
|
||||||
|
errorCheck(shaderID);
|
||||||
|
return shaderID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::init() {
|
||||||
|
_skyFromAtmosphereProgramID = glCreateProgramObjectARB();
|
||||||
|
glAttachObjectARB(_skyFromAtmosphereProgramID, compileShader(
|
||||||
|
GL_VERTEX_SHADER_ARB, "resources/shaders/SkyFromAtmosphere.vert"));
|
||||||
|
glAttachObjectARB(_skyFromAtmosphereProgramID, compileShader(
|
||||||
|
GL_FRAGMENT_SHADER_ARB, "resources/shaders/SkyFromAtmosphere.frag"));
|
||||||
|
glLinkProgramARB(_skyFromAtmosphereProgramID);
|
||||||
|
errorCheck(_skyFromAtmosphereProgramID);
|
||||||
|
|
||||||
|
_cameraPosLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "v3CameraPos");
|
||||||
|
_lightPosLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "v3LightPos");
|
||||||
|
_invWavelengthLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "v3InvWavelength");
|
||||||
|
_innerRadiusLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fInnerRadius");
|
||||||
|
_krESunLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fKrESun");
|
||||||
|
_kmESunLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fKmESun");
|
||||||
|
_kr4PiLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fKr4PI");
|
||||||
|
_km4PiLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fKm4PI");
|
||||||
|
_scaleLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fScale");
|
||||||
|
_scaleDepthLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fScaleDepth");
|
||||||
|
_scaleOverScaleDepthLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "fScaleOverScaleDepth");
|
||||||
|
_gLocation = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "g");
|
||||||
|
_g2Location = glGetUniformLocationARB(_skyFromAtmosphereProgramID, "g2");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Environment::render(Camera& camera) {
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(getAtmosphereCenter().x, getAtmosphereCenter().y, getAtmosphereCenter().z);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
gluPerspective(camera.getFieldOfView(), camera.getAspectRatio(), 100, 100000000);
|
||||||
|
|
||||||
|
glUseProgramObjectARB(_skyFromAtmosphereProgramID);
|
||||||
|
glm::vec3 relativeCameraPos = camera.getPosition() - getAtmosphereCenter();
|
||||||
|
glUniform3fARB(_cameraPosLocation, relativeCameraPos.x, relativeCameraPos.y, relativeCameraPos.z);
|
||||||
|
glm::vec3 lightDirection = glm::normalize(getSunLocation());
|
||||||
|
glUniform3fARB(_lightPosLocation, lightDirection.x, lightDirection.y, lightDirection.z);
|
||||||
|
glUniform3fARB(_invWavelengthLocation,
|
||||||
|
1 / powf(0.650f, 4.0f), 1 / powf(0.570f, 4.0f), 1 / powf(0.475f, 4.0f));
|
||||||
|
glUniform1fARB(_innerRadiusLocation, getAtmosphereInnerRadius());
|
||||||
|
glUniform1fARB(_krESunLocation, getRayleighScattering() * getSunBrightness());
|
||||||
|
glUniform1fARB(_kmESunLocation, getMieScattering() * getSunBrightness());
|
||||||
|
glUniform1fARB(_kr4PiLocation, getRayleighScattering() * 4.0f * PIf);
|
||||||
|
glUniform1fARB(_km4PiLocation, getMieScattering() * 4.0f * PIf);
|
||||||
|
glUniform1fARB(_scaleLocation, 1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius()));
|
||||||
|
glUniform1fARB(_scaleDepthLocation, 0.25f);
|
||||||
|
glUniform1fARB(_scaleOverScaleDepthLocation,
|
||||||
|
(1.0f / (getAtmosphereOuterRadius() - getAtmosphereInnerRadius())) / 0.25f);
|
||||||
|
glUniform1fARB(_gLocation, -0.990f);
|
||||||
|
glUniform1fARB(_g2Location, -0.990f * -0.990f);
|
||||||
|
|
||||||
|
glFrontFace(GL_CW);
|
||||||
|
glutSolidSphere(getAtmosphereOuterRadius(), 100, 50);
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
|
||||||
|
glUseProgramObjectARB(0);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,32 @@
|
||||||
#define __interface__Environment__
|
#define __interface__Environment__
|
||||||
|
|
||||||
#include "EnvironmentData.h"
|
#include "EnvironmentData.h"
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
|
||||||
class Environment : public EnvironmentData {
|
class Environment : public EnvironmentData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void render();
|
void init();
|
||||||
|
void render(Camera& camera);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
GLhandleARB _skyFromAtmosphereProgramID;
|
||||||
|
int _cameraPosLocation;
|
||||||
|
int _lightPosLocation;
|
||||||
|
int _invWavelengthLocation;
|
||||||
|
int _innerRadiusLocation;
|
||||||
|
int _krESunLocation;
|
||||||
|
int _kmESunLocation;
|
||||||
|
int _kr4PiLocation;
|
||||||
|
int _km4PiLocation;
|
||||||
|
int _scaleLocation;
|
||||||
|
int _scaleDepthLocation;
|
||||||
|
int _scaleOverScaleDepthLocation;
|
||||||
|
int _gLocation;
|
||||||
|
int _g2Location;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__Environment__) */
|
#endif /* defined(__interface__Environment__) */
|
||||||
|
|
|
@ -311,6 +311,8 @@ void init(void) {
|
||||||
voxels.setViewerAvatar(&myAvatar);
|
voxels.setViewerAvatar(&myAvatar);
|
||||||
voxels.setCamera(&myCamera);
|
voxels.setCamera(&myCamera);
|
||||||
|
|
||||||
|
environment.init();
|
||||||
|
|
||||||
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
||||||
|
|
||||||
headMouseX = WIDTH/2;
|
headMouseX = WIDTH/2;
|
||||||
|
@ -682,6 +684,9 @@ void renderViewFrustum(ViewFrustum& viewFrustum) {
|
||||||
void displaySide(Camera& whichCamera) {
|
void displaySide(Camera& whichCamera) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
|
// draw the sky dome
|
||||||
|
environment.render(whichCamera);
|
||||||
|
|
||||||
if (::starsOn) {
|
if (::starsOn) {
|
||||||
// should be the first rendering pass - w/o depth buffer / lighting
|
// should be the first rendering pass - w/o depth buffer / lighting
|
||||||
|
|
||||||
|
@ -1747,6 +1752,7 @@ void reshape(int width, int height) {
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
camera.setAspectRatio(aspectRatio);
|
||||||
camera.setFieldOfView(fov = 60);
|
camera.setFieldOfView(fov = 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,18 @@
|
||||||
#include "EnvironmentData.h"
|
#include "EnvironmentData.h"
|
||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
|
|
||||||
|
// initial values from Sean O'Neil's GPU Gems entry (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html),
|
||||||
|
// GameEngine.cpp
|
||||||
|
EnvironmentData::EnvironmentData() :
|
||||||
|
_atmosphereCenter(0, -6371000, 0),
|
||||||
|
_atmosphereInnerRadius(6371000),
|
||||||
|
_atmosphereOuterRadius(6530275),
|
||||||
|
_rayleighScattering(0.0025f),
|
||||||
|
_mieScattering(0.0010f),
|
||||||
|
_sunLocation(1000, 1000, 0),
|
||||||
|
_sunBrightness(20.0f) {
|
||||||
|
}
|
||||||
|
|
||||||
int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
|
int EnvironmentData::getBroadcastData(unsigned char* destinationBuffer) const {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,24 @@
|
||||||
class EnvironmentData {
|
class EnvironmentData {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void setAtmosphereCenter(const glm::vec3& center);
|
EnvironmentData();
|
||||||
void setAtmosphereInnerRadius(float radius);
|
|
||||||
void setAtmosphereOuterRadius(float radius);
|
void setAtmosphereCenter(const glm::vec3& center) { _atmosphereCenter = center; }
|
||||||
|
void setAtmosphereInnerRadius(float radius) { _atmosphereInnerRadius = radius; }
|
||||||
|
void setAtmosphereOuterRadius(float radius) { _atmosphereOuterRadius = radius; }
|
||||||
|
const glm::vec3& getAtmosphereCenter() const { return _atmosphereCenter; }
|
||||||
|
float getAtmosphereInnerRadius() const { return _atmosphereInnerRadius; }
|
||||||
|
float getAtmosphereOuterRadius() const { return _atmosphereOuterRadius; }
|
||||||
|
|
||||||
void setRayleighScattering(float scattering);
|
void setRayleighScattering(float scattering) { _rayleighScattering = scattering; }
|
||||||
void setMieScattering(float scattering);
|
void setMieScattering(float scattering) { _mieScattering = scattering; }
|
||||||
|
float getRayleighScattering() const { return _rayleighScattering; }
|
||||||
|
float getMieScattering() const { return _mieScattering; }
|
||||||
|
|
||||||
void setSunLocation(const glm::vec3 location);
|
void setSunLocation(const glm::vec3& location) { _sunLocation = location; }
|
||||||
void setSunBrightness(float brightness);
|
void setSunBrightness(float brightness) { _sunBrightness = brightness; }
|
||||||
|
const glm::vec3& getSunLocation() const { return _sunLocation; }
|
||||||
|
float getSunBrightness() const { return _sunBrightness; }
|
||||||
|
|
||||||
int getBroadcastData(unsigned char* destinationBuffer) const;
|
int getBroadcastData(unsigned char* destinationBuffer) const;
|
||||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||||
|
|
Loading…
Reference in a new issue