#top #library void vshader( //in uniform float4x4 mat_modelproj, in float4 vtx_position: POSITION, in uniform samplerCUBE tex_0: TEXUNIT0, in uniform sampler3D tex_2: TEXUNIT2, in uniform float4x4 trans_apiview_to_apiclip, in uniform float4x4 trans_view_to_apiview, //in uniform float4x4 trans_model_to_view, uniform float4 k_noiseFrequency, uniform float4 k_scale, uniform float4 k_maxHeight, uniform float4 k_viewScale, uniform float4 k_project1, uniform float4 k_project2, uniform float4 k_project3, uniform float4 k_project4, uniform float4 k_toSphere1, uniform float4 k_toSphere2, uniform float4 k_toSphere3, uniform float4 k_toSphere4, uniform float4 k_tileOrigin6000x1, uniform float4 k_tileOrigin6000x2, uniform float4 k_tileOrigin6000x3, uniform float4 k_tileOrigin6000x4, uniform float4 k_camPos, out float4 l_position: POSITION, out float3 l_pos, out float3 l_tile6000pos) { float4x4 toSphere=float4x4(k_toSphere1,k_toSphere2,k_toSphere3,k_toSphere4); float vDist=length(vtx_position.xy); float sa=k_scale.x*vDist; float t=sin(sa); float4 loc=vec4(t*vtx_position.x/vDist,(cos(sa)-1.0),t*vtx_position.y/vDist,1); float3x3 rot=float3x3(toSphere); l_pos=mul(rot,loc.xyz+vec3(0,1,0)); float3 centerLoc=mul(rot,vec3(0,1,0)); //float3 data=heightDetail(vdxyUnpack(texCUBE(tex_0,l_pos).xyz),l_pos,tex_2,k_noiseFrequency,length(k_camPos.xyz-l_pos.xyz)*100); float3 data=vdxyUnpack(texCUBE(tex_0,l_pos).xyz); float height=data.x; height=max(0.0,height)*k_maxHeight.x; float3 hVec=float3(height*loc.x,height*(1+loc.y),height*loc.z); const float minTrueSphereDist=.00001; const float maxFakeSphereDist=.0001; if (saminTrueSphereDist){ float fade=(sa-minTrueSphereDist)/(maxFakeSphereDist-minTrueSphereDist); loc.xyz=locAlt*(1.0-fade)+loc.xyz*fade; hVec=hVecAlt*(1.0-fade)+hVec*fade; }else{ loc.xyz=locAlt; hVec=hVecAlt; } } loc.xyz=loc.xyz+hVec; l_tile6000pos=loc.xyz; float4x4 tile6000mat=float4x4(k_tileOrigin6000x1,k_tileOrigin6000x2,k_tileOrigin6000x3,k_tileOrigin6000x4); l_tile6000pos=mul(tile6000mat,float4(l_tile6000pos,1)); l_pos=l_pos*(1+height); //Appear to move camera up and down along terrain //float3 hcenter=heightDetail(vdxyUnpack(texCUBE(tex_0,centerLoc).xyz),centerLoc,tex_2,k_noiseFrequency,length(k_camPos.xyz-centerLoc.xyz)*100); //hcenter.x=max(0.0,hcenter.x)*k_maxHeight.x; //loc.y=loc.y-hcenter.x; loc.xyz=loc.xyz*k_viewScale.x; //Make my own trans_model_to_view to get around using it, or the mat_modelproj based on it. //This solves the percision shakes issues. float4x4 projectMat=float4x4(k_project1,k_project2,k_project3,k_project4); float4 l=mul(projectMat,loc); l=mul(trans_view_to_apiview,l); l_position=mul(trans_apiview_to_apiclip,l); } void fshader( in uniform samplerCUBE tex_0: TEXUNIT0, in uniform samplerCUBE tex_1: TEXUNIT1, in uniform sampler3D tex_2: TEXUNIT2, in float3 l_pos, in float3 l_tile6000pos, uniform float4 k_exposure, uniform float4 k_noiseFrequency, uniform float4 k_lightDir, uniform float4 k_camPos, out float4 o_color: COLOR) { vec3 norm=normalize(l_pos); float4 climateData=texCUBE(tex_1,norm); float3 camToPos=k_camPos.xyz-l_pos; vec3 lightSource=k_lightDir.xyz; float camToPosDist=length(camToPos); vec3 camLoc=camToPos/camToPosDist; float3 data=texCUBE(tex_0,norm).xyz; data=vdxyUnpack(data); //data=heightDetail(data,norm,tex_2,k_noiseFrequency,camToPosDist); float height=data.x; float4 c; vec3 groundNorm; vec3 iceNorm; float slopeScaler=0; float spec; float4 specColor; float groundM; if (height<0) { iceNorm=norm; groundM=10000; spec=.6; height=-height; c=float4(.1-height*.1,.2-height*.2,1.0-height*.4,1); c=lerp(c,float4(.2,.8,1,1),clamp(pow(1-height,2)*4-3.0,0,1)); specColor=lerp(c,float4(1,1,1,1),.8); //add basic 3D noise! float waterFrequency=6000.0*100; float s=frequencyFade(camToPosDist,waterFrequency); float3 n=float3(0,0,0); if (s>0){ //n=s*vdxySample(l_pos,tex_2,waterFrequency/k_noiseFrequency.x)*.6; n=s*vdxySample(l_tile6000pos,norm,tex_2,waterFrequency/k_noiseFrequency.x)*.6; //s=frequencyFade(camToPosDist,300.0/k_noiseFrequency); //if (s>0){ //n=n+.4*s*vdxySample(l_pos,tex_2,300.0); //} float3 h=n; //Get normal //slopeScaler=length(h.yz); groundNorm=vdxyToNormal(h,norm,.02); }else{ groundNorm=norm; } }else{ groundM=10; spec=.0; slopeScaler=length(data.yz); float beach=clamp(((.01-height)*100*slopeScaler),0,1); float forestScaler=min(8.0,(1-(((1-climateData.z)-3.0+(climateData.y*2.0))*5)))*(data.x*.5+(slopeScaler/10.0+.1)*.5); forestScaler=forestScaler-beach; //forestScaler=forestScaler-(clamp(slopeScaler*8-2,0,1)); float bigNoiseFrequency=6000.0*1000/15;//Trees roughly 15 meters apart float smallNoiseFrequency=bigNoiseFrequency*3.1; //forest=clamp((forestScaler-.7)*10.0,0,1); //add basic 3D noise! float s=frequencyFade(camToPosDist,bigNoiseFrequency); float3 n=float3(0,0,0); float3 smallNoise=float3(0,0,0); float3 bigNoise=float3(0,0,0); if (s>0){ bigNoise=s*vdxySample(l_tile6000pos,norm,tex_2,bigNoiseFrequency/k_noiseFrequency.x); n=bigNoise*.66; s=frequencyFade(camToPosDist,smallNoiseFrequency); if (s>0){ smallNoise=s*vdxySample(l_tile6000pos,norm,tex_2,smallNoiseFrequency/k_noiseFrequency.x); n=n+.34*smallNoise; } } float forest=clamp((forestScaler+n.x/8.0-.7)*10.0,0,1); float forestPhase=pow(n.x/2+.5,2); float fNoise=forestPhase*n; float desert=clamp(((1-climateData.z)-.5+(climateData.y-.9)/1.0)*10,0,1)*(1-(slopeScaler/10.0+.1)); desert=clamp(desert*(1-pow(slopeScaler,4)),0,1); float3 h=data+n*.01*pow(1.0-desert,4)+fNoise*1.5*pow(forest,.5); //Get normal //slopeScaler=length(h.yz); groundNorm=vdxyToNormal(h,norm,0.5); iceNorm=vdxyToNormal(data+n*.005,norm,0.5); float hi2=pow(height,.5); c= lerp(float4(.5,.9,.3,1),float4(.05,.3,.05,1),clamp(climateData.z*2.0-0.2,0.0,1.0)); c= lerp(c,float4(1,.8,.5,1),pow(smallNoise.x/2.0+.5,3)*.2); c= lerp(c,float4(hi2*hi2/2,(hi2/2+.5),hi2/4,1),pow(bigNoise.x/4+smallNoise.x/2,1)*.5); //deserts //desert+=max(0,slopeScaler*2-.5)/2; c=lerp(c,float4(1,1,.5,1),(clamp(desert,0,1))); c=lerp(c,float4(1.0,.9,.9,1),beach); //forests forestScaler=clamp((forestScaler-0.5),0.0,1.0); float4 forestColor=lerp(c,float4(.2,.5,.2,1),forestScaler); float4 forestFloor=lerp(float4(.1,.2,.1,1),float4(.1,.1,0,1),forestScaler); forestColor=lerp(forestFloor,forestColor,forestPhase); c=lerp(c,forestColor,forest); //c=lerp(c,float4(.4,.4,.4,1),slopeScaler*(1-forest)/4); //c=lerp(c,float4(1.0,0,0,0),n.x/2+.5); specColor=lerp(c*1.5,float4(1.5,1.5,1.5,1),.5);//c; c=c*.8; } groundNorm=norm; iceNorm=norm; float pi=3.14159265; float diffuseAmp=1.0; float specAmp=2.0; vec3 hVec=normalize(lightSource + camLoc); float NdotL=dot(lightSource,groundNorm); float NdotH=dot(hVec,groundNorm); float ambient=.01; float difuse=((1.0-spec)-ambient)*diffuseAmp; spec=spec*specAmp; vec4 l=lit( NdotL, NdotH , groundM ); //Have the horizon, assumed to be at height 0 (sealevel) cast a shadow. //basically, is lightSource above sea level horizon //This equation computes the sin of the angle to the horizon from horizantal //tan((pi/2)-asin(1/length(l_pos.xyz))) //it simplifies to //sqrt(-1/(x*x)+1)*x where x=length(l_pos.xyz) float4 sunColor; float x=length(l_pos.xyz); float s=(dot(lightSource,norm)-(-sqrt(-1/(x*x)+1)*x)); if (s>0){ //Not shadowed by horizon sunColor=lerp(float4(1,.8,.6,1),float4(.4,.2,.0,1),1-clamp(s*3,0,1)); }else{ sunColor=float4(.1,.01,.0,1); } float skyLightLum=lit(dot(normalize(norm+lightSource*3.0),norm), NdotH , 0 ).y; skyLightLum=skyLightLum*(difuse+spec)*.2; float4 skyLight=skyLightLum*float4(.2,.2,1,1); float b=l.y*difuse; c=(c*b+specColor*l.z*spec*l.y)*sunColor+c*skyLight+ambient*c; specAmp=1; NdotL=dot(iceNorm,lightSource); NdotH=dot(iceNorm,hVec); l=lit( NdotL , NdotH , 4 ); spec=.6; difuse=1-spec-ambient; spec=spec*specAmp; b=ambient+l.y*difuse+l.z*spec*l.y; float tempC=climateData.y*(24+60)-60; //ice float iceNoise=vdxySample(l_pos,tex_2,1200.0/k_noiseFrequency.x).x*.01+vdxySample(l_pos,tex_2,600.0/k_noiseFrequency.x).x*.02; float iceFactor=min(1,100*clamp(iceNoise+min(1,-((tempC+25)*(climateData.z*.9+.1)+5)/20)*(max(0,climateData.z-.2)),0,1)); //iceFactor=clamp(elevationMeters-500,0,1); float4 iceColor=float4(1,1,1,1); //iceColor=lerp(iceColor,float4(.6,.6,.6,1),pow(slopeScaler,6)); c=lerp(c,iceColor*b*sunColor+skyLight*iceColor+ambient*iceColor,iceFactor); NdotL=dot(norm,lightSource); NdotH=dot(norm,hVec); l=lit( NdotL , NdotH , 1 ); spec=.1; difuse=1-spec-ambient; spec=spec*specAmp; b=ambient+l.y*difuse; //clouds float clouds=climateData.w*clamp((camToPosDist-.1)*5,0.0,1.0); clouds=clamp(clouds*.8,0,.8); c=lerp(c,float4(.9,.9,.9,1)*b+float4(1,1,1,1)*l.z*l.y*spec,clouds); float scatter=clamp(dot(norm,normalize(camToPos)),0.0,1.0); scatter=pow(1-scatter,3)*pow(clamp(camToPosDist,0.0,1.0),1.0); b=(b-ambient)/(1-ambient); c=lerp(c,float4(.8,.9,1,1)*b,scatter); float maxBrightness=2.0; c=float4(1.0)-exp(-k_exposure.x*c); //c=k_exposure.x*c; c=c*maxBrightness; //bloom using brigtness past 1 b=max(max(max(c.x,c.y),c.z),1.0); c=c/b; c.w=(b-1.0)/(maxBrightness-1.0); o_color=c; //o_color=float4(1.0,0,0,1); }