mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 12:04:18 +02:00
Merge pull request #3463 from ey6es/deference
Break deferred lighting business out into its own class, use deferred lighting for voxels/avatars/entities/particles in addition to metavoxels. Don't merge until after conference, obviously.
This commit is contained in:
commit
3d89aa9c9c
68 changed files with 1277 additions and 1649 deletions
|
@ -14,6 +14,9 @@
|
|||
// the depth texture
|
||||
uniform sampler2D depthTexture;
|
||||
|
||||
// the normal texture
|
||||
uniform sampler2D normalTexture;
|
||||
|
||||
// the random rotation texture
|
||||
uniform sampler2D rotationTexture;
|
||||
|
||||
|
@ -57,10 +60,11 @@ vec3 texCoordToViewSpace(vec2 texCoord) {
|
|||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 rotationX = texture2D(rotationTexture, gl_TexCoord[0].st * noiseScale).rgb;
|
||||
vec3 rotationY = normalize(cross(rotationX, vec3(0.0, 0.0, 1.0)));
|
||||
mat3 rotation = mat3(rotationX, rotationY, cross(rotationX, rotationY));
|
||||
|
||||
vec3 rotationZ = texture2D(normalTexture, gl_TexCoord[0].st).xyz * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
vec3 rotationY = normalize(cross(rotationZ, texture2D(rotationTexture,
|
||||
gl_TexCoord[0].st * noiseScale).xyz - vec3(0.5, 0.5, 0.5)));
|
||||
mat3 rotation = mat3(cross(rotationY, rotationZ), rotationY, rotationZ);
|
||||
|
||||
vec3 center = texCoordToViewSpace(gl_TexCoord[0].st);
|
||||
|
||||
vec2 rdenominator = 1.0 / (rightTop - leftBottom);
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// cascaded_shadow_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the color in shadow
|
||||
varying vec4 shadowColor;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
void main(void) {
|
||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||
dot(gl_EyePlaneR[shadowIndex], position));
|
||||
|
||||
gl_FragColor = mix(shadowColor, gl_Color, 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r));
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// cascaded_shadow_map.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the color in shadow
|
||||
varying vec4 shadowColor;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
void main(void) {
|
||||
// the shadow color includes only the ambient terms
|
||||
shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
||||
|
||||
// the normal color includes diffuse
|
||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||
|
||||
// generate the shadow texture coordinates using the eye position
|
||||
position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
// use the fixed function transform
|
||||
gl_Position = ftransform();
|
||||
}
|
17
interface/resources/shaders/deferred_light.vert
Normal file
17
interface/resources/shaders/deferred_light.vert
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// deferred_light.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/18/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
void main(void) {
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_Vertex;
|
||||
}
|
60
interface/resources/shaders/deferred_light_limited.vert
Normal file
60
interface/resources/shaders/deferred_light_limited.vert
Normal file
|
@ -0,0 +1,60 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// deferred_light_limited.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/19/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// find the right "right" direction
|
||||
vec3 firstRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(0.0, 1.0, 0.0));
|
||||
vec3 secondRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(1.0, 0.0, 0.0));
|
||||
vec3 right = mix(firstRightCandidate, secondRightCandidate, step(length(firstRightCandidate), length(secondRightCandidate)));
|
||||
right = normalize(right);
|
||||
|
||||
// and the "up"
|
||||
vec3 up = cross(right, gl_LightSource[1].spotDirection);
|
||||
|
||||
// and the "back," which depends on whether this is a spot light
|
||||
vec3 back = -gl_LightSource[1].spotDirection * step(gl_LightSource[1].spotCosCutoff, 0.0);
|
||||
|
||||
// find the eight corners of the bounds
|
||||
vec4 c0 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + back), 1.0);
|
||||
vec4 c1 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + back), 1.0);
|
||||
vec4 c2 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + back), 1.0);
|
||||
vec4 c3 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + back), 1.0);
|
||||
vec4 c4 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c5 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (-up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c6 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up - right + gl_LightSource[1].spotDirection), 1.0);
|
||||
vec4 c7 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz +
|
||||
radius * (up + right + gl_LightSource[1].spotDirection), 1.0);
|
||||
|
||||
// find their projected extents
|
||||
vec2 extents = max(
|
||||
max(max(gl_Vertex.xy * (c0.xy / max(c0.w, 0.001)), gl_Vertex.xy * (c1.xy / max(c1.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c2.xy / max(c2.w, 0.001)), gl_Vertex.xy * (c3.xy / max(c3.w, 0.001)))),
|
||||
max(max(gl_Vertex.xy * (c4.xy / max(c4.w, 0.001)), gl_Vertex.xy * (c5.xy / max(c5.w, 0.001))),
|
||||
max(gl_Vertex.xy * (c6.xy / max(c6.w, 0.001)), gl_Vertex.xy * (c7.xy / max(c7.w, 0.001)))));
|
||||
|
||||
// make sure they don't extend beyond the screen
|
||||
extents = min(extents, vec2(1.0, 1.0));
|
||||
|
||||
gl_Position = vec4(gl_Vertex.xy * extents, 0.0, 1.0);
|
||||
gl_TexCoord[0] = vec4(dot(gl_Position, gl_ObjectPlaneS[3]), dot(gl_Position, gl_ObjectPlaneT[3]), 0.0, 1.0);
|
||||
}
|
|
@ -17,10 +17,44 @@ uniform sampler2D diffuseMap;
|
|||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
// the distance to the near clip plane
|
||||
uniform float near;
|
||||
|
||||
// scale factor for depth: (far - near) / far
|
||||
uniform float depthScale;
|
||||
|
||||
// offset for depth texture coordinates
|
||||
uniform vec2 depthTexCoordOffset;
|
||||
|
||||
// scale for depth texture coordinates
|
||||
uniform vec2 depthTexCoordScale;
|
||||
|
||||
void main(void) {
|
||||
// compute the base color based on OpenGL lighting model
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 0.0);
|
||||
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4((texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal * 2.0 -
|
||||
vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position)))).rgb, normal.a);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
|
||||
// compute the specular multiplier (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(position)),
|
||||
normalizedNormal));
|
||||
|
||||
// add specular contribution
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
|
|||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
|
@ -51,15 +54,27 @@ void main(void) {
|
|||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||
dot(gl_EyePlaneR[shadowIndex], position));
|
||||
|
||||
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// average values from the shadow map
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
||||
|
||||
// compute the specular multiplier (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// add specular contribution
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ uniform sampler2D diffuseMap;
|
|||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
|
@ -46,15 +49,27 @@ void main(void) {
|
|||
// compute the corresponding texture coordinates
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
||||
|
||||
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// average values from the shadow map
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
||||
|
||||
// compute the specular multiplier (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// add specular contribution
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a);
|
||||
}
|
||||
|
|
|
@ -11,43 +11,19 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
||||
|
|
|
@ -11,31 +11,19 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
const int MAX_LOCAL_LIGHTS = 4;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
|
||||
// transform and store the normal for interpolation
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// likewise with the position
|
||||
position = gl_ModelViewMatrix * gl_Vertex;
|
||||
|
||||
// pass along the vertex color
|
||||
gl_FrontColor = gl_Color;
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// and the shadow texture coordinates
|
||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_cascaded_shadow_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||
dot(gl_EyePlaneR[shadowIndex], position));
|
||||
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_cascaded_shadow_normal_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||
int shadowIndex = int(dot(step(vec3(interpolatedPosition.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], interpolatedPosition),
|
||||
dot(gl_EyePlaneT[shadowIndex], interpolatedPosition),
|
||||
dot(gl_EyePlaneR[shadowIndex], interpolatedPosition));
|
||||
|
||||
// add up the local lights
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_cascaded_shadow_normal_specular_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular map texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||
int shadowIndex = int(dot(step(vec3(interpolatedPosition.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], interpolatedPosition),
|
||||
dot(gl_EyePlaneT[shadowIndex], interpolatedPosition),
|
||||
dot(gl_EyePlaneR[shadowIndex], interpolatedPosition));
|
||||
|
||||
// add up the local lights
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_cascaded_shadow_specular_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/29/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the distances to the cascade sections
|
||||
uniform vec3 shadowDistances;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position in view space
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||
dot(gl_EyePlaneR[shadowIndex], position));
|
||||
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
}
|
|
@ -11,23 +11,14 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
@ -36,30 +27,17 @@ varying vec4 interpolatedNormal;
|
|||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// add up the local lights
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5);
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
// the tangent vector
|
||||
attribute vec3 tangent;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
|
@ -24,22 +21,16 @@ varying vec4 interpolatedNormal;
|
|||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
|
||||
// transform and store the position, normal and tangent for interpolation
|
||||
interpolatedPosition = gl_ModelViewMatrix * gl_Vertex;
|
||||
// transform and store the normal and tangent for interpolation
|
||||
interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
|
||||
// pass along the vertex color
|
||||
gl_FrontColor = gl_Color;
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// and the shadow texture coordinates
|
||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], interpolatedPosition), dot(gl_EyePlaneT[0], interpolatedPosition),
|
||||
dot(gl_EyePlaneR[0], interpolatedPosition), 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
|
@ -11,15 +11,6 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
|
@ -29,8 +20,8 @@ uniform sampler2D normalMap;
|
|||
// the specular map texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
@ -39,31 +30,18 @@ varying vec4 interpolatedNormal;
|
|||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
// compute the view normal from the various bits
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// add up the local lights
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5);
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb,
|
||||
gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
||||
|
|
|
@ -13,5 +13,5 @@
|
|||
|
||||
void main(void) {
|
||||
// fixed color for now (we may eventually want to use texture alpha)
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_shadow_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/23/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_shadow_normal_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/23/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// add up the local lights
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * texture2D(diffuseMap, gl_TexCoord[0].st) +
|
||||
vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0);
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_shadow_normal_specular_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/23/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal map texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular map texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
// the interpolated tangent
|
||||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
vec3 normalizedNormal = normalize(vec3(interpolatedNormal));
|
||||
vec3 normalizedTangent = normalize(vec3(interpolatedTangent));
|
||||
vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent));
|
||||
vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0);
|
||||
|
||||
// add up the local lights
|
||||
vec4 viewNormal = vec4(normalizedTangent * localNormal.x +
|
||||
normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(viewNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position -
|
||||
normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_shadow_specular_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/23/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the shadow texture
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the interpolated position in view space
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
}
|
|
@ -11,47 +11,23 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the maximum number of local lights to apply
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
// the color of each local light
|
||||
uniform vec4 localLightColors[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the direction of each local light
|
||||
uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the interpolated position in view space
|
||||
varying vec4 position;
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// add up the local lights
|
||||
vec4 normalizedNormal = normalize(normal);
|
||||
vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i]));
|
||||
}
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
float diffuse = dot(normalizedNormal, gl_LightSource[0].position);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight);
|
||||
|
||||
// compute the specular component (sans exponent)
|
||||
float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
|
||||
// modulate texture by base color and add specular contribution
|
||||
gl_FragColor = vec4(base.rgb, gl_FrontMaterial.diffuse.a) * 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);
|
||||
// set the diffuse, normal, specular data
|
||||
vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)));
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb,
|
||||
gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
||||
|
|
20
interface/resources/shaders/model_translucent.frag
Normal file
20
interface/resources/shaders/model_translucent.frag
Normal file
|
@ -0,0 +1,20 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// model_translucent.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/19/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
void main(void) {
|
||||
// set the diffuse data
|
||||
gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||
}
|
|
@ -26,6 +26,9 @@ const float amplitude = 0.5;
|
|||
// the position in model space
|
||||
varying vec3 position;
|
||||
|
||||
// the normal in view space
|
||||
varying vec4 normal;
|
||||
|
||||
// gradient based on gradients from cube edge centers rather than random from texture lookup
|
||||
float randomEdgeGrad(int hash, vec3 position){
|
||||
int h = int(mod(hash, 16));
|
||||
|
@ -114,7 +117,8 @@ void main(void) {
|
|||
|
||||
// apply vertex lighting
|
||||
vec3 color = gl_Color.rgb * vec3(noise, noise, noise);
|
||||
gl_FragColor = vec4(color, 1);
|
||||
gl_FragData[0] = vec4(color, 1);
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,4 +160,4 @@ float perlin(vec3 location) {
|
|||
mix(mix(ffcv, cfcv, params.x), mix(fccv, cccv, params.x), params.y),
|
||||
params.z);
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
// the position in model space
|
||||
varying vec3 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
position = gl_Vertex.xyz;
|
||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
|
||||
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||
normal = vec4(gl_NormalMatrix * gl_Normal, 0.0);
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
69
interface/resources/shaders/point_light.frag
Normal file
69
interface/resources/shaders/point_light.frag
Normal file
|
@ -0,0 +1,69 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// spot_light.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/18/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
// the distance to the near clip plane
|
||||
uniform float near;
|
||||
|
||||
// scale factor for depth: (far - near) / far
|
||||
uniform float depthScale;
|
||||
|
||||
// offset for depth texture coordinates
|
||||
uniform vec2 depthTexCoordOffset;
|
||||
|
||||
// scale for depth texture coordinates
|
||||
uniform vec2 depthTexCoordScale;
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
vec4 lightVector = gl_LightSource[1].position - position;
|
||||
float lightDistance = length(lightVector);
|
||||
lightVector = lightVector / lightDistance;
|
||||
float diffuse = dot(normalizedNormal, lightVector);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightProduct[1].ambient +
|
||||
gl_FrontLightProduct[1].diffuse * (diffuse * facingLight));
|
||||
|
||||
// compute attenuation based on distance, etc.
|
||||
float attenuation = step(lightDistance, radius) / dot(vec3(gl_LightSource[1].constantAttenuation,
|
||||
gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation),
|
||||
vec3(1.0, lightDistance, lightDistance * lightDistance));
|
||||
|
||||
// add base to specular, modulate by attenuation
|
||||
float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// shadow_map.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 11/21/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
uniform sampler2DShadow shadowMap;
|
||||
|
||||
// the inverse of the size of the shadow map
|
||||
const float shadowScale = 1.0 / 2048.0;
|
||||
|
||||
// the color in shadow
|
||||
varying vec4 shadowColor;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = mix(shadowColor, gl_Color, 0.25 *
|
||||
(shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||
shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, shadowScale, 0.0)).r));
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// shadow_map.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 3/27/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the color in shadow
|
||||
varying vec4 shadowColor;
|
||||
|
||||
void main(void) {
|
||||
// the shadow color includes only the ambient terms
|
||||
shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
||||
|
||||
// the normal color includes diffuse
|
||||
vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||
|
||||
// generate the shadow texture coordinates using the eye position
|
||||
vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = vec4(dot(gl_EyePlaneS[0], eyePosition), dot(gl_EyePlaneT[0], eyePosition),
|
||||
dot(gl_EyePlaneR[0], eyePosition), 1.0);
|
||||
|
||||
// use the fixed function transform
|
||||
gl_Position = ftransform();
|
||||
}
|
25
interface/resources/shaders/simple.frag
Normal file
25
interface/resources/shaders/simple.frag
Normal file
|
@ -0,0 +1,25 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// simple.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
// the glow intensity
|
||||
uniform float glowIntensity;
|
||||
|
||||
void main(void) {
|
||||
// set the diffuse, normal, specular data
|
||||
gl_FragData[0] = vec4(gl_Color.rgb, glowIntensity);
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0);
|
||||
}
|
26
interface/resources/shaders/simple.vert
Normal file
26
interface/resources/shaders/simple.vert
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// simple.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal for interpolation
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
|
@ -19,14 +19,11 @@ uniform mat4 clusterMatrices[MAX_CLUSTERS];
|
|||
attribute vec4 clusterIndices;
|
||||
attribute vec4 clusterWeights;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 position;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
normal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])];
|
||||
|
@ -35,17 +32,13 @@ void main(void) {
|
|||
normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
||||
}
|
||||
|
||||
position = gl_ModelViewMatrix * position;
|
||||
normal = normalize(gl_ModelViewMatrix * normal);
|
||||
|
||||
// pass along the vertex color
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// and the shadow texture coordinates
|
||||
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_ModelViewProjectionMatrix * position;
|
||||
}
|
||||
|
|
|
@ -22,9 +22,6 @@ attribute vec3 tangent;
|
|||
attribute vec4 clusterIndices;
|
||||
attribute vec4 clusterWeights;
|
||||
|
||||
// the interpolated position
|
||||
varying vec4 interpolatedPosition;
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 interpolatedNormal;
|
||||
|
||||
|
@ -32,7 +29,7 @@ varying vec4 interpolatedNormal;
|
|||
varying vec4 interpolatedTangent;
|
||||
|
||||
void main(void) {
|
||||
interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
|
@ -42,19 +39,14 @@ void main(void) {
|
|||
interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight;
|
||||
interpolatedTangent += clusterMatrix * vec4(tangent, 0.0) * clusterWeight;
|
||||
}
|
||||
interpolatedPosition = gl_ModelViewMatrix * interpolatedPosition;
|
||||
interpolatedNormal = gl_ModelViewMatrix * interpolatedNormal;
|
||||
interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent;
|
||||
|
||||
// pass along the vertex color
|
||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_FrontMaterial.diffuse;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
// and the shadow texture coordinates
|
||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], interpolatedPosition), dot(gl_EyePlaneT[0], interpolatedPosition),
|
||||
dot(gl_EyePlaneR[0], interpolatedPosition), 1.0);
|
||||
|
||||
gl_Position = gl_ProjectionMatrix * interpolatedPosition;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * interpolatedPosition;
|
||||
}
|
||||
|
|
71
interface/resources/shaders/spot_light.frag
Normal file
71
interface/resources/shaders/spot_light.frag
Normal file
|
@ -0,0 +1,71 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// spot_light.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/18/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
// the normal texture
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
// the distance to the near clip plane
|
||||
uniform float near;
|
||||
|
||||
// scale factor for depth: (far - near) / far
|
||||
uniform float depthScale;
|
||||
|
||||
// offset for depth texture coordinates
|
||||
uniform vec2 depthTexCoordOffset;
|
||||
|
||||
// scale for depth texture coordinates
|
||||
uniform vec2 depthTexCoordScale;
|
||||
|
||||
// the radius (hard cutoff) of the light effect
|
||||
uniform float radius;
|
||||
|
||||
void main(void) {
|
||||
// compute the view space position using the depth
|
||||
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||
|
||||
// get the normal from the map
|
||||
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||
vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0));
|
||||
|
||||
// compute the base color based on OpenGL lighting model
|
||||
vec4 lightVector = gl_LightSource[1].position - position;
|
||||
float lightDistance = length(lightVector);
|
||||
lightVector = lightVector / lightDistance;
|
||||
float diffuse = dot(normalizedNormal, lightVector);
|
||||
float facingLight = step(0.0, diffuse);
|
||||
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightProduct[1].ambient +
|
||||
gl_FrontLightProduct[1].diffuse * (diffuse * facingLight));
|
||||
|
||||
// compute attenuation based on spot angle, distance, etc.
|
||||
float cosSpotAngle = max(-dot(lightVector.xyz, gl_LightSource[1].spotDirection), 0.0);
|
||||
float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) *
|
||||
pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation,
|
||||
gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation),
|
||||
vec3(1.0, lightDistance, lightDistance * lightDistance));
|
||||
|
||||
// add base to specular, modulate by attenuation
|
||||
float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))),
|
||||
normalizedNormal));
|
||||
vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st);
|
||||
gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0);
|
||||
}
|
21
interface/resources/shaders/voxel.frag
Normal file
21
interface/resources/shaders/voxel.frag
Normal file
|
@ -0,0 +1,21 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// voxel.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// store the color and normal directly
|
||||
gl_FragData[0] = gl_Color;
|
||||
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||
}
|
26
interface/resources/shaders/voxel.vert
Normal file
26
interface/resources/shaders/voxel.vert
Normal file
|
@ -0,0 +1,26 @@
|
|||
#version 120
|
||||
|
||||
//
|
||||
// voxel.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// the interpolated normal
|
||||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// store the normal for interpolation
|
||||
normal = vec4(gl_NormalMatrix * gl_Normal, 0.0);
|
||||
|
||||
// use the standard position
|
||||
gl_Position = ftransform();
|
||||
|
||||
// store the color directly
|
||||
gl_FrontColor = vec4(gl_Color.rgb, 0.0);
|
||||
}
|
|
@ -698,8 +698,6 @@ void Application::paintGL() {
|
|||
displaySide(whichCamera);
|
||||
glPopMatrix();
|
||||
|
||||
_glowEffect.render();
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
|
||||
renderRearViewMirror(_mirrorViewRect);
|
||||
|
||||
|
@ -707,6 +705,8 @@ void Application::paintGL() {
|
|||
_rearMirrorTools->render(true);
|
||||
}
|
||||
|
||||
_glowEffect.render();
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
||||
|
@ -1754,6 +1754,7 @@ void Application::init() {
|
|||
|
||||
_environment.init();
|
||||
|
||||
_deferredLightingEffect.init();
|
||||
_glowEffect.init();
|
||||
_ambientOcclusionEffect.init();
|
||||
_voxelShader.init();
|
||||
|
@ -2709,7 +2710,6 @@ void Application::updateShadowMap() {
|
|||
const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f };
|
||||
const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f };
|
||||
const GLfloat WORLD_SPECULAR_COLOR[] = { 0.94f, 0.94f, 0.737f, 1.0f };
|
||||
const GLfloat NO_SPECULAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
|
||||
void Application::setupWorldLight() {
|
||||
|
||||
|
@ -2843,6 +2843,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
_deferredLightingEffect.prepare();
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
// draw a red sphere
|
||||
float originSphereRadius = 0.05f;
|
||||
|
@ -2851,15 +2853,19 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
glutSolidSphere(originSphereRadius, 15, 15);
|
||||
glPopMatrix();
|
||||
|
||||
// disable specular lighting for ground and voxels
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR);
|
||||
|
||||
// draw the audio reflector overlay
|
||||
{
|
||||
PerformanceTimer perfTimer("audio");
|
||||
_audioReflector.render();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
|
||||
PerformanceTimer perfTimer("buckyBalls");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... bucky balls...");
|
||||
_buckyBalls.render();
|
||||
}
|
||||
|
||||
// Draw voxels
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
PerformanceTimer perfTimer("voxels");
|
||||
|
@ -2876,13 +2882,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
_metavoxels.render();
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) {
|
||||
PerformanceTimer perfTimer("buckyBalls");
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::displaySide() ... bucky balls...");
|
||||
_buckyBalls.render();
|
||||
}
|
||||
|
||||
// render particles...
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Particles)) {
|
||||
PerformanceTimer perfTimer("particles");
|
||||
|
@ -2906,27 +2905,34 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
|
|||
"Application::displaySide() ... AmbientOcclusion...");
|
||||
_ambientOcclusionEffect.render();
|
||||
}
|
||||
|
||||
// restore default, white specular
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR);
|
||||
|
||||
_nodeBoundsDisplay.draw();
|
||||
|
||||
}
|
||||
|
||||
bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR);
|
||||
{
|
||||
PerformanceTimer perfTimer("avatars");
|
||||
|
||||
_avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly);
|
||||
_avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE,
|
||||
false, selfAvatarOnly);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("lighting");
|
||||
_deferredLightingEffect.render();
|
||||
}
|
||||
|
||||
//Render the sixense lasers
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||
_myAvatar->renderLaserPointers();
|
||||
}
|
||||
{
|
||||
PerformanceTimer perfTimer("avatarsPostLighting");
|
||||
_avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE,
|
||||
true, selfAvatarOnly);
|
||||
}
|
||||
|
||||
//Render the sixense lasers
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||
_myAvatar->renderLaserPointers();
|
||||
}
|
||||
|
||||
if (!selfAvatarOnly) {
|
||||
_nodeBoundsDisplay.draw();
|
||||
|
||||
// Render the world box
|
||||
if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
|
||||
|
@ -3001,7 +3007,7 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
|
||||
|
||||
// allow 3DTV/Oculus to override parameters from camera
|
||||
_viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
_displayViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
if (OculusManager::isConnected()) {
|
||||
OculusManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
|
||||
|
@ -3800,8 +3806,8 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
|
|||
scriptEngine->getEntityScriptingInterface()->setPacketSender(&_entityEditSender);
|
||||
scriptEngine->getEntityScriptingInterface()->setEntityTree(_entities.getTree());
|
||||
|
||||
// model has some custom types
|
||||
Model::registerMetaTypes(scriptEngine);
|
||||
// AvatarManager has some custom types
|
||||
AvatarManager::registerMetaTypes(scriptEngine);
|
||||
|
||||
// hook our avatar object into this script engine
|
||||
scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "entities/EntityTreeRenderer.h"
|
||||
#include "particles/ParticleTreeRenderer.h"
|
||||
#include "renderer/AmbientOcclusionEffect.h"
|
||||
#include "renderer/DeferredLightingEffect.h"
|
||||
#include "renderer/GeometryCache.h"
|
||||
#include "renderer/GlowEffect.h"
|
||||
#include "renderer/PointShader.h"
|
||||
|
@ -247,6 +248,7 @@ public:
|
|||
GeometryCache* getGeometryCache() { return &_geometryCache; }
|
||||
AnimationCache* getAnimationCache() { return &_animationCache; }
|
||||
TextureCache* getTextureCache() { return &_textureCache; }
|
||||
DeferredLightingEffect* getDeferredLightingEffect() { return &_deferredLightingEffect; }
|
||||
GlowEffect* getGlowEffect() { return &_glowEffect; }
|
||||
ControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
|
||||
|
||||
|
@ -559,6 +561,7 @@ private:
|
|||
AnimationCache _animationCache;
|
||||
TextureCache _textureCache;
|
||||
|
||||
DeferredLightingEffect _deferredLightingEffect;
|
||||
GlowEffect _glowEffect;
|
||||
AmbientOcclusionEffect _ambientOcclusionEffect;
|
||||
VoxelShader _voxelShader;
|
||||
|
|
|
@ -367,7 +367,6 @@ Menu::Menu() :
|
|||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true));
|
||||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false));
|
||||
shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false));
|
||||
addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::AvatarsReceiveShadows, 0, true);
|
||||
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true);
|
||||
|
|
|
@ -346,7 +346,6 @@ namespace MenuOption {
|
|||
const QString AudioSourcePinkNoise = "Pink Noise";
|
||||
const QString AudioSourceSine440 = "Sine 440hz";
|
||||
const QString Avatars = "Avatars";
|
||||
const QString AvatarsReceiveShadows = "Avatars Receive Shadows";
|
||||
const QString Bandwidth = "Bandwidth Display";
|
||||
const QString BandwidthDetails = "Bandwidth Details";
|
||||
const QString BlueSpeechSphere = "Blue Sphere While Speaking";
|
||||
|
|
|
@ -51,12 +51,6 @@ void MetavoxelSystem::init() {
|
|||
new BufferDataAttribute("voxelBuffer"));
|
||||
_voxelBufferAttribute->setLODThresholdMultiplier(
|
||||
AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier());
|
||||
|
||||
loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations);
|
||||
loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap,
|
||||
_directionalLightShadowMapLocations);
|
||||
loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap,
|
||||
_directionalLightCascadedShadowMapLocations);
|
||||
}
|
||||
|
||||
MetavoxelLOD MetavoxelSystem::getLOD() {
|
||||
|
@ -127,150 +121,18 @@ int RenderVisitor::visit(MetavoxelInfo& info) {
|
|||
return STOP_RECURSION;
|
||||
}
|
||||
|
||||
const GLenum COLOR_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0 };
|
||||
const GLenum NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT1 };
|
||||
const GLenum COLOR_NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
|
||||
void MetavoxelSystem::render() {
|
||||
// update the frustum
|
||||
ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum();
|
||||
_frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(),
|
||||
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
|
||||
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
|
||||
|
||||
_needToLight = false;
|
||||
|
||||
// clear the normal buffer
|
||||
glDrawBuffers(sizeof(NORMAL_DRAW_BUFFERS) / sizeof(NORMAL_DRAW_BUFFERS[0]), NORMAL_DRAW_BUFFERS);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||
|
||||
|
||||
RenderVisitor renderVisitor(getLOD());
|
||||
guideToAugmented(renderVisitor, true);
|
||||
|
||||
// give external parties a chance to join in
|
||||
emit rendering();
|
||||
|
||||
if (!_needToLight) {
|
||||
return; // skip lighting if not needed
|
||||
}
|
||||
|
||||
// perform deferred lighting, rendering to free fbo
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
|
||||
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
||||
primaryFBO->release();
|
||||
|
||||
QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject();
|
||||
freeFBO->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
||||
|
||||
// get the viewport side (left, right, both)
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
const int VIEWPORT_X_INDEX = 0;
|
||||
const int VIEWPORT_WIDTH_INDEX = 2;
|
||||
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
|
||||
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
|
||||
|
||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
|
||||
ProgramObject* program = &_directionalLightShadowMap;
|
||||
const LightLocations* locations = &_directionalLightShadowMapLocations;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
program = &_directionalLightCascadedShadowMap;
|
||||
locations = &_directionalLightCascadedShadowMapLocations;
|
||||
_directionalLightCascadedShadowMap.bind();
|
||||
_directionalLightCascadedShadowMap.setUniform(locations->shadowDistances,
|
||||
Application::getInstance()->getShadowDistances());
|
||||
|
||||
} else {
|
||||
program->bind();
|
||||
}
|
||||
program->setUniformValue(locations->shadowScale,
|
||||
1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width());
|
||||
|
||||
float left, right, bottom, top, nearVal, farVal;
|
||||
glm::vec4 nearClipPlane, farClipPlane;
|
||||
Application::getInstance()->computeOffAxisFrustum(
|
||||
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
program->setUniformValue(locations->nearLocation, nearVal);
|
||||
program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal);
|
||||
float nearScale = -1.0f / nearVal;
|
||||
float sScale = 1.0f / sWidth;
|
||||
float depthTexCoordScaleS = (right - left) * nearScale * sScale;
|
||||
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS,
|
||||
bottom * nearScale);
|
||||
program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale);
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
||||
|
||||
program->release();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
||||
} else {
|
||||
_directionalLight.bind();
|
||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
||||
_directionalLight.release();
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
freeFBO->release();
|
||||
|
||||
// now transfer the lit region to the primary fbo
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
primaryFBO->bind();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
||||
|
@ -630,24 +492,6 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
|||
}
|
||||
}
|
||||
|
||||
void MetavoxelSystem::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) {
|
||||
program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name);
|
||||
program.link();
|
||||
|
||||
program.bind();
|
||||
program.setUniformValue("diffuseMap", 0);
|
||||
program.setUniformValue("normalMap", 1);
|
||||
program.setUniformValue("depthMap", 2);
|
||||
program.setUniformValue("shadowMap", 3);
|
||||
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
||||
locations.shadowScale = program.uniformLocation("shadowScale");
|
||||
locations.nearLocation = program.uniformLocation("near");
|
||||
locations.depthScale = program.uniformLocation("depthScale");
|
||||
locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset");
|
||||
locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale");
|
||||
program.release();
|
||||
}
|
||||
|
||||
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
||||
MetavoxelClient(node, updater) {
|
||||
}
|
||||
|
@ -980,7 +824,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
|
||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(false);
|
||||
|
@ -1053,7 +897,7 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
glDepthMask(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||
|
||||
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
||||
|
||||
|
@ -1077,14 +921,12 @@ void HeightfieldBuffer::render(bool cursor) {
|
|||
|
||||
bufferPair.first.release();
|
||||
bufferPair.second.release();
|
||||
|
||||
Application::getInstance()->getMetavoxels()->noteNeedToLight();
|
||||
}
|
||||
|
||||
QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
|
||||
|
||||
void HeightfieldPreview::render(const glm::vec3& translation, float scale) const {
|
||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
@ -1117,7 +959,7 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const
|
|||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||
}
|
||||
|
||||
VoxelBuffer::VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices,
|
||||
|
@ -1165,7 +1007,7 @@ void VoxelBuffer::render(bool cursor) {
|
|||
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
||||
|
||||
if (!_materials.isEmpty()) {
|
||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthMask(false);
|
||||
|
@ -1235,7 +1077,7 @@ void VoxelBuffer::render(bool cursor) {
|
|||
glDepthMask(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||
|
||||
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materials);
|
||||
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materialWeights);
|
||||
|
@ -1245,8 +1087,6 @@ void VoxelBuffer::render(bool cursor) {
|
|||
|
||||
_vertexBuffer.release();
|
||||
_indexBuffer.release();
|
||||
|
||||
Application::getInstance()->getMetavoxels()->noteNeedToLight();
|
||||
}
|
||||
|
||||
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
||||
|
@ -2282,7 +2122,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
|||
|
||||
_pointProgram.release();
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
|
@ -2325,7 +2165,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
|||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||
}
|
||||
|
||||
void DefaultMetavoxelRendererImplementation::loadSplatProgram(const char* type,
|
||||
|
|
|
@ -52,8 +52,6 @@ public:
|
|||
|
||||
Q_INVOKABLE void deleteTextures(int heightID, int colorID, int textureID);
|
||||
|
||||
void noteNeedToLight() { _needToLight = true; }
|
||||
|
||||
signals:
|
||||
|
||||
void rendering();
|
||||
|
@ -66,18 +64,6 @@ private:
|
|||
|
||||
void guideToAugmented(MetavoxelVisitor& visitor, bool render = false);
|
||||
|
||||
class LightLocations {
|
||||
public:
|
||||
int shadowDistances;
|
||||
int shadowScale;
|
||||
int nearLocation;
|
||||
int depthScale;
|
||||
int depthTexCoordOffset;
|
||||
int depthTexCoordScale;
|
||||
};
|
||||
|
||||
static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations);
|
||||
|
||||
AttributePointer _pointBufferAttribute;
|
||||
AttributePointer _heightfieldBufferAttribute;
|
||||
AttributePointer _voxelBufferAttribute;
|
||||
|
@ -85,14 +71,6 @@ private:
|
|||
MetavoxelLOD _lod;
|
||||
QReadWriteLock _lodLock;
|
||||
Frustum _frustum;
|
||||
bool _needToLight;
|
||||
|
||||
ProgramObject _directionalLight;
|
||||
LightLocations _directionalLightLocations;
|
||||
ProgramObject _directionalLightShadowMap;
|
||||
LightLocations _directionalLightShadowMapLocations;
|
||||
ProgramObject _directionalLightCascadedShadowMap;
|
||||
LightLocations _directionalLightCascadedShadowMapLocations;
|
||||
};
|
||||
|
||||
/// Describes contents of a point in a point buffer.
|
||||
|
|
|
@ -273,13 +273,12 @@ static TextRenderer* textRenderer(TextRendererType type) {
|
|||
return displayNameRenderer;
|
||||
}
|
||||
|
||||
void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
||||
void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool postLighting) {
|
||||
if (_referential) {
|
||||
_referential->update();
|
||||
}
|
||||
|
||||
if (glm::distance(Application::getInstance()->getAvatar()->getPosition(),
|
||||
_position) < 10.0f) {
|
||||
if (postLighting && glm::distance(Application::getInstance()->getAvatar()->getPosition(), _position) < 10.0f) {
|
||||
// render pointing lasers
|
||||
glm::vec3 laserColor = glm::vec3(1.0f, 0.0f, 1.0f);
|
||||
float laserLength = 50.0f;
|
||||
|
@ -351,17 +350,28 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
? 1.0f
|
||||
: GLOW_FROM_AVERAGE_LOUDNESS;
|
||||
|
||||
|
||||
// local lights directions and colors
|
||||
const QVector<Model::LocalLight>& localLights = Application::getInstance()->getAvatarManager().getLocalLights();
|
||||
_skeletonModel.setLocalLights(localLights);
|
||||
getHead()->getFaceModel().setLocalLights(localLights);
|
||||
|
||||
// render body
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
if (!postLighting && Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(renderMode, glowLevel);
|
||||
|
||||
if (renderMode != SHADOW_RENDER_MODE) {
|
||||
// add local lights
|
||||
const float BASE_LIGHT_DISTANCE = 2.0f;
|
||||
const float LIGHT_EXPONENT = 1.0f;
|
||||
const float LIGHT_CUTOFF = glm::radians(80.0f);
|
||||
float distance = BASE_LIGHT_DISTANCE * _scale;
|
||||
glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f);
|
||||
glm::quat orientation = getOrientation();
|
||||
foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) {
|
||||
glm::vec3 direction = orientation * light.direction;
|
||||
Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance,
|
||||
distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction,
|
||||
LIGHT_EXPONENT, LIGHT_CUTOFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renderMode != SHADOW_RENDER_MODE) {
|
||||
|
||||
if (postLighting) {
|
||||
bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes);
|
||||
bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes);
|
||||
bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes);
|
||||
|
@ -397,7 +407,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
// quick check before falling into the code below:
|
||||
// (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m)
|
||||
const float MIN_VOICE_SPHERE_DISTANCE = 12.0f;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere)
|
||||
if (postLighting && Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere)
|
||||
&& distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) {
|
||||
|
||||
// render voice intensity sphere for avatars that are farther away
|
||||
|
@ -425,7 +435,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
|||
|
||||
const float DISPLAYNAME_DISTANCE = 20.0f;
|
||||
setShowDisplayName(renderMode == NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE);
|
||||
if (renderMode != NORMAL_RENDER_MODE || (isMyAvatar() &&
|
||||
if (!postLighting || renderMode != NORMAL_RENDER_MODE || (isMyAvatar() &&
|
||||
Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) {
|
||||
return;
|
||||
}
|
||||
|
@ -501,7 +511,7 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) {
|
|||
return;
|
||||
}
|
||||
|
||||
_skeletonModel.render(1.0f, modelRenderMode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows));
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
getHand()->render(false, modelRenderMode);
|
||||
}
|
||||
|
@ -547,9 +557,8 @@ void Avatar::simulateAttachments(float deltaTime) {
|
|||
void Avatar::renderAttachments(RenderMode renderMode) {
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
bool receiveShadows = Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows);
|
||||
foreach (Model* model, _attachmentModels) {
|
||||
model->render(1.0f, modelRenderMode, receiveShadows);
|
||||
model->render(1.0f, modelRenderMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ public:
|
|||
|
||||
enum RenderMode { NORMAL_RENDER_MODE, SHADOW_RENDER_MODE, MIRROR_RENDER_MODE };
|
||||
|
||||
virtual void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE);
|
||||
virtual void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE,
|
||||
bool postLighting = false);
|
||||
|
||||
//setters
|
||||
void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); }
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <QScriptEngine>
|
||||
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
#include <PerfStat.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -26,6 +29,23 @@
|
|||
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
|
||||
const QUuid MY_AVATAR_KEY; // NULL key
|
||||
|
||||
static QScriptValue localLightToScriptValue(QScriptEngine* engine, const AvatarManager::LocalLight& light) {
|
||||
QScriptValue object = engine->newObject();
|
||||
object.setProperty("direction", vec3toScriptValue(engine, light.direction));
|
||||
object.setProperty("color", vec3toScriptValue(engine, light.color));
|
||||
return object;
|
||||
}
|
||||
|
||||
static void localLightFromScriptValue(const QScriptValue& value, AvatarManager::LocalLight& light) {
|
||||
vec3FromScriptValue(value.property("direction"), light.direction);
|
||||
vec3FromScriptValue(value.property("color"), light.color);
|
||||
}
|
||||
|
||||
void AvatarManager::registerMetaTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue);
|
||||
qScriptRegisterSequenceMetaType<QVector<AvatarManager::LocalLight> >(engine);
|
||||
}
|
||||
|
||||
AvatarManager::AvatarManager(QObject* parent) :
|
||||
_avatarFades() {
|
||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||
|
@ -79,7 +99,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
simulateAvatarFades(deltaTime);
|
||||
}
|
||||
|
||||
void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly) {
|
||||
void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool postLighting, bool selfAvatarOnly) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::renderAvatars()");
|
||||
bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors);
|
||||
|
@ -92,13 +112,13 @@ void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool selfAvatar
|
|||
if (!avatar->isInitialized()) {
|
||||
continue;
|
||||
}
|
||||
avatar->render(cameraPosition, renderMode);
|
||||
avatar->render(cameraPosition, renderMode, postLighting);
|
||||
avatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||
}
|
||||
renderAvatarFades(cameraPosition, renderMode);
|
||||
} else {
|
||||
// just render myAvatar
|
||||
_myAvatar->render(cameraPosition, renderMode);
|
||||
_myAvatar->render(cameraPosition, renderMode, postLighting);
|
||||
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||
}
|
||||
}
|
||||
|
@ -159,19 +179,19 @@ void AvatarManager::clearOtherAvatars() {
|
|||
_myAvatar->clearLookAtTargetAvatar();
|
||||
}
|
||||
|
||||
void AvatarManager::setLocalLights(const QVector<Model::LocalLight>& localLights) {
|
||||
void AvatarManager::setLocalLights(const QVector<AvatarManager::LocalLight>& localLights) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector<Model::LocalLight>&, localLights));
|
||||
QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector<AvatarManager::LocalLight>&, localLights));
|
||||
return;
|
||||
}
|
||||
_localLights = localLights;
|
||||
}
|
||||
|
||||
QVector<Model::LocalLight> AvatarManager::getLocalLights() const {
|
||||
QVector<AvatarManager::LocalLight> AvatarManager::getLocalLights() const {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QVector<Model::LocalLight> result;
|
||||
QVector<AvatarManager::LocalLight> result;
|
||||
QMetaObject::invokeMethod(const_cast<AvatarManager*>(this), "getLocalLights", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QVector<Model::LocalLight>, result));
|
||||
Q_RETURN_ARG(QVector<AvatarManager::LocalLight>, result));
|
||||
return result;
|
||||
}
|
||||
return _localLights;
|
||||
|
|
|
@ -26,6 +26,10 @@ class AvatarManager : public AvatarHashMap {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/// Registers the script types associated with the avatar manager.
|
||||
static void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
AvatarManager(QObject* parent = 0);
|
||||
|
||||
void init();
|
||||
|
@ -33,12 +37,18 @@ public:
|
|||
MyAvatar* getMyAvatar() { return _myAvatar.data(); }
|
||||
|
||||
void updateOtherAvatars(float deltaTime);
|
||||
void renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly = false);
|
||||
void renderAvatars(Avatar::RenderMode renderMode, bool postLighting = false, bool selfAvatarOnly = false);
|
||||
|
||||
void clearOtherAvatars();
|
||||
|
||||
Q_INVOKABLE void setLocalLights(const QVector<Model::LocalLight>& localLights);
|
||||
Q_INVOKABLE QVector<Model::LocalLight> getLocalLights() const;
|
||||
class LocalLight {
|
||||
public:
|
||||
glm::vec3 color;
|
||||
glm::vec3 direction;
|
||||
};
|
||||
|
||||
Q_INVOKABLE void setLocalLights(const QVector<AvatarManager::LocalLight>& localLights);
|
||||
Q_INVOKABLE QVector<AvatarManager::LocalLight> getLocalLights() const;
|
||||
|
||||
private:
|
||||
AvatarManager(const AvatarManager& other);
|
||||
|
@ -54,7 +64,10 @@ private:
|
|||
QVector<AvatarSharedPointer> _avatarFades;
|
||||
QSharedPointer<MyAvatar> _myAvatar;
|
||||
|
||||
QVector<Model::LocalLight> _localLights;
|
||||
QVector<AvatarManager::LocalLight> _localLights;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
||||
Q_DECLARE_METATYPE(QVector<AvatarManager::LocalLight>)
|
||||
|
||||
#endif // hifi_AvatarManager_h
|
||||
|
|
|
@ -194,12 +194,16 @@ void Head::relaxLean(float deltaTime) {
|
|||
}
|
||||
|
||||
void Head::render(float alpha, Model::RenderMode mode) {
|
||||
_faceModel.render(alpha, mode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows));
|
||||
_faceModel.render(alpha, mode);
|
||||
if (_renderLookatVectors && mode != Model::SHADOW_RENDER_MODE) {
|
||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||
Application::getInstance()->getDeferredLightingEffect()->addPostLightingRenderable(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Head::renderPostLighting() {
|
||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||
}
|
||||
|
||||
void Head::setScale (float scale) {
|
||||
if (_scale == scale) {
|
||||
return;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "FaceModel.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "world.h"
|
||||
#include "renderer/DeferredLightingEffect.h"
|
||||
|
||||
enum eyeContactTargets {
|
||||
LEFT_EYE,
|
||||
|
@ -35,7 +36,7 @@ const float EYE_EAR_GAP = 0.08f;
|
|||
class Avatar;
|
||||
class ProgramObject;
|
||||
|
||||
class Head : public HeadData {
|
||||
class Head : public HeadData, public PostLightingRenderable {
|
||||
public:
|
||||
Head(Avatar* owningAvatar);
|
||||
|
||||
|
@ -43,6 +44,7 @@ public:
|
|||
void reset();
|
||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||
void render(float alpha, Model::RenderMode mode);
|
||||
virtual void renderPostLighting();
|
||||
void setScale(float scale);
|
||||
void setPosition(glm::vec3 position) { _position = position; }
|
||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||
|
|
|
@ -411,16 +411,16 @@ void MyAvatar::renderDebugBodyPoints() {
|
|||
}
|
||||
|
||||
// virtual
|
||||
void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
|
||||
void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool postLighting) {
|
||||
// don't render if we've been asked to disable local rendering
|
||||
if (!_shouldRender) {
|
||||
return; // exit early
|
||||
}
|
||||
|
||||
Avatar::render(cameraPosition, renderMode);
|
||||
Avatar::render(cameraPosition, renderMode, postLighting);
|
||||
|
||||
// don't display IK constraints in shadow mode
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && renderMode != SHADOW_RENDER_MODE) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && postLighting) {
|
||||
_skeletonModel.renderIKConstraints();
|
||||
}
|
||||
}
|
||||
|
@ -1104,7 +1104,7 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
|
|||
// Render the body's voxels and head
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
_skeletonModel.render(1.0f, modelRenderMode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows));
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
|
||||
// Render head so long as the camera isn't inside it
|
||||
|
@ -1939,11 +1939,10 @@ void MyAvatar::renderAttachments(RenderMode renderMode) {
|
|||
QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name;
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
bool receiveShadows = Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows);
|
||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
const QString& jointName = _attachmentData.at(i).jointName;
|
||||
if (jointName != headJointName && jointName != "Head") {
|
||||
_attachmentModels.at(i)->render(1.0f, modelRenderMode, receiveShadows);
|
||||
_attachmentModels.at(i)->render(1.0f, modelRenderMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
void updateFromTrackers(float deltaTime);
|
||||
void moveWithLean();
|
||||
|
||||
void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE);
|
||||
void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, bool postLighting = false);
|
||||
void renderBody(RenderMode renderMode, float glowLevel = 0.0f);
|
||||
bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
void renderDebugBodyPoints();
|
||||
|
|
|
@ -50,7 +50,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
|||
glm::vec3 positionToCenter = center - position;
|
||||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
glutSolidCube(1.0f);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f);
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
} else {
|
||||
|
@ -86,6 +86,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
|||
|
||||
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
|
||||
|
||||
Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
|
@ -99,6 +101,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
|||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
|
||||
Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram();
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glutWireCube(size);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
|
||||
glPopMatrix();
|
||||
}
|
||||
} else {
|
||||
|
@ -133,7 +133,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glutWireCube(size);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
|||
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glutWireCube(size);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
|
|||
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
|
||||
|
||||
glScalef(dimensions.x, dimensions.y, dimensions.z);
|
||||
glutSolidSphere(0.5f, 15, 15);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(0.5f, 15, 15);
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include "ParticleTreeRenderer.h"
|
||||
|
@ -112,7 +113,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
|
|||
if (wantDebugSphere) {
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glutWireSphere(radius, 15, 15);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(radius, 15, 15);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
@ -120,7 +121,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg
|
|||
} else {
|
||||
glPushMatrix();
|
||||
glTranslatef(position.x, position.y, position.z);
|
||||
glutSolidSphere(radius, 15, 15);
|
||||
Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(radius, 15, 15);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ void AmbientOcclusionEffect::init() {
|
|||
+ "shaders/ambient_occlusion.frag");
|
||||
_occlusionProgram->link();
|
||||
|
||||
// create the sample kernel: an array of spherically distributed offset vectors
|
||||
// create the sample kernel: an array of hemispherically distributed offset vectors
|
||||
const int SAMPLE_KERNEL_SIZE = 16;
|
||||
QVector3D sampleKernel[SAMPLE_KERNEL_SIZE];
|
||||
for (int i = 0; i < SAMPLE_KERNEL_SIZE; i++) {
|
||||
|
@ -51,7 +51,8 @@ void AmbientOcclusionEffect::init() {
|
|||
|
||||
_occlusionProgram->bind();
|
||||
_occlusionProgram->setUniformValue("depthTexture", 0);
|
||||
_occlusionProgram->setUniformValue("rotationTexture", 1);
|
||||
_occlusionProgram->setUniformValue("normalTexture", 1);
|
||||
_occlusionProgram->setUniformValue("rotationTexture", 2);
|
||||
_occlusionProgram->setUniformValueArray("sampleKernel", sampleKernel, SAMPLE_KERNEL_SIZE);
|
||||
_occlusionProgram->setUniformValue("radius", 0.1f);
|
||||
_occlusionProgram->release();
|
||||
|
@ -71,10 +72,10 @@ void AmbientOcclusionEffect::init() {
|
|||
unsigned char rotationData[ROTATION_WIDTH * ROTATION_HEIGHT * ELEMENTS_PER_PIXEL];
|
||||
unsigned char* rotation = rotationData;
|
||||
for (int i = 0; i < ROTATION_WIDTH * ROTATION_HEIGHT; i++) {
|
||||
glm::vec3 randvec = glm::sphericalRand(1.0f);
|
||||
*rotation++ = ((randvec.x + 1.0f) / 2.0f) * 255.0f;
|
||||
*rotation++ = ((randvec.y + 1.0f) / 2.0f) * 255.0f;
|
||||
*rotation++ = ((randvec.z + 1.0f) / 2.0f) * 255.0f;
|
||||
glm::vec3 vector = glm::sphericalRand(1.0f);
|
||||
*rotation++ = ((vector.x + 1.0f) / 2.0f) * 255.0f;
|
||||
*rotation++ = ((vector.y + 1.0f) / 2.0f) * 255.0f;
|
||||
*rotation++ = ((vector.z + 1.0f) / 2.0f) * 255.0f;
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ROTATION_WIDTH, ROTATION_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, rotationData);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -101,6 +102,9 @@ void AmbientOcclusionEffect::render() {
|
|||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, _rotationTextureID);
|
||||
|
||||
// render with the occlusion shader to the secondary/tertiary buffer
|
||||
|
@ -137,6 +141,10 @@ void AmbientOcclusionEffect::render() {
|
|||
freeFBO->release();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// now render secondary to primary with 4x4 blur
|
||||
|
|
347
interface/src/renderer/DeferredLightingEffect.cpp
Normal file
347
interface/src/renderer/DeferredLightingEffect.cpp
Normal file
|
@ -0,0 +1,347 @@
|
|||
//
|
||||
// DeferredLightingEffect.cpp
|
||||
// interface/src/renderer
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DeferredLightingEffect.h"
|
||||
#include "RenderUtil.h"
|
||||
|
||||
void DeferredLightingEffect::init() {
|
||||
_simpleProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/simple.vert");
|
||||
_simpleProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/simple.frag");
|
||||
_simpleProgram.link();
|
||||
|
||||
_simpleProgram.bind();
|
||||
_glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity");
|
||||
_simpleProgram.release();
|
||||
|
||||
loadLightProgram("shaders/directional_light.frag", false, _directionalLight, _directionalLightLocations);
|
||||
loadLightProgram("shaders/directional_light_shadow_map.frag", false, _directionalLightShadowMap,
|
||||
_directionalLightShadowMapLocations);
|
||||
loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", false, _directionalLightCascadedShadowMap,
|
||||
_directionalLightCascadedShadowMapLocations);
|
||||
loadLightProgram("shaders/point_light.frag", true, _pointLight, _pointLightLocations);
|
||||
loadLightProgram("shaders/spot_light.frag", true, _spotLight, _spotLightLocations);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::bindSimpleProgram() {
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true, true);
|
||||
_simpleProgram.bind();
|
||||
_simpleProgram.setUniformValue(_glowIntensityLocation, Application::getInstance()->getGlowEffect()->getIntensity());
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::releaseSimpleProgram() {
|
||||
glEnable(GL_BLEND);
|
||||
_simpleProgram.release();
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) {
|
||||
bindSimpleProgram();
|
||||
glutSolidSphere(radius, slices, stacks);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderWireSphere(float radius, int slices, int stacks) {
|
||||
bindSimpleProgram();
|
||||
glutWireSphere(radius, slices, stacks);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderSolidCube(float size) {
|
||||
bindSimpleProgram();
|
||||
glutSolidCube(size);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::renderWireCube(float size) {
|
||||
bindSimpleProgram();
|
||||
glutWireCube(size);
|
||||
releaseSimpleProgram();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient,
|
||||
const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation,
|
||||
float linearAttenuation, float quadraticAttenuation) {
|
||||
addSpotLight(position, radius, ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient,
|
||||
const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, float linearAttenuation,
|
||||
float quadraticAttenuation, const glm::vec3& direction, float exponent, float cutoff) {
|
||||
if (exponent == 0.0f && cutoff == PI) {
|
||||
PointLight light;
|
||||
light.position = glm::vec4(position, 1.0f);
|
||||
light.radius = radius;
|
||||
light.ambient = glm::vec4(ambient, 1.0f);
|
||||
light.diffuse = glm::vec4(diffuse, 1.0f);
|
||||
light.specular = glm::vec4(specular, 1.0f);
|
||||
light.constantAttenuation = constantAttenuation;
|
||||
light.linearAttenuation = linearAttenuation;
|
||||
_pointLights.append(light);
|
||||
|
||||
} else {
|
||||
SpotLight light;
|
||||
light.position = glm::vec4(position, 1.0f);
|
||||
light.radius = radius;
|
||||
light.ambient = glm::vec4(ambient, 1.0f);
|
||||
light.diffuse = glm::vec4(diffuse, 1.0f);
|
||||
light.specular = glm::vec4(specular, 1.0f);
|
||||
light.constantAttenuation = constantAttenuation;
|
||||
light.linearAttenuation = linearAttenuation;
|
||||
light.direction = direction;
|
||||
light.exponent = exponent;
|
||||
light.cutoff = cutoff;
|
||||
_spotLights.append(light);
|
||||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::prepare() {
|
||||
// clear the normal and specular buffers
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, false, true);
|
||||
// clearing to zero alpha for specular causes problems on my Nvidia card; clear to lowest non-zero value instead
|
||||
const float MAX_SPECULAR_EXPONENT = 128.0f;
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::render() {
|
||||
// perform deferred lighting, rendering to free fbo
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glDepthMask(false);
|
||||
|
||||
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
||||
primaryFBO->release();
|
||||
|
||||
QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject();
|
||||
freeFBO->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimarySpecularTextureID());
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
||||
|
||||
// get the viewport side (left, right, both)
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
const int VIEWPORT_X_INDEX = 0;
|
||||
const int VIEWPORT_Y_INDEX = 1;
|
||||
const int VIEWPORT_WIDTH_INDEX = 2;
|
||||
const int VIEWPORT_HEIGHT_INDEX = 3;
|
||||
float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width();
|
||||
float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width();
|
||||
float tMin = viewport[VIEWPORT_Y_INDEX] / (float)primaryFBO->height();
|
||||
float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)primaryFBO->height();
|
||||
|
||||
ProgramObject* program = &_directionalLight;
|
||||
const LightLocations* locations = &_directionalLightLocations;
|
||||
bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled();
|
||||
if (shadowsEnabled) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
|
||||
program = &_directionalLightShadowMap;
|
||||
locations = &_directionalLightShadowMapLocations;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
program = &_directionalLightCascadedShadowMap;
|
||||
locations = &_directionalLightCascadedShadowMapLocations;
|
||||
_directionalLightCascadedShadowMap.bind();
|
||||
_directionalLightCascadedShadowMap.setUniform(locations->shadowDistances,
|
||||
Application::getInstance()->getShadowDistances());
|
||||
|
||||
} else {
|
||||
program->bind();
|
||||
}
|
||||
program->setUniformValue(locations->shadowScale,
|
||||
1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width());
|
||||
|
||||
} else {
|
||||
program->bind();
|
||||
}
|
||||
|
||||
float left, right, bottom, top, nearVal, farVal;
|
||||
glm::vec4 nearClipPlane, farClipPlane;
|
||||
Application::getInstance()->computeOffAxisFrustum(
|
||||
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||
program->setUniformValue(locations->nearLocation, nearVal);
|
||||
float depthScale = (farVal - nearVal) / farVal;
|
||||
program->setUniformValue(locations->depthScale, depthScale);
|
||||
float nearScale = -1.0f / nearVal;
|
||||
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
||||
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
||||
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
||||
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
||||
program->setUniformValue(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||
program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight);
|
||||
|
||||
program->release();
|
||||
|
||||
if (shadowsEnabled) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
}
|
||||
|
||||
// additive blending
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
||||
glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
||||
glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
||||
glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients);
|
||||
glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients);
|
||||
|
||||
if (!_pointLights.isEmpty()) {
|
||||
_pointLight.bind();
|
||||
_pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal);
|
||||
_pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale);
|
||||
_pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||
_pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||
|
||||
foreach (const PointLight& light, _pointLights) {
|
||||
_pointLight.setUniformValue(_pointLightLocations.radius, light.radius);
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular);
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position);
|
||||
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, light.constantAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);
|
||||
|
||||
renderFullscreenQuad();
|
||||
}
|
||||
_pointLights.clear();
|
||||
|
||||
_pointLight.release();
|
||||
}
|
||||
|
||||
if (!_spotLights.isEmpty()) {
|
||||
_spotLight.bind();
|
||||
_spotLight.setUniformValue(_spotLightLocations.nearLocation, nearVal);
|
||||
_spotLight.setUniformValue(_spotLightLocations.depthScale, depthScale);
|
||||
_spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||
_spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||
|
||||
foreach (const SpotLight& light, _spotLights) {
|
||||
_spotLight.setUniformValue(_spotLightLocations.radius, light.radius);
|
||||
glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient);
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse);
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular);
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position);
|
||||
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, light.constantAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation);
|
||||
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);
|
||||
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, (const GLfloat*)&light.direction);
|
||||
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent);
|
||||
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff));
|
||||
|
||||
renderFullscreenQuad();
|
||||
}
|
||||
_spotLights.clear();
|
||||
|
||||
_spotLight.release();
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
freeFBO->release();
|
||||
|
||||
// now transfer the lit region to the primary fbo
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
glColorMask(true, true, true, false);
|
||||
|
||||
primaryFBO->bind();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glColorMask(true, true, true, true);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
// now render the objects we held back until after deferred lighting
|
||||
foreach (PostLightingRenderable* renderable, _postLightingRenderables) {
|
||||
renderable->renderPostLighting();
|
||||
}
|
||||
_postLightingRenderables.clear();
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations) {
|
||||
program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
(limited ? "shaders/deferred_light_limited.vert" : "shaders/deferred_light.vert"));
|
||||
program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name);
|
||||
program.link();
|
||||
|
||||
program.bind();
|
||||
program.setUniformValue("diffuseMap", 0);
|
||||
program.setUniformValue("normalMap", 1);
|
||||
program.setUniformValue("specularMap", 2);
|
||||
program.setUniformValue("depthMap", 3);
|
||||
program.setUniformValue("shadowMap", 4);
|
||||
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
||||
locations.shadowScale = program.uniformLocation("shadowScale");
|
||||
locations.nearLocation = program.uniformLocation("near");
|
||||
locations.depthScale = program.uniformLocation("depthScale");
|
||||
locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset");
|
||||
locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale");
|
||||
locations.radius = program.uniformLocation("radius");
|
||||
program.release();
|
||||
}
|
127
interface/src/renderer/DeferredLightingEffect.h
Normal file
127
interface/src/renderer/DeferredLightingEffect.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// DeferredLightingEffect.h
|
||||
// interface/src/renderer
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_DeferredLightingEffect_h
|
||||
#define hifi_DeferredLightingEffect_h
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "ProgramObject.h"
|
||||
|
||||
class PostLightingRenderable;
|
||||
|
||||
/// Handles deferred lighting for the bits that require it (voxels, metavoxels...)
|
||||
class DeferredLightingEffect {
|
||||
public:
|
||||
|
||||
void init();
|
||||
|
||||
/// Returns a reference to a simple program suitable for rendering static
|
||||
/// untextured geometry (such as that generated by glutSolidSphere, etc.)
|
||||
ProgramObject& getSimpleProgram() { return _simpleProgram; }
|
||||
|
||||
/// Sets up the state necessary to render static untextured geometry with the simple program.
|
||||
void bindSimpleProgram();
|
||||
|
||||
/// Tears down the state necessary to render static untextured geometry with the simple program.
|
||||
void releaseSimpleProgram();
|
||||
|
||||
//// Renders a solid sphere with the simple program.
|
||||
void renderSolidSphere(float radius, int slices, int stacks);
|
||||
|
||||
//// Renders a wireframe sphere with the simple program.
|
||||
void renderWireSphere(float radius, int slices, int stacks);
|
||||
|
||||
//// Renders a solid cube with the simple program.
|
||||
void renderSolidCube(float size);
|
||||
|
||||
//// Renders a wireframe cube with the simple program.
|
||||
void renderWireCube(float size);
|
||||
|
||||
/// Adds a point light to render for the current frame.
|
||||
void addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f),
|
||||
float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f);
|
||||
|
||||
/// Adds a spot light to render for the current frame.
|
||||
void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f),
|
||||
const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f),
|
||||
float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f,
|
||||
const glm::vec3& direction = glm::vec3(0.0f, 0.0f, -1.0f), float exponent = 0.0f, float cutoff = PI);
|
||||
|
||||
/// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object).
|
||||
void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); }
|
||||
|
||||
void prepare();
|
||||
void render();
|
||||
|
||||
private:
|
||||
|
||||
class LightLocations {
|
||||
public:
|
||||
int shadowDistances;
|
||||
int shadowScale;
|
||||
int nearLocation;
|
||||
int depthScale;
|
||||
int depthTexCoordOffset;
|
||||
int depthTexCoordScale;
|
||||
int radius;
|
||||
};
|
||||
|
||||
static void loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations);
|
||||
|
||||
ProgramObject _simpleProgram;
|
||||
int _glowIntensityLocation;
|
||||
|
||||
ProgramObject _directionalLight;
|
||||
LightLocations _directionalLightLocations;
|
||||
ProgramObject _directionalLightShadowMap;
|
||||
LightLocations _directionalLightShadowMapLocations;
|
||||
ProgramObject _directionalLightCascadedShadowMap;
|
||||
LightLocations _directionalLightCascadedShadowMapLocations;
|
||||
ProgramObject _pointLight;
|
||||
LightLocations _pointLightLocations;
|
||||
ProgramObject _spotLight;
|
||||
LightLocations _spotLightLocations;
|
||||
|
||||
class PointLight {
|
||||
public:
|
||||
glm::vec4 position;
|
||||
float radius;
|
||||
glm::vec4 ambient;
|
||||
glm::vec4 diffuse;
|
||||
glm::vec4 specular;
|
||||
float constantAttenuation;
|
||||
float linearAttenuation;
|
||||
float quadraticAttenuation;
|
||||
};
|
||||
|
||||
class SpotLight : public PointLight {
|
||||
public:
|
||||
glm::vec3 direction;
|
||||
float exponent;
|
||||
float cutoff;
|
||||
};
|
||||
|
||||
QVector<PointLight> _pointLights;
|
||||
QVector<SpotLight> _spotLights;
|
||||
QVector<PostLightingRenderable*> _postLightingRenderables;
|
||||
};
|
||||
|
||||
/// Simple interface for objects that require something to be rendered after deferred lighting.
|
||||
class PostLightingRenderable {
|
||||
public:
|
||||
virtual void renderPostLighting() = 0;
|
||||
};
|
||||
|
||||
#endif // hifi_DeferredLightingEffect_h
|
|
@ -43,6 +43,9 @@ public:
|
|||
/// Stops using the glow effect.
|
||||
void end();
|
||||
|
||||
/// Returns the current glow intensity.
|
||||
float getIntensity() const { return _intensity; }
|
||||
|
||||
/// Renders the glow effect. To be called after rendering the scene.
|
||||
/// \param toTexture whether to render to a texture, rather than to the frame buffer
|
||||
/// \return the framebuffer object to which we rendered, or NULL if to the frame buffer
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include <QMetaType>
|
||||
#include <QRunnable>
|
||||
#include <QScriptEngine>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
@ -20,7 +19,6 @@
|
|||
#include <CapsuleShape.h>
|
||||
#include <GeometryUtil.h>
|
||||
#include <PhysicsEntity.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <ShapeCollider.h>
|
||||
#include <SphereShape.h>
|
||||
|
||||
|
@ -33,23 +31,6 @@ static int modelPointerTypeId = qRegisterMetaType<QPointer<Model> >();
|
|||
static int weakNetworkGeometryPointerTypeId = qRegisterMetaType<QWeakPointer<NetworkGeometry> >();
|
||||
static int vec3VectorTypeId = qRegisterMetaType<QVector<glm::vec3> >();
|
||||
|
||||
static QScriptValue localLightToScriptValue(QScriptEngine* engine, const Model::LocalLight& light) {
|
||||
QScriptValue object = engine->newObject();
|
||||
object.setProperty("direction", vec3toScriptValue(engine, light.direction));
|
||||
object.setProperty("color", vec3toScriptValue(engine, light.color));
|
||||
return object;
|
||||
}
|
||||
|
||||
static void localLightFromScriptValue(const QScriptValue& value, Model::LocalLight& light) {
|
||||
vec3FromScriptValue(value.property("direction"), light.direction);
|
||||
vec3FromScriptValue(value.property("color"), light.color);
|
||||
}
|
||||
|
||||
void Model::registerMetaTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue);
|
||||
qScriptRegisterSequenceMetaType<QVector<Model::LocalLight> >(engine);
|
||||
}
|
||||
|
||||
Model::Model(QObject* parent) :
|
||||
QObject(parent),
|
||||
_scale(1.0f, 1.0f, 1.0f),
|
||||
|
@ -77,16 +58,7 @@ ProgramObject Model::_program;
|
|||
ProgramObject Model::_normalMapProgram;
|
||||
ProgramObject Model::_specularMapProgram;
|
||||
ProgramObject Model::_normalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_shadowMapProgram;
|
||||
ProgramObject Model::_shadowNormalMapProgram;
|
||||
ProgramObject Model::_shadowSpecularMapProgram;
|
||||
ProgramObject Model::_shadowNormalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_cascadedShadowMapProgram;
|
||||
ProgramObject Model::_cascadedShadowNormalMapProgram;
|
||||
ProgramObject Model::_cascadedShadowSpecularMapProgram;
|
||||
ProgramObject Model::_cascadedShadowNormalSpecularMapProgram;
|
||||
ProgramObject Model::_translucentProgram;
|
||||
|
||||
ProgramObject Model::_shadowProgram;
|
||||
|
||||
|
@ -94,16 +66,7 @@ ProgramObject Model::_skinProgram;
|
|||
ProgramObject Model::_skinNormalMapProgram;
|
||||
ProgramObject Model::_skinSpecularMapProgram;
|
||||
ProgramObject Model::_skinNormalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_skinShadowMapProgram;
|
||||
ProgramObject Model::_skinShadowNormalMapProgram;
|
||||
ProgramObject Model::_skinShadowSpecularMapProgram;
|
||||
ProgramObject Model::_skinShadowNormalSpecularMapProgram;
|
||||
|
||||
ProgramObject Model::_skinCascadedShadowMapProgram;
|
||||
ProgramObject Model::_skinCascadedShadowNormalMapProgram;
|
||||
ProgramObject Model::_skinCascadedShadowSpecularMapProgram;
|
||||
ProgramObject Model::_skinCascadedShadowNormalSpecularMapProgram;
|
||||
ProgramObject Model::_skinTranslucentProgram;
|
||||
|
||||
ProgramObject Model::_skinShadowProgram;
|
||||
|
||||
|
@ -111,28 +74,14 @@ Model::Locations Model::_locations;
|
|||
Model::Locations Model::_normalMapLocations;
|
||||
Model::Locations Model::_specularMapLocations;
|
||||
Model::Locations Model::_normalSpecularMapLocations;
|
||||
Model::Locations Model::_shadowMapLocations;
|
||||
Model::Locations Model::_shadowNormalMapLocations;
|
||||
Model::Locations Model::_shadowSpecularMapLocations;
|
||||
Model::Locations Model::_shadowNormalSpecularMapLocations;
|
||||
Model::Locations Model::_cascadedShadowMapLocations;
|
||||
Model::Locations Model::_cascadedShadowNormalMapLocations;
|
||||
Model::Locations Model::_cascadedShadowSpecularMapLocations;
|
||||
Model::Locations Model::_cascadedShadowNormalSpecularMapLocations;
|
||||
|
||||
Model::Locations Model::_translucentLocations;
|
||||
|
||||
Model::SkinLocations Model::_skinLocations;
|
||||
Model::SkinLocations Model::_skinNormalMapLocations;
|
||||
Model::SkinLocations Model::_skinSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinNormalSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinShadowMapLocations;
|
||||
Model::SkinLocations Model::_skinShadowNormalMapLocations;
|
||||
Model::SkinLocations Model::_skinShadowSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinShadowNormalSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinCascadedShadowMapLocations;
|
||||
Model::SkinLocations Model::_skinCascadedShadowNormalMapLocations;
|
||||
Model::SkinLocations Model::_skinCascadedShadowSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinCascadedShadowNormalSpecularMapLocations;
|
||||
Model::SkinLocations Model::_skinShadowLocations;
|
||||
Model::SkinLocations Model::_skinTranslucentLocations;
|
||||
|
||||
void Model::setScale(const glm::vec3& scale) {
|
||||
setScaleInternal(scale);
|
||||
|
@ -164,23 +113,18 @@ void Model::setOffset(const glm::vec3& offset) {
|
|||
_snappedToRegistrationPoint = false;
|
||||
}
|
||||
|
||||
void Model::initProgram(ProgramObject& program, Model::Locations& locations,
|
||||
int specularTextureUnit, int shadowTextureUnit) {
|
||||
void Model::initProgram(ProgramObject& program, Model::Locations& locations, int specularTextureUnit) {
|
||||
program.bind();
|
||||
locations.tangent = program.attributeLocation("tangent");
|
||||
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
||||
locations.localLightColors = program.uniformLocation("localLightColors");
|
||||
locations.localLightDirections = program.uniformLocation("localLightDirections");
|
||||
locations.alphaThreshold = program.uniformLocation("alphaThreshold");
|
||||
program.setUniformValue("diffuseMap", 0);
|
||||
program.setUniformValue("normalMap", 1);
|
||||
program.setUniformValue("specularMap", specularTextureUnit);
|
||||
program.setUniformValue("shadowMap", shadowTextureUnit);
|
||||
program.release();
|
||||
}
|
||||
|
||||
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations,
|
||||
int specularTextureUnit, int shadowTextureUnit) {
|
||||
initProgram(program, locations, specularTextureUnit, shadowTextureUnit);
|
||||
void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations, int specularTextureUnit) {
|
||||
initProgram(program, locations, specularTextureUnit);
|
||||
|
||||
program.bind();
|
||||
locations.clusterMatrices = program.uniformLocation("clusterMatrices");
|
||||
|
@ -253,78 +197,19 @@ void Model::init() {
|
|||
|
||||
initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations, 2);
|
||||
|
||||
|
||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert");
|
||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/model_shadow_map.frag");
|
||||
_shadowMapProgram.link();
|
||||
|
||||
initProgram(_shadowMapProgram, _shadowMapLocations);
|
||||
|
||||
_shadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_shadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_normal_map.frag");
|
||||
_shadowNormalMapProgram.link();
|
||||
|
||||
initProgram(_shadowNormalMapProgram, _shadowNormalMapLocations, 1, 2);
|
||||
|
||||
_shadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
_translucentProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model.vert");
|
||||
_shadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_specular_map.frag");
|
||||
_shadowSpecularMapProgram.link();
|
||||
|
||||
initProgram(_shadowSpecularMapProgram, _shadowSpecularMapLocations, 1, 2);
|
||||
|
||||
_shadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_shadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_normal_specular_map.frag");
|
||||
_shadowNormalSpecularMapProgram.link();
|
||||
|
||||
initProgram(_shadowNormalSpecularMapProgram, _shadowNormalSpecularMapLocations, 2, 3);
|
||||
|
||||
|
||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/model.vert");
|
||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/model_cascaded_shadow_map.frag");
|
||||
_cascadedShadowMapProgram.link();
|
||||
|
||||
initProgram(_cascadedShadowMapProgram, _cascadedShadowMapLocations);
|
||||
|
||||
_cascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_cascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_map.frag");
|
||||
_cascadedShadowNormalMapProgram.link();
|
||||
|
||||
initProgram(_cascadedShadowNormalMapProgram, _cascadedShadowNormalMapLocations, 1, 2);
|
||||
|
||||
_cascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model.vert");
|
||||
_cascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_specular_map.frag");
|
||||
_cascadedShadowSpecularMapProgram.link();
|
||||
|
||||
initProgram(_cascadedShadowSpecularMapProgram, _cascadedShadowSpecularMapLocations, 1, 2);
|
||||
|
||||
_cascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/model_normal_map.vert");
|
||||
_cascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_specular_map.frag");
|
||||
_cascadedShadowNormalSpecularMapProgram.link();
|
||||
|
||||
initProgram(_cascadedShadowNormalSpecularMapProgram, _cascadedShadowNormalSpecularMapLocations, 2, 3);
|
||||
_translucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_translucent.frag");
|
||||
_translucentProgram.link();
|
||||
|
||||
initProgram(_translucentProgram, _translucentLocations);
|
||||
|
||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert");
|
||||
_shadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow.frag");
|
||||
_shadowProgram.link();
|
||||
|
||||
|
||||
_skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag");
|
||||
_skinProgram.link();
|
||||
|
@ -355,73 +240,6 @@ void Model::init() {
|
|||
|
||||
initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations, 2);
|
||||
|
||||
|
||||
_skinShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/skin_model.vert");
|
||||
_skinShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/model_shadow_map.frag");
|
||||
_skinShadowMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinShadowMapProgram, _skinShadowMapLocations);
|
||||
|
||||
_skinShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_normal_map.frag");
|
||||
_skinShadowNormalMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinShadowNormalMapProgram, _skinShadowNormalMapLocations, 1, 2);
|
||||
|
||||
_skinShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_specular_map.frag");
|
||||
_skinShadowSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinShadowSpecularMapProgram, _skinShadowSpecularMapLocations, 1, 2);
|
||||
|
||||
_skinShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_shadow_normal_specular_map.frag");
|
||||
_skinShadowNormalSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinShadowNormalSpecularMapProgram, _skinShadowNormalSpecularMapLocations, 2, 3);
|
||||
|
||||
|
||||
_skinCascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||
"shaders/skin_model.vert");
|
||||
_skinCascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||
"shaders/model_cascaded_shadow_map.frag");
|
||||
_skinCascadedShadowMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinCascadedShadowMapProgram, _skinCascadedShadowMapLocations);
|
||||
|
||||
_skinCascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinCascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_map.frag");
|
||||
_skinCascadedShadowNormalMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinCascadedShadowNormalMapProgram, _skinCascadedShadowNormalMapLocations, 1, 2);
|
||||
|
||||
_skinCascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinCascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_specular_map.frag");
|
||||
_skinCascadedShadowSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinCascadedShadowSpecularMapProgram, _skinCascadedShadowSpecularMapLocations, 1, 2);
|
||||
|
||||
_skinCascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_normal_map.vert");
|
||||
_skinCascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_specular_map.frag");
|
||||
_skinCascadedShadowNormalSpecularMapProgram.link();
|
||||
|
||||
initSkinProgram(_skinCascadedShadowNormalSpecularMapProgram, _skinCascadedShadowNormalSpecularMapLocations, 2, 3);
|
||||
|
||||
|
||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model_shadow.vert");
|
||||
_skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
|
@ -429,6 +247,14 @@ void Model::init() {
|
|||
_skinShadowProgram.link();
|
||||
|
||||
initSkinProgram(_skinShadowProgram, _skinShadowLocations);
|
||||
|
||||
_skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/skin_model.vert");
|
||||
_skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/model_translucent.frag");
|
||||
_skinTranslucentProgram.link();
|
||||
|
||||
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,7 +384,7 @@ void Model::setJointStates(QVector<JointState> states) {
|
|||
_boundingRadius = radius;
|
||||
}
|
||||
|
||||
bool Model::render(float alpha, RenderMode mode, bool receiveShadows) {
|
||||
bool Model::render(float alpha, RenderMode mode) {
|
||||
// render the attachments
|
||||
foreach (Model* attachment, _attachments) {
|
||||
attachment->render(alpha, mode);
|
||||
|
@ -588,34 +414,42 @@ bool Model::render(float alpha, RenderMode mode, bool receiveShadows) {
|
|||
glEnable(GL_CULL_FACE);
|
||||
if (mode == SHADOW_RENDER_MODE) {
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
} else if (mode == DEFAULT_RENDER_MODE) {
|
||||
// update the local lights
|
||||
for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) {
|
||||
if (i < _localLights.size()) {
|
||||
_localLightDirections[i] = glm::normalize(Application::getInstance()->getUntranslatedViewMatrix() *
|
||||
glm::vec4(_rotation * _localLights.at(i).direction, 0.0f));
|
||||
} else {
|
||||
_localLightColors[i] = glm::vec4();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render opaque meshes with alpha testing
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.5f * alpha);
|
||||
|
||||
receiveShadows &= Menu::getInstance()->getShadowsEnabled();
|
||||
renderMeshes(mode, false, receiveShadows);
|
||||
if (mode == SHADOW_RENDER_MODE) {
|
||||
glAlphaFunc(GL_EQUAL, 0.0f);
|
||||
}
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(
|
||||
mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE,
|
||||
mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE,
|
||||
mode == DEFAULT_RENDER_MODE);
|
||||
|
||||
renderMeshes(mode, false);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
||||
renderMeshes(mode, true, 0.75f);
|
||||
|
||||
renderMeshes(mode, true, receiveShadows);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glDepthMask(false);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true);
|
||||
|
||||
if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) {
|
||||
renderMeshes(mode, true, 0.0f);
|
||||
}
|
||||
|
||||
glDepthMask(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (mode == SHADOW_RENDER_MODE) {
|
||||
|
@ -1358,12 +1192,11 @@ void Model::deleteGeometry() {
|
|||
_blendedBlendshapeCoefficients.clear();
|
||||
}
|
||||
|
||||
void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows) {
|
||||
void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold) {
|
||||
updateVisibleJointStates();
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||
|
||||
bool cascadedShadows = Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows);
|
||||
for (int i = 0; i < networkMeshes.size(); i++) {
|
||||
// exit early if the translucency doesn't match what we're drawing
|
||||
const NetworkMesh& networkMesh = networkMeshes.at(i);
|
||||
|
@ -1373,7 +1206,7 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
continue;
|
||||
}
|
||||
const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bind();
|
||||
|
||||
|
||||
int vertexCount = mesh.vertices.size();
|
||||
if (vertexCount == 0) {
|
||||
// sanity check
|
||||
|
@ -1387,48 +1220,25 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
ProgramObject* skinProgram = &_skinProgram;
|
||||
SkinLocations* skinLocations = &_skinLocations;
|
||||
GLenum specularTextureUnit = 0;
|
||||
GLenum shadowTextureUnit = 0;
|
||||
if (mode == SHADOW_RENDER_MODE) {
|
||||
program = &_shadowProgram;
|
||||
skinProgram = &_skinShadowProgram;
|
||||
skinLocations = &_skinShadowLocations;
|
||||
|
||||
} else if (translucent && alphaThreshold == 0.0f) {
|
||||
program = &_translucentProgram;
|
||||
locations = &_translucentLocations;
|
||||
skinProgram = &_skinTranslucentProgram;
|
||||
skinLocations = &_skinTranslucentLocations;
|
||||
|
||||
} else if (!mesh.tangents.isEmpty()) {
|
||||
if (mesh.hasSpecularTexture()) {
|
||||
if (receiveShadows) {
|
||||
if (cascadedShadows) {
|
||||
program = &_cascadedShadowNormalSpecularMapProgram;
|
||||
locations = &_cascadedShadowNormalSpecularMapLocations;
|
||||
skinProgram = &_skinCascadedShadowNormalSpecularMapProgram;
|
||||
skinLocations = &_skinCascadedShadowNormalSpecularMapLocations;
|
||||
} else {
|
||||
program = &_shadowNormalSpecularMapProgram;
|
||||
locations = &_shadowNormalSpecularMapLocations;
|
||||
skinProgram = &_skinShadowNormalSpecularMapProgram;
|
||||
skinLocations = &_skinShadowNormalSpecularMapLocations;
|
||||
}
|
||||
shadowTextureUnit = GL_TEXTURE3;
|
||||
} else {
|
||||
program = &_normalSpecularMapProgram;
|
||||
locations = &_normalSpecularMapLocations;
|
||||
skinProgram = &_skinNormalSpecularMapProgram;
|
||||
skinLocations = &_skinNormalSpecularMapLocations;
|
||||
}
|
||||
program = &_normalSpecularMapProgram;
|
||||
locations = &_normalSpecularMapLocations;
|
||||
skinProgram = &_skinNormalSpecularMapProgram;
|
||||
skinLocations = &_skinNormalSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE2;
|
||||
|
||||
} else if (receiveShadows) {
|
||||
if (cascadedShadows) {
|
||||
program = &_cascadedShadowNormalMapProgram;
|
||||
locations = &_cascadedShadowNormalMapLocations;
|
||||
skinProgram = &_skinCascadedShadowNormalMapProgram;
|
||||
skinLocations = &_skinCascadedShadowNormalMapLocations;
|
||||
} else {
|
||||
program = &_shadowNormalMapProgram;
|
||||
locations = &_shadowNormalMapLocations;
|
||||
skinProgram = &_skinShadowNormalMapProgram;
|
||||
skinLocations = &_skinShadowNormalMapLocations;
|
||||
}
|
||||
shadowTextureUnit = GL_TEXTURE2;
|
||||
} else {
|
||||
program = &_normalMapProgram;
|
||||
locations = &_normalMapLocations;
|
||||
|
@ -1436,40 +1246,11 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
skinLocations = &_skinNormalMapLocations;
|
||||
}
|
||||
} else if (mesh.hasSpecularTexture()) {
|
||||
if (receiveShadows) {
|
||||
if (cascadedShadows) {
|
||||
program = &_cascadedShadowSpecularMapProgram;
|
||||
locations = &_cascadedShadowSpecularMapLocations;
|
||||
skinProgram = &_skinCascadedShadowSpecularMapProgram;
|
||||
skinLocations = &_skinCascadedShadowSpecularMapLocations;
|
||||
} else {
|
||||
program = &_shadowSpecularMapProgram;
|
||||
locations = &_shadowSpecularMapLocations;
|
||||
skinProgram = &_skinShadowSpecularMapProgram;
|
||||
skinLocations = &_skinShadowSpecularMapLocations;
|
||||
}
|
||||
shadowTextureUnit = GL_TEXTURE2;
|
||||
} else {
|
||||
program = &_specularMapProgram;
|
||||
locations = &_specularMapLocations;
|
||||
skinProgram = &_skinSpecularMapProgram;
|
||||
skinLocations = &_skinSpecularMapLocations;
|
||||
}
|
||||
specularTextureUnit = GL_TEXTURE1;
|
||||
|
||||
} else if (receiveShadows) {
|
||||
if (cascadedShadows) {
|
||||
program = &_cascadedShadowMapProgram;
|
||||
locations = &_cascadedShadowMapLocations;
|
||||
skinProgram = &_skinCascadedShadowMapProgram;
|
||||
skinLocations = &_skinCascadedShadowMapLocations;
|
||||
} else {
|
||||
program = &_shadowMapProgram;
|
||||
locations = &_shadowMapLocations;
|
||||
skinProgram = &_skinShadowMapProgram;
|
||||
skinLocations = &_skinShadowMapLocations;
|
||||
}
|
||||
shadowTextureUnit = GL_TEXTURE1;
|
||||
program = &_specularMapProgram;
|
||||
locations = &_specularMapLocations;
|
||||
skinProgram = &_skinSpecularMapProgram;
|
||||
skinLocations = &_skinSpecularMapLocations;
|
||||
specularTextureUnit = GL_TEXTURE1;
|
||||
}
|
||||
|
||||
const MeshState& state = _meshStates.at(i);
|
||||
|
@ -1497,14 +1278,9 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]);
|
||||
program->bind();
|
||||
}
|
||||
if (cascadedShadows) {
|
||||
activeProgram->setUniform(activeLocations->shadowDistances, Application::getInstance()->getShadowDistances());
|
||||
}
|
||||
if (mode != SHADOW_RENDER_MODE) {
|
||||
activeProgram->setUniformValueArray(activeLocations->localLightDirections,
|
||||
(const GLfloat*)_localLightDirections, MAX_LOCAL_LIGHTS, 4);
|
||||
}
|
||||
|
||||
|
||||
activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold);
|
||||
|
||||
if (mesh.blendshapes.isEmpty()) {
|
||||
if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) {
|
||||
activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3);
|
||||
|
@ -1550,18 +1326,19 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
|
||||
} else {
|
||||
glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity);
|
||||
glm::vec4 specular = glm::vec4(part.specularColor, part.opacity);
|
||||
if (!(translucent && alphaThreshold == 0.0f)) {
|
||||
float emissive = (part.emissiveColor.r + part.emissiveColor.g + part.emissiveColor.b) / 3.0f;
|
||||
diffuse.a = qMax(Application::getInstance()->getGlowEffect()->getIntensity(), emissive);
|
||||
glAlphaFunc(GL_EQUAL, diffuse.a);
|
||||
diffuse = glm::vec4(qMax(diffuse.r, part.emissiveColor.r), qMax(diffuse.g, part.emissiveColor.g),
|
||||
qMax(diffuse.b, part.emissiveColor.b), diffuse.a);
|
||||
}
|
||||
glm::vec4 specular = glm::vec4(part.specularColor, 1.0f);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
|
||||
glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular);
|
||||
glMaterialf(GL_FRONT, GL_SHININESS, part.shininess);
|
||||
|
||||
for (int k = 0; k < qMin(MAX_LOCAL_LIGHTS, _localLights.size()); k++) {
|
||||
_localLightColors[k] = glm::vec4(_localLights.at(k).color, 1.0f) * diffuse;
|
||||
}
|
||||
activeProgram->setUniformValueArray(activeLocations->localLightColors,
|
||||
(const GLfloat*)_localLightColors, MAX_LOCAL_LIGHTS, 4);
|
||||
|
||||
Texture* diffuseMap = networkPart.diffuseTexture.data();
|
||||
if (mesh.isEye && diffuseMap) {
|
||||
diffuseMap = (_dilatedTextures[i][j] =
|
||||
|
@ -1570,7 +1347,6 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
|
||||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
|
||||
|
||||
|
||||
if (!mesh.tangents.isEmpty()) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
Texture* normalMap = networkPart.normalTexture.data();
|
||||
|
@ -1586,12 +1362,6 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (shadowTextureUnit) {
|
||||
glActiveTexture(shadowTextureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
}
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
|
@ -1621,12 +1391,6 @@ void Model::renderMeshes(RenderMode mode, bool translucent, bool receiveShadows)
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (shadowTextureUnit) {
|
||||
glActiveTexture(shadowTextureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if (state.clusterMatrices.size() > 1) {
|
||||
skinProgram->disableAttributeArray(skinLocations->clusterIndices);
|
||||
skinProgram->disableAttributeArray(skinLocations->clusterWeights);
|
||||
|
|
|
@ -34,17 +34,12 @@ class Shape;
|
|||
typedef QSharedPointer<AnimationHandle> AnimationHandlePointer;
|
||||
typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
||||
|
||||
const int MAX_LOCAL_LIGHTS = 2;
|
||||
|
||||
/// A generic 3D model displaying geometry loaded from a URL.
|
||||
class Model : public QObject, public PhysicsEntity {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/// Registers the script types associated with models.
|
||||
static void registerMetaTypes(QScriptEngine* engine);
|
||||
|
||||
Model(QObject* parent = NULL);
|
||||
virtual ~Model();
|
||||
|
||||
|
@ -89,7 +84,7 @@ public:
|
|||
|
||||
enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE };
|
||||
|
||||
bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, bool receiveShadows = true);
|
||||
bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE);
|
||||
|
||||
/// Sets the URL of the model to render.
|
||||
/// \param fallback the URL of a fallback model to render if the requested model fails to load
|
||||
|
@ -171,22 +166,13 @@ public:
|
|||
void setBlendedVertices(int blendNumber, const QWeakPointer<NetworkGeometry>& geometry,
|
||||
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals);
|
||||
|
||||
class LocalLight {
|
||||
public:
|
||||
glm::vec3 color;
|
||||
glm::vec3 direction;
|
||||
};
|
||||
|
||||
void setLocalLights(const QVector<LocalLight>& localLights) { _localLights = localLights; }
|
||||
const QVector<LocalLight>& getLocalLights() const { return _localLights; }
|
||||
|
||||
void setShowTrueJointTransforms(bool show) { _showTrueJointTransforms = show; }
|
||||
|
||||
QVector<JointState>& getJointStates() { return _jointStates; }
|
||||
const QVector<JointState>& getJointStates() const { return _jointStates; }
|
||||
|
||||
void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority);
|
||||
|
||||
|
||||
protected:
|
||||
QSharedPointer<NetworkGeometry> _geometry;
|
||||
|
||||
|
@ -203,8 +189,6 @@ protected:
|
|||
|
||||
bool _showTrueJointTransforms;
|
||||
|
||||
QVector<LocalLight> _localLights;
|
||||
|
||||
QVector<JointState> _jointStates;
|
||||
|
||||
class MeshState {
|
||||
|
@ -258,7 +242,7 @@ private:
|
|||
|
||||
void applyNextGeometry();
|
||||
void deleteGeometry();
|
||||
void renderMeshes(RenderMode mode, bool translucent, bool receiveShadows);
|
||||
void renderMeshes(RenderMode mode, bool translucent, float alphaThreshold = 0.5f);
|
||||
QVector<JointState> createJointStates(const FBXGeometry& geometry);
|
||||
void initJointTransforms();
|
||||
|
||||
|
@ -284,9 +268,6 @@ private:
|
|||
|
||||
QList<AnimationHandlePointer> _runningAnimations;
|
||||
|
||||
glm::vec4 _localLightColors[MAX_LOCAL_LIGHTS];
|
||||
glm::vec4 _localLightDirections[MAX_LOCAL_LIGHTS];
|
||||
|
||||
QVector<float> _blendedBlendshapeCoefficients;
|
||||
int _blendNumber;
|
||||
int _appliedBlendNumber;
|
||||
|
@ -295,16 +276,7 @@ private:
|
|||
static ProgramObject _normalMapProgram;
|
||||
static ProgramObject _specularMapProgram;
|
||||
static ProgramObject _normalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _shadowMapProgram;
|
||||
static ProgramObject _shadowNormalMapProgram;
|
||||
static ProgramObject _shadowSpecularMapProgram;
|
||||
static ProgramObject _shadowNormalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _cascadedShadowMapProgram;
|
||||
static ProgramObject _cascadedShadowNormalMapProgram;
|
||||
static ProgramObject _cascadedShadowSpecularMapProgram;
|
||||
static ProgramObject _cascadedShadowNormalSpecularMapProgram;
|
||||
static ProgramObject _translucentProgram;
|
||||
|
||||
static ProgramObject _shadowProgram;
|
||||
|
||||
|
@ -312,54 +284,26 @@ private:
|
|||
static ProgramObject _skinNormalMapProgram;
|
||||
static ProgramObject _skinSpecularMapProgram;
|
||||
static ProgramObject _skinNormalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _skinShadowMapProgram;
|
||||
static ProgramObject _skinShadowNormalMapProgram;
|
||||
static ProgramObject _skinShadowSpecularMapProgram;
|
||||
static ProgramObject _skinShadowNormalSpecularMapProgram;
|
||||
|
||||
static ProgramObject _skinCascadedShadowMapProgram;
|
||||
static ProgramObject _skinCascadedShadowNormalMapProgram;
|
||||
static ProgramObject _skinCascadedShadowSpecularMapProgram;
|
||||
static ProgramObject _skinCascadedShadowNormalSpecularMapProgram;
|
||||
static ProgramObject _skinTranslucentProgram;
|
||||
|
||||
static ProgramObject _skinShadowProgram;
|
||||
|
||||
static int _normalMapTangentLocation;
|
||||
static int _normalSpecularMapTangentLocation;
|
||||
static int _shadowNormalMapTangentLocation;
|
||||
static int _shadowNormalSpecularMapTangentLocation;
|
||||
static int _cascadedShadowNormalMapTangentLocation;
|
||||
static int _cascadedShadowNormalSpecularMapTangentLocation;
|
||||
|
||||
static int _cascadedShadowMapDistancesLocation;
|
||||
static int _cascadedShadowNormalMapDistancesLocation;
|
||||
static int _cascadedShadowSpecularMapDistancesLocation;
|
||||
static int _cascadedShadowNormalSpecularMapDistancesLocation;
|
||||
|
||||
class Locations {
|
||||
public:
|
||||
int localLightColors;
|
||||
int localLightDirections;
|
||||
int tangent;
|
||||
int shadowDistances;
|
||||
int alphaThreshold;
|
||||
};
|
||||
|
||||
static Locations _locations;
|
||||
static Locations _normalMapLocations;
|
||||
static Locations _specularMapLocations;
|
||||
static Locations _normalSpecularMapLocations;
|
||||
static Locations _shadowMapLocations;
|
||||
static Locations _shadowNormalMapLocations;
|
||||
static Locations _shadowSpecularMapLocations;
|
||||
static Locations _shadowNormalSpecularMapLocations;
|
||||
static Locations _cascadedShadowMapLocations;
|
||||
static Locations _cascadedShadowNormalMapLocations;
|
||||
static Locations _cascadedShadowSpecularMapLocations;
|
||||
static Locations _cascadedShadowNormalSpecularMapLocations;
|
||||
static Locations _translucentLocations;
|
||||
|
||||
static void initProgram(ProgramObject& program, Locations& locations,
|
||||
int specularTextureUnit = 1, int shadowTextureUnit = 1);
|
||||
static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1);
|
||||
|
||||
class SkinLocations : public Locations {
|
||||
public:
|
||||
|
@ -371,26 +315,16 @@ private:
|
|||
static SkinLocations _skinLocations;
|
||||
static SkinLocations _skinNormalMapLocations;
|
||||
static SkinLocations _skinSpecularMapLocations;
|
||||
static SkinLocations _skinNormalSpecularMapLocations;
|
||||
static SkinLocations _skinShadowMapLocations;
|
||||
static SkinLocations _skinShadowNormalMapLocations;
|
||||
static SkinLocations _skinShadowSpecularMapLocations;
|
||||
static SkinLocations _skinShadowNormalSpecularMapLocations;
|
||||
static SkinLocations _skinCascadedShadowMapLocations;
|
||||
static SkinLocations _skinCascadedShadowNormalMapLocations;
|
||||
static SkinLocations _skinCascadedShadowSpecularMapLocations;
|
||||
static SkinLocations _skinCascadedShadowNormalSpecularMapLocations;
|
||||
static SkinLocations _skinNormalSpecularMapLocations;
|
||||
static SkinLocations _skinShadowLocations;
|
||||
|
||||
static void initSkinProgram(ProgramObject& program, SkinLocations& locations,
|
||||
int specularTextureUnit = 1, int shadowTextureUnit = 1);
|
||||
static SkinLocations _skinTranslucentLocations;
|
||||
|
||||
static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||
Q_DECLARE_METATYPE(QWeakPointer<NetworkGeometry>)
|
||||
Q_DECLARE_METATYPE(QVector<glm::vec3>)
|
||||
Q_DECLARE_METATYPE(Model::LocalLight)
|
||||
Q_DECLARE_METATYPE(QVector<Model::LocalLight>)
|
||||
|
||||
/// Represents a handle to a model animation.
|
||||
class AnimationHandle : public QObject {
|
||||
|
|
|
@ -12,15 +12,15 @@
|
|||
#include "InterfaceConfig.h"
|
||||
#include "RenderUtil.h"
|
||||
|
||||
void renderFullscreenQuad(float sMin, float sMax) {
|
||||
void renderFullscreenQuad(float sMin, float sMax, float tMin, float tMax) {
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(sMin, 0.0f);
|
||||
glTexCoord2f(sMin, tMin);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
glTexCoord2f(sMax, 0.0f);
|
||||
glTexCoord2f(sMax, tMin);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
glTexCoord2f(sMax, 1.0f);
|
||||
glTexCoord2f(sMax, tMax);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glTexCoord2f(sMin, 1.0f);
|
||||
glTexCoord2f(sMin, tMax);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glEnd();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifndef hifi_RenderUtil_h
|
||||
#define hifi_RenderUtil_h
|
||||
|
||||
/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, 0) to (sMax, 1).
|
||||
void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f);
|
||||
/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax).
|
||||
void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f);
|
||||
|
||||
#endif // hifi_RenderUtil_h
|
||||
|
|
|
@ -30,6 +30,7 @@ TextureCache::TextureCache() :
|
|||
_blueTextureID(0),
|
||||
_primaryDepthTextureID(0),
|
||||
_primaryNormalTextureID(0),
|
||||
_primarySpecularTextureID(0),
|
||||
_primaryFramebufferObject(NULL),
|
||||
_secondaryFramebufferObject(NULL),
|
||||
_tertiaryFramebufferObject(NULL),
|
||||
|
@ -48,6 +49,7 @@ TextureCache::~TextureCache() {
|
|||
if (_primaryFramebufferObject) {
|
||||
glDeleteTextures(1, &_primaryDepthTextureID);
|
||||
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||
glDeleteTextures(1, &_primarySpecularTextureID);
|
||||
}
|
||||
|
||||
if (_primaryFramebufferObject) {
|
||||
|
@ -75,6 +77,8 @@ void TextureCache::setFrameBufferSize(QSize frameBufferSize) {
|
|||
_primaryDepthTextureID = 0;
|
||||
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||
_primaryNormalTextureID = 0;
|
||||
glDeleteTextures(1, &_primarySpecularTextureID);
|
||||
_primarySpecularTextureID = 0;
|
||||
}
|
||||
|
||||
if (_secondaryFramebufferObject) {
|
||||
|
@ -222,9 +226,18 @@ QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenTextures(1, &_primarySpecularTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, _primarySpecularTextureID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameBufferSize.width(), _frameBufferSize.height(),
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_primaryFramebufferObject->bind();
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _primaryDepthTextureID, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _primaryNormalTextureID, 0);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, _primarySpecularTextureID, 0);
|
||||
_primaryFramebufferObject->release();
|
||||
}
|
||||
return _primaryFramebufferObject;
|
||||
|
@ -242,6 +255,26 @@ GLuint TextureCache::getPrimaryNormalTextureID() {
|
|||
return _primaryNormalTextureID;
|
||||
}
|
||||
|
||||
GLuint TextureCache::getPrimarySpecularTextureID() {
|
||||
getPrimaryFramebufferObject();
|
||||
return _primarySpecularTextureID;
|
||||
}
|
||||
|
||||
void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular) {
|
||||
GLenum buffers[3];
|
||||
int bufferCount = 0;
|
||||
if (color) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
if (normal) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
|
||||
}
|
||||
if (specular) {
|
||||
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
|
||||
}
|
||||
glDrawBuffers(bufferCount, buffers);
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
|
||||
if (!_secondaryFramebufferObject) {
|
||||
_secondaryFramebufferObject = createFramebufferObject();
|
||||
|
@ -296,6 +329,7 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
|
|||
_primaryFramebufferObject = NULL;
|
||||
glDeleteTextures(1, &_primaryDepthTextureID);
|
||||
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||
glDeleteTextures(1, &_primarySpecularTextureID);
|
||||
}
|
||||
if (_secondaryFramebufferObject && _secondaryFramebufferObject->size() != size) {
|
||||
delete _secondaryFramebufferObject;
|
||||
|
|
|
@ -64,6 +64,12 @@ public:
|
|||
/// Returns the ID of the primary framebuffer object's normal texture.
|
||||
GLuint getPrimaryNormalTextureID();
|
||||
|
||||
/// Returns the ID of the primary framebuffer object's specular texture.
|
||||
GLuint getPrimarySpecularTextureID();
|
||||
|
||||
/// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound.
|
||||
void setPrimaryDrawBuffers(bool color, bool normal = false, bool specular = false);
|
||||
|
||||
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
|
||||
/// screen effects.
|
||||
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
|
||||
|
@ -99,6 +105,7 @@ private:
|
|||
|
||||
GLuint _primaryDepthTextureID;
|
||||
GLuint _primaryNormalTextureID;
|
||||
GLuint _primarySpecularTextureID;
|
||||
QOpenGLFramebufferObject* _primaryFramebufferObject;
|
||||
QOpenGLFramebufferObject* _secondaryFramebufferObject;
|
||||
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
|
||||
|
|
|
@ -506,29 +506,13 @@ void VoxelSystem::initVoxelMemory() {
|
|||
_memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels);
|
||||
|
||||
// create our simple fragment shader if we're the first system to init
|
||||
if (!_shadowMapProgram.isLinked()) {
|
||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/shadow_map.vert");
|
||||
_shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/shadow_map.frag");
|
||||
_shadowMapProgram.link();
|
||||
|
||||
_shadowMapProgram.bind();
|
||||
_shadowMapProgram.setUniformValue("shadowMap", 0);
|
||||
_shadowMapProgram.release();
|
||||
|
||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/cascaded_shadow_map.vert");
|
||||
_cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/cascaded_shadow_map.frag");
|
||||
_cascadedShadowMapProgram.link();
|
||||
|
||||
_cascadedShadowMapProgram.bind();
|
||||
_cascadedShadowMapProgram.setUniformValue("shadowMap", 0);
|
||||
_shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances");
|
||||
_cascadedShadowMapProgram.release();
|
||||
if (!_program.isLinked()) {
|
||||
_program.addShaderFromSourceFile(QGLShader::Vertex,
|
||||
Application::resourcesPath() + "shaders/voxel.vert");
|
||||
_program.addShaderFromSourceFile(QGLShader::Fragment,
|
||||
Application::resourcesPath() + "shaders/voxel.frag");
|
||||
_program.link();
|
||||
}
|
||||
|
||||
}
|
||||
_renderer = new PrimitiveRenderer(_maxVoxels);
|
||||
|
||||
|
@ -1150,10 +1134,8 @@ glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float vo
|
|||
return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale;
|
||||
}
|
||||
|
||||
ProgramObject VoxelSystem::_program;
|
||||
ProgramObject VoxelSystem::_perlinModulateProgram;
|
||||
ProgramObject VoxelSystem::_shadowMapProgram;
|
||||
ProgramObject VoxelSystem::_cascadedShadowMapProgram;
|
||||
int VoxelSystem::_shadowDistancesLocation;
|
||||
|
||||
void VoxelSystem::init() {
|
||||
if (_initialized) {
|
||||
|
@ -1410,8 +1392,11 @@ void VoxelSystem::render() {
|
|||
|
||||
applyScaleAndBindProgram(texture);
|
||||
|
||||
// for performance, enable backface culling
|
||||
// for performance, enable backface culling and disable blending
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// draw voxels in 6 passes
|
||||
|
@ -1453,6 +1438,7 @@ void VoxelSystem::render() {
|
|||
PerformanceWarning warn(showWarnings, "render().. cleanup after glDrawRangeElementsEXT()...");
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
removeScaleAndReleaseProgram(texture);
|
||||
|
||||
|
@ -1478,41 +1464,31 @@ void VoxelSystem::render() {
|
|||
}
|
||||
|
||||
void VoxelSystem::applyScaleAndBindProgram(bool texture) {
|
||||
|
||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
_cascadedShadowMapProgram.bind();
|
||||
_cascadedShadowMapProgram.setUniform(_shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
||||
} else {
|
||||
_shadowMapProgram.bind();
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||
|
||||
} else if (texture) {
|
||||
if (texture) {
|
||||
bindPerlinModulateProgram();
|
||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID());
|
||||
} else {
|
||||
_program.bind();
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(_treeScale, _treeScale, _treeScale);
|
||||
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true);
|
||||
}
|
||||
|
||||
void VoxelSystem::removeScaleAndReleaseProgram(bool texture) {
|
||||
// scale back down to 1 so heads aren't massive
|
||||
glPopMatrix();
|
||||
|
||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||
_cascadedShadowMapProgram.release();
|
||||
} else {
|
||||
_shadowMapProgram.release();
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
} else if (texture) {
|
||||
if (texture) {
|
||||
_perlinModulateProgram.release();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
} else {
|
||||
_program.release();
|
||||
}
|
||||
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false);
|
||||
}
|
||||
|
||||
int VoxelSystem::_nodeCount = 0;
|
||||
|
|
|
@ -228,10 +228,8 @@ private:
|
|||
|
||||
bool _voxelsDirty;
|
||||
|
||||
static ProgramObject _program;
|
||||
static ProgramObject _perlinModulateProgram;
|
||||
static ProgramObject _shadowMapProgram;
|
||||
static ProgramObject _cascadedShadowMapProgram;
|
||||
static int _shadowDistancesLocation;
|
||||
|
||||
static void bindPerlinModulateProgram();
|
||||
|
||||
|
|
|
@ -656,6 +656,7 @@ class Material {
|
|||
public:
|
||||
glm::vec3 diffuse;
|
||||
glm::vec3 specular;
|
||||
glm::vec3 emissive;
|
||||
float shininess;
|
||||
float opacity;
|
||||
};
|
||||
|
@ -1281,7 +1282,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
textureContent.insert(filename, content);
|
||||
}
|
||||
} else if (object.name == "Material") {
|
||||
Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), 96.0f, 1.0f };
|
||||
Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(), 96.0f, 1.0f };
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
QByteArray propertyName;
|
||||
|
@ -1305,6 +1306,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
} else if (property.properties.at(0) == "SpecularColor") {
|
||||
material.specular = getVec3(property.properties, index);
|
||||
|
||||
} else if (property.properties.at(0) == "Emissive") {
|
||||
material.emissive = getVec3(property.properties, index);
|
||||
|
||||
} else if (property.properties.at(0) == "Shininess") {
|
||||
material.shininess = property.properties.at(index).value<double>();
|
||||
|
||||
|
@ -1605,6 +1609,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
FBXMeshPart& part = extracted.mesh.parts[j];
|
||||
part.diffuseColor = material.diffuse;
|
||||
part.specularColor = material.specular;
|
||||
part.emissiveColor = material.emissive;
|
||||
part.shininess = material.shininess;
|
||||
part.opacity = material.opacity;
|
||||
if (!diffuseTexture.filename.isNull()) {
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
|
||||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
glm::vec3 emissiveColor;
|
||||
float shininess;
|
||||
float opacity;
|
||||
|
||||
|
|
Loading…
Reference in a new issue