308 lines
9.1 KiB
C++
308 lines
9.1 KiB
C++
|
|
// scene reflection
|
|
uniform float reflectionCoeff = 0.0f;
|
|
uniform float specularCoeff = 0.0f;
|
|
|
|
uniform sampler2DRect reflectionTex;
|
|
|
|
// Shadow map
|
|
uniform float shadowAmbient = 0.0;
|
|
uniform sampler2D texture;
|
|
uniform sampler2DArrayShadow stex;
|
|
uniform sampler2DArrayShadow stex2;
|
|
uniform sampler2DArrayShadow stex3;
|
|
uniform samplerCube skyboxTex;
|
|
|
|
uniform float hdrScale = 5.0;
|
|
|
|
uniform vec2 texSize; // x - size, y - 1/size
|
|
uniform vec4 far_d;
|
|
|
|
// Spot lights
|
|
uniform vec3 spotLightDir;
|
|
uniform vec3 spotLightPos;
|
|
uniform float spotLightCosineDecayBegin;
|
|
uniform float spotLightCosineDecayEnd;
|
|
|
|
uniform vec3 spotLightDir2;
|
|
uniform vec3 spotLightPos2;
|
|
uniform float spotLightCosineDecayBegin2;
|
|
uniform float spotLightCosineDecayEnd2;
|
|
|
|
uniform vec3 spotLightDir3;
|
|
uniform vec3 spotLightPos3;
|
|
uniform float spotLightCosineDecayBegin3;
|
|
uniform float spotLightCosineDecayEnd3;
|
|
|
|
uniform vec3 parallelLightDir;
|
|
uniform float shadowAdd;
|
|
uniform int useTexture;
|
|
uniform int numShadows;
|
|
uniform vec3 ambientColor;
|
|
uniform vec2 shadowTaps[12];
|
|
float shadowCoeff1()
|
|
{
|
|
//const int index = 0;
|
|
|
|
int index = 3;
|
|
|
|
if(gl_FragCoord.z < far_d.x)
|
|
index = 0;
|
|
else if(gl_FragCoord.z < far_d.y)
|
|
index = 1;
|
|
else if(gl_FragCoord.z < far_d.z)
|
|
index = 2;
|
|
|
|
vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[1].xyz, 1);
|
|
|
|
shadow_coord.w = shadow_coord.z + shadowAdd;
|
|
// tell glsl in which layer to do the look up
|
|
shadow_coord.z = float(index);
|
|
|
|
|
|
// Gaussian 3x3 filter
|
|
// return shadow2DArray(stex, shadow_coord).x;
|
|
/*
|
|
const float X = 1.0f;
|
|
float ret = shadow2DArray(stex, shadow_coord).x * 0.25;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( -X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( -X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( -X, X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( 0, -X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( 0, X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex, shadow_coord, ivec2( X, X)).x * 0.0625;
|
|
return ret;*/
|
|
const int numTaps = 12;
|
|
float radius = 0.0003f / pow(2, index);
|
|
float s = 0.0f;
|
|
for (int i = 0; i < numTaps; i++)
|
|
{
|
|
s += shadow2DArray(stex, shadow_coord + vec4(shadowTaps[i] * radius, 0.0f, 0.0f)).r;
|
|
}
|
|
s /= numTaps;
|
|
return s;
|
|
}
|
|
float shadowCoeff2()
|
|
{
|
|
const int index = 1;
|
|
|
|
//int index = 3;
|
|
//if(gl_FragCoord.z < far_d.x)
|
|
// index = 0;
|
|
//else if(gl_FragCoord.z < far_d.y)
|
|
// index = 1;
|
|
//else if(gl_FragCoord.z < far_d.z)
|
|
// index = 2;
|
|
|
|
vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[1].xyz, 1);
|
|
|
|
shadow_coord.w = shadow_coord.z + shadowAdd;
|
|
shadow_coord.z = float(0);
|
|
// return shadow2DArray(stex, shadow_coord).x;
|
|
/*
|
|
const float X = 1.0f;
|
|
float ret = shadow2DArray(stex2, shadow_coord).x * 0.25;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( -X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( -X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( -X, X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( 0, -X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( 0, X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex2, shadow_coord, ivec2( X, X)).x * 0.0625;
|
|
return ret;*/
|
|
const int numTaps = 12;
|
|
float radius = 1.0f;
|
|
float s = 0.0f;
|
|
for (int i = 0; i < numTaps; i++)
|
|
{
|
|
s += shadow2DArray(stex, shadow_coord + vec4(shadowTaps[i] * radius, 0.0f, 0.0f)).r;
|
|
}
|
|
s /= numTaps;
|
|
return s;
|
|
}
|
|
float shadowCoeff3()
|
|
{
|
|
const int index = 2;
|
|
|
|
//int index = 3;
|
|
//if(gl_FragCoord.z < far_d.x)
|
|
// index = 0;
|
|
//else if(gl_FragCoord.z < far_d.y)
|
|
// index = 1;
|
|
//else if(gl_FragCoord.z < far_d.z)
|
|
// index = 2;
|
|
|
|
vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[1].xyz, 1);
|
|
|
|
shadow_coord.w = shadow_coord.z + shadowAdd;
|
|
shadow_coord.z = float(0);
|
|
|
|
// return shadow2DArray(stex, shadow_coord).x;
|
|
/*
|
|
const float X = 1.0f;
|
|
float ret = shadow2DArray(stex3, shadow_coord).x * 0.25;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( -X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( -X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( -X, X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( 0, -X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( 0, X)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( X, -X)).x * 0.0625;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( X, 0)).x * 0.125;
|
|
ret += shadow2DArrayOffset(stex3, shadow_coord, ivec2( X, X)).x * 0.0625;
|
|
return ret;*/
|
|
const int numTaps = 12;
|
|
float radius = 0.02f;
|
|
float s = 0.0f;
|
|
for (int i = 0; i < numTaps; i++)
|
|
{
|
|
s += shadow2DArray(stex, shadow_coord + vec4(shadowTaps[i] * radius, 0.0f, 0.0f)).r;
|
|
}
|
|
s /= numTaps;
|
|
return s;
|
|
}
|
|
|
|
float filterwidth(float2 v)
|
|
{
|
|
float2 fw = max(abs(ddx(v)), abs(ddy(v)));
|
|
return max(fw.x, fw.y);
|
|
}
|
|
|
|
float2 bump(float2 x)
|
|
{
|
|
return (floor((x) / 2) + 2.f * max(((x) / 2) - floor((x) / 2) - .5f, 0.f));
|
|
}
|
|
|
|
float checker(float2 uv)
|
|
{
|
|
float width = filterwidth(uv);
|
|
float2 p0 = uv - 0.5 * width;
|
|
float2 p1 = uv + 0.5 * width;
|
|
|
|
float2 i = (bump(p1) - bump(p0)) / width;
|
|
return i.x * i.y + (1 - i.x) * (1 - i.y);
|
|
}
|
|
uniform float fresnelBias = 0.0;
|
|
uniform float fresnelScale = 1.0;
|
|
uniform float fresnelPower = 3.0; // 5.0 is physically correct
|
|
|
|
uniform float RollOff = 0.5f;
|
|
void main()
|
|
{
|
|
|
|
//// TODO, expose this as user parameter
|
|
const float skyLightIntensity = 0.2;
|
|
const float rimLightIntensity = 0.3;
|
|
|
|
|
|
vec3 diffuseMat;
|
|
vec3 specularMat;
|
|
vec3 emissiveReflectSpecPow;
|
|
|
|
specularMat = vec3(1.0);
|
|
emissiveReflectSpecPow = vec3(0.0,0.0,0.0);
|
|
|
|
vec3 normal = normalize(gl_TexCoord[2].xyz);
|
|
vec3 wnormal = normalize(gl_TexCoord[4].xyz);
|
|
// read in material color for diffuse, specular, bump, emmisive
|
|
|
|
// 3D texture
|
|
vec4 colorx;
|
|
if (useTexture > 0)
|
|
colorx = texture2D(texture, gl_TexCoord[0]);
|
|
else {
|
|
colorx = gl_Color;
|
|
colorx *= 1.0 - 0.25*checker(float2(gl_TexCoord[3].x, gl_TexCoord[3].z));
|
|
}
|
|
colorx = clamp(colorx,0,1);
|
|
diffuseMat = colorx.xyz*0.4;
|
|
//diffuseMat = myTexture3D(gl_TexCoord[0].xyz);//texture3D(ttt3D, gl_TexCoord[0].xyz);
|
|
//diffuseMat = texture3D(ttt3D, gl_TexCoord[0].xyz);
|
|
|
|
if (dot(normal, gl_TexCoord[1].xyz) > 0) {
|
|
normal.xyz *= -1;
|
|
}
|
|
|
|
//gl_FragColor.xyz = normal*0.5 + vec3(0.5,0.5,0.5);
|
|
//gl_FragColor.w = 1;
|
|
//return;
|
|
vec3 eyeVec = normalize(gl_TexCoord[1].xyz);
|
|
|
|
// apply gamma correction for diffuse textures
|
|
//diffuseMat = pow(diffuseMat, 0.45);
|
|
|
|
float specularPower = emissiveReflectSpecPow.b*255.0f + 1.0f;
|
|
|
|
// TODO - fix this
|
|
specularPower = 10.0f;
|
|
|
|
float emissive = 0.0f;
|
|
float reflectivity = emissiveReflectSpecPow.b;
|
|
float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(normal, eyeVec)), fresnelPower);
|
|
float specular = 0.0f;
|
|
|
|
vec3 skyNormal = reflect(eyeVec, normal);
|
|
vec3 skyColor = skyLightIntensity * textureCube(skyboxTex, skyNormal).rgb;
|
|
vec3 ambientSkyColor = diffuseMat * skyColor;
|
|
|
|
vec3 diffuseColor = vec3(0.0, 0.0, 0.0);
|
|
|
|
if (numShadows >= 1) {
|
|
|
|
vec3 lightColor = hdrScale * vec3(1.0, 1.0, 1.0);
|
|
vec3 shadowColor = vec3(0.4, 0.4, 0.7); // colored shadow
|
|
//vec3 lvec = normalize(spotLightDir);
|
|
vec3 lvec = normalize(spotLightPos - gl_TexCoord[1].xyz);
|
|
float cosine = dot(lvec, spotLightDir);
|
|
float intensity = smoothstep(spotLightCosineDecayBegin, spotLightCosineDecayEnd, cosine);
|
|
|
|
float ldn = max(0.0f, dot(normal, lvec));
|
|
float shadowC = shadowCoeff1();
|
|
//gl_FragColor = vec4(shadowC,shadowC,shadowC,1.0f);
|
|
//return;
|
|
vec3 irradiance = shadowC * ldn * lightColor;
|
|
|
|
// diffuse irradiance
|
|
diffuseColor += diffuseMat * irradiance*intensity;
|
|
|
|
// add colored shadow
|
|
diffuseColor += (1.0 - shadowC*ldn) * shadowAmbient * shadowColor * diffuseMat*intensity;
|
|
|
|
vec3 r = reflect(lvec, normal);
|
|
specular += pow(max(0.0, dot(r, eyeVec)), specularPower)*shadowC*intensity;
|
|
}
|
|
|
|
// add rim light
|
|
if (numShadows >= 2) {
|
|
vec3 lightColor = hdrScale * vec3(1.0, 1.0, 1.0);
|
|
vec3 lvec = normalize(spotLightDir2);
|
|
float ldn = max(0.0f, dot(normal, lvec));
|
|
vec3 irradiance = ldn * lightColor;
|
|
|
|
// diffuse irradiance
|
|
diffuseColor += diffuseMat * irradiance;
|
|
}
|
|
|
|
vec3 color = vec3(0.0, 0.0, 0.0);
|
|
|
|
color += diffuseColor;
|
|
color += ambientSkyColor;
|
|
color += specular*specularMat;
|
|
color += hdrScale * emissive * diffuseMat;
|
|
|
|
//vec3 reflectColor = diffuseMat * texture2DRect(reflectionTex, gl_FragCoord.xy).rgb;
|
|
//color = reflectionCoeff * reflectColor + (1.0f - reflectionCoeff) * color;
|
|
color = (fresnel * skyColor + (1.0 - fresnel) * color) * reflectivity + (1.0 - reflectivity) * color;
|
|
|
|
gl_FragColor.rgb = color;
|
|
gl_FragColor.w = gl_Color.w;
|
|
|
|
//float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[1].z), 0.0, 1.0);
|
|
//vec4 fogCol = gl_Fog.color;
|
|
float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[1].z), 0.0, 1.0);
|
|
vec4 fogCol = gl_Fog.color;
|
|
gl_FragColor = mix(fogCol, gl_FragColor, fog);
|
|
|
|
} |