mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 16:23:39 +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.
|
||||
// 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__
|
||||
|
||||
#include "EnvironmentData.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
class Camera;
|
||||
|
||||
class Environment : public EnvironmentData {
|
||||
public:
|
||||
|
||||
void render();
|
||||
void init();
|
||||
void render(Camera& camera);
|
||||
|
||||
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__) */
|
||||
|
|
|
@ -311,6 +311,8 @@ void init(void) {
|
|||
voxels.setViewerAvatar(&myAvatar);
|
||||
voxels.setCamera(&myCamera);
|
||||
|
||||
environment.init();
|
||||
|
||||
handControl.setScreenDimensions(WIDTH, HEIGHT);
|
||||
|
||||
headMouseX = WIDTH/2;
|
||||
|
@ -682,6 +684,9 @@ void renderViewFrustum(ViewFrustum& viewFrustum) {
|
|||
void displaySide(Camera& whichCamera) {
|
||||
glPushMatrix();
|
||||
|
||||
// draw the sky dome
|
||||
environment.render(whichCamera);
|
||||
|
||||
if (::starsOn) {
|
||||
// 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);
|
||||
}
|
||||
} else {
|
||||
camera.setAspectRatio(aspectRatio);
|
||||
camera.setFieldOfView(fov = 60);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,18 @@
|
|||
#include "EnvironmentData.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 {
|
||||
unsigned char* bufferStart = destinationBuffer;
|
||||
|
||||
|
|
|
@ -14,15 +14,24 @@
|
|||
class EnvironmentData {
|
||||
public:
|
||||
|
||||
void setAtmosphereCenter(const glm::vec3& center);
|
||||
void setAtmosphereInnerRadius(float radius);
|
||||
void setAtmosphereOuterRadius(float radius);
|
||||
EnvironmentData();
|
||||
|
||||
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 setMieScattering(float scattering);
|
||||
void setRayleighScattering(float scattering) { _rayleighScattering = scattering; }
|
||||
void setMieScattering(float scattering) { _mieScattering = scattering; }
|
||||
float getRayleighScattering() const { return _rayleighScattering; }
|
||||
float getMieScattering() const { return _mieScattering; }
|
||||
|
||||
void setSunLocation(const glm::vec3 location);
|
||||
void setSunBrightness(float brightness);
|
||||
void setSunLocation(const glm::vec3& location) { _sunLocation = location; }
|
||||
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 parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
|
Loading…
Reference in a new issue