A shader about fog, porting in Java, can control the fog height, suitable for all kinds of mesh terrain.
Code is below:
function setup()
parameter.number("cx",-1000,1000,220)
parameter.number("cy",-1000,2000,175)
parameter.number("cz",-1000,1000,437)
parameter.number("tx",-100,100,-4)
parameter.number("ty",-100,200,0)
parameter.number("tz",-100,100,0)
parameter.number("fov",-360,360,17)
parameter.number("slabY",-100,200,17)
local yArray = loadLandForms()
m = Mountain(yArray, #yArray-1, #yArray[1]-1)
end
function draw()
background(0)
m:draw()
end
function loadLandForms()
result = {}
landHighAdjust = 2;
landHighest = 60;
myImg = readImage(asset.land);
local w,h = myImg.width, myImg.height
for i=1,h,1 do
result[i] = {}
for j=1,w,1 do
r,g,b,a = myImg:get(j,i)
local mh = (r+g+b)/3
result[i][j] = mh*landHighest/255 - landHighAdjust
end
end
return result
end
Mountain = class()
function Mountain:init(yArray, rows, cols)
self.mesh = mesh()
self.unitSize = 3
self.mesh.vertices = {}
self.mesh.texCoords = {}
self:initVertexData(yArray, rows, cols)
self:initShader()
end
function Mountain:initShader()
self.mesh.shader = shader(vs35.v,vs35.f)
self.mesh.shader.slabY = slabY or 13
self.mesh.shader.startAngle = 0
self.mesh.shader.uCameraLocation = vec3(0,25,0)
self.mesh.shader.landStartY = 0
self.mesh.shader.landYSpan = 50
self.mesh.shader.modelMatrix = modelMatrix()
self.mesh.shader.sTextureRock = readImage(asset.grass)
self.mesh.shader.sTextureGrass = readImage(asset.LMStone)
end
function Mountain:draw()
pushMatrix()
translate(0,0,1)
camera(cx,cy,cz,tx,ty,tz,0,1,0)
perspective(fov,WIDTH/HEIGHT,0.01,5000)
self.mesh.shader.slabY = slabY
self.mesh.shader.startAngle = ((self.mesh.shader.startAngle+0.03)%360)
self.mesh.shader.uCameraLocation = vec3(cx,cy,cz)
self.mesh:draw()
popMatrix()
end
function Mountain:initVertexData(yArray, rows, cols)
local count = 0
local vertices = {}
local unit = self.unitSize
for j=1,rows,1 do
for i=1,cols,1 do
zsx = -unit*cols/2 + i*unit
zsz = -unit*rows/2 + j*unit
vertices[count+1] = vec3(zsx, yArray[j][i], zsz)
vertices[count+2] = vec3(zsx, yArray[j+1][i], zsz+unit)
vertices[count+3] = vec3(zsx+unit, yArray[j][i+1], zsz)
vertices[count+4] = vec3(zsx+unit, yArray[j][i+1], zsz)
vertices[count+5] = vec3(zsx, yArray[j+1][i], zsz+unit)
vertices[count+6] = vec3(zsx+unit, yArray[j+1][i+1], zsz+unit)
count = count+6
end
end
self.mesh.vertices = vertices
self.mesh.texCoords = self:generateTexcoords(cols, rows)
end
function Mountain:generateTexcoords(bw, bh)
local result = {}
sizeW = 16/bw
sizeH = 16/bh
local c =0
for i=1,bh,1 do
for j=1,bw,1 do
local s,t = j*sizeW, i*sizeH
result[c+1] = vec2(s,t)
result[c+2] = vec2(s, t + sizeH)
result[c+3] = vec2(s + sizeW, t)
result[c+4] = vec2(s + sizeW, t)
result[c+5] = vec2(s, t + sizeH)
result[c+6] = vec2(s + sizeW, t + sizeH)
c=c+6
end
end
return result
end
vs35 = {
v = [[
#version 300 es
uniform mat4 modelViewProjection; //?????
uniform mat4 modelMatrix; //??????
uniform mat4 viewMatrix; //??????
in vec3 position; //????
in vec2 texCoord; //??????
out vec2 vTextureCoord; //???????????????
out float currY; //???????????Y??
out vec4 pLocation; //???????????????
void main(){
vTextureCoord = texCoord; //????????????????
currY = position.y; //????Y??????????
gl_Position=modelViewProjection * vec4(position,1); //???????????????????
pLocation= modelMatrix*vec4(position,1);//??????(??/??/??)??????
}
]],
f = [[
#version 300 es
precision mediump float; //?????????
in vec2 vTextureCoord; //????????????????
in float currY; //????????????Y??
in vec4 pLocation; //????????????????
uniform float slabY; //???????????
uniform float startAngle; //?????
uniform vec3 uCameraLocation; //?????
uniform sampler2D sTextureGrass; //??????????
uniform sampler2D sTextureRock; //??????????
uniform float landStartY; //??????Y??
uniform float landYSpan; //??????
out vec4 fragColor;//????????
float tjFogCal(vec4 pLocation){//????????????
float xAngle=pLocation.x/16.0*3.1415926;//?????X????????
float zAngle=pLocation.z/20.0*3.1415926;//?????Z????????
float slabYFactor=1.618*sin(xAngle+zAngle+startAngle);//???????????????
//??????????????????Pc+(Pp-Pc)t???????t?
float t=(slabY+slabYFactor-uCameraLocation.y)/(pLocation.y-uCameraLocation.y);
//???t??????0~1??????????????????????????
if(t>0.0&&t<1.0){//????????
//?????????????
float xJD=uCameraLocation.x+(pLocation.x-uCameraLocation.x)*t;
float zJD=uCameraLocation.z+(pLocation.z-uCameraLocation.z)*t;
vec3 locationJD=vec3(xJD,slabY,zJD);
float L=distance(locationJD,pLocation.xyz);//???????????????
float L0=10.0;
return L0/(L+L0);//???????????
}else{
return 1.0;//???????????????????????
}}
void main(){
vec4 gColor=texture(sTextureGrass, vTextureCoord);//???????????
vec4 rColor=texture(sTextureRock, vTextureCoord); //???????????
vec4 finalColor; //??????
if(currY<landStartY){
finalColor=gColor; //???Y??????????Y?????????
}else if(currY>landStartY+landYSpan){
finalColor=rColor;//???Y??????????Y????????????
}else{//???Y???????????????????
float currYRatio=(currY-landStartY)/landYSpan;//????????????
//???????????????
finalColor= currYRatio*rColor+(1.0- currYRatio)*gColor;
}
float fogFactor=tjFogCal(pLocation);//???????
//??????????????????????????????????
fragColor=fogFactor*finalColor+ (1.0-fogFactor)*vec4(0.9765,0.97490,0.9549,1.0); //?????????
/*
if (fogFactor == 1.0) { fragColor=finalColor;
}else{
fragColor= fogFactor*finalColor + (1.0-fogFactor)*vec4(0.9765, 0.97490, 0.90549, 1.0); //?????????
}
*/
}
]]
}