169 lines
5.0 KiB
GLSL
169 lines
5.0 KiB
GLSL
#version 300 es
|
||
precision highp float;
|
||
precision highp sampler2DShadow;
|
||
precision mediump int;
|
||
uniform float colorFac;
|
||
uniform bool isTex; //是否是纹理
|
||
uniform bool isShadow; //是否渲染阴影
|
||
uniform bool isNightDay; //是否是白天模式
|
||
uniform bool isRenderZebra; //斑马线渲染
|
||
uniform bool isSpotLight; //是否聚光灯
|
||
uniform bool isPcf; //是否聚光灯
|
||
uniform bool isWave; //流光效果
|
||
uniform sampler2D texId;
|
||
uniform sampler2DShadow depthTex; //深度纹理
|
||
uniform bool isRenderSignalLine; //信号线
|
||
uniform float signalLineTime; //信号线时间
|
||
uniform float signalLineCnt; //信号线时间
|
||
uniform int signalLineStep; //信号线时间
|
||
uniform int signalLineObj; //信号线对象
|
||
uniform vec4 shadowColor;
|
||
uniform float spotRadius; //聚光灯半径范围
|
||
uniform float spotBright; //聚光灯亮度
|
||
uniform float spotOffset; //聚光灯偏移
|
||
uniform bool isRenderText; //是否是文字渲染
|
||
uniform vec4 textColor; //信号线时间
|
||
uniform bool isWater; //水系
|
||
uniform vec4 waterColor;
|
||
uniform vec3 cameraPos;
|
||
uniform float shadowResolution;
|
||
in vec4 posInLight;
|
||
in vec4 _color;
|
||
in highp vec3 posInEye;
|
||
in vec2 _uv;
|
||
in float signalLineTexY;
|
||
uniform float waveVel;
|
||
uniform vec4 waveColor;
|
||
uniform float waveTime;
|
||
in highp float waveOff;
|
||
out vec4 fragColor;
|
||
in float distanceFromCamera;
|
||
|
||
uniform bool isFogEnable;
|
||
uniform vec3 fogColor;
|
||
uniform float fogStart;
|
||
uniform float fogEnd;
|
||
uniform float fogDensity;
|
||
void setSpotLightColor(){ //聚光灯光照效果
|
||
lowp float r_base= 4.0;
|
||
lowp float r_max = spotRadius * 32.0;
|
||
highp vec3 l_pos = vec3(0, 2, -(spotOffset+60.0));
|
||
highp vec3 v = posInEye - l_pos;
|
||
v.x = v.x*2.25; v.z = v.z/2.25;
|
||
highp float d = length(v);
|
||
highp float r = d - r_base;
|
||
if (r < r_max)
|
||
{
|
||
highp float p = pow((r_max-r)/r_max, 2.0);
|
||
lowp float t = spotBright*p * 0.15;
|
||
lowp vec4 c_light = fragColor + vec4(t*2.0,t*2.0,t*3.0,0);
|
||
fragColor = c_light;
|
||
}
|
||
}
|
||
bool isInScreen(vec4 p){ //是否在包围盒[(0,0)-(1,1)]内
|
||
if(p.x < 0.0 || p.x > 1.0 || p.y < 0.0 || p.y > 1.0)
|
||
return false;
|
||
else
|
||
return true;
|
||
}
|
||
|
||
void setZebra(){
|
||
vec4 c = texture(texId, _uv);
|
||
fragColor = vec4(c.rgb, step(0.8,c.a));
|
||
}
|
||
void setColor(){
|
||
fragColor = _color;
|
||
}
|
||
void setTex(){
|
||
fragColor = texture(texId,_uv);
|
||
}
|
||
float getShadowOffset(float x, float y)
|
||
{
|
||
float pixelSize = 1.0/shadowResolution;
|
||
vec4 offset = vec4(x,y,0.0, 0.0)*pixelSize * posInLight.w;
|
||
return textureProj(depthTex,posInLight + offset);
|
||
}
|
||
float getPcf(){
|
||
// 3x3 kernel with 4 taps per sample, effectively 6x6 PCF
|
||
float sum = 0.0;
|
||
for(int x=-2;x<=2;x+=2)
|
||
for(int y=-2;y<=2;y+=2)
|
||
sum+=getShadowOffset(float(x),float(y));
|
||
// divide sum by 9.0
|
||
sum = sum * 0.11;
|
||
return sum;
|
||
}
|
||
void setShadow(){
|
||
vec4 p = posInLight / posInLight.w; //ndc坐标
|
||
if(isInScreen(p)){ //坐标不在[0,1]内,光源看不到此片元,那就不用处理此片元的阴影
|
||
// float f = textureProj(depthTex,posInLight); //textureProj在阴影中返回0,否则返回1。即是否通过深度测试
|
||
float k;
|
||
if(isPcf)
|
||
k = 1.0-getPcf();
|
||
else
|
||
k = 1.0-textureProj(depthTex,posInLight); //textureProj在阴影中返回0,否则返回1。即是否通过深度测试
|
||
fragColor = vec4(mix(vec3(fragColor),vec3(shadowColor*k),shadowColor.a*k),fragColor.a);
|
||
}
|
||
}
|
||
void setWave(){
|
||
highp float k = clamp(cos(waveTime/20.0*waveVel-waveOff), 0.0,1.0);
|
||
k = clamp(pow(k, 25.0),0.02,0.98);
|
||
fragColor = mix(_color,waveColor,k);
|
||
}
|
||
void setSignalLine(){
|
||
if(signalLineObj==0){
|
||
if(signalLineStep==0 && _uv.y>1.0)
|
||
discard;
|
||
}else if(signalLineObj==1){
|
||
if(_uv.x<0.0 || _uv.x>1.0)
|
||
discard;
|
||
if(signalLineStep==1){
|
||
if(_uv.y<signalLineCnt)
|
||
discard;
|
||
}
|
||
}
|
||
fragColor = texture(texId,_uv);
|
||
// fragColor *= 1.0-0.5*smoothstep(0.0,signalLineCnt,signalLineTexY);
|
||
if(signalLineObj==1)
|
||
fragColor *= clamp(smoothstep(0.0,signalLineCnt,signalLineTexY)+0.5,0.0,1.0);
|
||
}
|
||
void setText(){
|
||
fragColor = vec4(vec3(textColor),texture(texId,_uv).a);
|
||
}
|
||
void setLinearFog()
|
||
{
|
||
if(!isFogEnable)
|
||
return;
|
||
float distanceFromCamera = length(posInEye-cameraPos);
|
||
if(distanceFromCamera<fogStart)
|
||
return;
|
||
float fogAlpha=(distanceFromCamera-fogStart)/(fogEnd-fogStart);
|
||
fogAlpha=clamp(fogAlpha,0.0,1.0)*fogDensity;
|
||
fragColor.rgb = mix(fragColor.rgb,fogColor,fogAlpha);
|
||
}
|
||
void main()
|
||
{
|
||
|
||
if (isRenderZebra)
|
||
setZebra();
|
||
else if (isRenderSignalLine)
|
||
setSignalLine();
|
||
else if (isWave)
|
||
setWave();
|
||
else if (isRenderText)
|
||
setText();
|
||
else if (isTex)
|
||
setTex();
|
||
else
|
||
setColor();
|
||
if (isSpotLight)
|
||
setSpotLightColor();
|
||
fragColor*=colorFac;
|
||
if (isShadow)
|
||
setShadow();
|
||
if (isWater){
|
||
fragColor = waterColor*dot(normalize(fragColor.rgb), vec3(0.0, 0.0, 1.0));
|
||
fragColor.a = 1.0;
|
||
}
|
||
setLinearFog();
|
||
} |