Merge remote-tracking branch 'upstream/master'
Conflicts: indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl indra/newview/app_settings/shaders/class1/deferred/giF.glsl indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
This commit is contained in:
@@ -155,6 +155,7 @@ set(viewer_SOURCE_FILES
|
||||
lldrawpoolavatar.cpp
|
||||
lldrawpoolbump.cpp
|
||||
lldrawpoolground.cpp
|
||||
lldrawpoolmaterials.cpp
|
||||
lldrawpoolsimple.cpp
|
||||
lldrawpoolsky.cpp
|
||||
lldrawpoolterrain.cpp
|
||||
@@ -671,6 +672,7 @@ set(viewer_HEADER_FILES
|
||||
lldrawpoolalpha.h
|
||||
lldrawpoolavatar.h
|
||||
lldrawpoolbump.h
|
||||
lldrawpoolmaterials.h
|
||||
lldrawpoolground.h
|
||||
lldrawpoolsimple.h
|
||||
lldrawpoolsky.h
|
||||
|
||||
@@ -25,31 +25,429 @@
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#define INDEXED 1
|
||||
#define NON_INDEXED 2
|
||||
#define NON_INDEXED_NO_COLOR 3
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
//uniform float display_gamma;
|
||||
uniform vec4 gamma;
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform float haze_horizon;
|
||||
uniform float haze_density;
|
||||
uniform float cloud_shadow;
|
||||
uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord);
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
#if HAS_SHADOW
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform float shadow_bias;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_DIFFUSE_TEX
|
||||
uniform sampler2D diffuseMap;
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
VARYING vec4 vertex_color;
|
||||
#endif
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
vec3 vary_SunlitColor;
|
||||
vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
a = pow(a, 1.0/1.3);
|
||||
return vec3(a,a,a);
|
||||
}
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = length(lv);
|
||||
|
||||
float da = 1.0;
|
||||
|
||||
vec3 col = vec3(0);
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist = d/la;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
|
||||
float lit = max(da * dist_atten,0.0);
|
||||
|
||||
col = light_col * lit * diffuse;
|
||||
|
||||
// no spec for alpha shader...
|
||||
}
|
||||
|
||||
return max(col, vec3(0.0,0.0,0.0));
|
||||
}
|
||||
|
||||
#if HAS_SHADOW
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
}
|
||||
vec3 getAmblitColor()
|
||||
{
|
||||
return vary_AmblitColor;
|
||||
}
|
||||
vec3 getAdditiveColor()
|
||||
{
|
||||
return vary_AdditiveColor;
|
||||
}
|
||||
vec3 getAtmosAttenuation()
|
||||
{
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
}
|
||||
|
||||
void setSunlitColor(vec3 v)
|
||||
{
|
||||
vary_SunlitColor = v;
|
||||
}
|
||||
|
||||
void setAmblitColor(vec3 v)
|
||||
{
|
||||
vary_AmblitColor = v;
|
||||
}
|
||||
|
||||
void setAdditiveColor(vec3 v)
|
||||
{
|
||||
vary_AdditiveColor = v;
|
||||
}
|
||||
|
||||
void setAtmosAttenuation(vec3 v)
|
||||
{
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
setPositionEye(P);
|
||||
|
||||
vec3 tmpLightnorm = lightnorm.xyz;
|
||||
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
vec4 temp1 = vec4(0);
|
||||
vec3 temp2 = vec3(0);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
//sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
//this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
//I had thought blue_density and haze_density should have equal weighting,
|
||||
//but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
temp1 = blue_density + vec4(haze_density);
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = vec4(haze_density) / temp1;
|
||||
|
||||
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
|
||||
temp2.y = max(0.0, tmpLightnorm.y);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// main atmospheric scattering line integral
|
||||
temp2.z = Plen * density_multiplier;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z * distance_multiplier);
|
||||
|
||||
//final atmosphere attenuation factor
|
||||
setAtmosAttenuation(temp1.rgb);
|
||||
|
||||
//compute haze glow
|
||||
//(can use temp2.x as temp because we haven't used it yet)
|
||||
temp2.x = dot(Pn, tmpLightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
//temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .03); //was glow.y
|
||||
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
//add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor();
|
||||
return (2.0 * light);
|
||||
}
|
||||
|
||||
vec3 atmosTransport(vec3 light) {
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
}
|
||||
|
||||
vec3 scaleDownLight(vec3 light)
|
||||
{
|
||||
return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 scaleUpLight(vec3 light)
|
||||
{
|
||||
return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 atmosAmbient(vec3 light)
|
||||
{
|
||||
return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity)
|
||||
{
|
||||
return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec3 ones = vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
light = ones - clamp(light, zeroes, ones);
|
||||
light = ones - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light) {
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
|
||||
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -58,16 +456,172 @@ void main()
|
||||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 diff= diffuseLookup(vary_texcoord0.xy);
|
||||
float shadow = 1.0;
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
|
||||
vec4 color = diff * col;
|
||||
#if HAS_SHADOW
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
shadow = 0.0;
|
||||
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
vec4 far_split = shadow_clip*-1.25;
|
||||
vec4 transition_domain = near_split-far_split;
|
||||
float weight = 0.0;
|
||||
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
weight += w;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap2, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
shadow += pcfShadow(shadowMap1, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
shadow += pcfShadow(shadowMap0, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
|
||||
shadow /= weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = 1.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_INDEXED_TEX
|
||||
vec4 diff = diffuseLookup(vary_texcoord0.xy);
|
||||
#else
|
||||
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
#endif
|
||||
|
||||
#ifdef FOR_IMPOSTOR
|
||||
vec4 color;
|
||||
color.rgb = diff.rgb;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
float final_alpha = diff.a * vertex_color.a;
|
||||
diff.rgb *= vertex_color.rgb;
|
||||
#else
|
||||
float final_alpha = diff.a;
|
||||
#endif
|
||||
|
||||
// Insure we don't pollute depth with invis pixels in impostor rendering
|
||||
//
|
||||
if (final_alpha < 0.01)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
float final_alpha = diff.a * vertex_color.a;
|
||||
diff.rgb *= vertex_color.rgb;
|
||||
#else
|
||||
float final_alpha = diff.a;
|
||||
#endif
|
||||
|
||||
|
||||
vec4 gamma_diff = diff;
|
||||
diff.rgb = srgb_to_linear(diff.rgb);
|
||||
|
||||
vec3 norm = vary_norm;
|
||||
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
norm.xyz = decode_normal(abnormal.xy);
|
||||
|
||||
float da = dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = da;
|
||||
final_da = min(final_da, shadow);
|
||||
final_da = max(final_da, 0.0f);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
vec4 color = vec4(0,0,0,0);
|
||||
|
||||
color.rgb = atmosAmbient(color.rgb);
|
||||
color.a = final_alpha;
|
||||
|
||||
float ambient = abs(da);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
color.rgb *= ambient;
|
||||
color.rgb += atmosAffectDirectionalLight(final_da);
|
||||
color.rgb *= gamma_diff.rgb;
|
||||
|
||||
//color.rgb = mix(diff.rgb, color.rgb, final_alpha);
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
vec4 light = vec4(0,0,0,0);
|
||||
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
LIGHT_LOOP(3)
|
||||
LIGHT_LOOP(4)
|
||||
LIGHT_LOOP(5)
|
||||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
// keep it linear
|
||||
//
|
||||
color.rgb += light.rgb;
|
||||
|
||||
// straight to display gamma, we're post-deferred
|
||||
//
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
color = applyWaterFogDeferred(pos.xyz, color);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @file alphaNonIndexedNoColorF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
|
||||
if (diff.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
|
||||
vec4 color = diff * col;
|
||||
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
/**
|
||||
* @file alphaSkinnedV.glsl
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
mat4 getObjectSkinnedTransform();
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
|
||||
uniform float near_clip;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vary_texcoord0 = texcoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getObjectSkinnedTransform();
|
||||
trans = modelview_matrix * trans;
|
||||
|
||||
pos = trans * vec4(position.xyz, 1.0);
|
||||
|
||||
norm = position.xyz + normal.xyz;
|
||||
norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz);
|
||||
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
|
||||
vary_position = pos.xyz;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*diffuse_color.rgb;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*diffuse_color.rgb;
|
||||
vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
|
||||
|
||||
col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
|
||||
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,126 +23,118 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#define INDEXED 1
|
||||
#define NON_INDEXED 2
|
||||
#define NON_INDEXED_NO_COLOR 3
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
#ifdef USE_INDEXED_TEX
|
||||
void passTextureIndex();
|
||||
#endif
|
||||
|
||||
ATTRIBUTE vec3 normal;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
#endif
|
||||
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
#ifdef HAS_SKIN
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
mat4 getSkinnedTransform();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
#endif
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
//transform vertex
|
||||
#ifdef HAS_SKIN
|
||||
mat4 trans = getObjectSkinnedTransform();
|
||||
trans = modelview_matrix * trans;
|
||||
|
||||
pos = trans * vec4(position.xyz, 1.0);
|
||||
|
||||
norm = position.xyz + normal.xyz;
|
||||
norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
#else
|
||||
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
mat4 trans = getSkinnedTransform();
|
||||
vec4 pos_in = vec4(position.xyz, 1.0);
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, normal);
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
#else
|
||||
norm = normalize(normal_matrix * normal);
|
||||
vec4 vert = vec4(position.xyz, 1.0);
|
||||
passTextureIndex();
|
||||
vec4 pos = (modelview_matrix * vert);
|
||||
pos = (modelview_matrix * vert);
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_INDEXED_TEX
|
||||
passTextureIndex();
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
#else
|
||||
vary_texcoord0 = texcoord0;
|
||||
#endif
|
||||
|
||||
vec3 norm = normalize(normal_matrix * normal);
|
||||
|
||||
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
|
||||
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
vary_norm = norm;
|
||||
vary_position = pos.xyz;
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
#ifdef USE_VERTEX_COLOR
|
||||
vertex_color = diffuse_color;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SKIN
|
||||
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
|
||||
#else
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*diffuse_color.rgb;
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*diffuse_color.rgb;
|
||||
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
|
||||
|
||||
col.rgb = col.rgb*diffuse_color.rgb;
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
|
||||
#ifdef IS_AVATAR_SKIN
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
#else
|
||||
pos = modelview_projection_matrix * vert;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,12 @@ void main()
|
||||
mat = modelview_matrix * mat;
|
||||
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
|
||||
|
||||
|
||||
vec4 p = projection_matrix * vec4(pos, 1.0);
|
||||
#if !DEPTH_CLAMP
|
||||
p.z = max(p.z, -p.w+0.01);
|
||||
gl_Position = p;
|
||||
#else
|
||||
gl_Position = p;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_norm;
|
||||
|
||||
|
||||
uniform float near_clip;
|
||||
@@ -112,6 +113,7 @@ void main()
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
vary_norm = norm;
|
||||
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @file avatarAlphaV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getSkinnedTransform();
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
|
||||
uniform float near_clip;
|
||||
|
||||
uniform vec4 color;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vary_texcoord0 = texcoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getSkinnedTransform();
|
||||
vec4 pos_in = vec4(position.xyz, 1.0);
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, normal);
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
vec4 frag_pos = projection_matrix * pos;
|
||||
gl_Position = frag_pos;
|
||||
|
||||
vary_position = pos.xyz;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*color.rgb;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*color.rgb;
|
||||
vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
|
||||
|
||||
col.rgb = col.rgb * color.rgb;
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
|
||||
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,25 +31,22 @@ out vec4 frag_data[3];
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
|
||||
if (diff.a < 0.2)
|
||||
if (diff.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
@@ -57,6 +54,6 @@ void main()
|
||||
frag_data[0] = vec4(diff.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,24 +64,28 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
vec4 ccol = texture2DRect(lightMap, tc).rgba;
|
||||
|
||||
@@ -39,15 +39,10 @@ VARYING vec3 vary_mat2;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -63,5 +58,5 @@ void main()
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
}
|
||||
|
||||
@@ -102,11 +102,6 @@ void main()
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -37,15 +37,10 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -60,6 +55,6 @@ void main()
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,10 @@ uniform float minimum_alpha;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -55,9 +50,9 @@ void main()
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn), 0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
@@ -37,15 +37,10 @@ uniform sampler2D diffuseMap;
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -60,6 +55,6 @@ void main()
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,10 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -53,6 +48,6 @@ void main()
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,24 +33,22 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
|
||||
|
||||
vec3 spec;
|
||||
spec.rgb = vec3(vertex_color.a);
|
||||
|
||||
frag_data[0] = vec4(col, 0.0);
|
||||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
frag_data[1] = vec4(spec, vertex_color.a); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ void main()
|
||||
float shadow = 1.0;
|
||||
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(2.2));
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
@@ -31,24 +31,147 @@ out vec4 frag_color;
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
#if !HAS_DIFFUSE_LOOKUP
|
||||
uniform sampler2D diffuseMap;
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransportDeferred(vec3 light)
|
||||
{
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClipDeferred(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
uniform float minimum_alpha;
|
||||
#endif
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
float shadow = 1.0;
|
||||
#if HAS_DIFFUSE_LOOKUP
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
#else
|
||||
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
#endif
|
||||
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
|
||||
float final_alpha = color.a * vertex_color.a;
|
||||
|
||||
#ifdef HAS_ALPHA_MASK
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
color.rgb = srgb_to_linear(color.rgb);
|
||||
color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
|
||||
color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
|
||||
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
color.rgb = linear_to_srgb(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
#ifdef WATER_FOG
|
||||
vec3 pos = vary_position;
|
||||
vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
|
||||
color.rgb = fogged.rgb;
|
||||
color.a = fogged.a;
|
||||
#else
|
||||
color.a = final_alpha;
|
||||
#endif
|
||||
|
||||
color.a = .0;
|
||||
frag_color = color;
|
||||
frag_color.rgb = color.rgb;
|
||||
frag_color.a = color.a;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file alphaF.glsl
|
||||
* @file fullbrightShinyF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
@@ -22,8 +22,6 @@
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
@@ -31,59 +29,42 @@ out vec4 frag_color;
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
#ifndef diffuseLookup
|
||||
uniform sampler2D diffuseMap;
|
||||
#endif
|
||||
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_texcoord1;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
vec3 fullbrightShinyAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
void main()
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
#if HAS_DIFFUSE_LOOKUP
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
#else
|
||||
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
color.rgb *= vertex_color.rgb;
|
||||
|
||||
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
|
||||
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
|
||||
vec4 color = diff * col;
|
||||
color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
color.a = 1.0;
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
color.rgb = pow(color.rgb, vec3(1.0/2.2));
|
||||
|
||||
frag_color = color;
|
||||
//frag_color = vec4(1,0,1,1);
|
||||
//frag_color = vec4(1,0,1,1)*shadow;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file fullbrightShinyV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 texture_matrix1;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
uniform vec4 origin;
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
void passTextureIndex();
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_texcoord1;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 vert = vec4(position.xyz,1.0);
|
||||
passTextureIndex();
|
||||
vec4 pos = (modelview_matrix * vert);
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
|
||||
vec3 norm = normalize(normal_matrix * normal);
|
||||
vec3 ref = reflect(pos.xyz, -norm);
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
}
|
||||
@@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
VARYING vec3 vary_position;
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
@@ -53,11 +56,15 @@ void main()
|
||||
passTextureIndex();
|
||||
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vary_position = pos.xyz;
|
||||
#endif
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
/**
|
||||
* @file giF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2D noiseMap;
|
||||
|
||||
uniform sampler2D diffuseGIMap;
|
||||
uniform sampler2D normalGIMap;
|
||||
uniform sampler2D depthGIMap;
|
||||
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
// Inputs
|
||||
VARYING vec2 vary_fragcoord;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space
|
||||
uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space
|
||||
uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix
|
||||
uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space
|
||||
uniform float gi_radius;
|
||||
uniform float gi_intensity;
|
||||
uniform int gi_samples;
|
||||
uniform vec2 gi_kern[25];
|
||||
uniform vec2 gi_scale;
|
||||
uniform vec3 gi_quad;
|
||||
uniform vec3 gi_spec;
|
||||
uniform float gi_direction_weight;
|
||||
uniform float gi_light_offset;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec4 getGIPosition(vec2 gi_tc)
|
||||
{
|
||||
float depth = texture2D(depthGIMap, gi_tc).a;
|
||||
vec2 sc = gi_tc*2.0;
|
||||
sc -= vec2(1.0, 1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = gi_inv_proj*ndc;
|
||||
pos.xyz /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 giAmbient(vec3 pos, vec3 norm)
|
||||
{
|
||||
vec4 gi_c = gi_mat_proj * vec4(pos, 1.0);
|
||||
gi_c.xyz /= gi_c.w;
|
||||
|
||||
vec4 gi_pos = gi_mat*vec4(pos,1.0);
|
||||
vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz;
|
||||
gi_norm = normalize(gi_norm);
|
||||
|
||||
vec2 tcx = gi_norm.xy;
|
||||
vec2 tcy = gi_norm.yx;
|
||||
|
||||
vec4 eye_pos = gi_mat*vec4(0,0,0,1.0);
|
||||
|
||||
vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w);
|
||||
|
||||
//vec3 eye_dir = vec3(0,0,-1);
|
||||
//eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz;
|
||||
//eye_dir = normalize(eye_dir);
|
||||
|
||||
//float round_x = gi_scale.x;
|
||||
//float round_y = gi_scale.y;
|
||||
|
||||
vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5;
|
||||
debug.xz = vec2(0.0,0.0);
|
||||
//debug = fract(debug);
|
||||
|
||||
float round_x = 1.0/64.0;
|
||||
float round_y = 1.0/64.0;
|
||||
|
||||
//gi_c.x = floor(gi_c.x/round_x+0.5)*round_x;
|
||||
//gi_c.y = floor(gi_c.y/round_y+0.5)*round_y;
|
||||
|
||||
float fda = 0.0;
|
||||
vec3 fdiff = vec3(0,0,0);
|
||||
|
||||
vec3 rcol = vec3(0,0,0);
|
||||
|
||||
float fsa = 0.0;
|
||||
|
||||
for (int i = -1; i < 2; i+=2 )
|
||||
{
|
||||
for (int j = -1; j < 2; j+=2)
|
||||
{
|
||||
vec2 tc = vec2(i, j)*0.75;
|
||||
vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz;
|
||||
//tc += gi_norm.xy*nz.z;
|
||||
tc += nz.xy*2.0;
|
||||
tc /= gi_samples;
|
||||
tc += gi_c.xy;
|
||||
|
||||
vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0);
|
||||
vec3 lpos = getGIPosition(tc.xy).xyz;
|
||||
|
||||
vec3 at = lpos-gi_pos.xyz;
|
||||
float dist = dot(at,at);
|
||||
float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0);
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
//add angular attenuation
|
||||
vec3 ldir = at;
|
||||
float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0);
|
||||
|
||||
float ld = -dot(ldir, lnorm);
|
||||
|
||||
if (ang_atten > 0.0 && ld < 0.0)
|
||||
{
|
||||
vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz;
|
||||
da = da*ang_atten;
|
||||
fda += da;
|
||||
fdiff += diff*da;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fdiff /= max(gi_spec.y*fda, gi_quad.z);
|
||||
fdiff = clamp(fdiff, vec3(0), vec3(1));
|
||||
|
||||
vec3 ret = fda*fdiff;
|
||||
//ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z;
|
||||
|
||||
//fda *= nz.z;
|
||||
|
||||
//rcol.rgb *= gi_intensity;
|
||||
//return rcol.rgb+vary_AmblitColor.rgb*0.25;
|
||||
//return vec4(debug, 0.0);
|
||||
//return vec4(fda*fdiff, 0.0);
|
||||
return clamp(ret,vec3(0.0), vec3(1.0));
|
||||
//return debug.xyz;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
|
||||
frag_color.xyz = giAmbient(pos, norm);
|
||||
}
|
||||
@@ -38,6 +38,42 @@ uniform sampler2D specularMap;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
@@ -47,7 +83,12 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
frag_data[0] = vec4(col.rgb, col.a * 0.005);
|
||||
frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
|
||||
frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
|
||||
vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
|
||||
vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
|
||||
|
||||
col.rgb = linear_to_srgb(col.rgb);
|
||||
|
||||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = spec;
|
||||
frag_data[2] = vec4(norm.xy,0,0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,788 @@
|
||||
/**
|
||||
* @file materialF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#define DIFFUSE_ALPHA_MODE_IGNORE 0
|
||||
#define DIFFUSE_ALPHA_MODE_BLEND 1
|
||||
#define DIFFUSE_ALPHA_MODE_MASK 2
|
||||
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
|
||||
|
||||
uniform float emissive_brightness;
|
||||
//uniform float display_gamma;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
#if HAS_SUN_SHADOW
|
||||
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 shadow_res;
|
||||
uniform float shadow_bias;
|
||||
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
// Inputs
|
||||
uniform vec4 morphFactor;
|
||||
uniform vec3 camPosLocal;
|
||||
//uniform vec4 camPosWorld;
|
||||
uniform vec4 gamma;
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 ambient;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform float haze_horizon;
|
||||
uniform float haze_density;
|
||||
uniform float cloud_shadow;
|
||||
uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform mat3 ssao_effect_mat;
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
VARYING vec2 vary_fragcoord;
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
|
||||
vec3 vary_SunlitColor;
|
||||
vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return vec3(a,a,a);
|
||||
}
|
||||
|
||||
|
||||
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = length(lv);
|
||||
|
||||
float da = 1.0;
|
||||
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist = d/la;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
|
||||
float lit = max(da * dist_atten, 0.0);
|
||||
|
||||
col = light_col*lit*diffuse;
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(n, h);
|
||||
float nv = dot(n, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
|
||||
col += speccol;
|
||||
|
||||
float cur_glare = max(speccol.r, speccol.g);
|
||||
cur_glare = max(cur_glare, speccol.b);
|
||||
glare = max(glare, speccol.r);
|
||||
glare += max(cur_glare, 0.0);
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max(col, vec3(0.0,0.0,0.0));
|
||||
|
||||
}
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
{
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
#ifndef WATER_FOG
|
||||
vec3 getPositionEye()
|
||||
{
|
||||
return vary_PositionEye;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 getSunlitColor()
|
||||
{
|
||||
return vary_SunlitColor;
|
||||
}
|
||||
vec3 getAmblitColor()
|
||||
{
|
||||
return vary_AmblitColor;
|
||||
}
|
||||
vec3 getAdditiveColor()
|
||||
{
|
||||
return vary_AdditiveColor;
|
||||
}
|
||||
vec3 getAtmosAttenuation()
|
||||
{
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
}
|
||||
|
||||
void setSunlitColor(vec3 v)
|
||||
{
|
||||
vary_SunlitColor = v;
|
||||
}
|
||||
|
||||
void setAmblitColor(vec3 v)
|
||||
{
|
||||
vary_AmblitColor = v;
|
||||
}
|
||||
|
||||
void setAdditiveColor(vec3 v)
|
||||
{
|
||||
vary_AdditiveColor = v;
|
||||
}
|
||||
|
||||
void setAtmosAttenuation(vec3 v)
|
||||
{
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
setPositionEye(P);
|
||||
|
||||
vec3 tmpLightnorm = lightnorm.xyz;
|
||||
|
||||
vec3 Pn = normalize(P);
|
||||
float Plen = length(P);
|
||||
|
||||
vec4 temp1 = vec4(0);
|
||||
vec3 temp2 = vec3(0);
|
||||
vec4 blue_weight;
|
||||
vec4 haze_weight;
|
||||
vec4 sunlight = sunlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
//sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
//this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
//I had thought blue_density and haze_density should have equal weighting,
|
||||
//but attenuation due to haze_density tends to seem too strong
|
||||
|
||||
temp1 = blue_density + vec4(haze_density);
|
||||
blue_weight = blue_density / temp1;
|
||||
haze_weight = vec4(haze_density) / temp1;
|
||||
|
||||
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
|
||||
temp2.y = max(0.0, tmpLightnorm.y);
|
||||
temp2.y = 1. / temp2.y;
|
||||
sunlight *= exp( - light_atten * temp2.y);
|
||||
|
||||
// main atmospheric scattering line integral
|
||||
temp2.z = Plen * density_multiplier;
|
||||
|
||||
// Transparency (-> temp1)
|
||||
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
|
||||
// compiler gets confused.
|
||||
temp1 = exp(-temp1 * temp2.z * distance_multiplier);
|
||||
|
||||
//final atmosphere attenuation factor
|
||||
setAtmosAttenuation(temp1.rgb);
|
||||
|
||||
//compute haze glow
|
||||
//(can use temp2.x as temp because we haven't used it yet)
|
||||
temp2.x = dot(Pn, tmpLightnorm.xyz);
|
||||
temp2.x = 1. - temp2.x;
|
||||
//temp2.x is 0 at the sun and increases away from sun
|
||||
temp2.x = max(temp2.x, .03); //was glow.y
|
||||
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
temp2.x *= glow.x;
|
||||
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
temp2.x = pow(temp2.x, glow.z);
|
||||
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
//add "minimum anti-solar illumination"
|
||||
temp2.x += .25;
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
|
||||
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
|
||||
* // The following line of code performs the equivalent of:
|
||||
* float ambAlpha = tmpAmbient.a;
|
||||
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
|
||||
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
|
||||
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
|
||||
*/
|
||||
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
|
||||
+ tmpAmbient)));
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor();
|
||||
return (2.0 * light);
|
||||
}
|
||||
|
||||
vec3 atmosTransport(vec3 light) {
|
||||
light *= getAtmosAttenuation().r;
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
}
|
||||
|
||||
vec3 scaleDownLight(vec3 light)
|
||||
{
|
||||
return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 scaleUpLight(vec3 light)
|
||||
{
|
||||
return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
|
||||
}
|
||||
|
||||
vec3 atmosAmbient(vec3 light)
|
||||
{
|
||||
return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
|
||||
}
|
||||
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity)
|
||||
{
|
||||
return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
|
||||
}
|
||||
|
||||
vec3 scaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
|
||||
vec3 ones = vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
light = ones - clamp(light, zeroes, ones);
|
||||
light = ones - pow(light, gamma.xxx);
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light) {
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
|
||||
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
|
||||
}
|
||||
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
#else
|
||||
#define frag_data gl_FragData
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
#if HAS_NORMAL_MAP
|
||||
uniform sampler2D bumpMap;
|
||||
#endif
|
||||
|
||||
#if HAS_SPECULAR_MAP
|
||||
uniform sampler2D specularMap;
|
||||
|
||||
VARYING vec2 vary_texcoord2;
|
||||
#endif
|
||||
|
||||
uniform float env_intensity;
|
||||
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
|
||||
uniform float minimum_alpha;
|
||||
#endif
|
||||
|
||||
#if HAS_NORMAL_MAP
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#else
|
||||
VARYING vec3 vary_normal;
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
|
||||
diffcol.rgb *= vertex_color.rgb;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (diffcol.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
vec3 gamma_diff = diffcol.rgb;
|
||||
diffcol.rgb = srgb_to_linear(diffcol.rgb);
|
||||
#endif
|
||||
|
||||
#if HAS_SPECULAR_MAP
|
||||
vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
|
||||
spec.rgb *= specular_color.rgb;
|
||||
#else
|
||||
vec4 spec = vec4(specular_color.rgb, 1.0);
|
||||
#endif
|
||||
|
||||
#if HAS_NORMAL_MAP
|
||||
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
|
||||
|
||||
norm.xyz = norm.xyz * 2 - 1;
|
||||
|
||||
vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
|
||||
dot(norm.xyz,vary_mat1),
|
||||
dot(norm.xyz,vary_mat2));
|
||||
#else
|
||||
vec4 norm = vec4(0,0,0,1.0);
|
||||
vec3 tnorm = vary_normal;
|
||||
#endif
|
||||
|
||||
norm.xyz = tnorm;
|
||||
norm.xyz = normalize(norm.xyz);
|
||||
|
||||
vec2 abnormal = encode_normal(norm.xyz);
|
||||
norm.xyz = decode_normal(abnormal.xy);
|
||||
|
||||
vec4 final_color = diffcol;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
|
||||
final_color.a = emissive_brightness;
|
||||
#else
|
||||
final_color.a = max(final_color.a, emissive_brightness);
|
||||
#endif
|
||||
|
||||
vec4 final_specular = spec;
|
||||
#if HAS_SPECULAR_MAP
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
|
||||
final_specular.a = specular_color.a * norm.a;
|
||||
#else
|
||||
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
|
||||
final_specular.a = specular_color.a;
|
||||
#endif
|
||||
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
//forward rendering, output just lit RGBA
|
||||
vec3 pos = vary_position;
|
||||
|
||||
#if HAS_SUN_SHADOW
|
||||
float shadow = 0.0;
|
||||
|
||||
vec4 spos = vec4(pos,1.0);
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
vec4 far_split = shadow_clip*-1.25;
|
||||
vec4 transition_domain = near_split-far_split;
|
||||
float weight = 0.0;
|
||||
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
weight += w;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap2, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
shadow += pcfShadow(shadowMap1, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
shadow += pcfShadow(shadowMap0, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
|
||||
shadow /= weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = 1.0;
|
||||
}
|
||||
#else
|
||||
float shadow = 1.0;
|
||||
#endif
|
||||
|
||||
spec = final_specular;
|
||||
vec4 diffuse = final_color;
|
||||
float envIntensity = final_normal.z;
|
||||
|
||||
vec3 col = vec3(0.0f,0.0f,0.0f);
|
||||
|
||||
float bloom = 0.0;
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
float da =dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = da;
|
||||
final_da = min(final_da, shadow);
|
||||
//final_da = max(final_da, diffuse.a);
|
||||
final_da = max(final_da, 0.0f);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
col.rgb = atmosAmbient(col);
|
||||
|
||||
float ambient = min(abs(da), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
|
||||
|
||||
col.rgb *= gamma_diff.rgb;
|
||||
|
||||
|
||||
float glare = 0.0;
|
||||
|
||||
if (spec.a > 0.0) // specular reflection
|
||||
{
|
||||
// the old infinite-sky shiny reflection
|
||||
//
|
||||
|
||||
float sa = dot(refnormpersp, sun_dir.xyz);
|
||||
vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
|
||||
|
||||
// add the two types of shiny together
|
||||
vec3 spec_contrib = dumbshiny * spec.rgb;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 6;
|
||||
|
||||
glare = max(spec_contrib.r, spec_contrib.g);
|
||||
glare = max(glare, spec_contrib.b);
|
||||
|
||||
col += spec_contrib;
|
||||
}
|
||||
|
||||
|
||||
col = mix(col.rgb, diffcol.rgb, diffuse.a);
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
//add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
|
||||
vec3 refcol = textureCube(environmentMap, env_vec).rgb;
|
||||
|
||||
col = mix(col.rgb, refcol,
|
||||
envIntensity);
|
||||
|
||||
float cur_glare = max(refcol.r, refcol.g);
|
||||
cur_glare = max(cur_glare, refcol.b);
|
||||
cur_glare *= envIntensity*4.0;
|
||||
glare += cur_glare;
|
||||
}
|
||||
|
||||
//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
|
||||
//convert to linear space before adding local lights
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
vec3 npos = normalize(-pos.xyz);
|
||||
|
||||
vec3 light = vec3(0,0,0);
|
||||
|
||||
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
|
||||
|
||||
LIGHT_LOOP(1)
|
||||
LIGHT_LOOP(2)
|
||||
LIGHT_LOOP(3)
|
||||
LIGHT_LOOP(4)
|
||||
LIGHT_LOOP(5)
|
||||
LIGHT_LOOP(6)
|
||||
LIGHT_LOOP(7)
|
||||
|
||||
col.rgb += light.rgb;
|
||||
|
||||
glare = min(glare, 1.0);
|
||||
float al = max(diffcol.a,glare)*vertex_color.a;
|
||||
|
||||
//convert to gamma space for display on screen
|
||||
col.rgb = linear_to_srgb(col.rgb);
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
|
||||
col.rgb = temp.rgb;
|
||||
al = temp.a;
|
||||
#endif
|
||||
|
||||
frag_color.rgb = col.rgb;
|
||||
frag_color.a = al;
|
||||
|
||||
#else
|
||||
frag_data[0] = final_color;
|
||||
frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
|
||||
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file bumpV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#define DIFFUSE_ALPHA_MODE_IGNORE 0
|
||||
#define DIFFUSE_ALPHA_MODE_BLEND 1
|
||||
#define DIFFUSE_ALPHA_MODE_MASK 2
|
||||
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
|
||||
|
||||
#if HAS_SKIN
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
mat4 getObjectSkinnedTransform();
|
||||
#else
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
#endif
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
|
||||
#if !HAS_SKIN
|
||||
uniform mat4 modelview_matrix;
|
||||
#endif
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
|
||||
#endif
|
||||
|
||||
uniform mat4 texture_matrix0;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
|
||||
#if HAS_NORMAL_MAP
|
||||
ATTRIBUTE vec4 tangent;
|
||||
ATTRIBUTE vec2 texcoord1;
|
||||
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#else
|
||||
VARYING vec3 vary_normal;
|
||||
#endif
|
||||
|
||||
#if HAS_SPECULAR_MAP
|
||||
ATTRIBUTE vec2 texcoord2;
|
||||
VARYING vec2 vary_texcoord2;
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void main()
|
||||
{
|
||||
#if HAS_SKIN
|
||||
mat4 mat = getObjectSkinnedTransform();
|
||||
|
||||
mat = modelview_matrix * mat;
|
||||
|
||||
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
vary_position = pos;
|
||||
#endif
|
||||
|
||||
gl_Position = projection_matrix*vec4(pos,1.0);
|
||||
|
||||
#else
|
||||
//transform vertex
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
|
||||
#endif
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
#if HAS_NORMAL_MAP
|
||||
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
|
||||
#endif
|
||||
|
||||
#if HAS_SPECULAR_MAP
|
||||
vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
|
||||
#endif
|
||||
|
||||
#if HAS_SKIN
|
||||
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
#if HAS_NORMAL_MAP
|
||||
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
vec3 b = cross(n, t)*tangent.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
#else //HAS_SKIN
|
||||
vec3 n = normalize(normal_matrix * normal);
|
||||
#if HAS_NORMAL_MAP
|
||||
vec3 t = normalize(normal_matrix * tangent.xyz);
|
||||
vec3 b = cross(n,t)*tangent.w;
|
||||
//vec3 t = cross(b,n) * binormal.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
#endif //HAS_SKIN
|
||||
|
||||
vertex_color = diffuse_color;
|
||||
|
||||
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
|
||||
#if !HAS_SKIN
|
||||
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -45,9 +45,8 @@ uniform float sun_wash;
|
||||
|
||||
uniform int light_count;
|
||||
|
||||
#define MAX_LIGHT_COUNT 16
|
||||
uniform vec4 light[MAX_LIGHT_COUNT];
|
||||
uniform vec4 light_col[MAX_LIGHT_COUNT];
|
||||
uniform vec4 light[LIGHT_COUNT];
|
||||
uniform vec4 light_col[LIGHT_COUNT];
|
||||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
@@ -56,6 +55,23 @@ uniform float far_z;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
@@ -69,20 +85,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
|
||||
@@ -92,70 +94,71 @@ void main()
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = decode_normal(norm.xy); // unpack norm
|
||||
norm = normalize(norm);
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
vec3 out_col = vec3(0,0,0);
|
||||
vec3 npos = normalize(-pos);
|
||||
|
||||
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
|
||||
for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
|
||||
for (int i = 0; i < LIGHT_COUNT; ++i)
|
||||
{
|
||||
bool light_contrib = (i < light_count);
|
||||
|
||||
vec3 lv = light[i].xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= light[i].w;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= light[i].w;
|
||||
if (dist <= 1.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
light_contrib = false;
|
||||
}
|
||||
|
||||
if (light_contrib)
|
||||
if (da > 0.0)
|
||||
{
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
|
||||
float fa = light_col[i].a+1.0;
|
||||
float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
|
||||
|
||||
vec3 col = light_col[i].rgb*lit*diff;
|
||||
|
||||
//vec3 col = vec3(dist2, light_col[i].a, lit);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
lit = min(da*6.0, 1.0) * dist_atten;
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
|
||||
float sa = dot(normalize(lv+npos),norm);
|
||||
|
||||
if (sa > 0.0)
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*light_col[i].rgb*spec.rgb;
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += lit*scol*light_col[i].rgb*spec.rgb;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
out_col += col;
|
||||
}
|
||||
}
|
||||
|
||||
if (dot(out_col, out_col) <= 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
frag_color.rgb = out_col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ out vec4 frag_color;
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
@@ -40,6 +41,7 @@ uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D projectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
@@ -66,9 +68,64 @@ uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -84,6 +141,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
|
||||
|
||||
@@ -101,6 +159,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret.rgb = srgb_to_linear(ret.rgb);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -125,20 +184,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -148,16 +193,19 @@ void main()
|
||||
|
||||
vec3 pos = getPosition(frag.xy).xyz;
|
||||
vec3 lv = center.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= size;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= size;
|
||||
if (dist > 1.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
float envIntensity = norm.z;
|
||||
|
||||
norm = decode_normal(norm.xy);
|
||||
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
@@ -169,7 +217,10 @@ void main()
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
if (dist_atten <= 0.0)
|
||||
{
|
||||
discard;
|
||||
@@ -182,7 +233,8 @@ void main()
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
vec3 dlit = vec3(0, 0, 0);
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
@@ -200,14 +252,13 @@ void main()
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
|
||||
dlit = color.rgb * plcol.rgb * plcol.a;
|
||||
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
col = lcol*lit*diff_tex;
|
||||
col = dlit*lit*diff_tex;
|
||||
amb_da += (da*0.5)*proj_ambiance;
|
||||
}
|
||||
|
||||
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
|
||||
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
|
||||
|
||||
@@ -216,13 +267,38 @@ void main()
|
||||
amb_da *= dist_atten * noise;
|
||||
|
||||
amb_da = min(amb_da, 1.0-lit);
|
||||
|
||||
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
|
||||
col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
|
||||
vec3 npos = -normalize(pos);
|
||||
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += dlit*scol*spec.rgb;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
@@ -235,12 +311,10 @@ void main()
|
||||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
|
||||
stc /= stc.w;
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
|
||||
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
|
||||
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
@@ -249,8 +323,7 @@ void main()
|
||||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,23 @@ uniform vec2 screen_res;
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec4 viewport;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
@@ -67,20 +84,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -90,21 +93,22 @@ void main()
|
||||
|
||||
vec3 pos = getPosition(frag.xy).xyz;
|
||||
vec3 lv = trans_center.xyz-pos;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= size;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= size;
|
||||
if (dist > 1.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = decode_normal(norm.xy); // unpack norm
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
norm = normalize(norm);
|
||||
lv = normalize(lv);
|
||||
da = dot(norm, lv);
|
||||
|
||||
@@ -112,20 +116,33 @@ void main()
|
||||
|
||||
vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
float lit = da * dist_atten * noise;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
float lit = da * dist_atten * noise;
|
||||
|
||||
col = color.rgb*lit*col;
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
float sa = dot(normalize(lv-normalize(pos)),norm);
|
||||
if (sa > 0.0)
|
||||
lit = min(da*6.0, 1.0) * dist_atten;
|
||||
|
||||
vec3 npos = -normalize(pos);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
|
||||
sa *= noise;
|
||||
col += da*sa*color.rgb*spec.rgb;
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += lit*scol*color.rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ VARYING vec3 trans_center;
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec3 p = position*sqrt(size)+center;
|
||||
vec3 p = position*size+center;
|
||||
vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
|
||||
vary_fragcoord = pos;
|
||||
trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file postDeferredGammaCorrect.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
VARYING vec2 vary_fragcoord;
|
||||
|
||||
//uniform float display_gamma;
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
|
||||
diff.rgb = linear_to_srgb(diff.rgb);
|
||||
frag_color = diff;
|
||||
}
|
||||
|
||||
@@ -61,11 +61,7 @@ void main()
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
|
||||
frag_data[1] = vec4(vary_HazeColor.a,0.0,0.0,0.0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,1.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
@@ -60,6 +61,7 @@ uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float global_gamma;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform float ssao_effect;
|
||||
@@ -77,6 +79,54 @@ vec3 vary_AtmosAttenuation;
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
{
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
@@ -142,6 +192,52 @@ void setAtmosAttenuation(vec3 v)
|
||||
vary_AtmosAttenuation = v;
|
||||
}
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
vec3 P = inPositionEye;
|
||||
@@ -230,6 +326,15 @@ vec3 atmosTransport(vec3 light) {
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light) {
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
|
||||
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
@@ -264,18 +369,10 @@ vec3 scaleSoftClip(vec3 light)
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
float luminance(vec3 color)
|
||||
@@ -290,57 +387,95 @@ void main()
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
vec4 norm = texture2DRect(normalMap, tc);
|
||||
float envIntensity = norm.z;
|
||||
norm.xyz = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
float da = dot(norm.xyz, sun_dir.xyz);
|
||||
|
||||
float final_da = max(0.0,da);
|
||||
final_da = min(final_da, 1.0f);
|
||||
final_da = pow(final_da, 1.0/1.3);
|
||||
|
||||
vec4 diffuse = texture2DRect(diffuseRect, tc);
|
||||
|
||||
//convert to gamma space
|
||||
diffuse.rgb = linear_to_srgb(diffuse.rgb);
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
|
||||
|
||||
vec3 col;
|
||||
float bloom = 0.0;
|
||||
if (diffuse.a < 0.9)
|
||||
{
|
||||
bloom = spec.r*norm.w;
|
||||
if (norm.w < 0.5)
|
||||
{
|
||||
calcAtmospherics(pos.xyz, 1.0);
|
||||
|
||||
col = atmosAmbient(vec3(0));
|
||||
col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
|
||||
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
col += atmosAffectDirectionalLight(final_da);
|
||||
|
||||
col *= diffuse.rgb;
|
||||
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
if (spec.a > 0.0) // specular reflection
|
||||
{
|
||||
// the old infinite-sky shiny reflection
|
||||
//
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
float sa = dot(refnormpersp, sun_dir.xyz);
|
||||
vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
|
||||
|
||||
// add the two types of shiny together
|
||||
vec3 spec_contrib = dumbshiny * spec.rgb;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 4;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 6;
|
||||
col += spec_contrib;
|
||||
|
||||
//add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
vec3 env = textureCube(environmentMap, env_vec).rgb;
|
||||
bloom = (luminance(env) - .45)*.25;
|
||||
col = mix(col.rgb, env,
|
||||
max(spec.a-diffuse.a*2.0, 0.0));
|
||||
}
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
|
||||
|
||||
col = mix(col.rgb, diffuse.rgb, diffuse.a);
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{ //add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
vec3 refcol = textureCube(environmentMap, env_vec).rgb;
|
||||
bloom = (luminance(refcol) - .45)*.25;
|
||||
col = mix(col.rgb, refcol,
|
||||
envIntensity);
|
||||
}
|
||||
|
||||
//if (norm.w < 0.5)
|
||||
{
|
||||
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
//bloom += (luminance(col))*.075; //This looks nice, but requires a larger glow rendertarget.
|
||||
}
|
||||
|
||||
col = mix(col, diffuse.rgb, diffuse.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
bloom = spec.r;
|
||||
col = diffuse.rgb;
|
||||
#ifdef WATER_FOG
|
||||
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
|
||||
col = fogged.rgb;
|
||||
bloom = fogged.a;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
col = diffuse.rgb;
|
||||
}
|
||||
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
//col = vec3(1,0,1);
|
||||
//col.g = envIntensity;
|
||||
}
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.rgb = col.rgb;
|
||||
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
@@ -32,8 +34,6 @@ out vec4 frag_color;
|
||||
|
||||
//class 1 -- no shadows
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect diffuseRect;
|
||||
uniform sampler2DRect specularRect;
|
||||
uniform sampler2DRect depthMap;
|
||||
@@ -41,6 +41,7 @@ uniform sampler2DRect normalMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D projectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
@@ -57,20 +58,79 @@ uniform float far_clip;
|
||||
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
|
||||
uniform float sun_wash;
|
||||
|
||||
uniform float size;
|
||||
uniform vec3 color;
|
||||
uniform float falloff;
|
||||
uniform float size;
|
||||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
VARYING vec3 trans_center;
|
||||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -86,6 +146,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
|
||||
|
||||
@@ -103,6 +164,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -127,20 +189,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -150,16 +198,19 @@ void main()
|
||||
|
||||
vec3 pos = getPosition(frag.xy).xyz;
|
||||
vec3 lv = trans_center.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= size;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= size;
|
||||
if (dist > 1.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
float envIntensity = norm.z;
|
||||
norm = decode_normal(norm.xy);
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
@@ -171,7 +222,10 @@ void main()
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
if (dist_atten <= 0.0)
|
||||
{
|
||||
discard;
|
||||
@@ -185,31 +239,35 @@ void main()
|
||||
|
||||
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
vec3 dlit = vec3(0, 0, 0);
|
||||
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
proj_tc.y < 1.0 &&
|
||||
proj_tc.x > 0.0 &&
|
||||
proj_tc.y > 0.0)
|
||||
{
|
||||
float lit = 0.0;
|
||||
float amb_da = proj_ambiance;
|
||||
float lit = 0.0;
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
|
||||
dlit = color.rgb * plcol.rgb * plcol.a;
|
||||
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
col = lcol*lit*diff_tex;
|
||||
amb_da += (da*0.5)*proj_ambiance;
|
||||
col = dlit*lit*diff_tex;
|
||||
//amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
|
||||
}
|
||||
|
||||
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
|
||||
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
|
||||
|
||||
@@ -218,13 +276,37 @@ void main()
|
||||
amb_da *= dist_atten * noise;
|
||||
|
||||
amb_da = min(amb_da, 1.0-lit);
|
||||
|
||||
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
|
||||
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
vec3 npos = -normalize(pos);
|
||||
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += dlit*scol*spec.rgb;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
@@ -242,8 +324,9 @@ void main()
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
|
||||
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
|
||||
|
||||
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
if (stc.x < 1.0 &&
|
||||
@@ -251,8 +334,7 @@ void main()
|
||||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
Normal file
46
indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file srgb.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
return mix(high_range, low_range, lte);
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
return mix(high_range, low_range, lt);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file srgb.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -42,10 +42,5 @@ void main()
|
||||
|
||||
frag_data[0] = vec4(col.rgb,col.a*custom_alpha);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
|
||||
#else
|
||||
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
|
||||
#endif
|
||||
frag_data[2] = vec4(0.5,0.5,0.0,1.0);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,23 @@ VARYING vec2 vary_fragcoord;
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
@@ -115,19 +132,6 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
return (rtn * rtn);
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
@@ -136,7 +140,8 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec3 norm = unpack(pos_screen); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = decode_normal(norm.xy);
|
||||
|
||||
frag_color[0] = 1.0;
|
||||
frag_color[1] = calcAmbientOcclusion(pos, norm);
|
||||
|
||||
@@ -39,15 +39,10 @@ VARYING vec3 vary_normal;
|
||||
VARYING vec4 vary_texcoord0;
|
||||
VARYING vec4 vary_texcoord1;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -67,6 +62,6 @@ void main()
|
||||
frag_data[0] = vec4(outColor.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,15 +37,10 @@ VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
#endif
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -59,5 +54,5 @@ void main()
|
||||
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(pack(nvn),0.0);
|
||||
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @file underWaterF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
#else
|
||||
#define frag_data gl_FragData
|
||||
#endif
|
||||
|
||||
uniform sampler2D diffuseMap;
|
||||
uniform sampler2D bumpMap;
|
||||
uniform sampler2D screenTex;
|
||||
uniform sampler2D refTex;
|
||||
uniform sampler2D screenDepth;
|
||||
|
||||
uniform vec4 fogCol;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 specular;
|
||||
uniform float lightExp;
|
||||
uniform vec2 fbScale;
|
||||
uniform float refScale;
|
||||
uniform float znear;
|
||||
uniform float zfar;
|
||||
uniform float kd;
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec3 eyeVec;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
uniform vec2 screenRes;
|
||||
|
||||
//bigWave is (refCoord.w, view.w);
|
||||
VARYING vec4 refCoord;
|
||||
VARYING vec4 littleWave;
|
||||
VARYING vec4 view;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec4 applyWaterFog(vec4 color, vec3 viewVec)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(viewVec);
|
||||
float es = -view.z;
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(viewVec);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
//return vec4(1.0, 0.0, 1.0, 1.0);
|
||||
return color * D + kc * L;
|
||||
//depth /= 10.0;
|
||||
//return vec4(depth,depth,depth,0.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color;
|
||||
|
||||
//get detail normals
|
||||
vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
|
||||
vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
|
||||
vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
|
||||
vec3 wavef = normalize(wave1+wave2+wave3);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
|
||||
distort = distort+wavef.xy*refScale;
|
||||
|
||||
vec4 fb = texture2D(screenTex, distort);
|
||||
|
||||
frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
|
||||
}
|
||||
@@ -67,15 +67,47 @@ VARYING vec4 littleWave;
|
||||
VARYING vec4 view;
|
||||
VARYING vec4 vary_position;
|
||||
|
||||
vec3 pack(vec3 norm)
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
float p = sqrt(8.0*norm.z+8.0);
|
||||
return vec3(norm.xy/p + 0.5, 0.0);
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return norm.xyz*0.5+0.5;
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -126,7 +158,7 @@ void main()
|
||||
refcol *= df1 * 0.333;
|
||||
|
||||
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
|
||||
//wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef.z *= max(-viewVec.z, 0.1);
|
||||
wavef = normalize(wavef);
|
||||
|
||||
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
|
||||
@@ -136,13 +168,14 @@ void main()
|
||||
vec2 refvec4 = distort+refdistort4/dmod;
|
||||
float dweight = min(dist2*blurMultiplier, 1.0);
|
||||
vec4 baseCol = texture2D(refTex, refvec4);
|
||||
|
||||
refcol = mix(baseCol*df2, refcol, dweight);
|
||||
|
||||
//get specular component
|
||||
//float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
|
||||
|
||||
//harden specular
|
||||
//spec = pow(spec, 128.0);
|
||||
spec = pow(spec, 128.0);
|
||||
|
||||
//figure out distortion vector (ripply)
|
||||
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
|
||||
@@ -153,25 +186,17 @@ void main()
|
||||
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
|
||||
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
|
||||
|
||||
float shadow = 1.0;
|
||||
vec4 pos = vary_position;
|
||||
|
||||
//vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
|
||||
vec4 spos = pos;
|
||||
|
||||
//spec *= shadow;
|
||||
//color.rgb += spec * specular;
|
||||
color.rgb += spec * specular;
|
||||
|
||||
color.rgb = atmosTransport(color.rgb);
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
color.a = spec * sunAngle2;
|
||||
|
||||
//color.a = spec * sunAngle2;
|
||||
|
||||
//wavef.z *= 0.1f;
|
||||
//wavef = normalize(wavef);
|
||||
vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
|
||||
vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
|
||||
|
||||
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(pack(screenspacewavef), 0.5);
|
||||
frag_data[0] = vec4(color.rgb, color.a); // diffuse
|
||||
frag_data[1] = vec4(0); // speccolor, spec
|
||||
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ void main()
|
||||
pos.w = 1.0;
|
||||
pos = modelview_matrix*pos;
|
||||
|
||||
calcAtmospherics(view.xyz);
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
|
||||
|
||||
@@ -48,40 +48,40 @@ float wave(vec2 v, float t, float f, vec2 d, float s)
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 pos = vec4(position.xyz, 1.0);
|
||||
mat4 modelViewProj = modelview_projection_matrix;
|
||||
|
||||
vec4 oPosition;
|
||||
|
||||
//get view vector
|
||||
vec3 oEyeVec;
|
||||
oEyeVec.xyz = position.xyz-eyeVec;
|
||||
oEyeVec.xyz = pos.xyz-eyeVec;
|
||||
|
||||
float d = length(oEyeVec.xy);
|
||||
float ld = min(d, 2560.0);
|
||||
|
||||
vec3 lpos = position;
|
||||
lpos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
|
||||
pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
|
||||
view.xyz = oEyeVec;
|
||||
|
||||
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
|
||||
d *= d;
|
||||
|
||||
oPosition = vec4(lpos, 1.0);
|
||||
oPosition = vec4(position, 1.0);
|
||||
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
|
||||
oPosition = modelViewProj * oPosition;
|
||||
|
||||
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
|
||||
|
||||
//get wave position parameter (create sweeping horizontal waves)
|
||||
vec3 v = lpos;
|
||||
vec3 v = pos.xyz;
|
||||
v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
|
||||
|
||||
//push position for further horizon effect.
|
||||
vec4 pos;
|
||||
pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
|
||||
pos.w = 1.0;
|
||||
pos = modelview_matrix*pos;
|
||||
|
||||
calcAtmospherics(view.xyz);
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
|
||||
//pass wave parameters to pixel shader
|
||||
|
||||
@@ -31,8 +31,6 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
||||
@@ -33,8 +33,6 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
||||
@@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;
|
||||
|
||||
void default_lighting()
|
||||
{
|
||||
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
|
||||
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
@@ -30,6 +30,7 @@ out vec4 frag_color;
|
||||
#endif
|
||||
|
||||
uniform float minimum_alpha;
|
||||
uniform float texture_gamma;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
@@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;
|
||||
|
||||
void fullbright_lighting()
|
||||
{
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy);
|
||||
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(texture_gamma));
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
@@ -32,6 +32,8 @@ out vec4 frag_color;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform float texture_gamma;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
|
||||
@@ -39,10 +41,14 @@ void fullbright_lighting()
|
||||
{
|
||||
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(texture_gamma));
|
||||
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ out vec4 frag_color;
|
||||
#endif
|
||||
|
||||
uniform float minimum_alpha;
|
||||
uniform float texture_gamma;
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec3 fullbrightScaleSoftClip(vec3 light);
|
||||
@@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;
|
||||
|
||||
void fullbright_lighting()
|
||||
{
|
||||
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
|
||||
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
|
||||
if (color.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
color.rgb *= vertex_color.rgb;
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(texture_gamma));
|
||||
color.rgb = fullbrightAtmosTransport(color.rgb);
|
||||
|
||||
color.rgb = fullbrightScaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ out vec4 frag_color;
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord);
|
||||
/* vec4 diffuseLookup(vec2 texcoord); */
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light);
|
||||
vec4 applyWaterFog(vec4 color);
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/**
|
||||
* @file alphaF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
float shadow = 0.0;
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
vec4 far_split = shadow_clip*-1.25;
|
||||
vec4 transition_domain = near_split-far_split;
|
||||
float weight = 0.0;
|
||||
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
weight += w;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap2, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
shadow += pcfShadow(shadowMap1, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
shadow += pcfShadow(shadowMap0, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
|
||||
shadow /= weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = 1.0;
|
||||
}
|
||||
|
||||
vec4 diff = diffuseLookup(vary_texcoord0.xy);
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
|
||||
vec4 color = diff * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
/**
|
||||
* @file alphaF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec4 vertex_color;
|
||||
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos.xyz /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
float shadow = 0.0;
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
vec4 far_split = shadow_clip*-1.25;
|
||||
vec4 transition_domain = near_split-far_split;
|
||||
float weight = 0.0;
|
||||
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
weight += w;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap2, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
shadow += pcfShadow(shadowMap1, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
shadow += pcfShadow(shadowMap0, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
|
||||
shadow /= weight;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = 1.0;
|
||||
}
|
||||
|
||||
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
|
||||
vec4 color = diff * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* @file alphaNonIndexedNoColorF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).a;
|
||||
vec2 sc = pos_screen.xy*2.0;
|
||||
sc /= screen_res;
|
||||
sc -= vec2(1.0,1.0);
|
||||
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
|
||||
vec4 pos = inv_proj * ndc;
|
||||
pos.xyz /= pos.w;
|
||||
pos.w = 1.0;
|
||||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
|
||||
frag *= screen_res;
|
||||
|
||||
float shadow = 0.0;
|
||||
vec4 pos = vec4(vary_position, 1.0);
|
||||
|
||||
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
|
||||
|
||||
if (diff.a < minimum_alpha)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 spos = pos;
|
||||
|
||||
if (spos.z > -shadow_clip.w)
|
||||
{
|
||||
vec4 lpos;
|
||||
|
||||
vec4 near_split = shadow_clip*-0.75;
|
||||
vec4 far_split = shadow_clip*-1.25;
|
||||
vec4 transition_domain = near_split-far_split;
|
||||
float weight = 0.0;
|
||||
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
weight += w;
|
||||
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
|
||||
}
|
||||
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap2, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
shadow += pcfShadow(shadowMap1, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
shadow += pcfShadow(shadowMap0, lpos)*w;
|
||||
weight += w;
|
||||
}
|
||||
|
||||
|
||||
shadow /= weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow = 1.0;
|
||||
}
|
||||
|
||||
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
|
||||
vec4 color = diff * col;
|
||||
|
||||
color.rgb = atmosLighting(color.rgb);
|
||||
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
color.rgb += diff.rgb * vary_pointlight_col.rgb;
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
/**
|
||||
* @file alphaSkinnedV.glsl
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 projection_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
mat4 getObjectSkinnedTransform();
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
mat4 mat = getObjectSkinnedTransform();
|
||||
|
||||
mat = modelview_matrix * mat;
|
||||
|
||||
vec3 pos = (mat*vec4(position, 1.0)).xyz;
|
||||
|
||||
gl_Position = projection_matrix * vec4(pos, 1.0);
|
||||
|
||||
vec4 n = vec4(position, 1.0);
|
||||
n.xyz += normal.xyz;
|
||||
n.xyz = (mat*n).xyz;
|
||||
n.xyz = normalize(n.xyz-pos.xyz);
|
||||
|
||||
vec3 norm = n.xyz;
|
||||
|
||||
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
|
||||
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*diffuse_color.rgb;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*diffuse_color.rgb;
|
||||
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
|
||||
|
||||
col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
|
||||
pos.xyz = (modelview_projection_matrix * vec4(position.xyz, 1.0)).xyz;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/**
|
||||
* @file alphaV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat3 normal_matrix;
|
||||
uniform mat4 texture_matrix0;
|
||||
uniform mat4 modelview_matrix;
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
void passTextureIndex();
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec4 diffuse_color;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//transform vertex
|
||||
vec4 vert = vec4(position.xyz, 1.0);
|
||||
passTextureIndex();
|
||||
vec4 pos = (modelview_matrix * vert);
|
||||
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
|
||||
|
||||
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
|
||||
|
||||
vec3 norm = normalize(normal_matrix * normal);
|
||||
|
||||
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
|
||||
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
|
||||
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*diffuse_color.rgb;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*diffuse_color.rgb;
|
||||
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
|
||||
|
||||
col.rgb = col.rgb*diffuse_color.rgb;
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
|
||||
pos = modelview_projection_matrix * vert;
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @file avatarAlphaV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2007, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
ATTRIBUTE vec3 normal;
|
||||
ATTRIBUTE vec2 texcoord0;
|
||||
|
||||
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
|
||||
mat4 getSkinnedTransform();
|
||||
void calcAtmospherics(vec3 inPositionEye);
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l);
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
|
||||
|
||||
vec3 atmosAmbient(vec3 light);
|
||||
vec3 atmosAffectDirectionalLight(float lightIntensity);
|
||||
vec3 scaleDownLight(vec3 light);
|
||||
vec3 scaleUpLight(vec3 light);
|
||||
|
||||
VARYING vec3 vary_position;
|
||||
VARYING vec3 vary_ambient;
|
||||
VARYING vec3 vary_directional;
|
||||
VARYING vec3 vary_fragcoord;
|
||||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform vec4 color;
|
||||
|
||||
uniform float near_clip;
|
||||
uniform float shadow_offset;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform vec4 light_position[8];
|
||||
uniform vec3 light_direction[8];
|
||||
uniform vec3 light_attenuation[8];
|
||||
uniform vec3 light_diffuse[8];
|
||||
|
||||
float calcDirectionalLight(vec3 n, vec3 l)
|
||||
{
|
||||
float a = max(dot(n,l),0.0);
|
||||
return a;
|
||||
}
|
||||
|
||||
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
|
||||
{
|
||||
//get light vector
|
||||
vec3 lv = lp.xyz-v;
|
||||
|
||||
//get distance
|
||||
float d = dot(lv,lv);
|
||||
|
||||
float da = 0.0;
|
||||
|
||||
if (d > 0.0 && la > 0.0 && fa > 0.0)
|
||||
{
|
||||
//normalize light vector
|
||||
lv = normalize(lv);
|
||||
|
||||
//distance attenuation
|
||||
float dist2 = d/la;
|
||||
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
|
||||
// spotlight coefficient.
|
||||
float spot = max(dot(-ln, lv), is_pointlight);
|
||||
da *= spot*spot; // GL_SPOT_EXPONENT=2
|
||||
|
||||
//angular attenuation
|
||||
da *= max(dot(n, lv), 0.0);
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vary_texcoord0 = texcoord0;
|
||||
|
||||
vec4 pos;
|
||||
vec3 norm;
|
||||
|
||||
mat4 trans = getSkinnedTransform();
|
||||
vec4 pos_in = vec4(position.xyz, 1.0);
|
||||
pos.x = dot(trans[0], pos_in);
|
||||
pos.y = dot(trans[1], pos_in);
|
||||
pos.z = dot(trans[2], pos_in);
|
||||
pos.w = 1.0;
|
||||
|
||||
norm.x = dot(trans[0].xyz, normal);
|
||||
norm.y = dot(trans[1].xyz, normal);
|
||||
norm.z = dot(trans[2].xyz, normal);
|
||||
norm = normalize(norm);
|
||||
|
||||
gl_Position = projection_matrix * pos;
|
||||
|
||||
float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
|
||||
vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
|
||||
|
||||
calcAtmospherics(pos.xyz);
|
||||
|
||||
vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// Collect normal lights
|
||||
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
|
||||
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
|
||||
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
|
||||
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
|
||||
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
|
||||
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
|
||||
|
||||
vary_pointlight_col = col.rgb*color.rgb;
|
||||
|
||||
col.rgb = vec3(0,0,0);
|
||||
|
||||
// Add windlight lights
|
||||
col.rgb = atmosAmbient(vec3(0.));
|
||||
|
||||
vary_ambient = col.rgb*color.rgb;
|
||||
vary_directional = atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
|
||||
|
||||
col.rgb = col.rgb*color.rgb;
|
||||
|
||||
vertex_color = col;
|
||||
|
||||
|
||||
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
@@ -39,6 +40,7 @@ uniform samplerCube environmentMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D projectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
@@ -67,10 +69,70 @@ uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
|
||||
@@ -85,7 +147,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
|
||||
|
||||
float det = min(lod/(proj_lod*0.5), 1.0);
|
||||
@@ -102,6 +165,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -126,20 +190,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -149,9 +199,9 @@ void main()
|
||||
|
||||
vec3 pos = getPosition(frag.xy).xyz;
|
||||
vec3 lv = center.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= size;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= size;
|
||||
if (dist > 1.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
@@ -167,9 +217,13 @@ void main()
|
||||
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
float envIntensity = norm.z;
|
||||
|
||||
norm = decode_normal(norm.xy);
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
@@ -181,7 +235,9 @@ void main()
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
if (dist_atten <= 0.0)
|
||||
{
|
||||
discard;
|
||||
@@ -190,11 +246,15 @@ void main()
|
||||
lv = proj_origin-pos.xyz;
|
||||
lv = normalize(lv);
|
||||
float da = dot(norm, lv);
|
||||
|
||||
|
||||
vec3 col = vec3(0,0,0);
|
||||
|
||||
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
vec3 dlit = vec3(0, 0, 0);
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
@@ -202,21 +262,21 @@ void main()
|
||||
proj_tc.x > 0.0 &&
|
||||
proj_tc.y > 0.0)
|
||||
{
|
||||
float lit = 0.0;
|
||||
float amb_da = proj_ambiance;
|
||||
|
||||
float lit = 0.0;
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
|
||||
dlit = color.rgb * plcol.rgb * plcol.a;
|
||||
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
col = lcol*lit*diff_tex*shadow;
|
||||
col = dlit*lit*diff_tex*shadow;
|
||||
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
|
||||
}
|
||||
|
||||
@@ -232,9 +292,36 @@ void main()
|
||||
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 npos = -normalize(pos);
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += dlit*scol*spec.rgb*shadow;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
@@ -247,13 +334,12 @@ void main()
|
||||
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
|
||||
|
||||
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
|
||||
stc /= stc.w;
|
||||
|
||||
if (stc.z > 0.0)
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
|
||||
|
||||
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
|
||||
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
if (stc.x < 1.0 &&
|
||||
@@ -261,13 +347,16 @@ void main()
|
||||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//not sure why, but this line prevents MATBUG-194
|
||||
col = max(col, vec3(0.0));
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform sampler2D lightFunc;
|
||||
uniform vec3 gi_quad;
|
||||
|
||||
uniform float blur_size;
|
||||
uniform float blur_fidelity;
|
||||
@@ -60,16 +59,13 @@ uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
uniform vec4 glow;
|
||||
uniform float global_gamma;
|
||||
uniform float scene_light_strength;
|
||||
uniform mat3 env_mat;
|
||||
uniform vec4 shadow_clip;
|
||||
uniform float ssao_effect;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
VARYING vec2 vary_fragcoord;
|
||||
|
||||
vec3 vary_PositionEye;
|
||||
@@ -79,11 +75,61 @@ vec3 vary_AmblitColor;
|
||||
vec3 vary_AdditiveColor;
|
||||
vec3 vary_AtmosAttenuation;
|
||||
|
||||
float luminance(vec3 color)
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
/// CALCULATING LUMINANCE (Using NTSC lum weights)
|
||||
/// http://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
return dot(color, vec3(0.299, 0.587, 0.114));
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition_d(vec2 pos_screen, float depth)
|
||||
@@ -125,7 +171,6 @@ vec3 getAtmosAttenuation()
|
||||
return vary_AtmosAttenuation;
|
||||
}
|
||||
|
||||
|
||||
void setPositionEye(vec3 v)
|
||||
{
|
||||
vary_PositionEye = v;
|
||||
@@ -211,7 +256,7 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
//increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
|
||||
|
||||
|
||||
//haze color
|
||||
setAdditiveColor(
|
||||
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
|
||||
@@ -220,13 +265,63 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
|
||||
|
||||
// decrease ambient value for occluded areas
|
||||
tmpAmbient *= mix(ssao_effect, 1.0, ambFactor);
|
||||
|
||||
|
||||
//brightness of surface both sunlight and ambient
|
||||
/*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
|
||||
setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
|
||||
setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
|
||||
|
||||
setSunlitColor(vec3(sunlight * .5));
|
||||
setAmblitColor(vec3(tmpAmbient * .25));
|
||||
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
|
||||
}
|
||||
|
||||
#ifdef WATER_FOG
|
||||
uniform vec4 waterPlane;
|
||||
uniform vec4 waterFogColor;
|
||||
uniform float waterFogDensity;
|
||||
uniform float waterFogKS;
|
||||
|
||||
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
|
||||
{
|
||||
//normalize view vector
|
||||
vec3 view = normalize(pos);
|
||||
float es = -(dot(view, waterPlane.xyz));
|
||||
|
||||
//find intersection point with water plane and eye vector
|
||||
|
||||
//get eye depth
|
||||
float e0 = max(-waterPlane.w, 0.0);
|
||||
|
||||
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//get object depth
|
||||
float depth = length(pos - int_v);
|
||||
|
||||
//get "thickness" of water
|
||||
float l = max(depth, 0.1);
|
||||
|
||||
float kd = waterFogDensity;
|
||||
float ks = waterFogKS;
|
||||
vec4 kc = waterFogColor;
|
||||
|
||||
float F = 0.98;
|
||||
|
||||
float t1 = -kd * pow(F, ks * e0);
|
||||
float t2 = kd + ks * es;
|
||||
float t3 = pow(F, t2*l) - 1.0;
|
||||
|
||||
float L = min(t1/t2*t3, 1.0);
|
||||
|
||||
float D = pow(0.98, l*kd);
|
||||
|
||||
color.rgb = color.rgb * D + kc.rgb * L;
|
||||
color.a = kc.a + color.a;
|
||||
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 atmosLighting(vec3 light)
|
||||
{
|
||||
light *= getAtmosAttenuation().r;
|
||||
@@ -239,6 +334,15 @@ vec3 atmosTransport(vec3 light) {
|
||||
light += getAdditiveColor() * 2.0;
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 fullbrightAtmosTransport(vec3 light) {
|
||||
float brightness = dot(light.rgb, vec3(0.33333));
|
||||
|
||||
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec3 atmosGetDiffuseSunlightColor()
|
||||
{
|
||||
return getSunlitColor();
|
||||
@@ -273,18 +377,18 @@ vec3 scaleSoftClip(vec3 light)
|
||||
return light;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
|
||||
vec3 fullbrightScaleSoftClip(vec3 light)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
//soft clip effect:
|
||||
return light;
|
||||
}
|
||||
|
||||
float luminance(vec3 color)
|
||||
{
|
||||
/// CALCULATING LUMINANCE (Using NTSC lum weights)
|
||||
/// http://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
return dot(color, vec3(0.299, 0.587, 0.114));
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -292,61 +396,107 @@ void main()
|
||||
vec2 tc = vary_fragcoord.xy;
|
||||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = unpack(tc); // unpack norm
|
||||
vec4 norm = texture2DRect(normalMap, tc);
|
||||
float envIntensity = norm.z;
|
||||
norm.xyz = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
vec4 diffuse = texture2DRect(diffuseRect, tc);
|
||||
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
|
||||
|
||||
float light_gamma = 1.0/1.3;
|
||||
da = pow(da, light_gamma);
|
||||
|
||||
|
||||
vec4 diffuse = texture2DRect(diffuseRect, tc);
|
||||
|
||||
//convert to gamma space
|
||||
diffuse.rgb = linear_to_srgb(diffuse.rgb);
|
||||
|
||||
vec3 col;
|
||||
float bloom = 0.0;
|
||||
|
||||
if (diffuse.a < 0.9)
|
||||
{
|
||||
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
|
||||
bloom = spec.r*norm.w;
|
||||
|
||||
if (norm.w < 0.5)
|
||||
{
|
||||
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
|
||||
scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
|
||||
|
||||
float scol = max(scol_ambocc.r, diffuse.a);
|
||||
|
||||
|
||||
|
||||
float ambocc = scol_ambocc.g;
|
||||
|
||||
calcAtmospherics(pos.xyz, ambocc);
|
||||
|
||||
col = atmosAmbient(vec3(0));
|
||||
col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
|
||||
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
|
||||
ambient *= 0.5;
|
||||
ambient *= ambient;
|
||||
ambient = (1.0-ambient);
|
||||
|
||||
col.rgb *= ambient;
|
||||
|
||||
col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
|
||||
|
||||
col *= diffuse.rgb;
|
||||
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
if (spec.a > 0.0) // specular reflection
|
||||
{
|
||||
// the old infinite-sky shiny reflection
|
||||
//
|
||||
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
|
||||
|
||||
float sa = dot(refnormpersp, sun_dir.xyz);
|
||||
vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
|
||||
|
||||
vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
|
||||
|
||||
// add the two types of shiny together
|
||||
vec3 spec_contrib = dumbshiny * spec.rgb;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 4;
|
||||
bloom = dot(spec_contrib, spec_contrib) / 6;
|
||||
col += spec_contrib;
|
||||
|
||||
//add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
vec3 env = textureCube(environmentMap, env_vec).rgb;
|
||||
bloom = (luminance(env) - .45)*.25;
|
||||
col = mix(col.rgb, env,
|
||||
max(spec.a-diffuse.a*2.0, 0.0));
|
||||
}
|
||||
|
||||
col = atmosLighting(col);
|
||||
col = scaleSoftClip(col);
|
||||
|
||||
col = mix(col, diffuse.rgb, diffuse.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
bloom = spec.r;
|
||||
col = diffuse.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
col = mix(col, diffuse.rgb, diffuse.a);
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{ //add environmentmap
|
||||
vec3 env_vec = env_mat * refnormpersp;
|
||||
|
||||
vec3 refcol = textureCube(environmentMap, env_vec).rgb*scol_ambocc.r;
|
||||
bloom = (luminance(refcol) - .45)*.25;
|
||||
col = mix(col.rgb, refcol,
|
||||
envIntensity);
|
||||
|
||||
}
|
||||
|
||||
//if (norm.w < 0.5)
|
||||
{
|
||||
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
|
||||
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
|
||||
//bloom += (luminance(col))*.075; //This looks nice, but requires a larger glow rendertarget.
|
||||
}
|
||||
|
||||
#ifdef WATER_FOG
|
||||
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
|
||||
col = fogged.rgb;
|
||||
bloom = fogged.a;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
col = diffuse.rgb;
|
||||
}
|
||||
|
||||
col = srgb_to_linear(col);
|
||||
|
||||
//col = vec3(1,0,1);
|
||||
//col.g = envIntensity;
|
||||
}
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = bloom;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
//#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_shader_texture_lod : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
@@ -39,6 +40,7 @@ uniform samplerCube environmentMap;
|
||||
uniform sampler2DRect lightMap;
|
||||
uniform sampler2D noiseMap;
|
||||
uniform sampler2D projectionMap;
|
||||
uniform sampler2D lightFunc;
|
||||
|
||||
uniform mat4 proj_mat; //screen space to light space
|
||||
uniform float proj_near; //near clip for projection
|
||||
@@ -67,9 +69,69 @@ uniform vec2 screen_res;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec3 srgb_to_linear(vec3 cs)
|
||||
{
|
||||
vec3 low_range = cs / vec3(12.92);
|
||||
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
|
||||
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lte.r ? low_range.r : high_range.r;
|
||||
result.g = lte.g ? low_range.g : high_range.g;
|
||||
result.b = lte.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lte);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec3 linear_to_srgb(vec3 cl)
|
||||
{
|
||||
cl = clamp(cl, vec3(0), vec3(1));
|
||||
vec3 low_range = cl * 12.92;
|
||||
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
|
||||
bvec3 lt = lessThan(cl,vec3(0.0031308));
|
||||
|
||||
#ifdef OLD_SELECT
|
||||
vec3 result;
|
||||
result.r = lt.r ? low_range.r : high_range.r;
|
||||
result.g = lt.g ? low_range.g : high_range.g;
|
||||
result.b = lt.b ? low_range.b : high_range.b;
|
||||
return result;
|
||||
#else
|
||||
return mix(high_range, low_range, lt);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
vec4 correctWithGamma(vec4 col)
|
||||
{
|
||||
return vec4(srgb_to_linear(col.rgb), col.a);
|
||||
}
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -85,6 +147,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
|
||||
|
||||
@@ -102,6 +165,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
|
||||
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
|
||||
{
|
||||
vec4 ret = texture2DLod(projectionMap, tc, lod);
|
||||
ret = correctWithGamma(ret);
|
||||
|
||||
vec2 dist = tc-vec2(0.5);
|
||||
|
||||
@@ -126,20 +190,6 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
vec3 unpack(vec2 tc)
|
||||
{
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
vec2 enc = texture2DRect(normalMap, tc).xy;
|
||||
enc = enc*4.0-2.0;
|
||||
float prod = dot(enc,enc);
|
||||
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
|
||||
#else
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
return norm*2.0-1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vary_fragcoord;
|
||||
@@ -149,9 +199,9 @@ void main()
|
||||
|
||||
vec3 pos = getPosition(frag.xy).xyz;
|
||||
vec3 lv = trans_center.xyz-pos.xyz;
|
||||
float dist2 = dot(lv,lv);
|
||||
dist2 /= size;
|
||||
if (dist2 > 1.0)
|
||||
float dist = length(lv);
|
||||
dist /= size;
|
||||
if (dist > 1.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
@@ -167,9 +217,11 @@ void main()
|
||||
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
|
||||
}
|
||||
|
||||
vec3 norm = unpack(frag.xy); // unpack norm
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
float envIntensity = norm.z;
|
||||
norm = decode_normal(norm.xy);
|
||||
|
||||
//norm = normalize(norm); // may be superfluous
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
||||
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
|
||||
@@ -181,7 +233,10 @@ void main()
|
||||
proj_tc.xyz /= proj_tc.w;
|
||||
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
|
||||
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
if (dist_atten <= 0.0)
|
||||
{
|
||||
discard;
|
||||
@@ -195,6 +250,10 @@ void main()
|
||||
|
||||
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
vec3 dlit = vec3(0, 0, 0);
|
||||
|
||||
float noise = texture2D(noiseMap, frag.xy/128.0).b;
|
||||
if (proj_tc.z > 0.0 &&
|
||||
proj_tc.x < 1.0 &&
|
||||
@@ -202,21 +261,21 @@ void main()
|
||||
proj_tc.x > 0.0 &&
|
||||
proj_tc.y > 0.0)
|
||||
{
|
||||
float lit = 0.0;
|
||||
float amb_da = proj_ambiance;
|
||||
float lit = 0.0;
|
||||
|
||||
if (da > 0.0)
|
||||
{
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
||||
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
|
||||
|
||||
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
|
||||
dlit = color.rgb * plcol.rgb * plcol.a;
|
||||
|
||||
lit = da * dist_atten * noise;
|
||||
|
||||
col = lcol*lit*diff_tex*shadow;
|
||||
col = dlit*lit*diff_tex*shadow;
|
||||
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
|
||||
}
|
||||
|
||||
@@ -232,9 +291,36 @@ void main()
|
||||
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
|
||||
}
|
||||
|
||||
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
vec3 npos = -normalize(pos);
|
||||
|
||||
//vec3 ref = dot(pos+lv, norm);
|
||||
vec3 h = normalize(lv+npos);
|
||||
float nh = dot(norm, h);
|
||||
float nv = dot(norm, npos);
|
||||
float vh = dot(npos, h);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
col += dlit*scol*spec.rgb*shadow;
|
||||
//col += spec.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (envIntensity > 0.0)
|
||||
{
|
||||
vec3 ref = reflect(normalize(pos), norm);
|
||||
|
||||
@@ -252,8 +338,9 @@ void main()
|
||||
{
|
||||
stc.xy /= stc.w;
|
||||
|
||||
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
|
||||
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
|
||||
|
||||
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
|
||||
|
||||
if (stc.x < 1.0 &&
|
||||
@@ -261,13 +348,15 @@ void main()
|
||||
stc.x > 0.0 &&
|
||||
stc.y > 0.0)
|
||||
{
|
||||
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
|
||||
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
|
||||
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//not sure why, but this line prevents MATBUG-194
|
||||
col = max(col, vec3(0.0));
|
||||
|
||||
frag_color.rgb = col;
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap4;
|
||||
uniform sampler2DShadow shadowMap5;
|
||||
|
||||
@@ -55,16 +55,33 @@ VARYING vec2 vary_fragcoord;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
uniform vec2 proj_shadow_res;
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
uniform float shadow_bias;
|
||||
uniform float shadow_offset;
|
||||
|
||||
uniform float spot_shadow_bias;
|
||||
uniform float spot_shadow_offset;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
@@ -78,30 +95,31 @@ vec4 getPosition(vec2 pos_screen)
|
||||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias*scl;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
|
||||
return shadow*0.2;
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += spot_shadow_bias*scl;
|
||||
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
|
||||
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
@@ -113,23 +131,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
vec4 unpack(vec2 tc)
|
||||
{
|
||||
vec4 norm = texture2DRect(normalMap, tc).xyzw;
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
norm.xy = (norm.xy*4.0)-2.0;
|
||||
float prod = dot(norm.xy,norm.xy);
|
||||
norm.xy *= sqrt(1.0-prod*.25);
|
||||
norm.z = 1.0-prod*.5;
|
||||
#else
|
||||
norm.xyz = norm.xyz*2.0-1.0;
|
||||
#endif
|
||||
norm.w *= norm.z;
|
||||
return norm;
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -140,10 +142,9 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = unpack(pos_screen); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
|
||||
{
|
||||
frag_color = vec4(0.0); // doesn't matter
|
||||
@@ -153,7 +154,7 @@ void main()
|
||||
float shadow = 0.0;
|
||||
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
|
||||
|
||||
vec3 shadow_pos = pos.xyz + displace*norm;
|
||||
vec3 shadow_pos = pos.xyz;
|
||||
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
|
||||
|
||||
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
|
||||
@@ -177,8 +178,7 @@ void main()
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
|
||||
@@ -189,8 +189,7 @@ void main()
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
@@ -201,7 +200,6 @@ void main()
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
@@ -213,7 +211,6 @@ void main()
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
@@ -252,11 +249,11 @@ void main()
|
||||
|
||||
//spotlight shadow 1
|
||||
vec4 lpos = shadow_matrix[4]*spos;
|
||||
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
|
||||
//spotlight shadow 2
|
||||
lpos = shadow_matrix[5]*spos;
|
||||
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
|
||||
//frag_color.rgb = pos.xyz;
|
||||
//frag_color.b = shadow;
|
||||
|
||||
@@ -34,10 +34,10 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap4;
|
||||
uniform sampler2DShadow shadowMap5;
|
||||
uniform sampler2D noiseMap;
|
||||
@@ -55,16 +55,34 @@ VARYING vec2 vary_fragcoord;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
uniform vec2 proj_shadow_res;
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
uniform float shadow_bias;
|
||||
uniform float shadow_offset;
|
||||
|
||||
uniform float spot_shadow_bias;
|
||||
uniform float spot_shadow_offset;
|
||||
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
@@ -133,25 +151,25 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
||||
return (rtn * rtn);
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias*scl;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666));
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += spot_shadow_bias*scl;
|
||||
@@ -171,22 +189,6 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
vec4 unpack(vec2 tc)
|
||||
{
|
||||
vec4 norm = texture2DRect(normalMap, tc).xyzw;
|
||||
//#define PACK_NORMALS
|
||||
#ifdef PACK_NORMALS
|
||||
norm.xy = (norm.xy*4.0)-2.0;
|
||||
float prod = dot(norm.xy,norm.xy);
|
||||
norm.xy *= sqrt(1.0-prod*.25);
|
||||
norm.z = 1.0-prod*.5;
|
||||
#else
|
||||
norm.xyz = norm.xyz*2.0-1.0;
|
||||
#endif
|
||||
norm.w *= norm.z;
|
||||
return norm;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 pos_screen = vary_fragcoord.xy;
|
||||
@@ -195,10 +197,9 @@ void main()
|
||||
|
||||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = unpack(pos_screen); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = decode_normal(norm.xy); // unpack norm
|
||||
|
||||
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
|
||||
{
|
||||
frag_color = vec4(0.0); // doesn't matter
|
||||
@@ -207,8 +208,8 @@ void main()
|
||||
|
||||
float shadow = 0.0;
|
||||
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
|
||||
|
||||
vec3 shadow_pos = pos.xyz + displace*norm;
|
||||
|
||||
vec3 shadow_pos = pos.xyz;
|
||||
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
|
||||
|
||||
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
|
||||
@@ -232,8 +233,7 @@ void main()
|
||||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
|
||||
@@ -244,8 +244,7 @@ void main()
|
||||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
@@ -256,8 +255,7 @@ void main()
|
||||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
@@ -268,8 +266,7 @@ void main()
|
||||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
@@ -307,11 +304,11 @@ void main()
|
||||
|
||||
//spotlight shadow 1
|
||||
vec4 lpos = shadow_matrix[4]*spos;
|
||||
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
|
||||
//spotlight shadow 2
|
||||
lpos = shadow_matrix[5]*spos;
|
||||
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
|
||||
//frag_color.rgb = pos.xyz;
|
||||
//frag_color.b = shadow;
|
||||
|
||||
@@ -275,6 +275,13 @@ namespace
|
||||
{
|
||||
if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection())
|
||||
{
|
||||
if (!selection->getFirstRootObject())
|
||||
{
|
||||
if (gSavedSettings.getBOOL("OBJExportNotifyFailed"))
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
return true;
|
||||
}
|
||||
|
||||
WavefrontSaver* wfsaver = new WavefrontSaver; // deleted in callback
|
||||
wfsaver->offset = -selection->getFirstRootObject()->getRenderPosition();
|
||||
S32 total = 0;
|
||||
|
||||
@@ -272,7 +272,9 @@ public:
|
||||
|
||||
void addSelectedObjects()
|
||||
{
|
||||
if (LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection())
|
||||
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
||||
|
||||
if (selection && selection->getFirstRootObject())
|
||||
{
|
||||
mSaver.mOffset = -selection->getFirstRootObject()->getRenderPosition();
|
||||
mObjectName = selection->getFirstRootNode()->mName;
|
||||
@@ -285,14 +287,15 @@ public:
|
||||
if (!node->getObject()->getVolume() || !DAEExportUtil::canExportNode(node)) continue;
|
||||
mSaver.add(node->getObject(), node->mName);
|
||||
}
|
||||
}
|
||||
|
||||
if (mSaver.mObjects.empty())
|
||||
{
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSaver.mObjects.empty())
|
||||
{
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
mSaver.updateTextureInfo();
|
||||
mNumTextures = mSaver.mTextures.size();
|
||||
mNumExportableTextures = getNumExportableTextures();
|
||||
|
||||
@@ -2023,13 +2023,21 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
|
||||
}
|
||||
|
||||
// Adds change to vector CachedControl, vec, at idx
|
||||
template <typename T, typename Vec>
|
||||
template <typename Vec, typename T>
|
||||
void change_vec(const T& change, LLCachedControl<Vec>& vec, const U32& idx = VZ)
|
||||
{
|
||||
Vec changed(vec);
|
||||
changed[idx] += change;
|
||||
vec = changed;
|
||||
}
|
||||
// Same as above, but for ControlVariables
|
||||
template <typename Vec, typename T>
|
||||
void change_vec(const T& change, LLPointer<LLControlVariable>& vec, const U32& idx = VZ)
|
||||
{
|
||||
Vec changed(vec->get());
|
||||
changed[idx] += change;
|
||||
vec->set(changed.getValue());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// handleScrollWheel()
|
||||
@@ -2072,13 +2080,11 @@ void LLAgentCamera::handleScrollWheel(S32 clicks)
|
||||
const F32 change(static_cast<F32>(clicks) * 0.1f);
|
||||
if (mask & MASK_SHIFT)
|
||||
{
|
||||
static LLCachedControl<LLVector3d> focus_offset("FocusOffsetRearView");
|
||||
change_vec(change, focus_offset);
|
||||
change_vec<LLVector3d>(change, mFocusOffsetInitial[mCameraPreset]);
|
||||
}
|
||||
if (mask & MASK_CONTROL)
|
||||
{
|
||||
static LLCachedControl<LLVector3> camera_offset("CameraOffsetRearView");
|
||||
change_vec(change, camera_offset);
|
||||
change_vec<LLVector3>(change, mCameraOffsetInitial[mCameraPreset]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2625,7 +2625,11 @@ void LLAppViewer::writeSystemInfo()
|
||||
gDebugInfo["ClientInfo"]["MinorVersion"] = gVersionMinor;
|
||||
gDebugInfo["ClientInfo"]["PatchVersion"] = gVersionPatch;
|
||||
gDebugInfo["ClientInfo"]["BuildVersion"] = gVersionBuild;
|
||||
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
gDebugInfo["ClientInfo"]["Architecture"] = "x86_64";
|
||||
#else
|
||||
gDebugInfo["ClientInfo"]["Architecture"] = "i386";
|
||||
#endif
|
||||
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
|
||||
|
||||
gDebugInfo["CPUInfo"]["CPUString"] = gSysCPU.getCPUString();
|
||||
|
||||
@@ -304,6 +304,49 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
|
||||
|
||||
}
|
||||
|
||||
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
|
||||
{
|
||||
LLFace *face;
|
||||
face = new LLFace(this, mVObjp);
|
||||
|
||||
face->setTEOffset(mFaces.size());
|
||||
face->setTexture(texturep);
|
||||
face->setNormalMap(normalp);
|
||||
face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
|
||||
|
||||
mFaces.push_back(face);
|
||||
|
||||
if (isState(UNLIT))
|
||||
{
|
||||
face->setState(LLFace::FULLBRIGHT);
|
||||
}
|
||||
|
||||
return face;
|
||||
|
||||
}
|
||||
|
||||
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
|
||||
{
|
||||
LLFace *face;
|
||||
face = new LLFace(this, mVObjp);
|
||||
|
||||
face->setTEOffset(mFaces.size());
|
||||
face->setTexture(texturep);
|
||||
face->setNormalMap(normalp);
|
||||
face->setSpecularMap(specularp);
|
||||
face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
|
||||
|
||||
mFaces.push_back(face);
|
||||
|
||||
if (isState(UNLIT))
|
||||
{
|
||||
face->setState(LLFace::FULLBRIGHT);
|
||||
}
|
||||
|
||||
return face;
|
||||
|
||||
}
|
||||
|
||||
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
|
||||
{
|
||||
if (newFaces == (S32)mFaces.size())
|
||||
@@ -565,10 +608,10 @@ F32 LLDrawable::updateXform(BOOL undamped)
|
||||
mVObjp->dirtySpatialGroup();
|
||||
}
|
||||
}
|
||||
else if (!isRoot() && (
|
||||
dist_vec_squared(old_pos, target_pos) > 0.f
|
||||
|| old_rot != target_rot ))
|
||||
{ //fix for BUG-860, MAINT-2275, MAINT-1742, MAINT-2247
|
||||
else if (!isRoot() &&
|
||||
((dist_vec_squared(old_pos, target_pos) > 0.f)
|
||||
|| (1.f - dot(old_rot, target_rot)) > 0.f))
|
||||
{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
|
||||
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
|
||||
}
|
||||
else if (!getVOVolume() && !isAvatar())
|
||||
|
||||
@@ -151,6 +151,8 @@ public:
|
||||
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
|
||||
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
|
||||
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
|
||||
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
|
||||
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
|
||||
void deleteFaces(S32 offset, S32 count);
|
||||
void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
|
||||
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "lldrawpoolalpha.h"
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "lldrawpoolbump.h"
|
||||
#include "lldrawpoolmaterials.h"
|
||||
#include "lldrawpoolground.h"
|
||||
#include "lldrawpoolsimple.h"
|
||||
#include "lldrawpoolsky.h"
|
||||
@@ -47,6 +48,7 @@
|
||||
#include "llspatialpartition.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "lldrawpoolwlsky.h"
|
||||
#include "llglslshader.h"
|
||||
|
||||
S32 LLDrawPool::sNumDrawPools = 0;
|
||||
|
||||
@@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
|
||||
case POOL_GRASS:
|
||||
poolp = new LLDrawPoolGrass();
|
||||
break;
|
||||
case POOL_ALPHA_MASK:
|
||||
poolp = new LLDrawPoolAlphaMask();
|
||||
break;
|
||||
case POOL_FULLBRIGHT_ALPHA_MASK:
|
||||
poolp = new LLDrawPoolFullbrightAlphaMask();
|
||||
break;
|
||||
case POOL_FULLBRIGHT:
|
||||
poolp = new LLDrawPoolFullbright();
|
||||
break;
|
||||
@@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
|
||||
case POOL_BUMP:
|
||||
poolp = new LLDrawPoolBump();
|
||||
break;
|
||||
case POOL_MATERIALS:
|
||||
poolp = new LLDrawPoolMaterials();
|
||||
break;
|
||||
case POOL_WL_SKY:
|
||||
poolp = new LLDrawPoolWLSky();
|
||||
break;
|
||||
@@ -408,6 +419,27 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
|
||||
{
|
||||
LLDrawInfo* pparams = *i;
|
||||
if (pparams)
|
||||
{
|
||||
if (LLGLSLShader::sCurBoundShaderPtr)
|
||||
{
|
||||
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff);
|
||||
}
|
||||
|
||||
pushBatch(*pparams, mask, texture, batch_textures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
|
||||
{
|
||||
if (params.mModelMatrix != gGLLastMatrix)
|
||||
|
||||
@@ -50,8 +50,11 @@ public:
|
||||
POOL_GROUND,
|
||||
POOL_FULLBRIGHT,
|
||||
POOL_BUMP,
|
||||
POOL_MATERIALS,
|
||||
POOL_TERRAIN,
|
||||
POOL_TREE, // Singu Note: Before sky for zcull.
|
||||
POOL_ALPHA_MASK,
|
||||
POOL_FULLBRIGHT_ALPHA_MASK,
|
||||
POOL_SKY,
|
||||
POOL_WL_SKY,
|
||||
POOL_GRASS,
|
||||
@@ -129,6 +132,22 @@ public:
|
||||
PASS_SHINY,
|
||||
PASS_BUMP,
|
||||
PASS_POST_BUMP,
|
||||
PASS_MATERIAL,
|
||||
PASS_MATERIAL_ALPHA,
|
||||
PASS_MATERIAL_ALPHA_MASK,
|
||||
PASS_MATERIAL_ALPHA_EMISSIVE,
|
||||
PASS_SPECMAP,
|
||||
PASS_SPECMAP_BLEND,
|
||||
PASS_SPECMAP_MASK,
|
||||
PASS_SPECMAP_EMISSIVE,
|
||||
PASS_NORMMAP,
|
||||
PASS_NORMMAP_BLEND,
|
||||
PASS_NORMMAP_MASK,
|
||||
PASS_NORMMAP_EMISSIVE,
|
||||
PASS_NORMSPEC,
|
||||
PASS_NORMSPEC_BLEND,
|
||||
PASS_NORMSPEC_MASK,
|
||||
PASS_NORMSPEC_EMISSIVE,
|
||||
PASS_GLOW,
|
||||
PASS_ALPHA,
|
||||
PASS_ALPHA_MASK,
|
||||
@@ -147,6 +166,7 @@ public:
|
||||
|
||||
static void applyModelMatrix(LLDrawInfo& params);
|
||||
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
|
||||
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
|
||||
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
|
||||
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
|
||||
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);
|
||||
|
||||
@@ -77,33 +77,6 @@ void LLDrawPoolAlpha::prerender()
|
||||
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
}
|
||||
|
||||
S32 LLDrawPoolAlpha::getNumDeferredPasses()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::endDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderDeferred(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_GRASS);
|
||||
gDeferredDiffuseAlphaMaskProgram.bind();
|
||||
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
|
||||
|
||||
//render alpha masked objects
|
||||
LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
gDeferredDiffuseAlphaMaskProgram.unbind();
|
||||
}
|
||||
|
||||
|
||||
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
|
||||
{
|
||||
static const LLCachedControl<bool> render_depth_of_field("RenderDepthOfField");
|
||||
@@ -127,25 +100,63 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gDeferredAlphaImpostorProgram;
|
||||
fullbright_shader = &gDeferredFullbrightProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gDeferredAlphaWaterProgram;
|
||||
fullbright_shader = &gDeferredFullbrightWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_shader = &gDeferredAlphaProgram;
|
||||
fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
|
||||
fullbright_shader = &gDeferredFullbrightProgram;
|
||||
}
|
||||
|
||||
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
|
||||
fullbright_shader->bind();
|
||||
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
//fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
fullbright_shader->unbind();
|
||||
|
||||
//prime simple shader (loads shadow relevant uniforms)
|
||||
gPipeline.bindDeferredShader(*simple_shader);
|
||||
|
||||
//simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
else
|
||||
else if (!LLPipeline::sImpostorRender)
|
||||
{
|
||||
//update depth buffer sampler
|
||||
gPipeline.mScreen.flush();
|
||||
gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
|
||||
0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
gPipeline.mDeferredDepth.bindTarget();
|
||||
simple_shader = NULL;
|
||||
fullbright_shader = NULL;
|
||||
simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
|
||||
}
|
||||
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
emissive_shader = &gDeferredEmissiveProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
emissive_shader = &gObjectEmissiveWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
emissive_shader = &gObjectEmissiveProgram;
|
||||
}
|
||||
}
|
||||
|
||||
deferred_render = TRUE;
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
@@ -157,8 +168,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
|
||||
|
||||
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
if (pass == 1)
|
||||
if (pass == 1 && !LLPipeline::sImpostorRender)
|
||||
{
|
||||
gPipeline.mDeferredDepth.flush();
|
||||
gPipeline.mScreen.bindTarget();
|
||||
@@ -178,16 +188,22 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
|
||||
fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
|
||||
simple_shader = &gObjectSimpleImpostorProgram;
|
||||
fullbright_shader = &gObjectFullbrightProgram;
|
||||
emissive_shader = &gObjectEmissiveProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterProgram;
|
||||
fullbright_shader = &gObjectFullbrightWaterProgram;
|
||||
emissive_shader = &gObjectEmissiveWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_shader = &gObjectSimpleAlphaMaskProgram;
|
||||
fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
|
||||
simple_shader = &gObjectSimpleProgram;
|
||||
fullbright_shader = &gObjectFullbrightProgram;
|
||||
emissive_shader = &gObjectEmissiveProgram;
|
||||
}
|
||||
|
||||
@@ -205,7 +221,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass )
|
||||
LLFastTimer t(FTM_RENDER_ALPHA);
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
|
||||
if(mVertexShaderLevel > 0)
|
||||
if(gPipeline.canUseWindLightShaders())
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
}
|
||||
@@ -225,45 +241,14 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
{
|
||||
gGL.setColorMask(true, true);
|
||||
}
|
||||
|
||||
bool write_depth = LLDrawPoolWater::sSkipScreenCopy
|
||||
|| (deferred_render && pass == 1)
|
||||
// we want depth written so that rendered alpha will
|
||||
// contribute to the alpha mask used for impostors
|
||||
|| LLPipeline::sImpostorRenderAlphaDepthPass;
|
||||
|
||||
if (LLPipeline::sAutoMaskAlphaNonDeferred)
|
||||
{
|
||||
mColorSFactor = LLRender::BF_ONE; // }
|
||||
mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
|
||||
mAlphaSFactor = LLRender::BF_ZERO;
|
||||
mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
|
||||
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
if (!LLPipeline::sRenderDeferred || !deferred_render)
|
||||
{
|
||||
simple_shader->bind();
|
||||
simple_shader->setMinimumAlpha(0.33f);
|
||||
|
||||
pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
}
|
||||
if (fullbright_shader)
|
||||
{
|
||||
fullbright_shader->bind();
|
||||
fullbright_shader->setMinimumAlpha(0.33f);
|
||||
}
|
||||
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
//LLGLSLShader::bindNoShader();
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
|
||||
gPipeline.enableLightsDynamic();
|
||||
pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
|
||||
}
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, (LLDrawPoolWater::sSkipScreenCopy ||
|
||||
(deferred_render && pass == 1)) ? GL_TRUE : GL_FALSE);
|
||||
LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
|
||||
|
||||
if (deferred_render && pass == 1)
|
||||
{
|
||||
@@ -309,11 +294,11 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX);
|
||||
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderAlpha(getVertexDataMask());
|
||||
renderAlpha(getVertexDataMask(), pass);
|
||||
}
|
||||
|
||||
gGL.setColorMask(true, false);
|
||||
@@ -335,7 +320,7 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
}
|
||||
|
||||
gGL.diffuseColor4f(0.9,0,0,0.4);
|
||||
gGL.diffuseColor4f(1,0,0,1);
|
||||
|
||||
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
|
||||
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
|
||||
@@ -386,7 +371,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
|
||||
{
|
||||
BOOL initialized_lighting = FALSE;
|
||||
BOOL light_enabled = TRUE;
|
||||
@@ -402,13 +387,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
if (group->mSpatialPartition->mRenderByGroup &&
|
||||
!group->isDead())
|
||||
{
|
||||
bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
|
||||
// All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
|
||||
#if ENABLE_CLASSIC_CLOUDS
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD &&
|
||||
#endif
|
||||
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
|
||||
bool is_particle_or_hud_particle = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|
||||
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CLOUD
|
||||
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
|
||||
|
||||
bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP);
|
||||
|
||||
bool disable_cull = is_particle_or_hud_particle;
|
||||
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
|
||||
|
||||
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
|
||||
|
||||
@@ -422,9 +411,32 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
continue;
|
||||
}
|
||||
|
||||
LLRenderPass::applyModelMatrix(params);
|
||||
// Fix for bug - NORSPEC-271
|
||||
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
|
||||
// We don't want the nearly invisible objects to cause of DoF effects
|
||||
if(pass == 1 && !LLPipeline::sImpostorRender)
|
||||
{
|
||||
LLFace* face = params.mFace;
|
||||
if(face)
|
||||
{
|
||||
const LLTextureEntry* tep = face->getTextureEntry();
|
||||
if(tep)
|
||||
{
|
||||
if(tep->getColor().mV[3] < 0.1f)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLRenderPass::applyModelMatrix(params);
|
||||
|
||||
LLMaterial* mat = NULL;
|
||||
|
||||
if (deferred_render)
|
||||
{
|
||||
mat = params.mMaterial;
|
||||
}
|
||||
|
||||
if (params.mFullbright)
|
||||
{
|
||||
// Turn off lighting if it hasn't already been so.
|
||||
@@ -455,13 +467,37 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
light_enabled = TRUE;
|
||||
}
|
||||
|
||||
if (deferred_render && mat)
|
||||
{
|
||||
U32 mask = params.mShaderMask;
|
||||
|
||||
llassert(mask < LLMaterial::SHADER_COUNT);
|
||||
target_shader = &(gDeferredMaterialProgram[mask]);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
target_shader = &(gDeferredMaterialWaterProgram[mask]);
|
||||
}
|
||||
|
||||
// If we need shaders, and we're not ALREADY using the proper shader, then bind it
|
||||
// (this way we won't rebind shaders unnecessarily).
|
||||
if(use_shaders && (current_shader != target_shader))
|
||||
if (current_shader != target_shader)
|
||||
{
|
||||
gPipeline.bindDeferredShader(*target_shader);
|
||||
}
|
||||
}
|
||||
else if (!params.mFullbright)
|
||||
{
|
||||
llassert(target_shader != NULL);
|
||||
target_shader = simple_shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
target_shader = fullbright_shader;
|
||||
}
|
||||
|
||||
if(use_shaders && (current_shader != target_shader))
|
||||
{// If we need shaders, and we're not ALREADY using the proper shader, then bind it
|
||||
// (this way we won't rebind shaders unnecessarily).
|
||||
current_shader = target_shader;
|
||||
current_shader->bind();
|
||||
}
|
||||
@@ -470,6 +506,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
LLGLSLShader::bindNoShader();
|
||||
current_shader = NULL;
|
||||
}
|
||||
|
||||
if (use_shaders && mat)
|
||||
{
|
||||
// We have a material. Supply the appropriate data here.
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
|
||||
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
|
||||
current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
|
||||
|
||||
if (params.mNormalMap)
|
||||
{
|
||||
params.mNormalMap->addTextureStats(params.mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
|
||||
}
|
||||
|
||||
if (params.mSpecularMap)
|
||||
{
|
||||
params.mSpecularMap->addTextureStats(params.mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
|
||||
{
|
||||
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
|
||||
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
|
||||
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
|
||||
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
|
||||
}
|
||||
|
||||
if (params.mGroup)
|
||||
{
|
||||
@@ -493,7 +561,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
params.mTexture->addTextureStats(params.mVSize);
|
||||
gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
|
||||
if (use_shaders && mat)
|
||||
{
|
||||
current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(params.mTexture, TRUE);
|
||||
}
|
||||
|
||||
if (params.mTextureMatrix)
|
||||
{
|
||||
tex_setup = true;
|
||||
@@ -509,9 +585,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
params.mVertexBuffer->setBuffer(mask);
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_PUSH);
|
||||
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
|
||||
params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
|
||||
|
||||
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
|
||||
}
|
||||
|
||||
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
|
||||
if (current_shader &&
|
||||
@@ -547,6 +629,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
if (!light_enabled)
|
||||
|
||||
@@ -56,11 +56,6 @@ public:
|
||||
LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
|
||||
/*virtual*/ ~LLDrawPoolAlpha();
|
||||
|
||||
/*virtual*/ S32 getNumDeferredPasses();
|
||||
/*virtual*/ void beginDeferredPass(S32 pass);
|
||||
/*virtual*/ void endDeferredPass(S32 pass);
|
||||
/*virtual*/ void renderDeferred(S32 pass);
|
||||
|
||||
/*virtual*/ S32 getNumPostDeferredPasses();
|
||||
/*virtual*/ void beginPostDeferredPass(S32 pass);
|
||||
/*virtual*/ void endPostDeferredPass(S32 pass);
|
||||
@@ -74,9 +69,9 @@ public:
|
||||
/*virtual*/ void prerender();
|
||||
|
||||
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
|
||||
void renderAlpha(U32 mask);
|
||||
void renderAlpha(U32 mask, S32 pass);
|
||||
void renderAlphaHighlight(U32 mask);
|
||||
|
||||
|
||||
static BOOL sShowDebugAlpha;
|
||||
|
||||
private:
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "llappviewer.h"
|
||||
#include "llrendersphere.h"
|
||||
#include "llviewerpartsim.h"
|
||||
#include "llviewercontrol.h" // for gSavedSettings
|
||||
|
||||
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
|
||||
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
|
||||
@@ -65,9 +66,11 @@ LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
|
||||
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
|
||||
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
|
||||
S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
|
||||
F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;
|
||||
|
||||
|
||||
static bool is_deferred_render = false;
|
||||
static bool is_post_deferred_render = false;
|
||||
|
||||
extern BOOL gUseGLPick;
|
||||
|
||||
@@ -197,6 +200,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
|
||||
case 4:
|
||||
beginDeferredRiggedBump();
|
||||
break;
|
||||
default:
|
||||
beginDeferredRiggedMaterial(pass-5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,6 +235,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
|
||||
case 4:
|
||||
endDeferredRiggedBump();
|
||||
break;
|
||||
default:
|
||||
endDeferredRiggedMaterial(pass-5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +248,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)
|
||||
|
||||
S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
|
||||
{
|
||||
return 6;
|
||||
return 10;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
|
||||
@@ -261,9 +270,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
|
||||
case 4:
|
||||
beginRiggedFullbrightAlpha();
|
||||
break;
|
||||
case 5:
|
||||
case 9:
|
||||
beginRiggedGlow();
|
||||
break;
|
||||
default:
|
||||
beginDeferredRiggedMaterialAlpha(pass-5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +288,7 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
|
||||
|
||||
gPipeline.bindDeferredShader(*sVertexProgram);
|
||||
|
||||
sVertexProgram->setMinimumAlpha(0.2f);
|
||||
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
|
||||
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
}
|
||||
@@ -289,11 +301,34 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
|
||||
{
|
||||
switch (pass)
|
||||
{
|
||||
case 0: pass = 1; break;
|
||||
case 1: pass = 5; break;
|
||||
case 2: pass = 9; break;
|
||||
default: pass = 13; break;
|
||||
}
|
||||
pass += LLMaterial::SHADER_COUNT;
|
||||
sVertexProgram = &gDeferredMaterialProgram[pass];
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
sVertexProgram = &(gDeferredMaterialWaterProgram[pass]);
|
||||
}
|
||||
gPipeline.bindDeferredShader(*sVertexProgram);
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
|
||||
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
gPipeline.enableLightsDynamic();
|
||||
}
|
||||
void LLDrawPoolAvatar::endDeferredRiggedAlpha()
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
gPipeline.unbindDeferredShader(*sVertexProgram);
|
||||
sDiffuseChannel = 0;
|
||||
normal_channel = -1;
|
||||
specular_channel = -1;
|
||||
sVertexProgram = NULL;
|
||||
}
|
||||
|
||||
@@ -319,6 +354,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
|
||||
case 5:
|
||||
endRiggedGlow();
|
||||
break;
|
||||
default:
|
||||
endDeferredRiggedAlpha();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,16 +381,22 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
|
||||
7, //rigged alpha
|
||||
8, //rigged fullbright alpha
|
||||
9, //rigged glow
|
||||
10,//rigged material alpha 2
|
||||
11,//rigged material alpha 3
|
||||
12,//rigged material alpha 4
|
||||
13, //rigged glow
|
||||
};
|
||||
|
||||
pass = actual_pass[pass];
|
||||
S32 p = actual_pass[pass];
|
||||
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{ //HACK for impostors so actual pass ends up being proper pass
|
||||
pass -= 2;
|
||||
p -= 2;
|
||||
}
|
||||
|
||||
render(pass);
|
||||
is_post_deferred_render = true;
|
||||
render(p);
|
||||
is_post_deferred_render = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -439,12 +483,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
|
||||
}
|
||||
else
|
||||
{
|
||||
renderRigged(avatarp, RIGGED_SIMPLE);
|
||||
renderRigged(avatarp, RIGGED_ALPHA);
|
||||
renderRigged(avatarp, RIGGED_FULLBRIGHT);
|
||||
renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
|
||||
renderRigged(avatarp, RIGGED_SHINY);
|
||||
renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
|
||||
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
|
||||
{
|
||||
renderRigged(avatarp, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,11 +507,11 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
|
||||
{
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
return 3;
|
||||
return 19;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 5;
|
||||
return 21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,7 +666,7 @@ void LLDrawPoolAvatar::beginRigid()
|
||||
if (sVertexProgram != NULL)
|
||||
{ //eyeballs render with the specular shader
|
||||
sVertexProgram->bind();
|
||||
sVertexProgram->setMinimumAlpha(0.2f);
|
||||
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -666,8 +708,9 @@ void LLDrawPoolAvatar::endDeferredImpostor()
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
sVertexProgram->unbind();
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gPipeline.unbindDeferredShader(*sVertexProgram);
|
||||
sVertexProgram = NULL;
|
||||
sDiffuseChannel = 0;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredRigid()
|
||||
@@ -675,7 +718,7 @@ void LLDrawPoolAvatar::beginDeferredRigid()
|
||||
sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
sVertexProgram->bind();
|
||||
sVertexProgram->setMinimumAlpha(0.2f);
|
||||
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::endDeferredRigid()
|
||||
@@ -733,7 +776,7 @@ void LLDrawPoolAvatar::beginSkinned()
|
||||
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
sVertexProgram->setMinimumAlpha(0.2f);
|
||||
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,6 +896,9 @@ void LLDrawPoolAvatar::beginRiggedGlow()
|
||||
{
|
||||
sDiffuseChannel = 0;
|
||||
sVertexProgram->bind();
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
|
||||
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
//sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,7 +917,14 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
sVertexProgram = &gDeferredSkinnedFullbrightProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
sVertexProgram = &gSkinnedObjectFullbrightProgram;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -890,6 +943,16 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
|
||||
{
|
||||
sDiffuseChannel = 0;
|
||||
sVertexProgram->bind();
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
//sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,7 +1019,14 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -976,6 +1046,16 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
|
||||
{
|
||||
sVertexProgram->bind();
|
||||
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
//F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
|
||||
//sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1024,6 +1104,43 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
|
||||
sVertexProgram = NULL;
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
|
||||
{
|
||||
if (pass == 1 ||
|
||||
pass == 5 ||
|
||||
pass == 9 ||
|
||||
pass == 13)
|
||||
{ //skip alpha passes
|
||||
return;
|
||||
}
|
||||
sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]);
|
||||
}
|
||||
sVertexProgram->bind();
|
||||
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
|
||||
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
}
|
||||
void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
|
||||
{
|
||||
if (pass == 1 ||
|
||||
pass == 5 ||
|
||||
pass == 9 ||
|
||||
pass == 13)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLVertexBuffer::unbind();
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
|
||||
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
sVertexProgram->unbind();
|
||||
normal_channel = -1;
|
||||
sDiffuseChannel = 0;
|
||||
sVertexProgram = NULL;
|
||||
}
|
||||
void LLDrawPoolAvatar::beginDeferredSkinned()
|
||||
{
|
||||
sShaderLevel = mVertexShaderLevel;
|
||||
@@ -1031,7 +1148,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
|
||||
sRenderingSkinned = TRUE;
|
||||
|
||||
sVertexProgram->bind();
|
||||
sVertexProgram->setMinimumAlpha(0.2f);
|
||||
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
|
||||
|
||||
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
@@ -1184,6 +1301,21 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
else
|
||||
{
|
||||
renderRiggedSimple(avatarp);
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{ //render "simple" materials
|
||||
renderRigged(avatarp, RIGGED_MATERIAL);
|
||||
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
|
||||
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_MASK);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP_MASK);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
|
||||
renderRigged(avatarp, RIGGED_NORMSPEC);
|
||||
renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
|
||||
renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1202,6 +1334,18 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_deferred_render && pass >= 5 && pass <= 21)
|
||||
{
|
||||
S32 p = pass-5;
|
||||
if (p != 1 &&
|
||||
p != 5 &&
|
||||
p != 9 &&
|
||||
p != 13)
|
||||
{
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (pass == 5)
|
||||
{
|
||||
renderRiggedShinySimple(avatarp);
|
||||
@@ -1214,11 +1358,26 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
return;
|
||||
}
|
||||
|
||||
if (pass >= 7 && pass < 9)
|
||||
if (pass >= 7 && pass < 13)
|
||||
{
|
||||
if (pass == 7)
|
||||
{
|
||||
renderRiggedAlpha(avatarp);
|
||||
if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
|
||||
{ //render transparent materials under water
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.setColorMask(true, true);
|
||||
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
|
||||
LLRender::BF_ZERO,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
|
||||
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
|
||||
renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
|
||||
renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
|
||||
renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
gGL.setColorMask(true, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1227,9 +1386,30 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
renderRiggedFullbrightAlpha(avatarp);
|
||||
return;
|
||||
}
|
||||
if (LLPipeline::sRenderDeferred && is_post_deferred_render)
|
||||
{
|
||||
S32 p = 0;
|
||||
switch (pass)
|
||||
{
|
||||
case 9: p = 1; break;
|
||||
case 10: p = 5; break;
|
||||
case 11: p = 9; break;
|
||||
case 12: p = 13; break;
|
||||
}
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
renderDeferredRiggedMaterial(avatarp, p);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (pass == 9)
|
||||
{
|
||||
renderRiggedGlow(avatarp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pass == 9)
|
||||
if (pass == 13)
|
||||
{
|
||||
renderRiggedGlow(avatarp);
|
||||
|
||||
@@ -1267,27 +1447,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
{
|
||||
LLVector4a* weight = vol_face.mWeights;
|
||||
if (!weight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
|
||||
U32 data_mask = face->getRiggedVertexBufferDataMask();
|
||||
|
||||
if (buffer.isNull() ||
|
||||
buffer->getTypeMask() != data_mask ||
|
||||
buffer->getNumVerts() != vol_face.mNumVertices ||
|
||||
buffer->getNumIndices() != vol_face.mNumIndices ||
|
||||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
|
||||
{
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
face->setGeomIndex(0);
|
||||
face->setIndicesIndex(0);
|
||||
|
||||
//rigged faces do not batch textures
|
||||
face->setTextureIndex(255);
|
||||
@@ -1334,12 +1497,55 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
}
|
||||
else
|
||||
{
|
||||
face->setPoolType(LLDrawPool::POOL_AVATAR);
|
||||
face->setPoolType(LLDrawPool::POOL_AVATAR);
|
||||
}
|
||||
|
||||
//llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
|
||||
|
||||
buffer->flush();
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
|
||||
{
|
||||
LLVector4a* weight = vol_face.mWeights;
|
||||
if (!weight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
|
||||
LLDrawable* drawable = face->getDrawable();
|
||||
|
||||
U32 data_mask = face->getRiggedVertexBufferDataMask();
|
||||
|
||||
if (buffer.isNull() ||
|
||||
buffer->getTypeMask() != data_mask ||
|
||||
buffer->getNumVerts() != vol_face.mNumVertices ||
|
||||
buffer->getNumIndices() != vol_face.mNumIndices ||
|
||||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
|
||||
{
|
||||
if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
|
||||
{ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
|
||||
{
|
||||
LLFace* facep = drawable->getFace(i);
|
||||
U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
|
||||
if (face_data_mask)
|
||||
{
|
||||
LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
|
||||
const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
|
||||
getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
|
||||
}
|
||||
}
|
||||
drawable->clearState(LLDrawable::REBUILD_ALL);
|
||||
|
||||
buffer = face->getVertexBuffer();
|
||||
}
|
||||
else
|
||||
{ //just rebuild this face
|
||||
getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
|
||||
}
|
||||
|
||||
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
|
||||
|
||||
buffer->flush();
|
||||
}
|
||||
|
||||
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
|
||||
@@ -1426,11 +1632,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
|
||||
{
|
||||
drawable->clearState(LLDrawable::REBUILD_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
@@ -1531,13 +1732,62 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
|
||||
}*/
|
||||
|
||||
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
|
||||
if (normal_channel > -1)
|
||||
const LLTextureEntry* te = face->getTextureEntry();
|
||||
LLMaterial* mat = te->getMaterialParams().get();
|
||||
|
||||
if (mat)
|
||||
{
|
||||
LLDrawPoolBump::bindBumpMap(face, normal_channel);
|
||||
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
|
||||
gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
|
||||
gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));
|
||||
|
||||
LLColor4 col = mat->getSpecularLightColor();
|
||||
F32 spec = mat->getSpecularLightExponent()/255.f;
|
||||
|
||||
F32 env = mat->getEnvironmentIntensity()/255.f;
|
||||
|
||||
if (mat->getSpecularID().isNull())
|
||||
{
|
||||
env = te->getShiny()*0.25f;
|
||||
col.set(env,env,env,0);
|
||||
spec = env;
|
||||
}
|
||||
|
||||
BOOL fullbright = te->getFullbright();
|
||||
|
||||
sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
|
||||
sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
|
||||
sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
|
||||
|
||||
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
sVertexProgram->setMinimumAlpha(0.f);
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
LLViewerTexture* tex = face->getTexture(i);
|
||||
if (tex)
|
||||
{
|
||||
tex->addTextureStats(avatar->getPixelArea());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
|
||||
sVertexProgram->setMinimumAlpha(0.f);
|
||||
if (normal_channel > -1)
|
||||
{
|
||||
LLDrawPoolBump::bindBumpMap(face, normal_channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (face->mTextureMatrix)
|
||||
if (face->mTextureMatrix && vobj->mTexAnimMode)
|
||||
{
|
||||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
|
||||
@@ -1551,6 +1801,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
buff->setBuffer(data_mask);
|
||||
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
|
||||
}
|
||||
|
||||
gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1565,6 +1817,11 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
|
||||
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
|
||||
{
|
||||
renderRigged(avatar, pass);
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");
|
||||
|
||||
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
|
||||
|
||||
@@ -119,6 +119,8 @@ public:
|
||||
void beginRiggedFullbrightAlpha();
|
||||
void beginRiggedGlow();
|
||||
void beginDeferredRiggedAlpha();
|
||||
void beginDeferredRiggedMaterial(S32 pass);
|
||||
void beginDeferredRiggedMaterialAlpha(S32 pass);
|
||||
|
||||
void endRiggedSimple();
|
||||
void endRiggedFullbright();
|
||||
@@ -128,6 +130,8 @@ public:
|
||||
void endRiggedFullbrightAlpha();
|
||||
void endRiggedGlow();
|
||||
void endDeferredRiggedAlpha();
|
||||
void endDeferredRiggedMaterial(S32 pass);
|
||||
void endDeferredRiggedMaterialAlpha(S32 pass);
|
||||
|
||||
void beginDeferredRiggedSimple();
|
||||
void beginDeferredRiggedBump();
|
||||
@@ -135,6 +139,7 @@ public:
|
||||
void endDeferredRiggedSimple();
|
||||
void endDeferredRiggedBump();
|
||||
|
||||
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
|
||||
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
|
||||
LLFace* facep,
|
||||
const LLMeshSkinInfo* skin,
|
||||
@@ -152,10 +157,27 @@ public:
|
||||
void renderRiggedGlow(LLVOAvatar* avatar);
|
||||
void renderDeferredRiggedSimple(LLVOAvatar* avatar);
|
||||
void renderDeferredRiggedBump(LLVOAvatar* avatar);
|
||||
|
||||
void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RIGGED_SIMPLE = 0,
|
||||
RIGGED_MATERIAL=0,
|
||||
RIGGED_MATERIAL_ALPHA,
|
||||
RIGGED_MATERIAL_ALPHA_MASK,
|
||||
RIGGED_MATERIAL_ALPHA_EMISSIVE,
|
||||
RIGGED_SPECMAP,
|
||||
RIGGED_SPECMAP_BLEND,
|
||||
RIGGED_SPECMAP_MASK,
|
||||
RIGGED_SPECMAP_EMISSIVE,
|
||||
RIGGED_NORMMAP,
|
||||
RIGGED_NORMMAP_BLEND,
|
||||
RIGGED_NORMMAP_MASK,
|
||||
RIGGED_NORMMAP_EMISSIVE,
|
||||
RIGGED_NORMSPEC,
|
||||
RIGGED_NORMSPEC_BLEND,
|
||||
RIGGED_NORMSPEC_MASK,
|
||||
RIGGED_NORMSPEC_EMISSIVE,
|
||||
RIGGED_SIMPLE,
|
||||
RIGGED_FULLBRIGHT,
|
||||
RIGGED_SHINY,
|
||||
RIGGED_FULLBRIGHT_SHINY,
|
||||
@@ -170,6 +192,48 @@ public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RIGGED_MATERIAL_MASK =
|
||||
LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4,
|
||||
RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK,
|
||||
RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK,
|
||||
RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK,
|
||||
RIGGED_SPECMAP_VMASK =
|
||||
LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_TEXCOORD2 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4,
|
||||
RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK,
|
||||
RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK,
|
||||
RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK,
|
||||
RIGGED_NORMMAP_VMASK =
|
||||
LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TANGENT |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_TEXCOORD1 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4,
|
||||
RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK,
|
||||
RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK,
|
||||
RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK,
|
||||
RIGGED_NORMSPEC_VMASK =
|
||||
LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TANGENT |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_TEXCOORD1 |
|
||||
LLVertexBuffer::MAP_TEXCOORD2 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_WEIGHT4,
|
||||
RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK,
|
||||
RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK,
|
||||
RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,
|
||||
RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
@@ -214,6 +278,7 @@ public:
|
||||
static BOOL sSkipOpaque;
|
||||
static BOOL sSkipTransparent;
|
||||
static S32 sDiffuseChannel;
|
||||
static F32 sMinimumAlpha;
|
||||
|
||||
static LLGLSLShader* sVertexProgram;
|
||||
};
|
||||
|
||||
@@ -456,9 +456,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
|
||||
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
|
||||
if( cube_map )
|
||||
{
|
||||
cube_map->disable();
|
||||
cube_map->restoreMatrix();
|
||||
|
||||
if (!invisible && shader_level > 1)
|
||||
{
|
||||
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
|
||||
@@ -471,6 +468,10 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
|
||||
}
|
||||
}
|
||||
}
|
||||
// Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
|
||||
// MAINT-755
|
||||
cube_map->disable();
|
||||
cube_map->restoreMatrix();
|
||||
}
|
||||
|
||||
if (!LLGLSLShader::sNoFixedFunction)
|
||||
@@ -521,7 +522,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gObjectFullbrightShinyProgram;
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
shader = &gDeferredFullbrightShinyProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gObjectFullbrightShinyProgram;
|
||||
}
|
||||
}
|
||||
|
||||
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
|
||||
@@ -1381,7 +1389,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
||||
|
||||
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
|
||||
gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getHeight());
|
||||
gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
|
||||
|
||||
LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
|
||||
(F32) bump->getHeight()/gPipeline.mScreen.getHeight());
|
||||
|
||||
224
indra/newview/lldrawpoolmaterials.cpp
Normal file
224
indra/newview/lldrawpoolmaterials.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @file lldrawpool.cpp
|
||||
* @brief LLDrawPoolMaterials class implementation
|
||||
* @author Jonathan "Geenz" Goodman
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "lldrawpoolmaterials.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
S32 diffuse_channel = -1;
|
||||
|
||||
LLDrawPoolMaterials::LLDrawPoolMaterials()
|
||||
: LLRenderPass(LLDrawPool::POOL_MATERIALS)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::prerender()
|
||||
{
|
||||
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
}
|
||||
|
||||
S32 LLDrawPoolMaterials::getNumDeferredPasses()
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
|
||||
{
|
||||
U32 shader_idx[] =
|
||||
{
|
||||
0, //LLRenderPass::PASS_MATERIAL,
|
||||
//1, //LLRenderPass::PASS_MATERIAL_ALPHA,
|
||||
2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
|
||||
3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW,
|
||||
4, //LLRenderPass::PASS_SPECMAP,
|
||||
//5, //LLRenderPass::PASS_SPECMAP_BLEND,
|
||||
6, //LLRenderPass::PASS_SPECMAP_MASK,
|
||||
7, //LLRenderPass::PASS_SPECMAP_GLOW,
|
||||
8, //LLRenderPass::PASS_NORMMAP,
|
||||
//9, //LLRenderPass::PASS_NORMMAP_BLEND,
|
||||
10, //LLRenderPass::PASS_NORMMAP_MASK,
|
||||
11, //LLRenderPass::PASS_NORMMAP_GLOW,
|
||||
12, //LLRenderPass::PASS_NORMSPEC,
|
||||
//13, //LLRenderPass::PASS_NORMSPEC_BLEND,
|
||||
14, //LLRenderPass::PASS_NORMSPEC_MASK,
|
||||
15, //LLRenderPass::PASS_NORMSPEC_GLOW,
|
||||
};
|
||||
|
||||
mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
|
||||
}
|
||||
|
||||
mShader->bind();
|
||||
|
||||
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
|
||||
|
||||
LLFastTimer t(FTM_RENDER_MATERIALS);
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::endDeferredPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_MATERIALS);
|
||||
|
||||
mShader->unbind();
|
||||
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::renderDeferred(S32 pass)
|
||||
{
|
||||
U32 type_list[] =
|
||||
{
|
||||
LLRenderPass::PASS_MATERIAL,
|
||||
//LLRenderPass::PASS_MATERIAL_ALPHA,
|
||||
LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
|
||||
LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
|
||||
LLRenderPass::PASS_SPECMAP,
|
||||
//LLRenderPass::PASS_SPECMAP_BLEND,
|
||||
LLRenderPass::PASS_SPECMAP_MASK,
|
||||
LLRenderPass::PASS_SPECMAP_EMISSIVE,
|
||||
LLRenderPass::PASS_NORMMAP,
|
||||
//LLRenderPass::PASS_NORMMAP_BLEND,
|
||||
LLRenderPass::PASS_NORMMAP_MASK,
|
||||
LLRenderPass::PASS_NORMMAP_EMISSIVE,
|
||||
LLRenderPass::PASS_NORMSPEC,
|
||||
//LLRenderPass::PASS_NORMSPEC_BLEND,
|
||||
LLRenderPass::PASS_NORMSPEC_MASK,
|
||||
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
|
||||
};
|
||||
|
||||
llassert(pass < sizeof(type_list)/sizeof(U32));
|
||||
|
||||
U32 type = type_list[pass];
|
||||
|
||||
U32 mask = mShader->mAttributeMask;
|
||||
|
||||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
|
||||
mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
|
||||
|
||||
if (params.mNormalMap)
|
||||
{
|
||||
params.mNormalMap->addTextureStats(params.mVSize);
|
||||
bindNormalMap(params.mNormalMap);
|
||||
}
|
||||
|
||||
if (params.mSpecularMap)
|
||||
{
|
||||
params.mSpecularMap->addTextureStats(params.mVSize);
|
||||
bindSpecularMap(params.mSpecularMap);
|
||||
}
|
||||
|
||||
mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
|
||||
mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
|
||||
|
||||
pushBatch(params, mask, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
|
||||
{
|
||||
mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
|
||||
{
|
||||
mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
|
||||
}
|
||||
|
||||
void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
applyModelMatrix(params);
|
||||
|
||||
bool tex_setup = false;
|
||||
|
||||
if (batch_textures && params.mTextureList.size() > 1)
|
||||
{
|
||||
for (U32 i = 0; i < params.mTextureList.size(); ++i)
|
||||
{
|
||||
if (params.mTextureList[i].notNull())
|
||||
{
|
||||
gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
|
||||
if (params.mTextureMatrix)
|
||||
{
|
||||
//if (mShiny)
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
}
|
||||
|
||||
gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
|
||||
gPipeline.mTextureMatrixOps++;
|
||||
|
||||
tex_setup = true;
|
||||
}
|
||||
|
||||
if (mVertexShaderLevel > 1 && texture)
|
||||
{
|
||||
if (params.mTexture.notNull())
|
||||
{
|
||||
gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
|
||||
params.mTexture->addTextureStats(params.mVSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.mGroup)
|
||||
{
|
||||
params.mGroup->rebuildMesh();
|
||||
}
|
||||
params.mVertexBuffer->setBuffer(mask);
|
||||
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
|
||||
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
|
||||
if (tex_setup)
|
||||
{
|
||||
gGL.getTexUnit(0)->activate();
|
||||
gGL.loadIdentity();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
75
indra/newview/lldrawpoolmaterials.h
Normal file
75
indra/newview/lldrawpoolmaterials.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lldrawpoolmaterials.h
|
||||
* @brief LLDrawPoolMaterials class definition
|
||||
* @author Jonathan "Geenz" Goodman
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLDRAWPOOLMATERIALS_H
|
||||
#define LL_LLDRAWPOOLMATERIALS_H
|
||||
|
||||
#include "v4coloru.h"
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "llvertexbuffer.h"
|
||||
#include "lldrawpool.h"
|
||||
|
||||
class LLViewerTexture;
|
||||
class LLDrawInfo;
|
||||
class LLGLSLShader;
|
||||
|
||||
class LLDrawPoolMaterials : public LLRenderPass
|
||||
{
|
||||
LLGLSLShader *mShader;
|
||||
public:
|
||||
LLDrawPoolMaterials();
|
||||
|
||||
enum
|
||||
{
|
||||
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_TEXCOORD1 |
|
||||
LLVertexBuffer::MAP_TEXCOORD2 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_TANGENT
|
||||
};
|
||||
|
||||
/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
|
||||
|
||||
/*virtual*/ void render(S32 pass = 0) { }
|
||||
/*virtual*/ S32 getNumPasses() {return 0;}
|
||||
/*virtual*/ void prerender();
|
||||
|
||||
/*virtual*/ S32 getNumDeferredPasses();
|
||||
/*virtual*/ void beginDeferredPass(S32 pass);
|
||||
/*virtual*/ void endDeferredPass(S32 pass);
|
||||
/*virtual*/ void renderDeferred(S32 pass);
|
||||
|
||||
void bindSpecularMap(LLViewerTexture* tex);
|
||||
void bindNormalMap(LLViewerTexture* tex);
|
||||
|
||||
/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
|
||||
};
|
||||
|
||||
#endif //LL_LLDRAWPOOLMATERIALS_H
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llrender.h"
|
||||
|
||||
#define GE_FORCE_WORKAROUND LL_DARWIN
|
||||
|
||||
static LLGLSLShader* simple_shader = NULL;
|
||||
static LLGLSLShader* fullbright_shader = NULL;
|
||||
@@ -47,6 +48,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
|
||||
void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
gDeferredEmissiveProgram.bind();
|
||||
gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push");
|
||||
@@ -110,6 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
|
||||
|
||||
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
|
||||
shader->bind();
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{
|
||||
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
|
||||
}
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
gGL.setColorMask(false, true);
|
||||
@@ -146,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_SIMPLE);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleImpostorProgram;
|
||||
}
|
||||
else if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterProgram;
|
||||
}
|
||||
@@ -198,7 +212,11 @@ void LLDrawPoolSimple::render(S32 pass)
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{ //if deferred rendering is enabled, bump faces aren't registered as simple
|
||||
//render bump faces here as simple so bump faces will appear under water
|
||||
pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -210,6 +228,169 @@ void LLDrawPoolSimple::render(S32 pass)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask");
|
||||
|
||||
LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
|
||||
LLRenderPass(POOL_ALPHA_MASK)
|
||||
{
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::prerender()
|
||||
{
|
||||
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_shader = &gObjectSimpleAlphaMaskProgram;
|
||||
}
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
simple_shader->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't use shaders!
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
stop_glerror();
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
stop_glerror();
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
simple_shader->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::render(S32 pass)
|
||||
{
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
simple_shader->bind();
|
||||
simple_shader->setMinimumAlpha(0.33f);
|
||||
|
||||
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLGLEnable test(GL_ALPHA_TEST);
|
||||
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
|
||||
}
|
||||
}
|
||||
|
||||
LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
|
||||
LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK)
|
||||
{
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::prerender()
|
||||
{
|
||||
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
simple_shader = &gObjectFullbrightWaterAlphaMaskProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_shader = &gObjectFullbrightAlphaMaskProgram;
|
||||
}
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
simple_shader->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't use shaders!
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
LLGLSLShader::bindNoShader();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
stop_glerror();
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
stop_glerror();
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
simple_shader->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
|
||||
|
||||
if (mVertexShaderLevel > 0)
|
||||
{
|
||||
if (simple_shader)
|
||||
{
|
||||
simple_shader->bind();
|
||||
simple_shader->setMinimumAlpha(0.33f);
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
|
||||
} else {
|
||||
simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
}
|
||||
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
//LLGLSLShader::bindNoShader();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLGLEnable test(GL_ALPHA_TEST);
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
|
||||
gPipeline.enableLightsDynamic();
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
|
||||
}
|
||||
}
|
||||
|
||||
//===============================
|
||||
//DEFERRED IMPLEMENTATION
|
||||
//===============================
|
||||
@@ -239,6 +420,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
|
||||
}
|
||||
}
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
|
||||
|
||||
void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED);
|
||||
gDeferredDiffuseAlphaMaskProgram.bind();
|
||||
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
|
||||
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
|
||||
gDeferredDiffuseAlphaMaskProgram.unbind();
|
||||
}
|
||||
|
||||
|
||||
// grass drawpool
|
||||
LLDrawPoolGrass::LLDrawPoolGrass() :
|
||||
LLRenderPass(POOL_GRASS)
|
||||
@@ -345,7 +548,15 @@ void LLDrawPoolFullbright::prerender()
|
||||
|
||||
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
gDeferredFullbrightProgram.bind();
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightWaterProgram.bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightProgram.bind();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
|
||||
@@ -362,9 +573,15 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
|
||||
|
||||
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
gDeferredFullbrightProgram.unbind();
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightWaterProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightProgram.unbind();
|
||||
}
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbright::beginRenderPass(S32 pass)
|
||||
@@ -407,14 +624,24 @@ void LLDrawPoolFullbright::render(S32 pass)
|
||||
{
|
||||
fullbright_shader->bind();
|
||||
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
|
||||
fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
|
||||
|
||||
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
|
||||
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
|
||||
pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
|
||||
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
|
||||
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
|
||||
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
|
||||
pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask);
|
||||
pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask);
|
||||
pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
@@ -425,3 +652,75 @@ S32 LLDrawPoolFullbright::getNumPasses()
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
|
||||
{
|
||||
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Work-around until we can figure out why the right shader causes
|
||||
// the GeForce driver to go tango uniform on OS X 10.6.8 only
|
||||
//
|
||||
#if GE_FORCE_WORKAROUND
|
||||
gObjectFullbrightAlphaMaskProgram.bind();
|
||||
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
#else
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.bind();
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskProgram.bind();
|
||||
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
|
||||
{
|
||||
LLFastTimer t(FTM_RENDER_FULLBRIGHT);
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
|
||||
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
|
||||
}
|
||||
|
||||
void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
|
||||
{
|
||||
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
|
||||
{
|
||||
gObjectFullbrightAlphaMaskProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Work-around until we can figure out why the right shader causes
|
||||
// the GeForce driver to go tango uniform on OS X 10.6.8 only
|
||||
//
|
||||
#if GE_FORCE_WORKAROUND
|
||||
gObjectFullbrightAlphaMaskProgram.unbind();
|
||||
#else
|
||||
if (LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskWaterProgram.unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDeferredFullbrightAlphaMaskProgram.unbind();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
LLRenderPass::endRenderPass(pass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,6 +90,59 @@ public:
|
||||
/*virtual*/ void prerender();
|
||||
};
|
||||
|
||||
class LLDrawPoolAlphaMask : public LLRenderPass
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR
|
||||
};
|
||||
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
|
||||
|
||||
LLDrawPoolAlphaMask();
|
||||
|
||||
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
|
||||
/*virtual*/ void beginDeferredPass(S32 pass);
|
||||
/*virtual*/ void endDeferredPass(S32 pass);
|
||||
/*virtual*/ void renderDeferred(S32 pass);
|
||||
|
||||
/*virtual*/ S32 getNumPasses() { return 1; }
|
||||
/*virtual*/ void beginRenderPass(S32 pass);
|
||||
/*virtual*/ void endRenderPass(S32 pass);
|
||||
/*virtual*/ void render(S32 pass = 0);
|
||||
/*virtual*/ void prerender();
|
||||
|
||||
};
|
||||
|
||||
class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR
|
||||
};
|
||||
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
|
||||
|
||||
LLDrawPoolFullbrightAlphaMask();
|
||||
|
||||
/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
|
||||
/*virtual*/ void beginPostDeferredPass(S32 pass);
|
||||
/*virtual*/ void endPostDeferredPass(S32 pass);
|
||||
/*virtual*/ void renderPostDeferred(S32 pass);
|
||||
|
||||
/*virtual*/ S32 getNumPasses() { return 1; }
|
||||
/*virtual*/ void beginRenderPass(S32 pass);
|
||||
/*virtual*/ void endRenderPass(S32 pass);
|
||||
/*virtual*/ void render(S32 pass = 0);
|
||||
/*virtual*/ void prerender();
|
||||
};
|
||||
|
||||
|
||||
class LLDrawPoolFullbright : public LLRenderPass
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -564,14 +564,21 @@ void LLDrawPoolWater::shade()
|
||||
|
||||
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
|
||||
|
||||
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
|
||||
{
|
||||
if (deferred_render)
|
||||
{
|
||||
shader = &gDeferredWaterProgram;
|
||||
shader = &gDeferredUnderWaterProgram;
|
||||
}
|
||||
else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
|
||||
else
|
||||
{
|
||||
shader = &gUnderWaterProgram;
|
||||
}
|
||||
}
|
||||
else if (deferred_render)
|
||||
{
|
||||
shader = &gDeferredWaterProgram;
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gWaterProgram;
|
||||
@@ -592,7 +599,7 @@ void LLDrawPoolWater::shade()
|
||||
sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
|
||||
}
|
||||
|
||||
S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
|
||||
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
|
||||
|
||||
if (reftex > -1)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "llvoavatar.h"
|
||||
|
||||
#define LL_MAX_INDICES_COUNT 1000000
|
||||
|
||||
@@ -140,9 +142,13 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
||||
|
||||
//special value to indicate uninitialized position
|
||||
mIndicesIndex = 0xFFFFFFFF;
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mIndexInTex[i] = 0;
|
||||
mTexture[i] = NULL;
|
||||
}
|
||||
|
||||
mIndexInTex = 0;
|
||||
mTexture = NULL;
|
||||
mTEOffset = -1;
|
||||
mTextureIndex = 255;
|
||||
|
||||
@@ -169,9 +175,12 @@ void LLFace::destroy()
|
||||
gPipeline.checkReferences(this);
|
||||
}
|
||||
|
||||
if(mTexture.notNull())
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
mTexture->removeFace(this) ;
|
||||
if(mTexture[i].notNull())
|
||||
{
|
||||
mTexture[i]->removeFace(i, this) ;
|
||||
}
|
||||
}
|
||||
|
||||
if (isState(LLFace::PARTICLE))
|
||||
@@ -264,47 +273,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
|
||||
setTexture(texturep) ;
|
||||
}
|
||||
|
||||
void LLFace::setTexture(LLViewerTexture* tex)
|
||||
void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
|
||||
{
|
||||
if(mTexture == tex)
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mTexture[ch] == tex)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(mTexture.notNull())
|
||||
if(mTexture[ch].notNull())
|
||||
{
|
||||
mTexture->removeFace(this) ;
|
||||
}
|
||||
mTexture[ch]->removeFace(ch, this) ;
|
||||
}
|
||||
|
||||
if(tex)
|
||||
{
|
||||
tex->addFace(this) ;
|
||||
tex->addFace(ch, this) ;
|
||||
}
|
||||
|
||||
mTexture = tex ;
|
||||
mTexture[ch] = tex ;
|
||||
}
|
||||
|
||||
void LLFace::setTexture(LLViewerTexture* tex)
|
||||
{
|
||||
setDiffuseMap(tex);
|
||||
}
|
||||
|
||||
void LLFace::setDiffuseMap(LLViewerTexture* tex)
|
||||
{
|
||||
setTexture(LLRender::DIFFUSE_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::setNormalMap(LLViewerTexture* tex)
|
||||
{
|
||||
setTexture(LLRender::NORMAL_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::setSpecularMap(LLViewerTexture* tex)
|
||||
{
|
||||
setTexture(LLRender::SPECULAR_MAP, tex);
|
||||
}
|
||||
|
||||
void LLFace::dirtyTexture()
|
||||
{
|
||||
LLDrawable* drawablep = getDrawable();
|
||||
|
||||
if (mVObjp.notNull() && mVObjp->getVolume() &&
|
||||
mTexture.notNull() && mTexture->getComponents() == 4)
|
||||
{ //dirty texture on an alpha object should be treated as an LoD update
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (vobj)
|
||||
if (mVObjp.notNull() && mVObjp->getVolume())
|
||||
{
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
{
|
||||
vobj->mLODChanged = TRUE;
|
||||
if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
|
||||
{ //dirty texture on an alpha object should be treated as an LoD update
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
vobj->mLODChanged = TRUE;
|
||||
}
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
}
|
||||
}
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
gPipeline.markTextured(drawablep);
|
||||
}
|
||||
|
||||
void LLFace::switchTexture(LLViewerTexture* new_texture)
|
||||
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
|
||||
{
|
||||
if(mTexture == new_texture)
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
if(mTexture[ch] == new_texture)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
@@ -314,10 +352,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
|
||||
llerrs << "Can not switch to a null texture." << llendl;
|
||||
return;
|
||||
}
|
||||
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
|
||||
|
||||
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
|
||||
setTexture(new_texture) ;
|
||||
llassert(mTexture[ch].notNull());
|
||||
|
||||
new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
|
||||
|
||||
if (ch == LLRender::DIFFUSE_MAP)
|
||||
{
|
||||
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
|
||||
}
|
||||
|
||||
setTexture(ch, new_texture) ;
|
||||
dirtyTexture();
|
||||
}
|
||||
|
||||
@@ -737,7 +782,7 @@ bool less_than_max_mag(const LLVector4a& vec)
|
||||
}
|
||||
|
||||
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
|
||||
const LLMatrix4& mat_vert_in, BOOL global_volume)
|
||||
{
|
||||
//get bounding box
|
||||
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
|
||||
@@ -746,16 +791,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
LLMatrix4a mat_vert;
|
||||
mat_vert.loadu(mat_vert_in);
|
||||
|
||||
LLMatrix4a mat_normal;
|
||||
mat_normal.loadu(mat_normal_in);
|
||||
|
||||
//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
|
||||
//{ //vertex buffer no longer valid
|
||||
// mVertexBuffer = NULL;
|
||||
// mLastVertexBuffer = NULL;
|
||||
//}
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLVector4a min,max;
|
||||
|
||||
if (f >= volume.getNumVolumeFaces())
|
||||
@@ -772,100 +807,68 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
llassert(less_than_max_mag(max));
|
||||
|
||||
//min, max are in volume space, convert to drawable render space
|
||||
LLVector4a center;
|
||||
LLVector4a t;
|
||||
t.setAdd(min, max);
|
||||
t.mul(0.5f);
|
||||
mat_vert.affineTransform(t, center);
|
||||
LLVector4a size;
|
||||
size.setSub(max, min);
|
||||
size.mul(0.5f);
|
||||
|
||||
llassert(less_than_max_mag(min));
|
||||
llassert(less_than_max_mag(max));
|
||||
//get 8 corners of bounding box
|
||||
LLVector4Logical mask[6];
|
||||
|
||||
if (!global_volume)
|
||||
for (U32 i = 0; i < 6; ++i)
|
||||
{
|
||||
//VECTORIZE THIS
|
||||
LLVector4a scale;
|
||||
scale.load3(mDrawablep->getVObj()->getScale().mV);
|
||||
size.mul(scale);
|
||||
mask[i].clear();
|
||||
}
|
||||
|
||||
// Catch potential badness from normalization before it happens
|
||||
//
|
||||
//llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
//llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
//llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
|
||||
|
||||
mat_normal.mMatrix[0].normalize3fast();
|
||||
mat_normal.mMatrix[1].normalize3fast();
|
||||
mat_normal.mMatrix[2].normalize3fast();
|
||||
mask[0].setElement<2>(); //001
|
||||
mask[1].setElement<1>(); //010
|
||||
mask[2].setElement<1>(); //011
|
||||
mask[2].setElement<2>();
|
||||
mask[3].setElement<0>(); //100
|
||||
mask[4].setElement<0>(); //101
|
||||
mask[4].setElement<2>();
|
||||
mask[5].setElement<0>(); //110
|
||||
mask[5].setElement<1>();
|
||||
|
||||
LLVector4a v[4];
|
||||
LLVector4a v[8];
|
||||
|
||||
//get 4 corners of bounding box
|
||||
mat_normal.rotate(size,v[0]);
|
||||
v[6] = min;
|
||||
v[7] = max;
|
||||
|
||||
//VECTORIZE THIS
|
||||
LLVector4a scale;
|
||||
|
||||
scale.set(-1.f, -1.f, 1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[1]);
|
||||
|
||||
scale.set(1.f, -1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[2]);
|
||||
|
||||
scale.set(-1.f, 1.f, -1.f);
|
||||
scale.mul(size);
|
||||
mat_normal.rotate(scale, v[3]);
|
||||
for (U32 i = 0; i < 6; ++i)
|
||||
{
|
||||
v[i].setSelectWithMask(mask[i], min, max);
|
||||
}
|
||||
|
||||
LLVector4a tv[8];
|
||||
|
||||
//transform bounding box into drawable space
|
||||
for (U32 i = 0; i < 8; ++i)
|
||||
{
|
||||
mat_vert.affineTransform(v[i], tv[i]);
|
||||
}
|
||||
|
||||
//find bounding box
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
newMin = newMax = center;
|
||||
|
||||
llassert(less_than_max_mag(center));
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
|
||||
newMin = newMax = tv[0];
|
||||
|
||||
for (U32 i = 1; i < 8; ++i)
|
||||
{
|
||||
LLVector4a delta;
|
||||
delta.setAbs(v[i]);
|
||||
LLVector4a min;
|
||||
min.setSub(center, delta);
|
||||
LLVector4a max;
|
||||
max.setAdd(center, delta);
|
||||
|
||||
newMin.setMin(newMin,min);
|
||||
newMax.setMax(newMax,max);
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
newMin.setMin(newMin, tv[i]);
|
||||
newMax.setMax(newMax, tv[i]);
|
||||
}
|
||||
|
||||
if (!mDrawablep->isActive())
|
||||
{
|
||||
{ // Shift position for region
|
||||
LLVector4a offset;
|
||||
offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
|
||||
newMin.add(offset);
|
||||
newMax.add(offset);
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
}
|
||||
|
||||
t.setAdd(newMin, newMax);
|
||||
LLVector4a t;
|
||||
t.setAdd(newMin,newMax);
|
||||
t.mul(0.5f);
|
||||
|
||||
llassert(less_than_max_mag(t));
|
||||
|
||||
//VECTORIZE THIS
|
||||
mCenterLocal.set(t.getF32ptr());
|
||||
|
||||
llassert(less_than_max_mag(newMin));
|
||||
llassert(less_than_max_mag(newMax));
|
||||
|
||||
t.setSub(newMax,newMin);
|
||||
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
|
||||
@@ -1189,21 +1192,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
}
|
||||
|
||||
|
||||
// <FS:ND> The volume face vf can have more indices/vertices than this face. All striders below are aquired with a size of this face, but then written with num_verices/num_indices values,
|
||||
// thus overflowing the buffer when vf holds more data.
|
||||
// We can either clamp num_* down like here, or aquire all striders not using the face size, but the size if vf (that is swapping out mGeomCount with num_vertices and mIndicesCout with num_indices
|
||||
// in all calls to nVertbuffer->get*Strider(...). Final solution is to just return FALSE and be done with it.
|
||||
//
|
||||
// The correct poison of choice is debatable, either copying not all data of vf (clamping) or writing more data than this face claims to have (aquiring bigger striders). Returning will not display this face at all.
|
||||
//
|
||||
// clamping it is for now.
|
||||
|
||||
num_vertices = llclamp( num_vertices, (S32)0, (S32)mGeomCount );
|
||||
num_indices = llclamp( num_indices, (S32)0, (S32)mIndicesCount );
|
||||
|
||||
// </FS:ND>
|
||||
|
||||
|
||||
//don't use map range (generates many redundant unmap calls)
|
||||
bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
|
||||
|
||||
@@ -1288,30 +1276,34 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
if (tep &&
|
||||
getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
|
||||
{
|
||||
LLMaterial* mat = tep->getMaterialParams().get();
|
||||
|
||||
bool shiny_in_alpha = false;
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
{ //store shiny in alpha if we don't have a specular map
|
||||
//if (!mat || mat->getSpecularID().isNull())
|
||||
if (!mat || mat->getSpecularID().isNull())
|
||||
{
|
||||
shiny_in_alpha = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(LLPipeline::sRenderBump && tep->getShiny())
|
||||
if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
shiny_in_alpha = true;
|
||||
}
|
||||
}
|
||||
if(shiny_in_alpha)
|
||||
|
||||
if (shiny_in_alpha)
|
||||
{
|
||||
|
||||
GLfloat alpha[4] =
|
||||
{
|
||||
0.00f,
|
||||
0.25f,
|
||||
0.5f,
|
||||
0.75f
|
||||
0.00f,
|
||||
0.25f,
|
||||
0.5f,
|
||||
0.75f
|
||||
};
|
||||
|
||||
llassert(tep->getShiny() <= 3);
|
||||
@@ -1570,11 +1562,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
break;
|
||||
case BE_BRIGHTNESS:
|
||||
case BE_DARKNESS:
|
||||
if( mTexture.notNull() && mTexture->hasGLTexture())
|
||||
if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
|
||||
{
|
||||
// Offset by approximately one texel
|
||||
S32 cur_discard = mTexture->getDiscardLevel();
|
||||
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
|
||||
S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
|
||||
S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
|
||||
max_size <<= cur_discard;
|
||||
const F32 ARTIFICIAL_OFFSET = 2.f;
|
||||
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
|
||||
@@ -1615,11 +1607,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
U8 tex_mode = 0;
|
||||
|
||||
bool tex_anim = false;
|
||||
|
||||
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
|
||||
tex_mode = vobj->mTexAnimMode;
|
||||
|
||||
if (vobj->mTextureAnimp)
|
||||
{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
|
||||
tex_anim = true;
|
||||
}
|
||||
|
||||
if (isState(TEXTURE_ANIM))
|
||||
{
|
||||
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
|
||||
tex_mode = vobj->mTexAnimMode;
|
||||
|
||||
if (!tex_mode)
|
||||
{
|
||||
clearState(TEXTURE_ANIM);
|
||||
@@ -1644,7 +1643,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
LLVector4a scalea;
|
||||
scalea.load3(scale.mV);
|
||||
|
||||
LLMaterial* mat = tep->getMaterialParams().get();
|
||||
|
||||
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
|
||||
|
||||
if (mat && !do_bump)
|
||||
{
|
||||
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|
||||
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
|
||||
}
|
||||
|
||||
bool do_tex_mat = tex_mode && mTextureMatrix;
|
||||
|
||||
if (!do_bump)
|
||||
@@ -1659,14 +1667,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
if (!do_xform)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
|
||||
|
||||
// <FS:ND> Don't round up, or there's high risk to write past buffer
|
||||
|
||||
// S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
|
||||
S32 tc_size = (num_vertices*2*sizeof(F32));
|
||||
|
||||
// </FS:ND>
|
||||
|
||||
S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
|
||||
LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size);
|
||||
}
|
||||
else
|
||||
@@ -1773,47 +1774,99 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
std::vector<LLVector2> bump_tc;
|
||||
|
||||
if (mat && !mat->getNormalID().isNull())
|
||||
{ //writing out normal and specular texture coordinates, not bump offsets
|
||||
do_bump = false;
|
||||
}
|
||||
|
||||
LLStrider<LLVector2> dst;
|
||||
|
||||
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
|
||||
for (U32 ch = 0; ch < 3; ++ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 0:
|
||||
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
|
||||
break;
|
||||
case 1:
|
||||
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
|
||||
{
|
||||
mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
|
||||
if (mat && !tex_anim)
|
||||
{
|
||||
r = mat->getNormalRotation();
|
||||
mat->getNormalOffset(os, ot);
|
||||
mat->getNormalRepeat(ms, mt);
|
||||
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
cos_ang = cos(r);
|
||||
sin_ang = sin(r);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
|
||||
{
|
||||
mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
|
||||
if (mat && !tex_anim)
|
||||
{
|
||||
r = mat->getSpecularRotation();
|
||||
mat->getSpecularOffset(os, ot);
|
||||
mat->getSpecularRepeat(ms, mt);
|
||||
|
||||
cos_ang = cos(r);
|
||||
sin_ang = sin(r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
{
|
||||
LLVector2 tc(vf.mTexCoords[i]);
|
||||
|
||||
LLVector4a& norm = vf.mNormals[i];
|
||||
LLVector4a& norm = vf.mNormals[i];
|
||||
|
||||
LLVector4a& center = *(vf.mCenter);
|
||||
LLVector4a& center = *(vf.mCenter);
|
||||
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
LLVector4a vec = vf.mPositions[i];
|
||||
|
||||
vec.mul(scalea);
|
||||
|
||||
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
||||
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
|
||||
{
|
||||
planarProjection(tc, norm, center, vec);
|
||||
LLVector4a vec = vf.mPositions[i];
|
||||
|
||||
vec.mul(scalea);
|
||||
|
||||
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
|
||||
{
|
||||
planarProjection(tc, norm, center, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tex_mode && mTextureMatrix)
|
||||
{
|
||||
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
|
||||
tmp = tmp * *mTextureMatrix;
|
||||
tc.mV[0] = tmp.mV[0];
|
||||
tc.mV[1] = tmp.mV[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
}
|
||||
if (tex_mode && mTextureMatrix)
|
||||
{
|
||||
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
|
||||
tmp = tmp * *mTextureMatrix;
|
||||
tc.mV[0] = tmp.mV[0];
|
||||
tc.mV[1] = tmp.mV[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
|
||||
}
|
||||
|
||||
*dst++ = tc;
|
||||
if (do_bump)
|
||||
{
|
||||
bump_tc.push_back(tc);
|
||||
*dst++ = tc;
|
||||
if (do_bump)
|
||||
{
|
||||
bump_tc.push_back(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1822,7 +1875,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
mVertexBuffer->flush();
|
||||
}
|
||||
|
||||
if (do_bump)
|
||||
if (!mat && do_bump)
|
||||
{
|
||||
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
|
||||
|
||||
@@ -1868,20 +1921,31 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (rebuild_pos)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_GEOM_POSITION);
|
||||
LLVector4a* src = vf.mPositions;
|
||||
|
||||
//_mm_prefetch((char*)src, _MM_HINT_T0);
|
||||
|
||||
LLVector4a* end = src+num_vertices;
|
||||
//LLVector4a* end_64 = end-4;
|
||||
|
||||
//LLFastTimer t(FTM_FACE_GEOM_POSITION);
|
||||
llassert(num_vertices > 0);
|
||||
|
||||
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
|
||||
|
||||
|
||||
LLMatrix4a mat_vert;
|
||||
mat_vert.loadu(mat_vert_in);
|
||||
|
||||
LLVector4a* src = vf.mPositions;
|
||||
volatile F32* dst = (volatile F32*) vert.get();
|
||||
F32* dst = (F32*) vert.get();
|
||||
F32* end_f32 = dst+mGeomCount*4;
|
||||
|
||||
volatile F32* end = dst+num_vertices*4;
|
||||
LLVector4a res;
|
||||
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
|
||||
//_mm_prefetch((char*)src, _MM_HINT_NTA);
|
||||
|
||||
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
|
||||
|
||||
|
||||
LLVector4a res0; //,res1,res2,res3;
|
||||
|
||||
LLVector4a texIdx;
|
||||
|
||||
@@ -1899,29 +1963,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
texIdx.set(0,0,0,val);
|
||||
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_POSITION_STORE);
|
||||
LLVector4a tmp;
|
||||
LLVector4a tmp;
|
||||
|
||||
do
|
||||
{
|
||||
//LLFastTimer t2(FTM_FACE_POSITION_STORE);
|
||||
|
||||
/*if (num_vertices > 4)
|
||||
{ //more than 64 bytes
|
||||
while (src < end_64)
|
||||
{
|
||||
_mm_prefetch((char*)src + 64, _MM_HINT_T0);
|
||||
_mm_prefetch((char*)dst + 64, _MM_HINT_T0);
|
||||
|
||||
mat_vert.affineTransform(*src, res0);
|
||||
tmp.setSelectWithMask(mask, texIdx, res0);
|
||||
tmp.store4a((F32*) dst);
|
||||
|
||||
mat_vert.affineTransform(*(src+1), res1);
|
||||
tmp.setSelectWithMask(mask, texIdx, res1);
|
||||
tmp.store4a((F32*) dst+4);
|
||||
|
||||
mat_vert.affineTransform(*(src+2), res2);
|
||||
tmp.setSelectWithMask(mask, texIdx, res2);
|
||||
tmp.store4a((F32*) dst+8);
|
||||
|
||||
mat_vert.affineTransform(*(src+3), res3);
|
||||
tmp.setSelectWithMask(mask, texIdx, res3);
|
||||
tmp.store4a((F32*) dst+12);
|
||||
|
||||
dst += 16;
|
||||
src += 4;
|
||||
}
|
||||
}*/
|
||||
|
||||
while (src < end)
|
||||
{
|
||||
mat_vert.affineTransform(*src++, res);
|
||||
tmp.setSelectWithMask(mask, texIdx, res);
|
||||
mat_vert.affineTransform(*src++, res0);
|
||||
tmp.setSelectWithMask(mask, texIdx, res0);
|
||||
tmp.store4a((F32*) dst);
|
||||
dst += 4;
|
||||
}
|
||||
while(dst < end);
|
||||
}
|
||||
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_POSITION_PAD);
|
||||
S32 aligned_pad_vertices = mGeomCount - num_vertices;
|
||||
res.set(res[0], res[1], res[2], 0.f);
|
||||
|
||||
while (aligned_pad_vertices > 0)
|
||||
//LLFastTimer t(FTM_FACE_POSITION_PAD);
|
||||
while (dst < end_f32)
|
||||
{
|
||||
--aligned_pad_vertices;
|
||||
res.store4a((F32*) dst);
|
||||
res0.store4a((F32*) dst);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
@@ -1935,14 +2023,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
if (rebuild_normal)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
|
||||
//LLFastTimer t(FTM_FACE_GEOM_NORMAL);
|
||||
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
|
||||
F32* normals = (F32*) norm.get();
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
LLVector4a* src = vf.mNormals;
|
||||
LLVector4a* end = src+num_vertices;
|
||||
|
||||
while (src < end)
|
||||
{
|
||||
LLVector4a normal;
|
||||
mat_normal.rotate(vf.mNormals[i], normal);
|
||||
normal.normalize3fast();
|
||||
mat_normal.rotate(*src++, normal);
|
||||
normal.store4a(normals);
|
||||
normals += 4;
|
||||
}
|
||||
@@ -1965,14 +2055,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
mask.clear();
|
||||
mask.setElement<3>();
|
||||
|
||||
for (S32 i = 0; i < num_vertices; i++)
|
||||
LLVector4a* src = vf.mTangents;
|
||||
LLVector4a* end = vf.mTangents+num_vertices;
|
||||
|
||||
while (src < end)
|
||||
{
|
||||
LLVector4a tangent_out;
|
||||
mat_normal.rotate(vf.mTangents[i], tangent_out);
|
||||
mat_normal.rotate(*src, tangent_out);
|
||||
tangent_out.normalize3fast();
|
||||
tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out);
|
||||
tangent_out.setSelectWithMask(mask, *src, tangent_out);
|
||||
tangent_out.store4a(tangents);
|
||||
|
||||
src++;
|
||||
tangents += 4;
|
||||
}
|
||||
|
||||
@@ -2092,16 +2186,23 @@ BOOL LLFace::hasMedia() const
|
||||
{
|
||||
return TRUE ;
|
||||
}
|
||||
if(mTexture.notNull())
|
||||
if(mTexture[LLRender::DIFFUSE_MAP].notNull())
|
||||
{
|
||||
return mTexture->hasParcelMedia() ; //if has a parcel media
|
||||
return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
|
||||
}
|
||||
|
||||
return FALSE ; //no media.
|
||||
}
|
||||
|
||||
const F32 LEAST_IMPORTANCE = 0.05f ;
|
||||
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
|
||||
|
||||
void LLFace::resetVirtualSize()
|
||||
{
|
||||
setVirtualSize(0.f);
|
||||
mImportanceToCamera = 0.f;
|
||||
}
|
||||
|
||||
F32 LLFace::getTextureVirtualSize()
|
||||
{
|
||||
F32 radius;
|
||||
@@ -2137,11 +2238,11 @@ F32 LLFace::getTextureVirtualSize()
|
||||
}
|
||||
|
||||
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
|
||||
if (/*mImportanceToCamera < 1.0f && */face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
|
||||
{
|
||||
if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
|
||||
{
|
||||
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius);
|
||||
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
|
||||
{
|
||||
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2167,9 +2268,18 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||
LLVector4a t;
|
||||
t.load3(camera->getOrigin().mV);
|
||||
lookAt.setSub(center, t);
|
||||
|
||||
F32 dist = lookAt.getLength3().getF32();
|
||||
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
|
||||
lookAt.normalize3fast() ;
|
||||
//ramp down distance for nearby objects
|
||||
if (dist < 16.f)
|
||||
{
|
||||
dist /= 16.f;
|
||||
dist *= dist;
|
||||
dist *= 16.f;
|
||||
}
|
||||
|
||||
lookAt.normalize3fast();
|
||||
|
||||
//get area of circle around node
|
||||
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
|
||||
@@ -2505,9 +2615,12 @@ LLVector3 LLFace::getPositionAgent() const
|
||||
return mCenterLocal * getRenderMatrix();
|
||||
}
|
||||
}
|
||||
LLViewerTexture* LLFace::getTexture() const
|
||||
|
||||
LLViewerTexture* LLFace::getTexture(U32 ch) const
|
||||
{
|
||||
return mTexture ;
|
||||
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
|
||||
|
||||
return mTexture[ch] ;
|
||||
}
|
||||
|
||||
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
|
||||
@@ -2525,6 +2638,22 @@ void LLFace::clearVertexBuffer()
|
||||
U32 LLFace::getRiggedDataMask(U32 type)
|
||||
{
|
||||
static const U32 rigged_data_mask[] = {
|
||||
LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
|
||||
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
|
||||
LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
|
||||
LLDrawPoolAvatar::RIGGED_SHINY_MASK,
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llface.h
|
||||
* @brief LLFace class definition
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -115,8 +109,12 @@ public:
|
||||
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
|
||||
void setTextureIndex(U8 index);
|
||||
U8 getTextureIndex() const { return mTextureIndex; }
|
||||
void setTexture(U32 ch, LLViewerTexture* tex);
|
||||
void setTexture(LLViewerTexture* tex) ;
|
||||
void switchTexture(LLViewerTexture* new_texture);
|
||||
void setDiffuseMap(LLViewerTexture* tex);
|
||||
void setNormalMap(LLViewerTexture* tex);
|
||||
void setSpecularMap(LLViewerTexture* tex);
|
||||
void switchTexture(U32 ch, LLViewerTexture* new_texture);
|
||||
void dirtyTexture();
|
||||
LLXformMatrix* getXform() const { return mXform; }
|
||||
BOOL hasGeometry() const { return mGeomCount > 0; }
|
||||
@@ -135,8 +133,8 @@ public:
|
||||
F32 getVirtualSize() const { return mVSize; }
|
||||
F32 getPixelArea() const { return mPixelArea; }
|
||||
|
||||
S32 getIndexInTex() const {return mIndexInTex ;}
|
||||
void setIndexInTex(S32 index) { mIndexInTex = index ;}
|
||||
S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
|
||||
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
|
||||
|
||||
void renderSetColor() const;
|
||||
S32 renderElements(const U16 *index_array) const;
|
||||
@@ -154,7 +152,7 @@ public:
|
||||
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
|
||||
void setPoolType(U32 type) { mPoolType = type; }
|
||||
S32 getTEOffset() { return mTEOffset; }
|
||||
LLViewerTexture* getTexture() const;
|
||||
LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
|
||||
|
||||
void setViewerObject(LLViewerObject* object);
|
||||
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
|
||||
@@ -196,10 +194,9 @@ public:
|
||||
S32 getColors(LLStrider<LLColor4U> &colors);
|
||||
S32 getIndices(LLStrider<U16> &indices);
|
||||
|
||||
void setSize(S32 numVertices, const S32 num_indices = 0, bool align = false);
|
||||
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
|
||||
|
||||
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,
|
||||
const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE);
|
||||
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE);
|
||||
|
||||
void init(LLDrawable* drawablep, LLViewerObject* objp);
|
||||
void destroy();
|
||||
@@ -224,9 +221,13 @@ public:
|
||||
|
||||
F32 getTextureVirtualSize() ;
|
||||
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
|
||||
void resetVirtualSize();
|
||||
|
||||
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
|
||||
BOOL hasMedia() const ;
|
||||
|
||||
BOOL switchTexture() ;
|
||||
|
||||
//vertex buffer tracking
|
||||
void setVertexBuffer(LLVertexBuffer* buffer);
|
||||
void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
|
||||
@@ -258,6 +259,8 @@ public:
|
||||
F32 mLastSkinTime;
|
||||
F32 mLastMoveTime;
|
||||
LLMatrix4* mTextureMatrix;
|
||||
LLMatrix4* mSpecMapMatrix;
|
||||
LLMatrix4* mNormalMapMatrix;
|
||||
LLDrawInfo* mDrawInfo;
|
||||
|
||||
private:
|
||||
@@ -273,10 +276,12 @@ private:
|
||||
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
|
||||
U32 mIndicesCount;
|
||||
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
|
||||
S32 mIndexInTex ;
|
||||
S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
|
||||
|
||||
LLXformMatrix* mXform;
|
||||
LLPointer<LLViewerTexture> mTexture;
|
||||
|
||||
LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
|
||||
|
||||
LLPointer<LLDrawable> mDrawablep;
|
||||
LLPointer<LLViewerObject> mVObjp;
|
||||
S32 mTEOffset;
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llface.inl
|
||||
* @brief Inline functions for LLFace
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#define MATERIALS_CAP_MATERIAL_FIELD "Material"
|
||||
#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
|
||||
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
|
||||
#define SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION "MaxMaterialsPerTransaction"
|
||||
|
||||
#define MATERIALS_GET_MAX_ENTRIES 50
|
||||
#define MATERIALS_GET_TIMEOUT (60.f * 20)
|
||||
@@ -339,36 +340,29 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
|
||||
itMaterial = ret.first;
|
||||
}
|
||||
|
||||
// we may have cleared our queues on leaving a region before we recv'd our
|
||||
// update for this material...too late now!
|
||||
//
|
||||
if (isGetPending(region_id, material_id))
|
||||
{
|
||||
|
||||
TEMaterialPair te_mat_pair;
|
||||
te_mat_pair.materialID = material_id;
|
||||
TEMaterialPair te_mat_pair;
|
||||
te_mat_pair.materialID = material_id;
|
||||
|
||||
U32 i = 0;
|
||||
while (i < LLTEContents::MAX_TES)
|
||||
U32 i = 0;
|
||||
while (i < LLTEContents::MAX_TES)
|
||||
{
|
||||
te_mat_pair.te = i++;
|
||||
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
|
||||
if (itCallbackTE != mGetTECallbacks.end())
|
||||
{
|
||||
te_mat_pair.te = i++;
|
||||
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
|
||||
if (itCallbackTE != mGetTECallbacks.end())
|
||||
{
|
||||
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
|
||||
delete itCallbackTE->second;
|
||||
mGetTECallbacks.erase(itCallbackTE);
|
||||
}
|
||||
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
|
||||
delete itCallbackTE->second;
|
||||
mGetTECallbacks.erase(itCallbackTE);
|
||||
}
|
||||
}
|
||||
|
||||
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
|
||||
if (itCallback != mGetCallbacks.end())
|
||||
{
|
||||
(*itCallback->second)(material_id, itMaterial->second);
|
||||
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
|
||||
if (itCallback != mGetCallbacks.end())
|
||||
{
|
||||
(*itCallback->second)(material_id, itMaterial->second);
|
||||
|
||||
delete itCallback->second;
|
||||
mGetCallbacks.erase(itCallback);
|
||||
}
|
||||
delete itCallback->second;
|
||||
mGetCallbacks.erase(itCallback);
|
||||
}
|
||||
|
||||
mGetPending.erase(pending_material_t(region_id, material_id));
|
||||
@@ -555,11 +549,9 @@ void LLMaterialMgr::onIdle(void*)
|
||||
instancep->processGetAllQueue();
|
||||
}
|
||||
|
||||
static LLFrameTimer mPutTimer;
|
||||
if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
|
||||
if (!instancep->mPutQueue.empty())
|
||||
{
|
||||
instancep->processPutQueue();
|
||||
mPutTimer.reset(MATERIALS_PUT_THROTTLE_SECS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,14 +568,14 @@ void LLMaterialMgr::processGetQueue()
|
||||
continue;
|
||||
}
|
||||
|
||||
const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
|
||||
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
|
||||
if (!regionp)
|
||||
{
|
||||
LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
|
||||
mGetQueue.erase(itRegionQueue);
|
||||
continue;
|
||||
}
|
||||
else if (!regionp->capabilitiesReceived())
|
||||
else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -606,8 +598,9 @@ void LLMaterialMgr::processGetQueue()
|
||||
LLSD materialsData = LLSD::emptyArray();
|
||||
|
||||
material_queue_t& materials = itRegionQueue->second;
|
||||
U32 max_entries = regionp->getMaxMaterialsPerTransaction();
|
||||
material_queue_t::iterator loopMaterial = materials.begin();
|
||||
while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
|
||||
while ( (materials.end() != loopMaterial) && (materialsData.size() < (int)max_entries) )
|
||||
{
|
||||
material_queue_t::iterator itMaterial = loopMaterial++;
|
||||
materialsData.append((*itMaterial).asLLSD());
|
||||
@@ -639,6 +632,7 @@ void LLMaterialMgr::processGetQueue()
|
||||
LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
|
||||
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
|
||||
LLHTTPClient::post(capURL, postData, materialsResponder);
|
||||
regionp->resetMaterialsCapThrottle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,7 +651,7 @@ void LLMaterialMgr::processGetAllQueue()
|
||||
clearGetQueues(region_id); // Invalidates region_id
|
||||
continue;
|
||||
}
|
||||
else if (!regionp->capabilitiesReceived())
|
||||
else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -674,6 +668,7 @@ void LLMaterialMgr::processGetAllQueue()
|
||||
LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
|
||||
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
|
||||
LLHTTPClient::get(capURL, materialsResponder);
|
||||
regionp->resetMaterialsCapThrottle();
|
||||
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
|
||||
mGetAllQueue.erase(itRegion); // Invalidates region_id
|
||||
}
|
||||
@@ -681,7 +676,7 @@ void LLMaterialMgr::processGetAllQueue()
|
||||
|
||||
void LLMaterialMgr::processPutQueue()
|
||||
{
|
||||
typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
|
||||
typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
|
||||
regionput_request_map requests;
|
||||
|
||||
put_queue_t::iterator loopQueue = mPutQueue.begin();
|
||||
@@ -691,25 +686,27 @@ void LLMaterialMgr::processPutQueue()
|
||||
|
||||
const LLUUID& object_id = itQueue->first;
|
||||
const LLViewerObject* objectp = gObjectList.findObject(object_id);
|
||||
if ( (!objectp) || (!objectp->getRegion()) )
|
||||
if ( !objectp )
|
||||
{
|
||||
LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL;
|
||||
|
||||
LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;
|
||||
mPutQueue.erase(itQueue);
|
||||
continue;
|
||||
}
|
||||
|
||||
const LLViewerRegion* regionp = objectp->getRegion();
|
||||
if (!regionp->capabilitiesReceived())
|
||||
else
|
||||
{
|
||||
continue;
|
||||
LLViewerRegion* regionp = objectp->getRegion();
|
||||
if ( !regionp )
|
||||
{
|
||||
LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
|
||||
mPutQueue.erase(itQueue);
|
||||
}
|
||||
|
||||
else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
|
||||
{
|
||||
LLSD& facesData = requests[regionp];
|
||||
|
||||
facematerial_map_t& face_map = itQueue->second;
|
||||
U32 max_entries = regionp->getMaxMaterialsPerTransaction();
|
||||
facematerial_map_t::iterator itFace = face_map.begin();
|
||||
while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) )
|
||||
while ( (face_map.end() != itFace) && (facesData.size() < (int)max_entries) )
|
||||
{
|
||||
LLSD faceData = LLSD::emptyMap();
|
||||
faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
|
||||
@@ -726,14 +723,17 @@ void LLMaterialMgr::processPutQueue()
|
||||
mPutQueue.erase(itQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
|
||||
{
|
||||
std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
|
||||
LLViewerRegion* regionp = itRequest->first;
|
||||
std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
|
||||
if (capURL.empty())
|
||||
{
|
||||
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
|
||||
<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
|
||||
<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -756,6 +756,7 @@ void LLMaterialMgr::processPutQueue()
|
||||
LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
|
||||
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
|
||||
LLHTTPClient::put(capURL, putData, materialsResponder);
|
||||
regionp->resetMaterialsCapThrottle();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -124,6 +124,8 @@ protected:
|
||||
put_queue_t mPutQueue;
|
||||
|
||||
material_map_t mMaterials;
|
||||
|
||||
U32 getMaxEntries(const LLViewerRegion* regionp);
|
||||
};
|
||||
|
||||
#endif // LL_LLMATERIALMGR_H
|
||||
|
||||
@@ -60,10 +60,36 @@ const F32 SOUND_GAIN = 1.0f;
|
||||
|
||||
LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid) :
|
||||
LLPreview( name, rect, title, item_uuid, object_uuid)
|
||||
, mIsCopyable(false)
|
||||
{
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_sound.xml");
|
||||
|
||||
setTitle(title);
|
||||
|
||||
if (!getHost())
|
||||
{
|
||||
LLRect curRect = getRect();
|
||||
translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLPreviewSound::postBuild()
|
||||
{
|
||||
const LLInventoryItem* item = getItem();
|
||||
if (item)
|
||||
{
|
||||
getChild<LLUICtrl>("desc")->setValue(item->getDescription());
|
||||
mIsCopyable = (item->getPermissions().getCreator() == gAgentID);
|
||||
if (gAudiop)
|
||||
// <edit>
|
||||
// that thing above doesn't actually start a sound transfer, so I will do it
|
||||
if (LLAudioSource* asp = gAgentAvatarp->getAudioSource(gAgentID))
|
||||
asp->preload(item->getAssetUUID()); // preload the sound
|
||||
// </edit>
|
||||
}
|
||||
|
||||
childSetAction("Sound play btn",&LLPreviewSound::playSound,this);
|
||||
childSetAction("Sound audition btn",&LLPreviewSound::auditionSound,this);
|
||||
// <edit>
|
||||
@@ -77,40 +103,10 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons
|
||||
button = getChild<LLButton>("Sound audition btn");
|
||||
button->setSoundFlags(LLView::SILENT);
|
||||
|
||||
const LLInventoryItem* item = getItem();
|
||||
|
||||
mIsCopyable = false;
|
||||
if(item)
|
||||
{
|
||||
const LLPermissions& perm = item->getPermissions();
|
||||
mIsCopyable = (perm.getCreator() == gAgent.getID());
|
||||
}
|
||||
|
||||
childSetCommitCallback("desc", LLPreview::onText, this);
|
||||
childSetText("desc", item->getDescription());
|
||||
getChild<LLLineEditor>("desc")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
|
||||
|
||||
// preload the sound
|
||||
if(item && gAudiop)
|
||||
{
|
||||
// <edit>
|
||||
// that thing above doesn't actually start a sound transfer, so I will do it
|
||||
LLAudioSource *asp = gAgentAvatarp->getAudioSource(gAgent.getID());
|
||||
if(asp)
|
||||
{
|
||||
asp->preload(item->getAssetUUID());
|
||||
}
|
||||
// </edit>
|
||||
}
|
||||
|
||||
setTitle(title);
|
||||
|
||||
if (!getHost())
|
||||
{
|
||||
LLRect curRect = getRect();
|
||||
translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
|
||||
}
|
||||
|
||||
return LLPreview::postBuild();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
// </edit>
|
||||
|
||||
protected:
|
||||
/*virtual*/ BOOL postBuild();
|
||||
virtual const char *getTitleName() const { return "Sound"; }
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
|
||||
@@ -2386,7 +2386,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
|
||||
}
|
||||
}
|
||||
|
||||
void pushBufferVerts(LLSpatialGroup* group, U32 mask)
|
||||
void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
|
||||
{
|
||||
if (group->mSpatialPartition->mRenderByGroup)
|
||||
{
|
||||
@@ -2395,7 +2395,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
|
||||
LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
|
||||
LLRenderPass::applyModelMatrix(*params);
|
||||
|
||||
pushBufferVerts(group->mVertexBuffer, mask);
|
||||
if (push_alpha)
|
||||
{
|
||||
pushBufferVerts(group->mVertexBuffer, mask);
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
|
||||
{
|
||||
@@ -2858,20 +2861,23 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
|
||||
const LLVector4a* ext;
|
||||
LLVector4a pos, size;
|
||||
|
||||
//render face bounding boxes
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); i++)
|
||||
if (drawable->getVOVolume())
|
||||
{
|
||||
LLFace* facep = drawable->getFace(i);
|
||||
if (facep)
|
||||
//render face bounding boxes
|
||||
for (S32 i = 0; i < drawable->getNumFaces(); i++)
|
||||
{
|
||||
ext = facep->mExtents;
|
||||
LLFace* facep = drawable->getFace(i);
|
||||
if (facep)
|
||||
{
|
||||
ext = facep->mExtents;
|
||||
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
pos.setAdd(ext[0], ext[1]);
|
||||
pos.mul(0.5f);
|
||||
size.setSub(ext[1], ext[0]);
|
||||
size.mul(0.5f);
|
||||
|
||||
drawBoxOutline(pos,size);
|
||||
drawBoxOutline(pos,size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4442,7 +4448,16 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
|
||||
mGroup(NULL),
|
||||
mFace(NULL),
|
||||
mDistance(0.f),
|
||||
mDrawMode(LLRender::TRIANGLES)
|
||||
mDrawMode(LLRender::TRIANGLES),
|
||||
mMaterial(NULL),
|
||||
mShaderMask(0),
|
||||
mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
|
||||
mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
|
||||
mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
|
||||
mHasGlow(FALSE),
|
||||
mEnvIntensity(0.0f),
|
||||
mAlphaMaskCutoff(0.5f),
|
||||
mDiffuseAlphaMode(0)
|
||||
{
|
||||
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ public:
|
||||
U32 mOffset;
|
||||
BOOL mFullbright;
|
||||
U8 mBump;
|
||||
U8 mShiny;
|
||||
BOOL mParticle;
|
||||
F32 mPartSize;
|
||||
F32 mVSize;
|
||||
@@ -124,6 +125,21 @@ public:
|
||||
LL_ALIGN_16(LLFace* mFace); //associated face
|
||||
F32 mDistance;
|
||||
U32 mDrawMode;
|
||||
LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
|
||||
LLMaterialID mMaterialID;
|
||||
U32 mShaderMask;
|
||||
U32 mBlendFuncSrc;
|
||||
U32 mBlendFuncDst;
|
||||
BOOL mHasGlow;
|
||||
LLPointer<LLViewerTexture> mSpecularMap;
|
||||
const LLMatrix4* mSpecularMapMatrix;
|
||||
LLPointer<LLViewerTexture> mNormalMap;
|
||||
const LLMatrix4* mNormalMapMatrix;
|
||||
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
|
||||
F32 mEnvIntensity;
|
||||
F32 mAlphaMaskCutoff;
|
||||
U8 mDiffuseAlphaMode;
|
||||
|
||||
|
||||
struct CompareTexture
|
||||
{
|
||||
|
||||
@@ -824,7 +824,7 @@ BOOL LLToolCompGun::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
||||
}
|
||||
else mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV();
|
||||
|
||||
mTargetFOV = gSavedPerAccountSettings.getF32("zmm_mlfov");
|
||||
mTargetFOV = gSavedSettings.getF32("zmm_mlfov");
|
||||
mTimerFOV.start();
|
||||
|
||||
return TRUE;
|
||||
@@ -836,7 +836,7 @@ BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
mStartFOV = LLViewerCamera::getInstance()->getDefaultFOV();
|
||||
|
||||
gSavedPerAccountSettings.setF32(
|
||||
gSavedSettings.setF32(
|
||||
"zmm_mlfov",
|
||||
mTargetFOV = clicks > 0 ?
|
||||
llclamp(mTargetFOV += (0.05f * clicks), 0.1f, 3.0f) :
|
||||
|
||||
@@ -1158,6 +1158,7 @@ void render_hud_attachments()
|
||||
|
||||
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
|
||||
{
|
||||
LLPipeline::sRenderingHUDs = TRUE;
|
||||
LLCamera hud_cam = *LLViewerCamera::getInstance();
|
||||
hud_cam.setOrigin(-1.f,0,0);
|
||||
hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
|
||||
@@ -1203,10 +1204,13 @@ void render_hud_attachments()
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
|
||||
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
|
||||
@@ -1231,6 +1235,7 @@ void render_hud_attachments()
|
||||
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
|
||||
}
|
||||
LLPipeline::sUseOcclusion = use_occlusion;
|
||||
LLPipeline::sRenderingHUDs = FALSE;
|
||||
}
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
#include "llvovolume.h"
|
||||
|
||||
#include "hippogridmanager.h"
|
||||
#include "wlfPanel_AdvSettings.h"
|
||||
|
||||
void toggle_search_floater();
|
||||
|
||||
@@ -4122,6 +4123,16 @@ void reset_view_final( BOOL proceed )
|
||||
}
|
||||
|
||||
gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
|
||||
if (wlfPanel_AdvSettings::instanceExists()) // Fix up the buttons on the wlf panel to match the preset switch
|
||||
{
|
||||
wlfPanel_AdvSettings& inst(wlfPanel_AdvSettings::instance());
|
||||
if (inst.isExpanded())
|
||||
{
|
||||
inst.getChildView("Rear")->setValue(true);
|
||||
inst.getChildView("Front")->setValue(false);
|
||||
inst.getChildView("Group")->setValue(false);
|
||||
}
|
||||
}
|
||||
gAgentCamera.resetView(TRUE, TRUE);
|
||||
gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
|
||||
|
||||
|
||||
@@ -208,6 +208,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
|
||||
mTotalCRC(0),
|
||||
mListIndex(-1),
|
||||
mTEImages(NULL),
|
||||
mTENormalMaps(NULL),
|
||||
mTESpecularMaps(NULL),
|
||||
mGLName(0),
|
||||
mbCanSelect(TRUE),
|
||||
mFlags(0),
|
||||
@@ -336,6 +338,18 @@ void LLViewerObject::deleteTEImages()
|
||||
{
|
||||
delete[] mTEImages;
|
||||
mTEImages = NULL;
|
||||
|
||||
if (mTENormalMaps != NULL)
|
||||
{
|
||||
delete[] mTENormalMaps;
|
||||
mTENormalMaps = NULL;
|
||||
}
|
||||
|
||||
if (mTESpecularMaps != NULL)
|
||||
{
|
||||
delete[] mTESpecularMaps;
|
||||
mTESpecularMaps = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::markDead()
|
||||
@@ -1600,6 +1614,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
dp->setPassFlags(value);
|
||||
dp->unpackUUID(owner_id, "Owner");
|
||||
|
||||
mOwnerID = owner_id;
|
||||
|
||||
if (value & 0x80)
|
||||
{
|
||||
dp->unpackVector3(new_angv, "Omega");
|
||||
@@ -1688,9 +1704,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
|
||||
//
|
||||
if (value & 0x8)
|
||||
{
|
||||
unpackParticleSource(*dp, owner_id);
|
||||
unpackParticleSource(*dp, owner_id, true);
|
||||
}
|
||||
else
|
||||
else if (!(value & 0x400))
|
||||
{
|
||||
deleteParticleSource();
|
||||
}
|
||||
@@ -4048,25 +4064,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
|
||||
{
|
||||
LLPointer<LLViewerTexture> *new_images;
|
||||
new_images = new LLPointer<LLViewerTexture>[num_tes];
|
||||
|
||||
LLPointer<LLViewerTexture> *new_normmaps;
|
||||
new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
|
||||
|
||||
LLPointer<LLViewerTexture> *new_specmaps;
|
||||
new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
|
||||
for (i = 0; i < num_tes; i++)
|
||||
{
|
||||
if (i < getNumTEs())
|
||||
{
|
||||
new_images[i] = mTEImages[i];
|
||||
new_normmaps[i] = mTENormalMaps[i];
|
||||
new_specmaps[i] = mTESpecularMaps[i];
|
||||
}
|
||||
else if (getNumTEs())
|
||||
{
|
||||
new_images[i] = mTEImages[getNumTEs()-1];
|
||||
new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
|
||||
new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
new_images[i] = NULL;
|
||||
new_normmaps[i] = NULL;
|
||||
new_specmaps[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
deleteTEImages();
|
||||
|
||||
mTEImages = new_images;
|
||||
mTENormalMaps = new_normmaps;
|
||||
mTESpecularMaps = new_specmaps;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4161,12 +4191,18 @@ void LLViewerObject::sendTEUpdate() const
|
||||
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
|
||||
{
|
||||
LLPrimitive::setTE(te, texture_entry);
|
||||
// This doesn't work, don't get any textures.
|
||||
// if (mDrawable.notNull() && mDrawable->isVisible())
|
||||
// {
|
||||
const LLUUID& image_id = getTE(te)->getID();
|
||||
|
||||
const LLUUID& image_id = getTE(te)->getID();
|
||||
mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
// }
|
||||
|
||||
if (getTE(te)->getMaterialParams().notNull())
|
||||
{
|
||||
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
|
||||
mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
|
||||
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
|
||||
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
|
||||
@@ -4201,6 +4237,52 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
|
||||
return retval;
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
|
||||
{
|
||||
S32 retval = TEM_CHANGE_TEXTURE;
|
||||
const LLUUID& uuid = image ? image->getID() : LLUUID::null;
|
||||
if (uuid != getTE(te)->getID() ||
|
||||
uuid == LLUUID::null)
|
||||
{
|
||||
LLTextureEntry* tep = getTE(te);
|
||||
LLMaterial* mat = NULL;
|
||||
if (tep)
|
||||
{
|
||||
mat = tep->getMaterialParams();
|
||||
}
|
||||
|
||||
if (mat)
|
||||
{
|
||||
mat->setNormalID(uuid);
|
||||
}
|
||||
}
|
||||
changeTENormalMap(te,image);
|
||||
return retval;
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
|
||||
{
|
||||
S32 retval = TEM_CHANGE_TEXTURE;
|
||||
const LLUUID& uuid = image ? image->getID() : LLUUID::null;
|
||||
if (uuid != getTE(te)->getID() ||
|
||||
uuid == LLUUID::null)
|
||||
{
|
||||
LLTextureEntry* tep = getTE(te);
|
||||
LLMaterial* mat = NULL;
|
||||
if (tep)
|
||||
{
|
||||
mat = tep->getMaterialParams();
|
||||
}
|
||||
|
||||
if (mat)
|
||||
{
|
||||
mat->setSpecularID(uuid);
|
||||
}
|
||||
}
|
||||
changeTESpecularMap(te, image);
|
||||
return retval;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
|
||||
{
|
||||
@@ -4211,6 +4293,25 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
|
||||
mTEImages[index] = new_image ;
|
||||
}
|
||||
|
||||
void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
|
||||
{
|
||||
if(index < 0 || index >= getNumTEs())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
mTENormalMaps[index] = new_image ;
|
||||
refreshMaterials();
|
||||
}
|
||||
|
||||
void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
|
||||
{
|
||||
if(index < 0 || index >= getNumTEs())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
mTESpecularMaps[index] = new_image ;
|
||||
refreshMaterials();
|
||||
}
|
||||
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
|
||||
{
|
||||
// Invalid host == get from the agent's sim
|
||||
@@ -4219,6 +4320,19 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
|
||||
return setTETextureCore(te,image);
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
|
||||
{
|
||||
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
|
||||
uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
|
||||
return setTENormalMapCore(te, image);
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
|
||||
{
|
||||
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
|
||||
uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
|
||||
return setTESpecularMapCore(te, image);
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
|
||||
{
|
||||
@@ -4379,6 +4493,59 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
|
||||
return retval;
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
|
||||
{
|
||||
S32 retval = 0;
|
||||
const LLTextureEntry *tep = getTE(te);
|
||||
if (!tep)
|
||||
{
|
||||
LL_WARNS("Material") << "No texture entry for te " << (S32)te
|
||||
<< ", object " << mID
|
||||
<< ", material " << pMaterialID
|
||||
<< LL_ENDL;
|
||||
}
|
||||
//else if (pMaterialID != tep->getMaterialID())
|
||||
{
|
||||
LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
|
||||
<< ", object " << mID
|
||||
<< ", material " << pMaterialID
|
||||
<< LL_ENDL;
|
||||
retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
|
||||
refreshMaterials();
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
|
||||
{
|
||||
S32 retval = 0;
|
||||
const LLTextureEntry *tep = getTE(te);
|
||||
if (!tep)
|
||||
{
|
||||
llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
|
||||
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
|
||||
<< ", object " << mID
|
||||
<< " (" << retval << ")"
|
||||
<< LL_ENDL;
|
||||
setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
|
||||
setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
|
||||
|
||||
refreshMaterials();
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LLViewerObject::refreshMaterials()
|
||||
{
|
||||
setChanged(TEXTURE);
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
gPipeline.markTextured(mDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
|
||||
{
|
||||
@@ -4480,6 +4647,74 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
|
||||
}
|
||||
|
||||
|
||||
bool LLViewerObject::isImageAlphaBlended(const U8 te) const
|
||||
{
|
||||
LLViewerTexture* image = getTEImage(te);
|
||||
LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
|
||||
switch (format)
|
||||
{
|
||||
case GL_RGBA:
|
||||
case GL_ALPHA:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_RGB: break;
|
||||
default:
|
||||
{
|
||||
llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
|
||||
{
|
||||
// llassert(mTEImages);
|
||||
|
||||
if (face < getNumTEs())
|
||||
{
|
||||
LLViewerTexture* image = mTENormalMaps[face];
|
||||
if (image)
|
||||
{
|
||||
return image;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
|
||||
}
|
||||
}
|
||||
|
||||
llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const
|
||||
{
|
||||
// llassert(mTEImages);
|
||||
|
||||
if (face < getNumTEs())
|
||||
{
|
||||
LLViewerTexture* image = mTESpecularMaps[face];
|
||||
if (image)
|
||||
{
|
||||
return image;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
|
||||
}
|
||||
}
|
||||
|
||||
llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLViewerObject::fitFaceTexture(const U8 face)
|
||||
{
|
||||
llinfos << "fitFaceTexture not implemented" << llendl;
|
||||
@@ -4766,7 +5001,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
|
||||
void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy)
|
||||
{
|
||||
if (!mPartSourcep.isNull() && mPartSourcep->isDead())
|
||||
{
|
||||
@@ -4775,7 +5010,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
|
||||
if (mPartSourcep)
|
||||
{
|
||||
// If we've got one already, just update the existing source (or remove it)
|
||||
if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
|
||||
if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))
|
||||
{
|
||||
mPartSourcep->setDead();
|
||||
mPartSourcep = NULL;
|
||||
@@ -4783,7 +5018,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
|
||||
LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);
|
||||
//If the owner is muted, don't create the system
|
||||
if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
|
||||
// We need to be able to deal with a particle source that hasn't changed, but still got an update!
|
||||
@@ -5633,6 +5868,11 @@ F32 LLAlphaObject::getPartSize(S32 idx)
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLStaticViewerObject::updateDrawable(BOOL force_damped)
|
||||
{
|
||||
|
||||
@@ -224,6 +224,7 @@ public:
|
||||
virtual BOOL isFlexible() const { return FALSE; }
|
||||
virtual BOOL isSculpted() const { return FALSE; }
|
||||
virtual BOOL isMesh() const { return FALSE; }
|
||||
virtual BOOL hasLightTexture() const { return FALSE; }
|
||||
|
||||
// This method returns true if the object is over land owned by
|
||||
// the agent, one of its groups, or it encroaches and
|
||||
@@ -306,7 +307,11 @@ public:
|
||||
/*virtual*/ void setNumTEs(const U8 num_tes);
|
||||
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
|
||||
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
|
||||
S32 setTETextureCore(const U8 te, LLViewerTexture *image);
|
||||
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
|
||||
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
|
||||
S32 setTETextureCore(const U8 te, LLViewerTexture *image);
|
||||
S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
|
||||
S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
|
||||
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
|
||||
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
|
||||
@@ -323,11 +328,25 @@ public:
|
||||
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
|
||||
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
|
||||
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
|
||||
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
|
||||
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
|
||||
|
||||
// Used by Materials update functions to properly kick off rebuilds
|
||||
// of VBs etc when materials updates require changes.
|
||||
//
|
||||
void refreshMaterials();
|
||||
|
||||
/*virtual*/ BOOL setMaterial(const U8 material);
|
||||
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
|
||||
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
|
||||
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
|
||||
virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
|
||||
virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
|
||||
LLViewerTexture *getTEImage(const U8 te) const;
|
||||
LLViewerTexture *getTENormalMap(const U8 te) const;
|
||||
LLViewerTexture *getTESpecularMap(const U8 te) const;
|
||||
|
||||
bool isImageAlphaBlended(const U8 te) const;
|
||||
|
||||
void fitFaceTexture(const U8 face);
|
||||
void sendTEUpdate() const; // Sends packed representation of all texture entry information
|
||||
|
||||
@@ -596,6 +615,7 @@ public:
|
||||
} EPhysicsShapeType;
|
||||
|
||||
LLUUID mID;
|
||||
LLUUID mOwnerID; //null if unknown
|
||||
|
||||
// unique within region, not unique across regions
|
||||
// Local ID = 0 is not used
|
||||
@@ -608,6 +628,8 @@ public:
|
||||
S32 mListIndex;
|
||||
|
||||
LLPointer<LLViewerTexture> *mTEImages;
|
||||
LLPointer<LLViewerTexture> *mTENormalMaps;
|
||||
LLPointer<LLViewerTexture> *mTESpecularMaps;
|
||||
|
||||
// Selection, picking and rendering variables
|
||||
U32 mGLName; // GL "name" used by selection code
|
||||
@@ -679,7 +701,7 @@ protected:
|
||||
BOOL isOnMap();
|
||||
|
||||
void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
|
||||
void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
|
||||
void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
|
||||
void deleteParticleSource();
|
||||
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
|
||||
|
||||
@@ -847,8 +869,11 @@ public:
|
||||
LLStrider<LLVector3>& normalsp,
|
||||
LLStrider<LLVector2>& texcoordsp,
|
||||
LLStrider<LLColor4U>& colorsp,
|
||||
LLStrider<LLColor4U>& emissivep,
|
||||
LLStrider<U16>& indicesp) = 0;
|
||||
|
||||
virtual void getBlendFunc(S32 face, U32& src, U32& dst);
|
||||
|
||||
F32 mDepth;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,12 +86,31 @@ LLViewerPart::LLViewerPart() :
|
||||
mImagep(NULL)
|
||||
{
|
||||
mPartSourcep = NULL;
|
||||
|
||||
mParent = NULL;
|
||||
mChild = NULL;
|
||||
++LLViewerPartSim::sParticleCount2 ;
|
||||
}
|
||||
|
||||
LLViewerPart::~LLViewerPart()
|
||||
{
|
||||
if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this)
|
||||
{
|
||||
mPartSourcep->mLastPart = NULL;
|
||||
}
|
||||
|
||||
//patch up holes in the ribbon
|
||||
if (mParent)
|
||||
{
|
||||
llassert(mParent->mChild == this);
|
||||
mParent->mChild = mChild;
|
||||
}
|
||||
|
||||
if (mChild)
|
||||
{
|
||||
llassert (mChild->mParent == this);
|
||||
mChild->mParent = mParent;
|
||||
}
|
||||
|
||||
mPartSourcep = NULL;
|
||||
|
||||
--LLViewerPartSim::sParticleCount2 ;
|
||||
@@ -147,7 +166,11 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo
|
||||
}
|
||||
mVOPartGroupp->setViewerPartGroup(this);
|
||||
mVOPartGroupp->setPositionAgent(getCenterAgent());
|
||||
|
||||
mBoxSide = box_side;
|
||||
|
||||
F32 scale = box_side * 0.5f;
|
||||
|
||||
mVOPartGroupp->setScale(LLVector3(scale,scale,scale));
|
||||
|
||||
//gPipeline.addObject(mVOPartGroupp);
|
||||
@@ -373,6 +396,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
|
||||
part->mScale += frac*part->mEndScale;
|
||||
}
|
||||
|
||||
// Do glow interpolation
|
||||
part->mGlow.mV[3] = (U8) llround(lerp(part->mStartGlow, part->mEndGlow, frac)*255.f);
|
||||
|
||||
// Set the last update time to now.
|
||||
part->mLastUpdateTime = cur_time;
|
||||
|
||||
@@ -491,11 +517,16 @@ void LLViewerPartSim::destroyClass()
|
||||
mViewerPartSources.clear();
|
||||
}
|
||||
|
||||
//static
|
||||
BOOL LLViewerPartSim::shouldAddPart()
|
||||
{
|
||||
if (sParticleCount >= MAX_PART_COUNT)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
|
||||
{
|
||||
|
||||
F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
|
||||
frac -= PART_THROTTLE_THRESHOLD;
|
||||
frac *= PART_THROTTLE_RESCALE;
|
||||
@@ -505,7 +536,10 @@ BOOL LLViewerPartSim::shouldAddPart()
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (sParticleCount >= MAX_PART_COUNT)
|
||||
|
||||
// Check frame rate, and don't add more if the viewer is really slow
|
||||
const F32 MIN_FRAME_RATE_FOR_NEW_PARTICLES = 4.f;
|
||||
if (gFPSClamped < MIN_FRAME_RATE_FOR_NEW_PARTICLES)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -621,6 +655,9 @@ void LLViewerPartSim::updateSimulation()
|
||||
{
|
||||
static LLFrameTimer update_timer;
|
||||
|
||||
//reset VBO cursor
|
||||
LLVOPartGroup::sVBSlotCursor = 0;
|
||||
|
||||
const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);
|
||||
|
||||
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
|
||||
|
||||
@@ -71,15 +71,22 @@ public:
|
||||
|
||||
LLVPCallback mVPCallback; // Callback function for more complicated behaviors
|
||||
LLPointer<LLViewerPartSource> mPartSourcep; // Particle source used for this object
|
||||
|
||||
|
||||
LLViewerPart* mParent; // particle to connect to if this is part of a particle ribbon
|
||||
LLViewerPart* mChild; // child particle for clean reference destruction
|
||||
|
||||
// Current particle state (possibly used for rendering)
|
||||
LLPointer<LLViewerTexture> mImagep;
|
||||
LLVector3 mPosAgent;
|
||||
LLVector3 mVelocity;
|
||||
LLVector3 mAccel;
|
||||
LLVector3 mAxis;
|
||||
LLColor4 mColor;
|
||||
LLVector2 mScale;
|
||||
F32 mStartGlow;
|
||||
F32 mEndGlow;
|
||||
LLColor4U mGlow;
|
||||
|
||||
|
||||
static U32 sNextPartID;
|
||||
};
|
||||
@@ -104,6 +111,9 @@ public:
|
||||
|
||||
void shift(const LLVector3 &offset);
|
||||
|
||||
F32 getBoxRadius() { return mBoxRadius; }
|
||||
F32 getBoxSide() { return mBoxSide; }
|
||||
|
||||
typedef std::vector<LLViewerPart*> part_list_t;
|
||||
part_list_t mParticles;
|
||||
|
||||
@@ -124,6 +134,7 @@ public:
|
||||
protected:
|
||||
LLVector3 mCenterAgent;
|
||||
F32 mBoxRadius;
|
||||
F32 mBoxSide;
|
||||
LLVector3 mMinObjPos;
|
||||
LLVector3 mMaxObjPos;
|
||||
|
||||
@@ -148,7 +159,7 @@ public:
|
||||
|
||||
void cleanupRegion(LLViewerRegion *regionp);
|
||||
|
||||
BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
|
||||
static BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
|
||||
F32 maxRate() // Return maximum particle generation rate
|
||||
{
|
||||
if (sParticleCount >= MAX_PART_COUNT)
|
||||
|
||||
@@ -58,6 +58,8 @@ LLViewerPartSource::LLViewerPartSource(const U32 type) :
|
||||
static U32 id_seed = 0;
|
||||
mID = ++id_seed;
|
||||
|
||||
mLastPart = NULL;
|
||||
|
||||
mDelay = 0 ;
|
||||
}
|
||||
|
||||
@@ -285,6 +287,22 @@ void LLViewerPartSourceScript::update(const F32 dt)
|
||||
{
|
||||
part->mFlags |= LLPartData::LL_PART_HUD;
|
||||
}
|
||||
|
||||
if (part->mFlags & LLPartData::LL_PART_RIBBON_MASK && mLastPart)
|
||||
{ //set previous particle's parent to this particle to chain ribbon together
|
||||
mLastPart->mParent = part;
|
||||
part->mChild = mLastPart;
|
||||
part->mAxis = LLVector3(0,0,1);
|
||||
|
||||
if (mSourceObjectp.notNull())
|
||||
{
|
||||
LLQuaternion rot = mSourceObjectp->getRenderRotation();
|
||||
part->mAxis *= rot;
|
||||
}
|
||||
}
|
||||
|
||||
mLastPart = part;
|
||||
|
||||
part->mMaxAge = mPartSysData.mPartData.mMaxAge;
|
||||
part->mStartColor = mPartSysData.mPartData.mStartColor;
|
||||
part->mEndColor = mPartSysData.mPartData.mEndColor;
|
||||
@@ -296,6 +314,13 @@ void LLViewerPartSourceScript::update(const F32 dt)
|
||||
|
||||
part->mAccel = mPartSysData.mPartAccel;
|
||||
|
||||
part->mBlendFuncDest = mPartSysData.mPartData.mBlendFuncDest;
|
||||
part->mBlendFuncSource = mPartSysData.mPartData.mBlendFuncSource;
|
||||
|
||||
part->mStartGlow = mPartSysData.mPartData.mStartGlow;
|
||||
part->mEndGlow = mPartSysData.mPartData.mEndGlow;
|
||||
part->mGlow = LLColor4U(0, 0, 0, (U8) llround(part->mStartGlow*255.f));
|
||||
|
||||
if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_DROP)
|
||||
{
|
||||
part->mPosAgent = mPosAgent;
|
||||
@@ -436,28 +461,51 @@ LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewer
|
||||
}
|
||||
|
||||
|
||||
LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp)
|
||||
LLPointer<LLViewerPartSourceScript> LLViewerPartSourceScript::unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy)
|
||||
{
|
||||
if (!pssp)
|
||||
{
|
||||
LLPointer<LLViewerPartSourceScript> new_pssp = new LLViewerPartSourceScript(source_objp);
|
||||
if (!new_pssp->mPartSysData.unpack(dp))
|
||||
if (legacy)
|
||||
{
|
||||
return NULL;
|
||||
if (!new_pssp->mPartSysData.unpackLegacy(dp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!new_pssp->mPartSysData.unpack(dp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_pssp->mPartSysData.mTargetUUID.notNull())
|
||||
{
|
||||
LLViewerObject *target_objp = gObjectList.findObject(new_pssp->mPartSysData.mTargetUUID);
|
||||
new_pssp->setTargetObject(target_objp);
|
||||
}
|
||||
|
||||
return new_pssp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pssp->mPartSysData.unpack(dp))
|
||||
if (legacy)
|
||||
{
|
||||
return NULL;
|
||||
if (!pssp->mPartSysData.unpackLegacy(dp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pssp->mPartSysData.unpack(dp))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pssp->mPartSysData.mTargetUUID.notNull())
|
||||
{
|
||||
LLViewerObject *target_objp = gObjectList.findObject(pssp->mPartSysData.mTargetUUID);
|
||||
@@ -575,6 +623,11 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
|
||||
part->mScale.mV[0] = 0.25f;
|
||||
part->mScale.mV[1] = 0.25f;
|
||||
part->mParameter = ll_frand(F_TWO_PI);
|
||||
part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
|
||||
part->mStartGlow = 0.f;
|
||||
part->mEndGlow = 0.f;
|
||||
part->mGlow = LLColor4U(0, 0, 0, 0);
|
||||
|
||||
LLViewerPartSim::getInstance()->addPart(part);
|
||||
}
|
||||
@@ -727,6 +780,12 @@ void LLViewerPartSourceBeam::update(const F32 dt)
|
||||
part->mPosAgent = mPosAgent;
|
||||
part->mVelocity = mTargetPosAgent - mPosAgent;
|
||||
|
||||
part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
|
||||
part->mStartGlow = 0.f;
|
||||
part->mEndGlow = 0.f;
|
||||
part->mGlow = LLColor4U(0, 0, 0, 0);
|
||||
|
||||
LLViewerPartSim::getInstance()->addPart(part);
|
||||
}
|
||||
}
|
||||
@@ -831,6 +890,12 @@ void LLViewerPartSourceChat::update(const F32 dt)
|
||||
part->mScale.mV[0] = 0.25f;
|
||||
part->mScale.mV[1] = 0.25f;
|
||||
part->mParameter = ll_frand(F_TWO_PI);
|
||||
part->mBlendFuncDest = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
|
||||
part->mBlendFuncSource = LLRender::BF_SOURCE_ALPHA;
|
||||
part->mStartGlow = 0.f;
|
||||
part->mEndGlow = 0.f;
|
||||
part->mGlow = LLColor4U(0, 0, 0, 0);
|
||||
|
||||
|
||||
LLViewerPartSim::getInstance()->addPart(part);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
LLVector3 mLastUpdatePosAgent;
|
||||
LLPointer<LLViewerObject> mSourceObjectp;
|
||||
U32 mID;
|
||||
LLViewerPart* mLastPart; //last particle emitted (for making particle ribbons)
|
||||
|
||||
protected:
|
||||
U32 mType;
|
||||
@@ -120,7 +121,7 @@ public:
|
||||
|
||||
// Returns a new particle source to attach to an object...
|
||||
static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, const S32 block_num);
|
||||
static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp);
|
||||
static LLPointer<LLViewerPartSourceScript> unpackPSS(LLViewerObject *source_objp, LLPointer<LLViewerPartSourceScript> pssp, LLDataPacker &dp, bool legacy);
|
||||
static LLPointer<LLViewerPartSourceScript> createPSS(LLViewerObject *source_objp, const LLPartSysData& particle_parameters);
|
||||
|
||||
LLViewerTexture *getImage() const { return mImagep; }
|
||||
|
||||
@@ -2093,3 +2093,45 @@ boost::signals2::connection LLViewerRegion::setFeaturesReceivedCallback(const fe
|
||||
return mFeaturesReceivedSignal.connect(cb);
|
||||
}
|
||||
|
||||
void LLViewerRegion::resetMaterialsCapThrottle()
|
||||
{
|
||||
F32 requests_per_sec = 1.0f; // original default;
|
||||
if ( mSimulatorFeatures.has("RenderMaterialsCapability")
|
||||
&& mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
|
||||
{
|
||||
requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
|
||||
if ( requests_per_sec == 0.0f )
|
||||
{
|
||||
requests_per_sec = 1.0f;
|
||||
LL_WARNS("Materials")
|
||||
<< "region '" << getName()
|
||||
<< "' returned zero for RenderMaterialsCapability; using default "
|
||||
<< requests_per_sec << " per second"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
LL_DEBUGS("Materials") << "region '" << getName()
|
||||
<< "' RenderMaterialsCapability " << requests_per_sec
|
||||
<< LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Materials")
|
||||
<< "region '" << getName()
|
||||
<< "' did not return RenderMaterialsCapability, using default "
|
||||
<< requests_per_sec << " per second"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
|
||||
}
|
||||
|
||||
U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
|
||||
{
|
||||
U32 max_entries = 50; // original hard coded default
|
||||
if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
|
||||
&& mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
|
||||
{
|
||||
max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
|
||||
}
|
||||
return max_entries;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user