mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:09:24 +02:00
Merge pull request #3134 from wdings23/light_and_haze
Added local lights to avatar. Added haze to voxel.
This commit is contained in:
commit
af6704a83c
15 changed files with 337 additions and 16 deletions
126
examples/avatarLocalLight.js
Normal file
126
examples/avatarLocalLight.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
//
|
||||||
|
// avatarLocalLight.js
|
||||||
|
//
|
||||||
|
// Created by Tony Peng on July 2nd, 2014
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Set the local light direction and color on the avatar
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
var localLightDirections = [ {x: 1.0, y:0.0, z: 0.0}, {x: 0.0, y:1.0, z: 1.0}, {x: 0.0, y:0.0, z: 1.0}, {x: 1.0, y:1.0, z: 1.0} ];
|
||||||
|
var localLightColors = [ {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0}, {x: 0.0, y:0.0, z: 0.0} ];
|
||||||
|
|
||||||
|
var currentSelection = 0;
|
||||||
|
var currentNumLights = 1;
|
||||||
|
var maxNumLights = 2;
|
||||||
|
|
||||||
|
function keyPressEvent(event) {
|
||||||
|
|
||||||
|
var choice = parseInt(event.text);
|
||||||
|
|
||||||
|
if (event.text == "1") {
|
||||||
|
currentSelection = 0;
|
||||||
|
print("light election = " + currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "2" ) {
|
||||||
|
currentSelection = 1;
|
||||||
|
print("light selection = " + currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "3" ) {
|
||||||
|
currentSelection = 2;
|
||||||
|
print("light selection = " + currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "4" ) {
|
||||||
|
currentSelection = 3;
|
||||||
|
print("light selection = " + currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "5" ) {
|
||||||
|
localLightColors[currentSelection].x += 0.01;
|
||||||
|
if ( localLightColors[currentSelection].x > 1.0) {
|
||||||
|
localLightColors[currentSelection].x = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "6" ) {
|
||||||
|
localLightColors[currentSelection].y += 0.01;
|
||||||
|
if ( localLightColors[currentSelection].y > 1.0) {
|
||||||
|
localLightColors[currentSelection].y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "7" ) {
|
||||||
|
localLightColors[currentSelection].z += 0.01;
|
||||||
|
if ( localLightColors[currentSelection].z > 1.0) {
|
||||||
|
localLightColors[currentSelection].z = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightColor(localLightColors[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "8" ) {
|
||||||
|
localLightDirections[currentSelection].x += 0.01;
|
||||||
|
if (localLightDirections[currentSelection].x > 1.0) {
|
||||||
|
localLightDirections[currentSelection].x = -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "9" ) {
|
||||||
|
localLightDirections[currentSelection].x -= 0.01;
|
||||||
|
if (localLightDirections[currentSelection].x < -1.0) {
|
||||||
|
localLightDirections[currentSelection].x = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "[" ) {
|
||||||
|
localLightDirections[currentSelection].y += 0.01;
|
||||||
|
if (localLightDirections[currentSelection].y > 1.0) {
|
||||||
|
localLightDirections[currentSelection].y = -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "]" ) {
|
||||||
|
localLightDirections[currentSelection].y -= 0.01;
|
||||||
|
if (localLightDirections[currentSelection].y < -1.0) {
|
||||||
|
localLightDirections[currentSelection].y = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.setLocalLightDirection(localLightDirections[currentSelection], currentSelection);
|
||||||
|
}
|
||||||
|
else if (event.text == "," ) {
|
||||||
|
if (currentNumLights + 1 <= maxNumLights) {
|
||||||
|
var darkGrayColor = {x:0.3, y:0.3, z:0.3};
|
||||||
|
|
||||||
|
// default light
|
||||||
|
localLightColors[currentNumLights].x = darkGrayColor.x;
|
||||||
|
localLightColors[currentNumLights].y = darkGrayColor.y;
|
||||||
|
localLightColors[currentNumLights].z = darkGrayColor.z;
|
||||||
|
|
||||||
|
MyAvatar.addLocalLight();
|
||||||
|
MyAvatar.setLocalLightColor(localLightColors[currentNumLights], currentNumLights);
|
||||||
|
MyAvatar.setLocalLightDirection(localLightDirections[currentNumLights], currentNumLights);
|
||||||
|
|
||||||
|
++currentNumLights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.text == "." ) {
|
||||||
|
if (currentNumLights - 1 >= 0 ) {
|
||||||
|
|
||||||
|
// no light contribution
|
||||||
|
localLightColors[currentNumLights - 1].x = 0.0;
|
||||||
|
localLightColors[currentNumLights - 1].y = 0.0;
|
||||||
|
localLightColors[currentNumLights - 1].z = 0.0;
|
||||||
|
|
||||||
|
MyAvatar.removeLocalLight();
|
||||||
|
--currentNumLights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.keyPressEvent.connect(keyPressEvent);
|
|
@ -11,9 +11,16 @@
|
||||||
// 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
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// local lights
|
||||||
|
const int MAX_LOCAL_LIGHTS = 2; // 2 lights for now, will probably need more later on
|
||||||
|
uniform int numLocalLights;
|
||||||
|
uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||||
|
uniform vec3 localLightColors[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
// the interpolated position
|
// the interpolated position
|
||||||
varying vec4 position;
|
varying vec4 position;
|
||||||
|
|
||||||
|
@ -25,8 +32,19 @@ void main(void) {
|
||||||
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 < numLocalLights; i++) {
|
||||||
|
float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0));
|
||||||
|
float localLight = step(0.0, localDiffuse);
|
||||||
|
float localLightVal = localDiffuse * localLight;
|
||||||
|
|
||||||
|
totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
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))),
|
||||||
|
|
|
@ -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 interpolated position
|
// the interpolated position
|
||||||
varying vec4 position;
|
varying vec4 position;
|
||||||
|
|
||||||
|
@ -37,3 +39,4 @@ void main(void) {
|
||||||
// use standard pipeline transform
|
// use standard pipeline transform
|
||||||
gl_Position = ftransform();
|
gl_Position = ftransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// 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 = 2;
|
||||||
|
|
||||||
|
uniform int numLocalLights;
|
||||||
|
uniform vec3 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||||
|
uniform vec3 localLightColors[MAX_LOCAL_LIGHTS];
|
||||||
|
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
@ -28,8 +33,19 @@ void main(void) {
|
||||||
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 < numLocalLights; i++) {
|
||||||
|
float localDiffuse = dot(normalizedNormal, vec4(localLightDirections[i], 1.0));
|
||||||
|
float localLight = step(0.0, localDiffuse);
|
||||||
|
float localLightVal = localDiffuse * localLight;
|
||||||
|
|
||||||
|
totalLocalLight += (localLightVal * vec4( localLightColors[i], 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
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))),
|
||||||
|
@ -38,4 +54,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) + vec4(pow(specular, gl_FrontMaterial.shininess) *
|
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) *
|
||||||
gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0);
|
gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,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);
|
||||||
|
|
||||||
|
|
|
@ -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 <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
@ -60,7 +61,8 @@ Avatar::Avatar() :
|
||||||
_moving(false),
|
_moving(false),
|
||||||
_collisionGroups(0),
|
_collisionGroups(0),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_shouldRenderBillboard(true)
|
_shouldRenderBillboard(true),
|
||||||
|
_numLocalLights(1)
|
||||||
{
|
{
|
||||||
// we may have been created in the network thread, but we live in the main thread
|
// we may have been created in the network thread, but we live in the main thread
|
||||||
moveToThread(Application::getInstance()->thread());
|
moveToThread(Application::getInstance()->thread());
|
||||||
|
@ -81,6 +83,23 @@ 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::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
_localLightDirections[i] = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 darkGrayColor(0.3f, 0.3f, 0.3f);
|
||||||
|
glm::vec3 greenColor(0.0f, 1.0f, 0.0f);
|
||||||
|
glm::vec3 directionX(1.0f, 0.0f, 0.0f);
|
||||||
|
glm::vec3 directionY(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
// initialize local lights
|
||||||
|
_localLightColors[0] = darkGrayColor;
|
||||||
|
_localLightColors[1] = greenColor;
|
||||||
|
|
||||||
|
_localLightDirections[0] = directionX;
|
||||||
|
_localLightDirections[1] = directionY;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getChestPosition() const {
|
glm::vec3 Avatar::getChestPosition() const {
|
||||||
|
@ -232,7 +251,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);
|
||||||
|
@ -243,7 +262,23 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
|
// local lights directions and colors
|
||||||
|
getSkeletonModel().setNumLocalLights(_numLocalLights);
|
||||||
|
getHead()->getFaceModel().setNumLocalLights(_numLocalLights);
|
||||||
|
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||||
|
glm::vec3 normalized = glm::normalize(_localLightDirections[i]);
|
||||||
|
|
||||||
|
// body
|
||||||
|
getSkeletonModel().setLocalLightColor(_localLightColors[i], i);
|
||||||
|
getSkeletonModel().setLocalLightDirection(normalized, i);
|
||||||
|
|
||||||
|
// head
|
||||||
|
getHead()->getFaceModel().setLocalLightColor(_localLightColors[i], i);
|
||||||
|
getHead()->getFaceModel().setLocalLightDirection(_localLightDirections[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
// render body
|
// render body
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||||
renderBody(renderMode, glowLevel);
|
renderBody(renderMode, glowLevel);
|
||||||
|
@ -1122,3 +1157,29 @@ 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::vec3& color, int lightIndex) {
|
||||||
|
_localLightColors[lightIndex] = color;
|
||||||
|
qDebug( "set light %d color ( %f, %f, %f )\n", lightIndex, color.x, color.y, color.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::addLocalLight() {
|
||||||
|
if (_numLocalLights + 1 <= MAX_LOCAL_LIGHTS) {
|
||||||
|
++_numLocalLights;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("ADD LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Avatar::removeLocalLight() {
|
||||||
|
if (_numLocalLights - 1 >= 0) {
|
||||||
|
--_numLocalLights;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("REMOVE LOCAL LIGHT (numLocalLights = %d)\n", _numLocalLights);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,11 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCollisionGroups();
|
void updateCollisionGroups();
|
||||||
|
void setLocalLightDirection(const glm::vec3& direction, int lightIndex);
|
||||||
|
void setLocalLightColor(const glm::vec3& color, int lightIndex);
|
||||||
|
void addLocalLight();
|
||||||
|
void removeLocalLight();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
||||||
|
|
||||||
|
@ -176,9 +180,14 @@ 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::vec3 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||||
|
int _numLocalLights;
|
||||||
|
|
||||||
// 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; }
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
void resetShapePositionsToDefaultPose(); // DEBUG method
|
void resetShapePositionsToDefaultPose(); // DEBUG method
|
||||||
|
|
||||||
void renderRagdoll();
|
void renderRagdoll();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// virtual overrrides from Ragdoll
|
// virtual overrrides from Ragdoll
|
||||||
|
|
|
@ -1488,14 +1488,19 @@ 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 {
|
|
||||||
|
// local light uniforms
|
||||||
|
skinProgram->setUniformValue("numLocalLights", _numLocalLights);
|
||||||
|
skinProgram->setUniformArray("localLightDirections", _localLightDirections, MAX_LOCAL_LIGHTS);
|
||||||
|
skinProgram->setUniformArray("localLightColors", _localLightColors, MAX_LOCAL_LIGHTS);
|
||||||
|
} else {
|
||||||
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
||||||
program->bind();
|
program->bind();
|
||||||
if (cascadedShadows) {
|
if (cascadedShadows) {
|
||||||
program->setUniform(shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
program->setUniform(shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.blendshapes.isEmpty()) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
|
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
|
||||||
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
activeProgram->setAttributeBuffer(tangentLocation, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
||||||
|
@ -1622,6 +1627,20 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::setLocalLightDirection(const glm::vec3& direction, int lightIndex) {
|
||||||
|
assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS);
|
||||||
|
_localLightDirections[lightIndex] = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::setLocalLightColor(const glm::vec3& color, int lightIndex) {
|
||||||
|
assert(lightIndex >= 0 && lightIndex < MAX_LOCAL_LIGHTS);
|
||||||
|
_localLightColors[lightIndex] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::setNumLocalLights(int numLocalLights) {
|
||||||
|
_numLocalLights = numLocalLights;
|
||||||
|
}
|
||||||
|
|
||||||
void AnimationHandle::setURL(const QUrl& url) {
|
void AnimationHandle::setURL(const QUrl& url) {
|
||||||
if (_url != url) {
|
if (_url != url) {
|
||||||
_animation = Application::getInstance()->getAnimationCache()->getAnimation(_url = url);
|
_animation = Application::getInstance()->getAnimationCache()->getAnimation(_url = url);
|
||||||
|
|
|
@ -32,6 +32,8 @@ class Shape;
|
||||||
typedef QSharedPointer<AnimationHandle> AnimationHandlePointer;
|
typedef QSharedPointer<AnimationHandle> AnimationHandlePointer;
|
||||||
typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
||||||
|
|
||||||
|
const int MAX_LOCAL_LIGHTS = 2;
|
||||||
|
|
||||||
/// A generic 3D model displaying geometry loaded from a URL.
|
/// A generic 3D model displaying geometry loaded from a URL.
|
||||||
class Model : public QObject, public PhysicsEntity {
|
class Model : public QObject, public PhysicsEntity {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -143,6 +145,10 @@ public:
|
||||||
/// Sets blended vertices computed in a separate thread.
|
/// Sets blended vertices computed in a separate thread.
|
||||||
void setBlendedVertices(const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
void setBlendedVertices(const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
||||||
|
|
||||||
|
void setLocalLightDirection(const glm::vec3& direction, int lightIndex);
|
||||||
|
void setLocalLightColor(const glm::vec3& color, int lightIndex);
|
||||||
|
void setNumLocalLights(int numLocalLights);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSharedPointer<NetworkGeometry> _geometry;
|
QSharedPointer<NetworkGeometry> _geometry;
|
||||||
|
|
||||||
|
@ -158,6 +164,10 @@ protected:
|
||||||
bool _showTrueJointTransforms;
|
bool _showTrueJointTransforms;
|
||||||
int _rootIndex;
|
int _rootIndex;
|
||||||
|
|
||||||
|
glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS];
|
||||||
|
glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||||
|
int _numLocalLights;
|
||||||
|
|
||||||
QVector<JointState> _jointStates;
|
QVector<JointState> _jointStates;
|
||||||
|
|
||||||
class MeshState {
|
class MeshState {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "ProgramObject.h"
|
#include "ProgramObject.h"
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
ProgramObject::ProgramObject(QObject* parent) : QGLShaderProgram(parent) {
|
ProgramObject::ProgramObject(QObject* parent) : QGLShaderProgram(parent) {
|
||||||
}
|
}
|
||||||
|
@ -22,3 +23,17 @@ void ProgramObject::setUniform(const char* name, const glm::vec3& value) {
|
||||||
setUniformValue(name, value.x, value.y, value.z);
|
setUniformValue(name, value.x, value.y, value.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProgramObject::setUniformArray(const char* name, const glm::vec3* values, int count) {
|
||||||
|
GLfloat* floatVal = new GLfloat[count*3];
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
assert(index < count*3);
|
||||||
|
const float* valPtr = glm::value_ptr(values[i]);
|
||||||
|
floatVal[index++] = valPtr[0];
|
||||||
|
floatVal[index++] = valPtr[1];
|
||||||
|
floatVal[index++] = valPtr[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
setUniformValueArray(name, floatVal, count, 3);
|
||||||
|
delete[] floatVal;
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
void setUniform(int location, const glm::vec3& value);
|
void setUniform(int location, const glm::vec3& value);
|
||||||
void setUniform(const char* name, const glm::vec3& value);
|
void setUniform(const char* name, const glm::vec3& value);
|
||||||
|
void setUniformArray(const char* name, const glm::vec3* values, int count);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ProgramObject_h
|
#endif // hifi_ProgramObject_h
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -57,6 +59,8 @@ GLubyte identityIndicesRight[] = { 1, 2, 6, 1, 6, 5 };
|
||||||
GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 };
|
GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 };
|
||||||
GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 };
|
GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 };
|
||||||
|
|
||||||
|
static glm::vec3 grayColor = glm::vec3(0.3f, 0.3f, 0.3f);
|
||||||
|
|
||||||
VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree)
|
||||||
: NodeData(),
|
: NodeData(),
|
||||||
_treeScale(treeScale),
|
_treeScale(treeScale),
|
||||||
|
@ -67,7 +71,10 @@ 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(false),
|
||||||
|
_farHazeDistance(300.0f),
|
||||||
|
_hazeColor(grayColor)
|
||||||
{
|
{
|
||||||
|
|
||||||
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
_voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0;
|
||||||
|
@ -373,6 +380,7 @@ void VoxelSystem::cleanupVoxelMemory() {
|
||||||
delete[] _readVoxelDirtyArray;
|
delete[] _readVoxelDirtyArray;
|
||||||
_writeVoxelDirtyArray = _readVoxelDirtyArray = NULL;
|
_writeVoxelDirtyArray = _readVoxelDirtyArray = NULL;
|
||||||
_readArraysLock.unlock();
|
_readArraysLock.unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,6 +462,7 @@ void VoxelSystem::initVoxelMemory() {
|
||||||
|
|
||||||
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
_readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels];
|
||||||
_memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels);
|
_memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Global Normals mode uses a technique of not including normals on any voxel vertices, and instead
|
// Global Normals mode uses a technique of not including normals on any voxel vertices, and instead
|
||||||
|
@ -521,13 +530,23 @@ 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;
|
||||||
|
|
||||||
_writeArraysLock.unlock();
|
_writeArraysLock.unlock();
|
||||||
_readArraysLock.unlock();
|
_readArraysLock.unlock();
|
||||||
|
|
||||||
|
// fog for haze
|
||||||
|
if (_drawHaze) {
|
||||||
|
GLfloat fogColor[] = {_hazeColor.x, _hazeColor.y, _hazeColor.z, 1.0f};
|
||||||
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
|
glFogfv(GL_FOG_COLOR, fogColor);
|
||||||
|
glFogf(GL_FOG_START, 0.0f);
|
||||||
|
glFogf(GL_FOG_END, _farHazeDistance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VoxelSystem::parseData(const QByteArray& packet) {
|
int VoxelSystem::parseData(const QByteArray& packet) {
|
||||||
|
@ -1114,6 +1133,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());
|
||||||
}
|
}
|
||||||
|
@ -1131,11 +1151,13 @@ 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 (_initialized && nodeIndex <= _maxVoxels) {
|
if (_initialized && nodeIndex <= _maxVoxels) {
|
||||||
_writeVoxelDirtyArray[nodeIndex] = true;
|
_writeVoxelDirtyArray[nodeIndex] = true;
|
||||||
|
|
||||||
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,6 +1179,7 @@ void VoxelSystem::updateArraysDetails(glBufferIndex nodeIndex, const glm::vec3&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,6 +1430,10 @@ void VoxelSystem::render() {
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (!_usePrimitiveRenderer) {
|
if (!_usePrimitiveRenderer) {
|
||||||
|
if (_drawHaze) {
|
||||||
|
glEnable(GL_FOG);
|
||||||
|
}
|
||||||
|
|
||||||
PerformanceWarning warn(showWarnings, "render().. TRIANGLES...");
|
PerformanceWarning warn(showWarnings, "render().. TRIANGLES...");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1478,6 +1505,10 @@ void VoxelSystem::render() {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_drawHaze) {
|
||||||
|
glDisable(GL_FOG);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
applyScaleAndBindProgram(texture);
|
applyScaleAndBindProgram(texture);
|
||||||
|
|
|
@ -273,7 +273,11 @@ 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
|
||||||
|
bool _drawHaze;
|
||||||
|
float _farHazeDistance;
|
||||||
|
glm::vec3 _hazeColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_VoxelSystem_h
|
#endif // hifi_VoxelSystem_h
|
||||||
|
|
Loading…
Reference in a new issue