mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-17 15:46:18 +02:00
Added local lights to avatar. Added haze to voxel.
This commit is contained in:
parent
f7f9dfd26e
commit
94e81da557
9 changed files with 218 additions and 10 deletions
|
@ -11,6 +11,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const int MAX_LOCAL_LIGHTS = 4;
|
||||||
|
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
@ -20,13 +22,27 @@ varying vec4 position;
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 normal;
|
||||||
|
|
||||||
|
// static local light position
|
||||||
|
varying vec4 localLightPos[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// compute the base color based on OpenGL lighting model
|
// compute the base color based on OpenGL lighting model
|
||||||
vec4 normalizedNormal = normalize(normal);
|
vec4 normalizedNormal = normalize(normal);
|
||||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||||
float facingLight = step(0.0, diffuse);
|
float facingLight = step(0.0, diffuse);
|
||||||
|
|
||||||
|
// the local light that is always present
|
||||||
|
vec4 totalLocalLight = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
float localDiffuse = dot(normalizedNormal, localLightPos[i]);
|
||||||
|
float localLight = step(0.0, localDiffuse);
|
||||||
|
float localLightVal = localDiffuse * localLight;
|
||||||
|
|
||||||
|
totalLocalLight += (localLightVal * gl_LightSource[i+1].diffuse);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + totalLocalLight);
|
||||||
|
|
||||||
// compute the specular component (sans exponent)
|
// compute the specular component (sans exponent)
|
||||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||||
|
@ -35,4 +51,5 @@ void main(void) {
|
||||||
// modulate texture by base color and add specular contribution
|
// modulate texture by base color and add specular contribution
|
||||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,17 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
const int MAX_LOCAL_LIGHTS = 4;
|
||||||
|
|
||||||
// the interpolated position
|
// the interpolated position
|
||||||
varying vec4 position;
|
varying vec4 position;
|
||||||
|
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 normal;
|
||||||
|
|
||||||
|
// local light position that is always present
|
||||||
|
varying vec4 localLightPos[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
|
||||||
// transform and store the normal for interpolation
|
// transform and store the normal for interpolation
|
||||||
|
@ -36,4 +41,8 @@ void main(void) {
|
||||||
|
|
||||||
// use standard pipeline transform
|
// use standard pipeline transform
|
||||||
gl_Position = ftransform();
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,9 +37,14 @@ void main(void) {
|
||||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||||
float facingLight = step(0.0, diffuse);
|
float facingLight = step(0.0, diffuse);
|
||||||
|
float localDiffuse = dot(viewNormal, gl_LightSource[1].position);
|
||||||
|
float localLight = step(0.0, localDiffuse);
|
||||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + gl_FrontLightProduct[1].diffuse * (localDiffuse * localLight));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// compute the specular component (sans exponent)
|
// compute the specular component (sans exponent)
|
||||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||||
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
const int MAX_CLUSTERS = 128;
|
const int MAX_CLUSTERS = 128;
|
||||||
const int INDICES_PER_VERTEX = 4;
|
const int INDICES_PER_VERTEX = 4;
|
||||||
|
const int MAX_LOCAL_LIGHTS = 4;
|
||||||
|
|
||||||
uniform mat4 clusterMatrices[MAX_CLUSTERS];
|
uniform mat4 clusterMatrices[MAX_CLUSTERS];
|
||||||
|
|
||||||
|
@ -25,6 +26,9 @@ varying vec4 position;
|
||||||
// the interpolated normal
|
// the interpolated normal
|
||||||
varying vec4 normal;
|
varying vec4 normal;
|
||||||
|
|
||||||
|
// static local light position (inverse from eye space)
|
||||||
|
varying vec4 localLightPos[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
position = vec4(0.0, 0.0, 0.0, 0.0);
|
position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
normal = vec4(0.0, 0.0, 0.0, 0.0);
|
normal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
@ -34,6 +38,7 @@ void main(void) {
|
||||||
position += clusterMatrix * gl_Vertex * clusterWeight;
|
position += clusterMatrix * gl_Vertex * clusterWeight;
|
||||||
normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
position = gl_ModelViewMatrix * position;
|
position = gl_ModelViewMatrix * position;
|
||||||
normal = normalize(gl_ModelViewMatrix * normal);
|
normal = normalize(gl_ModelViewMatrix * normal);
|
||||||
|
|
||||||
|
@ -47,4 +52,10 @@ void main(void) {
|
||||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
||||||
|
|
||||||
gl_Position = gl_ProjectionMatrix * position;
|
gl_Position = gl_ProjectionMatrix * position;
|
||||||
|
|
||||||
|
// inverse view to make the light source position static
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
localLightPos[i] = gl_ModelViewMatrixInverse * gl_LightSource[i+1].position;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
#include <glm/gtx/vector_angle.hpp>
|
#include <glm/gtx/vector_angle.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
|
@ -81,6 +82,16 @@ void Avatar::init() {
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
_shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE);
|
_shouldRenderBillboard = (getLODDistance() >= BILLBOARD_LOD_DISTANCE);
|
||||||
initializeHair();
|
initializeHair();
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
_localLightColors[i] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
_localLightDirections[i] = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize first light
|
||||||
|
_localLightColors[0].r = 0.2f; _localLightColors[0].g = 0.2f, _localLightColors[0].b = 0.2f;
|
||||||
|
_localLightDirections[0].x = 1.0f; _localLightDirections[0].y = 0.0f; _localLightDirections[0].z = 0.0f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getChestPosition() const {
|
glm::vec3 Avatar::getChestPosition() const {
|
||||||
|
@ -219,7 +230,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
||||||
const float GLOW_DISTANCE = 20.0f;
|
const float GLOW_DISTANCE = 20.0f;
|
||||||
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
const float GLOW_MAX_LOUDNESS = 2500.0f;
|
||||||
const float MAX_GLOW = 0.5f;
|
const float MAX_GLOW = 0.5f;
|
||||||
|
|
||||||
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar())
|
float GLOW_FROM_AVERAGE_LOUDNESS = ((this == Application::getInstance()->getAvatar())
|
||||||
? 0.0f
|
? 0.0f
|
||||||
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
: MAX_GLOW * getHeadData()->getAudioLoudness() / GLOW_MAX_LOUDNESS);
|
||||||
|
@ -230,7 +241,17 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
||||||
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE
|
float glowLevel = _moving && distanceToTarget > GLOW_DISTANCE && renderMode == NORMAL_RENDER_MODE
|
||||||
? 1.0f
|
? 1.0f
|
||||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
glm::vec3 normalized = glm::normalize(_localLightDirections[i]);
|
||||||
|
glm::vec4 localLight = glm::vec4(normalized, 1.0f);
|
||||||
|
|
||||||
|
// local light parameters
|
||||||
|
glLightfv(GL_LIGHT1 + i, GL_POSITION, glm::value_ptr(localLight));
|
||||||
|
glLightfv(GL_LIGHT1 + i, GL_DIFFUSE, glm::value_ptr(_localLightColors[i]));
|
||||||
|
}
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||||
renderBody(renderMode, glowLevel);
|
renderBody(renderMode, glowLevel);
|
||||||
|
@ -1107,3 +1128,13 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Avatar::setLocalLightDirection(const glm::vec3& direction, int lightIndex) {
|
||||||
|
_localLightDirections[lightIndex] = direction;
|
||||||
|
qDebug( "set light %d direction ( %f, %f, %f )\n", lightIndex, direction.x, direction.y, direction.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::setLocalLightColor(const glm::vec4& color, int lightIndex) {
|
||||||
|
_localLightColors[lightIndex] = color;
|
||||||
|
qDebug( "set light %d color ( %f, %f, %f )\n", lightIndex, color.x, color.y, color.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ const int HAIR_STRANDS = 150; // Number of strands of hair
|
||||||
const int HAIR_LINKS = 10; // Number of links in a hair strand
|
const int HAIR_LINKS = 10; // Number of links in a hair strand
|
||||||
const int HAIR_MAX_CONSTRAINTS = 2; // Hair verlet is connected to at most how many others
|
const int HAIR_MAX_CONSTRAINTS = 2; // Hair verlet is connected to at most how many others
|
||||||
|
|
||||||
|
const int MAX_LOCAL_LIGHTS = 6;
|
||||||
|
|
||||||
enum DriveKeys {
|
enum DriveKeys {
|
||||||
FWD = 0,
|
FWD = 0,
|
||||||
BACK,
|
BACK,
|
||||||
|
@ -154,7 +156,9 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCollisionGroups();
|
void updateCollisionGroups();
|
||||||
|
void setLocalLightDirection(const glm::vec3& direction, int lightIndex);
|
||||||
|
void setLocalLightColor(const glm::vec4& color, int lightIndex);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
||||||
|
|
||||||
|
@ -174,9 +178,13 @@ protected:
|
||||||
glm::vec3 _mouseRayDirection;
|
glm::vec3 _mouseRayDirection;
|
||||||
float _stringLength;
|
float _stringLength;
|
||||||
bool _moving; ///< set when position is changing
|
bool _moving; ///< set when position is changing
|
||||||
|
|
||||||
quint32 _collisionGroups;
|
quint32 _collisionGroups;
|
||||||
|
|
||||||
|
// always-present local lighting for the avatar
|
||||||
|
glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS];
|
||||||
|
glm::vec4 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
// protected methods...
|
// protected methods...
|
||||||
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||||
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
|
||||||
|
|
|
@ -1488,6 +1488,7 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re
|
||||||
if (cascadedShadows) {
|
if (cascadedShadows) {
|
||||||
program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances());
|
program->setUniform(skinLocations->shadowDistances, Application::getInstance()->getShadowDistances());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
||||||
program->bind();
|
program->bind();
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
|
@ -67,7 +69,13 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
||||||
_inOcclusions(false),
|
_inOcclusions(false),
|
||||||
_showCulledSharedFaces(false),
|
_showCulledSharedFaces(false),
|
||||||
_usePrimitiveRenderer(false),
|
_usePrimitiveRenderer(false),
|
||||||
_renderer(0)
|
_renderer(0),
|
||||||
|
_drawHaze(true),
|
||||||
|
_updateHaze(false),
|
||||||
|
_farHazeDistance(300.0f),
|
||||||
|
_hazeColor(0.24f, 0.27f, 0.34f),
|
||||||
|
_lastHazeCameraPosition(0.0f, 0.0f, 0.0f),
|
||||||
|
_lastYawAngle(0.0f)
|
||||||
{
|
{
|
||||||
|
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
||||||
|
@ -108,6 +116,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
||||||
|
|
||||||
_lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
_lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
_lastKnownBoundaryLevelAdjust = 0;
|
_lastKnownBoundaryLevelAdjust = 0;
|
||||||
|
|
||||||
|
_voxelColors = NULL;
|
||||||
|
_voxelPositions = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelSystem::elementDeleted(OctreeElement* element) {
|
void VoxelSystem::elementDeleted(OctreeElement* element) {
|
||||||
|
@ -373,6 +384,9 @@ void VoxelSystem::cleanupVoxelMemory() {
|
||||||
delete[] _readVoxelDirtyArray;
|
delete[] _readVoxelDirtyArray;
|
||||||
_writeVoxelDirtyArray = _readVoxelDirtyArray = NULL;
|
_writeVoxelDirtyArray = _readVoxelDirtyArray = NULL;
|
||||||
_readArraysLock.unlock();
|
_readArraysLock.unlock();
|
||||||
|
|
||||||
|
delete[] _voxelColors;
|
||||||
|
delete[] _voxelPositions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,11 +535,17 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
_shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances");
|
_shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances");
|
||||||
_cascadedShadowMapProgram.release();
|
_cascadedShadowMapProgram.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
_renderer = new PrimitiveRenderer(_maxVoxels);
|
_renderer = new PrimitiveRenderer(_maxVoxels);
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
|
||||||
|
_voxelColors = new xColor[_maxVoxels];
|
||||||
|
memset(_voxelColors, 0, sizeof(xColor) *_maxVoxels);
|
||||||
|
|
||||||
|
_voxelPositions = new glm::vec3[_maxVoxels];
|
||||||
|
|
||||||
_writeArraysLock.unlock();
|
_writeArraysLock.unlock();
|
||||||
_readArraysLock.unlock();
|
_readArraysLock.unlock();
|
||||||
}
|
}
|
||||||
|
@ -1114,6 +1134,7 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo
|
||||||
node->setBufferIndex(nodeIndex);
|
node->setBufferIndex(nodeIndex);
|
||||||
node->setVoxelSystem(this);
|
node->setVoxelSystem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate the array with points for the 8 vertices and RGB color for each added vertex
|
// populate the array with points for the 8 vertices and RGB color for each added vertex
|
||||||
updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor());
|
updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor());
|
||||||
}
|
}
|
||||||
|
@ -1132,10 +1153,24 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo
|
||||||
void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3& startVertex,
|
||||||
float voxelScale, const nodeColor& color) {
|
float voxelScale, const nodeColor& color) {
|
||||||
|
|
||||||
|
// if (nodeIndex < 0 || nodeIndex > 1000) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
if (_initialized && nodeIndex <= _maxVoxels) {
|
if (_initialized && nodeIndex <= _maxVoxels) {
|
||||||
_writeVoxelDirtyArray[nodeIndex] = true;
|
_writeVoxelDirtyArray[nodeIndex] = true;
|
||||||
|
|
||||||
|
// cache the colors and position
|
||||||
|
_voxelColors[nodeIndex].red = color[0];
|
||||||
|
_voxelColors[nodeIndex].green = color[1];
|
||||||
|
_voxelColors[nodeIndex].blue = color[2];
|
||||||
|
|
||||||
|
// scaled voxel position
|
||||||
|
_voxelPositions[nodeIndex] = startVertex * (float)TREE_SCALE;
|
||||||
|
|
||||||
if (_useVoxelShader) {
|
if (_useVoxelShader) {
|
||||||
|
// write in position, scale, and color for the voxel
|
||||||
|
|
||||||
if (_writeVoxelShaderData) {
|
if (_writeVoxelShaderData) {
|
||||||
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex];
|
||||||
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
writeVerticesAt->x = startVertex.x * TREE_SCALE;
|
||||||
|
@ -1157,9 +1192,85 @@ void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// want new color for haze
|
||||||
|
if (_drawHaze) {
|
||||||
|
_updateHaze = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelSystem::updateHazeColors() {
|
||||||
|
|
||||||
|
// only update when player moves
|
||||||
|
if (_lastHazeCameraPosition != Application::getInstance()->getAvatar()->getPosition()) {
|
||||||
|
_updateHaze = true;
|
||||||
|
_lastHazeCameraPosition = Application::getInstance()->getAvatar()->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// update when yaw angle changes
|
||||||
|
float avatarYaw = Application::getInstance()->getAvatar()->getBodyYaw();
|
||||||
|
if (_lastYawAngle != avatarYaw) {
|
||||||
|
_updateHaze = true;
|
||||||
|
_lastYawAngle = avatarYaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_updateHaze) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 cameraPosition = Application::getInstance()->getAvatar()->getPosition();
|
||||||
|
float* hazeColor = glm::value_ptr(_hazeColor);
|
||||||
|
GLubyte* writeColorsAt = _writeColorsArray;
|
||||||
|
|
||||||
|
// update voxel color
|
||||||
|
int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL;
|
||||||
|
for (int i = 0; i < _voxelsInWriteArrays; i++) {
|
||||||
|
|
||||||
|
float distanceToCamera = glm::length(_voxelPositions[i] - cameraPosition);
|
||||||
|
if(distanceToCamera > _farHazeDistance) {
|
||||||
|
distanceToCamera = _farHazeDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// how much haze there is at the distance
|
||||||
|
float hazeStrength = 1.0f - distanceToCamera / _farHazeDistance;
|
||||||
|
|
||||||
|
// [0, 1] clamp
|
||||||
|
if (hazeStrength > 1.0f) {
|
||||||
|
hazeStrength = 1.0f;
|
||||||
|
}
|
||||||
|
else if (hazeStrength < 0.0f) {
|
||||||
|
hazeStrength = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// color [0.0, 1.0]
|
||||||
|
float floatColor[] = {(float)_voxelColors[i].red / 255.0f, (float)_voxelColors[i].green / 255.0f, (float)_voxelColors[i].blue / 255.0f };
|
||||||
|
assert(i >= 0 && i < _maxVoxels);
|
||||||
|
|
||||||
|
// color * haze_strength + haze_color * (1.0 - haze_strength)
|
||||||
|
float oneMinusHazeStrength = 1.0f - hazeStrength;
|
||||||
|
nodeColor colorWithHaze = {
|
||||||
|
(unsigned char)((floatColor[0] * hazeStrength + hazeColor[0] * oneMinusHazeStrength) * 255.0f),
|
||||||
|
(unsigned char)((floatColor[1] * hazeStrength + hazeColor[1] * oneMinusHazeStrength) * 255.0f),
|
||||||
|
(unsigned char)((floatColor[2] * hazeStrength + hazeColor[2] * oneMinusHazeStrength) * 255.0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int j = 0; j < vertexPointsPerVoxel/3; j++ ) {
|
||||||
|
*(writeColorsAt + j*3) = colorWithHaze[0];
|
||||||
|
*(writeColorsAt + j*3+1) = colorWithHaze[1];
|
||||||
|
*(writeColorsAt + j*3+2) = colorWithHaze[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
writeColorsAt += vertexPointsPerVoxel;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyWrittenDataToReadArraysFullVBOs();
|
||||||
|
_voxelsDirty = true;
|
||||||
|
_readRenderFullVBO = true;
|
||||||
|
_updateHaze = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const {
|
glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float voxelScale, int index) const {
|
||||||
const float* identityVertex = identityVertices + index * 3;
|
const float* identityVertex = identityVertices + index * 3;
|
||||||
return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale;
|
return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale;
|
||||||
|
@ -1340,6 +1451,9 @@ void VoxelSystem::render() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_useVoxelShader && _drawHaze) {
|
||||||
|
updateHazeColors();
|
||||||
|
}
|
||||||
updateVBOs();
|
updateVBOs();
|
||||||
|
|
||||||
// if not don't... then do...
|
// if not don't... then do...
|
||||||
|
|
|
@ -273,7 +273,19 @@ private:
|
||||||
static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index
|
static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index
|
||||||
static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask
|
static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask
|
||||||
static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask
|
static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask
|
||||||
|
|
||||||
|
// haze
|
||||||
|
xColor* _voxelColors; ///< Cached Voxel Colors
|
||||||
|
glm::vec3* _voxelPositions; ///< Cached Voxel Positions
|
||||||
|
bool _drawHaze;
|
||||||
|
bool _updateHaze;
|
||||||
|
float _farHazeDistance;
|
||||||
|
glm::vec3 _hazeColor;
|
||||||
|
glm::vec3 _lastHazeCameraPosition;
|
||||||
|
float _lastYawAngle;
|
||||||
|
|
||||||
|
|
||||||
|
void updateHazeColors();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_VoxelSystem_h
|
#endif // hifi_VoxelSystem_h
|
||||||
|
|
Loading…
Reference in a new issue