#version 130 /*EXTENSIONS*/ #define FULL 1 #define TEX3D 1 #define BASIC 1 #define SHADED 1 #define LIT 1 #define LITE 1 /* DEFINES */ #ifdef MOBILE //precision highp float; precision mediump float; #endif //MOBILE vec4 HeatMapColor(float value, float minValue, float maxValue) { //used for debugging. If min=0,max=1 then magenta is 0, blue,green,yellow, red is 1 vec4 ret; int HEATMAP_COLORS_COUNT; vec4 colors[6]; HEATMAP_COLORS_COUNT = 6; colors[0] = vec4(0.32, 0.00, 0.32, 1.0); colors[1] = vec4( 0.00, 0.00, 1.00, 1.00); colors[2] = vec4(0.00, 1.00, 0.00, 1.00); colors[3] = vec4(1.00, 1.00, 0.00, 1.00); colors[4] = vec4(1.00, 0.60, 0.00, 1.00); colors[5] = vec4(1.00, 0.00, 0.00, 1.00); float ratio=(float(HEATMAP_COLORS_COUNT)-1.0)*clamp((value-minValue)/(maxValue-minValue),0.0,1.0); int indexMin=int(floor(ratio)); int indexMax= indexMin+1 < HEATMAP_COLORS_COUNT-1 ? indexMin+1 : HEATMAP_COLORS_COUNT-1; ret = mix(colors[indexMin], colors[indexMax], ratio-float(indexMin)); if(value < minValue) ret = vec4(0.0,0.0,0.0,1.0); if(value > maxValue) ret = vec4(1.0,1.0,1.0,1.0); return ret; } vec4 debug_color; float hash( float n ) { return fract(sin(n)*43758.5453); } float noise( vec3 xyz ) { // The noise function returns a value in the range -1.0f -> 1.0f vec3 p = floor(xyz); vec3 f = fract(xyz); f = f*f*(3.0-2.0*f); float n = p.x + p.y*57.0 + 113.0*p.z; return mix(mix(mix( hash(n+0.0), hash(n+1.0),f.x), mix( hash(n+57.0), hash(n+58.0),f.x),f.y), mix(mix( hash(n+113.0), hash(n+114.0),f.x), mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z); } vec3 noise3( in vec3 xyz, in float range ){ vec3 rxyz = vec3(xyz); rxyz.x += noise(xyz)*range; rxyz.y += noise(xyz)*range; rxyz.z += noise(xyz)*range; return rxyz; } varying vec4 castle_vertex_eye; varying vec4 castle_Color; uniform mat4 fw_ModelViewProjInverse; //uniform float fw_FocalLength; uniform vec4 fw_viewport; uniform vec3 fw_dimensions; //uniform vec3 fw_RayOrigin; uniform sampler2D fw_Texture_unit0; uniform sampler2D fw_Texture_unit1; uniform sampler2D fw_Texture_unit2; uniform sampler2D fw_Texture_unit3; #ifdef TEX3D uniform int tex3dTiles[3]; uniform int repeatSTR[3]; uniform int magFilter; #endif //TEX3D #ifdef SEGMENT uniform int fw_nIDs; uniform int fw_enableIDs[10]; uniform int fw_surfaceStyles[2]; uniform int fw_nStyles; vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3); vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, int magfilter); bool inEnabledSegment(in vec3 texcoords, inout int jstyle){ bool inside = true; jstyle = 1; //DEFAULT vec4 segel = texture3Demu0(fw_Texture_unit1,texcoords,0); //convert from GL_FLOAT 0-1 to int 0-255 //Q. is there a way to do int images in GLES2? int ID = int(floor(segel.a * 255.0 + .1)); //debug_color = HeatMapColor(float(ID),0.0,5.0); //debug_color.a = .2; if(ID < fw_nIDs){ //specs: The indices of this array corresponds to the segment identifier. inside = fw_enableIDs[ID] == 0 ? false : true; } if(inside){ int kstyle = fw_nStyles-1; kstyle = ID < fw_nStyles ? ID : kstyle; jstyle = fw_surfaceStyles[kstyle]; jstyle = jstyle == 1 ? 0 : jstyle; } return inside; } #endif //SEGMENT #ifdef ISO uniform float fw_stepSize; uniform float fw_tolerance; uniform float fw_surfaceVals[]; uniform int fw_nVals; uniform int fw_surfaceStyles[]; uniform int fw_nStyles; #endif //ISO struct Ray { vec3 Origin; vec3 Dir; }; struct AABB { vec3 Min; vec3 Max; }; bool IntersectBox(Ray r, AABB aabb, out float t0, out float t1) { vec3 invR = 1.0 / r.Dir; vec3 tbot = invR * (aabb.Min-r.Origin); vec3 ttop = invR * (aabb.Max-r.Origin); vec3 tmin = min(ttop, tbot); vec3 tmax = max(ttop, tbot); vec2 t = max(tmin.xx, tmin.yz); t0 = max(t.x, t.y); t = min(tmax.xx, tmax.yz); t1 = min(t.x, t.y); return t0 <= t1; } void texture3D_0( inout vec4 sample, in vec3 texcoord3 ); void voxel_apply_SHADED_2(inout vec4 voxel, inout vec3 gradient); void voxel_apply_3(inout vec4 voxel, inout vec3 gradient); void add_light_contribution2_4(inout vec3 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float mat_shininess, in float mat_ambient, in vec3 mat_diffuse, in vec3 mat_specular); /* PLUG-DECLARATIONS */ vec3 fw_TexCoord[1]; #ifdef CLIP #define FW_MAXCLIPPLANES 4 uniform int fw_nclipplanes; uniform vec4 fw_clipplanes[FW_MAXCLIPPLANES]; bool clip (in vec3 vertex_object){ bool iclip = false; for ( int i=0; i fw_tolerance ){ voxel.a = 1.0; int jstyle = min(i,fw_nStyles-1); jstyle = fw_surfaceStyles[jstyle]; if(jstyle == 1){ /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ } else if(jstyle == 2) { /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ } else if(jstyle == 3) { /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ } else if(jstyle == 4) { /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ } else if(jstyle == 5) { /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ } else if(jstyle == 6) { /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ } else if(jstyle == 7) { /* PLUG: voxel_apply_EDGE (voxel, gradient) */ } else if(jstyle == 8) { /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ } else if(jstyle == 9) { voxel_apply_SHADED_2(voxel, gradient); /* PLUG: voxel_apply_SHADED (voxel, gradient) */ } else if(jstyle == 10) { /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ } else if(jstyle == 11) { /* PLUG: voxel_apply_TONE (voxel, gradient) */ } } else { voxel = vec4(0.0); //similar to discard } } lastdensity = density; } #else //ISO_MODE3 if(MODE == 1){ float iso = fw_surfaceVals[0]; if( sign( density - iso) != sign( lastdensity - iso) && length(gradient) > fw_tolerance ){ //debug_color = HeatMapColor(iso,0.0,.3); voxel.a = 1.0; voxel_apply_3(voxel, gradient); /* PLUG: voxel_apply (voxel, gradient) */ } else { voxel = vec4(0.0); //similar to discard } lastdensity = density; } else if(MODE == 2){ float iso = fw_surfaceVals[0]; float density_iso = density / fw_stepSize; if( sign( density_iso - iso) != sign( lastdensity_iso - iso) && length(gradient) > fw_tolerance ){ voxel.a = 1.0; voxel_apply_3(voxel, gradient); /* PLUG: voxel_apply (voxel, gradient) */ } else { voxel = vec4(0.0); //similar to discard } lastdensity = density; lastdensity_iso = density_iso; } #endif //ISO_MODE3 #else //ISO #ifdef SEGMENT //debug_color = HeatMapColor(float(jstyle),1.0,12.0); //debug_color.a = .2; if(jstyle == 1){ /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ } else if(jstyle == 2) { /* PLUG: voxel_apply_OPACITY (voxel, gradient) */ } else if(jstyle == 3) { /* PLUG: voxel_apply_BLENDED (voxel, gradient) */ } else if(jstyle == 4) { /* PLUG: voxel_apply_BOUNDARY (voxel, gradient) */ } else if(jstyle == 5) { /* PLUG: voxel_apply_CARTOON (voxel, gradient) */ } else if(jstyle == 6) { /* PLUG: voxel_apply_DEFAULT (voxel, gradient) */ } else if(jstyle == 7) { /* PLUG: voxel_apply_EDGE (voxel, gradient) */ } else if(jstyle == 8) { /* PLUG: voxel_apply_PROJECTION (voxel, gradient) */ } else if(jstyle == 9) { voxel_apply_SHADED_2(voxel, gradient); /* PLUG: voxel_apply_SHADED (voxel, gradient) */ } else if(jstyle == 10) { /* PLUG: voxel_apply_SILHOUETTE (voxel, gradient) */ } else if(jstyle == 11) { /* PLUG: voxel_apply_TONE (voxel, gradient) */ } #else //SEGMENT //non-iso rendering styles //void PLUG_voxel_apply (inout vec4 voxel, inout vec3 gradient) voxel_apply_3(voxel, gradient); /* PLUG: voxel_apply (voxel, gradient) */ #endif //SEGMENT #endif //ISO density = voxel.a; //debug_color = HeatMapColor(densityFactor,0.134,.135); T = (1.0 - raysum.a); raysum.a += density * T; raysum.rgb += voxel.rgb * T * density; if(raysum.a > .99) { break; } #ifdef SEGMENT } //if inEnabledSegment #endif //SEGMENT } //iclip travel -= stepSize; depth += stepSize; if(travel <= 0.0) break; pos += step; } //void PLUG_ray_apply (inout vec4 raysum) /* PLUG: ray_apply (raysum) */ if(true) gl_FragColor = raysum; else gl_FragColor = debug_color; } vec4 texture3Demu0( sampler2D sampler, in vec3 texcoord3, in int magfilter){ vec4 sample = vec4(0.0); #ifdef TEX3D //TILED method (vs Y strip method) vec3 texcoord = texcoord3; //texcoord.z = 1.0 - texcoord.z; //flip z from RHS to LHS float depth = max(1.0,float(tex3dTiles[2])); if(repeatSTR[0] == 0) texcoord.x = clamp(texcoord.x,0.0001,.9999); else texcoord.x = mod(texcoord.x,1.0); if(repeatSTR[1] == 0) texcoord.y = clamp(texcoord.y,0.0001,.9999); else texcoord.y = mod(texcoord.y,1.0); if(repeatSTR[2] == 0) texcoord.z = clamp(texcoord.z,0.0001,.9999); else texcoord.z = mod(texcoord.z,1.0); vec4 texel; int izf = int(floor(texcoord.z*depth)); //floor z int izc = int(ceil(texcoord.z*depth)); //ceiling z izc = izc == tex3dTiles[2] ? izc - 1 : izc; //clamp int z vec4 ftexel, ctexel; int nx = tex3dTiles[0]; //0-11 int ny = tex3dTiles[1]; float fnx = 1.0/float(nx); //.1 float fny = 1.0/float(ny); int ix = izc / ny; //60/11=5 int ixny = ix * ny; //5*11=55 int iy = izc - ixny; //60-55=5 modulus remainder float cix = float(ix); //5 float ciy = float(iy); float xxc = (cix + texcoord.s)*fnx; //(5 + .5)*.1 = .55 float yyc = (ciy + texcoord.t)*fny; ix = izf / ny; ixny = ix * ny; iy = izf - ixny; //modulus remainder float fix = float(ix); float fiy = float(iy); float xxf = (fix + texcoord.s)*fnx; float yyf = (fiy + texcoord.t)*fny; vec2 ftexcoord, ctexcoord; //texcoord is 3D, ftexcoord and ctexcoord are 2D coords ftexcoord.s = xxf; ftexcoord.t = yyf; ctexcoord.s = xxc; ctexcoord.t = yyc; ftexel = texture2D(sampler,ftexcoord.st); ctexel = texture2D(sampler,ctexcoord.st); float fraction = mod(texcoord.z*depth,1.0); if(magfilter == 1) texel = mix(ctexel,ftexel,1.0-fraction); //lerp GL_LINEAR else texel = ftexel; //fraction > .5 ? ctexel : ftexel; //GL_NEAREST sample = texel; #endif //TEX3D return sample; } vec4 texture3Demu( sampler2D sampler, in vec3 texcoord3){ //use uniform magfilter return texture3Demu0( sampler, texcoord3, magFilter); } void texture3D_0( inout vec4 sample, in vec3 texcoord3 ){ sample = texture3Demu(fw_Texture_unit0,texcoord3); } void texture_apply_1 (inout vec4 finalFrag, in int iuse ){ vec4 sample; sample = texture3Demu(fw_Texture_unit0,fw_TexCoord[0]); finalFrag *= sample; } #ifdef LITE #define MAX_LIGHTS 8 uniform int lightcount; //uniform float lightRadius[MAX_LIGHTS]; uniform int lightType[MAX_LIGHTS];//ANGLE like this struct fw_LightSourceParameters { float ambient; vec3 color; float intensity; vec3 location; vec3 halfVector; vec3 direction; float spotBeamWidth; float spotCutoff; vec3 Attenuations; float lightRadius; bool shadows; float shadowIntensity; int depthmap; }; uniform fw_LightSourceParameters fw_LightSource[MAX_LIGHTS] /* gl_MaxLights */ ; #endif //LITE #ifdef FOG struct fogParams { vec4 fogColor; float visibilityRange; float fogScale; int fogType; // 0 None, 1= FOGTYPE_LINEAR, 2 = FOGTYPE_EXPONENTIAL // ifdefed int haveFogCoords; }; uniform fogParams fw_fogparams; #endif //FOG #ifdef LIT #ifdef LITE //per-fragment lighting ie phong struct fw_MaterialParameters { vec3 diffuse; vec3 emissive; vec3 specular; float ambient; float shininess; float occlusion; float transparency; vec3 baseColor; float metallic; float roughness; int type; // multitextures are disaggregated int tindex[10]; int mode[10]; int source[10]; int func[10]; int samplr[10]; //0 texture2D 1 cubeMap int cmap[10]; int nt; //total single textures //iunit [0] normal [1] emissive [2] occlusion [3] diffuse OR base [4] shininess OR metallicRoughness [5] specular [6] ambient int tcount[7]; //num single textures 1= one texture 0=no texture 2+ = multitexture int tstart[7]; // where in packed tindex list to start looping //int cindex[7]; // which geometry multitexcoord channel 0=default }; uniform fw_MaterialParameters fw_FrontMaterial; //#ifdef TWO uniform fw_MaterialParameters fw_BackMaterial; //#endif //TWO vec3 castle_ColorES; #else //LITE //per-vertex lighting - interpolated Emissive-specular varying vec3 castle_ColorES; //emissive shininess term #endif //LITE #endif //LIT uniform int fw_phase; uniform int fw_lighting; uniform int fw_shadows; void voxel_apply_SHADED (inout vec4 voxel, inout vec3 gradient) { float len = length(gradient); vec3 ng = vec3(0.0); if(len > 0.0) ng = normalize(gradient); vec3 color = vec3(1.0); #ifdef LIT vec3 castle_ColorES = fw_FrontMaterial.specular; color.rgb = fw_FrontMaterial.diffuse.rgb; #else //LIT color.rgb = vec3(0,0,0.0,0.0); vec3 castle_ColorES = vec3(0.0,0.0,0.0); #endif //LIT // void add_light_contribution2(inout vec3 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, // in float mat_shininess, in float mat_ambient, in vec3 mat_diffuse, in vec3 mat_specular); vec4 vertex_eye4 = vec4(vertex_eye,1.0); add_light_contribution2_4(color, castle_ColorES, vertex_eye4, ng, fw_FrontMaterial.shininess, fw_FrontMaterial.ambient, fw_FrontMaterial.diffuse, fw_FrontMaterial..specular); /* PLUG: add_light_contribution2 (color, castle_ColorES, vertex_eye4, ng, fw_FrontMaterial.shininess, fw_FrontMaterial.ambient, fw_FrontMaterial.diffuse, fw_FrontMaterial..specular) */ // voxel.rgb = color.rgb; color = mix(color,castle_ColorES,dot(ng,normal_eye)); voxel.rgb = color.rgb; //voxel.rgb = voxel.rgb * color.rgb; } void voxel_apply_SHADED_2 (inout vec4 voxel, inout vec3 gradient) { voxel_apply_SHADED(voxel, gradient); } void voxel_apply_3 (inout vec4 voxel, inout vec3 gradient) { voxel_apply_SHADED(voxel, gradient); } /* use ADSLightModel here the ADS colour is returned from the function. */ void add_light_contribution2_4 (inout vec3 vertexcolor, inout vec3 specularcolor, in vec4 myPosition, in vec3 myNormal, in float mat_shininess, in float mat_ambient, in vec3 mat_diffuse, in vec3 mat_specular){ //working in eye space: eye is at 0,0,0 looking generally in direction 0,0,-1 //myPosition, myNormal - of surface vertex, in eyespace //vertexcolor - diffuse+ambient -will be replaced or modulated by texture color //specularcolor - specular+emissive or non-diffuse (emissive added outside this function) //algo: uses Blinn-Phong specular reflection: half-vector pow(N*H,shininess) // https://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/lighting.html#Lightingequations // fog and emissive are done elsewhere, this function does: // SUM(on[i] x attenuation[i] x spot[i] x ILrgb[i] x (ambient[i] + diffuse[i] + specular[i])) int i; vec3 N = normalize (myNormal); vec3 E = -normalize(myPosition.xyz); // apply the lights to this material // weird but ANGLE needs constant loop vec3 sum_vertex = vec3(0.,0.,0.); vec3 sum_specular = vec3(0.,0.,0.); for (i=0; i light.lightRadius) on = 0.0; attenuation = 1.0/max(1.0,(light.Attenuations.x + (light.Attenuations.y * D) + (light.Attenuations.z *D*D))); } float NdotL = max(dot(N, L), 0.0); //Lambertian diffuse term //specular reflection models, phong or blinn-phong //#define PHONG 1 #ifdef PHONG //Phong vec3 R = normalize(-reflect(L,N)); float RdotE = max(dot(R,E),0.0); float specbase = RdotE; // assume shader gets shininess in 0 to 1 range, and scales it to 0 to 128 range here float specpow = mat_shininess*128.0; #else //PHONG //Blinn-Phong vec3 H = normalize(L + E); //halfvector x3d specs this is L+v/|L+v| float NdotH = max(dot(N,H),0.0); float specbase = NdotH; float specpow = mat_shininess*128.0; #endif //PHONG float powerFactor = 0.0; // for light dropoff if (specbase > 0.0) { powerFactor = pow(specbase,specpow); // tone down the power factor if mat_shininess borders 0 } ambient += light.ambient * mat_diffuse * mat_ambient; specular += light.intensity * mat_specular *powerFactor; diffuse += light.intensity * mat_diffuse * NdotL; if (myLightType==1) { // SpotLight spot = 0.0; float spotDot = dot (-L,light.direction); // check against spotCosCutoff if (spotDot > light.spotCutoff) { if(spotDot > light.spotBeamWidth) { spot = 1.0; } else { spot = (spotDot - light.spotCutoff)/(light.spotBeamWidth - light.spotCutoff); } } } sum_vertex += on * attenuation * spot * light.color * (ambient + diffuse); sum_specular += on * attenuation * spot * light.color * (specular); } vertexcolor = clamp(sum_vertex + vertexcolor, 0.0, 1.0); specularcolor = clamp(sum_specular + specularcolor, 0.0, 1.0); }