QString ShaderFactory2::genDefaultSliceShaderString(bool lighting, bool emissive, QList<CropObject> crops, int nvol, bool peel, int peelType, float peelMin, float peelMax, float peelMix, int mixvol, bool mixColor, bool mixOpacity, int interpolateVolumes) { bool cropPresent = false; bool tearPresent = false; bool viewPresent = false; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() < CropObject::Tear_Tear) cropPresent = true; else if (crops[i].cropType() < CropObject::View_Tear) tearPresent = true; else viewPresent = true; bool pathCropPresent = PathShaderFactory::cropPresent(); bool pathViewPresent = PathShaderFactory::blendPresent(); float lastSet[4]; for(int i=1; i<=nvol; i++) { float idx = nvol-i+1; lastSet[i-1] = (Global::lutSize()-idx)/Global::lutSize(); } QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "varying vec3 pointpos;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect dataTex;\n"; shader += "uniform sampler1D paintTex;\n"; shader += "uniform float tfSet;\n"; shader += "uniform vec3 delta;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 lightpos;\n"; shader += "uniform float ambient;\n"; shader += "uniform float diffuse;\n"; shader += "uniform float specular;\n"; shader += "uniform float speccoeff;\n"; shader += "uniform int gridx;\n"; shader += "uniform int tsizex;\n"; shader += "uniform int tsizey;\n"; shader += "uniform float depthcue;\n"; shader += "uniform sampler2DRect lightTex;\n"; shader += "uniform int lightgridx;\n"; shader += "uniform int lightgridy;\n"; shader += "uniform int lightgridz;\n"; shader += "uniform int lightnrows;\n"; shader += "uniform int lightncols;\n"; shader += "uniform int lightlod;\n"; shader += "uniform sampler2DRect pruneTex;\n"; shader += "uniform int prunegridx;\n"; shader += "uniform int prunetsizex;\n"; shader += "uniform int prunetsizey;\n"; shader += "uniform float prunelod;\n"; shader += "uniform int zoffset;\n"; shader += "uniform vec2 dataMin;\n"; shader += "uniform vec2 dataSize;\n"; shader += "uniform int tminz;\n"; shader += "uniform int lod;\n"; shader += "uniform vec3 dirFront;\n"; shader += "uniform vec3 dirUp;\n"; shader += "uniform vec3 dirRight;\n"; shader += "uniform float interpVol;\n"; shader += "uniform bool mixTag;\n"; shader += "uniform vec3 brickMin;\n"; shader += "uniform vec3 brickMax;\n"; shader += "uniform int shdlod;\n"; shader += "uniform sampler2DRect shdTex;\n"; shader += "uniform float shdIntensity;\n"; shader += "uniform float opmod;\n"; shader += "uniform bool linearInterpolation;\n"; shader += "uniform float dofscale;\n"; shader += ShaderFactory::genTextureCoordinate(); if (tearPresent) shader += TearShaderFactory::generateTear(crops); if (cropPresent) shader += CropShaderFactory::generateCropping(crops); if (viewPresent) shader += BlendShaderFactory::generateBlend(crops, nvol); if (pathViewPresent) shader += PathShaderFactory::applyPathBlend(nvol); if (pathCropPresent) shader += PathShaderFactory::applyPathCrop(); shader += "void main(void)\n"; shader += "{\n"; shader += " vec3 lightcol = vec3(1.0,1.0,1.0);\n"; shader += " vec3 texCoord = gl_TexCoord[0].xyz;\n"; shader += "if (any(lessThan(texCoord,brickMin)) || "; shader += "any(greaterThan(texCoord, brickMax)))\n"; shader += " discard;\n"; if (crops.count() > 0) { shader += " vec3 otexCoord = texCoord;\n"; shader += " float feather = 1.0;\n"; } else { if (pathCropPresent) shader += " float feather = 1.0;\n"; if (pathViewPresent) shader += " vec3 otexCoord = texCoord;\n"; } if (tearPresent) { shader += "vec4 tcf = dissect(texCoord);\n"; shader += "texCoord = tcf.xyz;\n"; shader += "feather *= tcf.w;\n"; } if (cropPresent) shader += "feather *= crop(texCoord, true);\n"; if (pathCropPresent) shader += "feather *= pathcrop(texCoord, true);\n"; shader += "texCoord.x = 1.0 + float(tsizex-2)*(texCoord.x-dataMin.x)/dataSize.x;\n"; shader += "texCoord.y = 1.0 + float(tsizey-2)*(texCoord.y-dataMin.y)/dataSize.y;\n"; shader += "texCoord.z = 1.0 + (texCoord.z-float(tminz))/float(lod);\n"; shader += genVgx(nvol); //---------------------------------- // shader += "if (shdlod > 0)\n"; // shader += " {\n"; // shader += " vec4 shadow = texture2DRect(shdTex, gl_FragCoord.xy/vec2(shdlod));\n"; // shader += " lightcol = vec3(1.0-smoothstep(0.0, shdIntensity, shadow.a));\n"; // shader += " lightcol = clamp(vec3(0.1), lightcol, vec3(1));\n"; // shader += " }\n"; // shader += "else\n"; shader += " {\n"; shader += " if (lightlod > 0)\n"; shader += " {\n"; // calculate light color shader += " vec2 pvg = texCoord.xy/(prunelod*float(lightlod));\n"; shader += " int lbZslc = int(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; shader += " float lbZslcf = fract(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; shader += " vec2 pvg0 = getTextureCoordinate(lbZslc, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec2 pvg1 = getTextureCoordinate(lbZslc+1, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec3 lc0 = texture2DRect(lightTex, pvg0).xyz;\n"; shader += " vec3 lc1 = texture2DRect(lightTex, pvg1).xyz;\n"; shader += " lightcol = mix(lc0, lc1, lbZslcf);\n"; shader += " lightcol = 1.0-pow((vec3(1,1,1)-lightcol),vec3(lod,lod,lod));\n"; shader += " }\n"; shader += " else\n"; shader += " lightcol = vec3(1.0,1.0,1.0);\n"; shader += " }\n"; shader += "if (shdlod > 0)\n"; shader += " {\n"; shader += " float sa = texture2DRect(shdTex, gl_FragCoord.xy*vec2(dofscale)/vec2(shdlod)).a;\n"; shader += " sa = 1.0-smoothstep(0.0, shdIntensity, sa);\n"; shader += " sa = clamp(0.1, sa, 1.0);\n"; shader += " lightcol *= sa;\n"; shader += " }\n"; //---------------------------------- // //---------------------------------- // shader += " if (lightlod > 0)\n"; // shader += " {\n"; // calculate light color // shader += " vec2 pvg = texCoord.xy/(prunelod*float(lightlod));\n"; // // shader += " int lbZslc = int(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; // shader += " float lbZslcf = fract(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; // // shader += " vec2 pvg0 = getTextureCoordinate(lbZslc, "; // shader += " lightncols, lightgridx, lightgridy, pvg);\n"; // shader += " vec2 pvg1 = getTextureCoordinate(lbZslc+1, "; // shader += " lightncols, lightgridx, lightgridy, pvg);\n"; // // shader += " vec3 lc0 = texture2DRect(lightTex, pvg0).xyz;\n"; // shader += " vec3 lc1 = texture2DRect(lightTex, pvg1).xyz;\n"; // shader += " lightcol = mix(lc0, lc1, lbZslcf);\n"; // // shader += " lightcol = 1.0-pow((vec3(1,1,1)-lightcol),vec3(lod,lod,lod));\n"; // shader += " }\n"; // shader += " else\n"; // shader += " lightcol = vec3(1.0,1.0,1.0);\n"; // //---------------------------------- if (peel || lighting || !Global::use1D()) shader += getNormal(nvol); if (interpolateVolumes == 2 && nvol == 2) { shader += " vg.x = mix(vg.x, vg.y, interpVol);\n"; shader += " grad1 = mix(grad1, grad2, interpVol);\n"; shader += " normal1 = mix(normal1, normal2, interpVol);\n"; shader += " vg.y = vg.x;\n"; shader += " grad2 = grad1;\n"; shader += " normal2 = normal1;\n"; } for(int i=1; i<=nvol; i++) { QString c; if (i == 1) c = "x"; else if (i == 2) c = "y"; else if (i == 3) c = "z"; else if (i == 4) c = "w"; if (Global::use1D()) shader += QString(" vec2 vol%1 = vec2(vg.%2, 0.0);\n").arg(i).arg(c); else shader += QString(" vec2 vol%1 = vec2(vg.%2, grad%1/float(%3));\n"). \ arg(i).arg(c).arg(Global::lutSize()); if (emissive) shader += QString(" vec2 emis%1 = vol%1;\n").arg(i); // interpolate values between the volumes if (interpolateVolumes == 2 && nvol == 2) shader += QString(" vol%1.y += tfSet;\n").arg(i); else shader += QString(" vol%1.y += tfSet+float(%2);\n"). \ arg(i).arg((i-1)*1.0/Global::lutSize()); } for(int i=1; i<=nvol; i++) shader += QString(" vec4 color%1 = texture2D(lutTex, vol%1);\n").arg(i); if (Global::emptySpaceSkip()) { if (PruneHandler::blend()) shader += blendVolume(nvol); else shader += tagVolume(); } if (lighting) shader += addLighting(nvol); //------------------ if (peel) { if (!lighting) { shader += QString(" if (grad1 > 0.0)\n"); shader += QString(" normal1 = normalize(normal1);\n"); shader += " else\n"; shader += QString(" normal1 = vec3(0.0,0.0,0.0);\n"); shader += " normal1 = mix(vec3(0.0,0.0,0.0), normal1, step(0.0, grad1));"; shader += " vec3 voxpos = pointpos;\n"; shader += " vec3 I = voxpos - eyepos;\n"; shader += " I = normalize(I);\n"; } shader += " float IdotN = dot(I, normal1);\n"; if(nvol == 2) { shader += QString(" vec2 one = vec2(1.0, 1.0);\n"); shader += QString(" vec2 vIdotN = vec2(IdotN, IdotN);\n"); shader += QString(" vec2 peelMix = vec2(float(%1), float(%1));\n").arg(peelMix); shader += QString(" vec2 peelMin = vec2(float(%1), float(%1));\n").arg(peelMin); shader += QString(" vec2 peelMinSub = vec2(float(%1), float(%1));\n").arg(peelMin-0.1); shader += QString(" vec2 peelMax = vec2(float(%1), float(%1));\n").arg(peelMax); shader += QString(" vec2 peelMaxPlus = vec2(float(%1), float(%1));\n").arg(peelMax+0.1); } else if(nvol == 3) { shader += QString(" vec3 one = vec3(1.0, 1.0, 1.0);\n"); shader += QString(" vec3 vIdotN = vec3(IdotN, IdotN, IdotN);\n"); shader += QString(" vec3 peelMix = vec3(float(%1), float(%1), float(%1));\n").arg(peelMix); shader += QString(" vec3 peelMin = vec3(float(%1), float(%1), float(%1));\n").arg(peelMin); shader += QString(" vec3 peelMinSub = vec3(float(%1), float(%1), float(%1));\n").arg(peelMin-0.1); shader += QString(" vec3 peelMax = vec3(float(%1), float(%1), float(%1));\n").arg(peelMax); shader += QString(" vec3 peelMaxPlus = vec3(float(%1), float(%1), float(%1));\n").arg(peelMax+0.1); } else if(nvol == 4) { shader += QString(" vec4 one = vec4(1.0, 1.0, 1.0, 1.0);\n"); shader += QString(" vec4 vIdotN = vec4(IdotN, IdotN, IdotN, IdotN);\n"); shader += QString(" vec4 peelMix = vec4(float(%1), float(%1), float(%1), float(%1));\n").arg(peelMix); shader += QString(" vec4 peelMin = vec4(float(%1), float(%1), float(%1), float(%1));\n").arg(peelMin); shader += QString(" vec4 peelMinSub = vec4(float(%1), float(%1), float(%1), float(%1));\n").arg(peelMin-0.1); shader += QString(" vec4 peelMax = vec4(float(%1), float(%1), float(%1), float(%1));\n").arg(peelMax); shader += QString(" vec4 peelMaxPlus = vec4(float(%1), float(%1), float(%1), float(%1));\n").arg(peelMax+0.1); } if (peelType == 0) { if (peelMin < peelMax) shader += QString(" val1 = smoothstep(peelMin, peelMax, vIdotN);\n"); else shader += QString(" val1 = smoothstep(peelMax, peelMin, -vIdotN);\n"); } else if (peelType == 1) { //---- keep inside shader += QString(" val1 = one-smoothstep(peelMinSub, peelMin, vIdotN);\n"); shader += QString(" val1 *= smoothstep(peelMax, peelMaxPlus, vIdotN);\n"); } shader += QString(" vIdotN = mix(val1, one, peelMix);\n").arg(peelMix); for(int i=1; i<=nvol; i++) { QString c; if (i == 1) c = "x"; else if (i == 2) c = "y"; else if (i == 3) c = "z"; else if (i == 4) c = "w"; shader += QString(" color%2.rgba *= vIdotN.").arg(i); shader += c + ";\n"; } } //------------------ if (viewPresent) { if (nvol == 2) shader += "blend(otexCoord, vol1, vol2, grad1, grad2, color1, color2);\n"; if (nvol == 3) shader += "blend(otexCoord, vol1, vol2, vol3, grad1, grad2, grad3, color1, color2, color3);\n"; if (nvol == 4) shader += "blend(otexCoord, vol1, vol2, vol3, vol4, grad1, grad2, grad3, grad4, color1, color2, color3, color4);\n"; } if (pathViewPresent) { if (nvol == 2) shader += "pathblend(otexCoord, vol1, vol2, grad1, grad2, color1, color2);\n"; if (nvol == 3) shader += "pathblend(otexCoord, vol1, vol2, vol3, grad1, grad2, grad3, color1, color2, color3);\n"; if (nvol == 4) shader += "pathblend(otexCoord, vol1, vol2, vol3, vol4, grad1, grad2, grad3, grad4, color1, color2, color3, color4);\n"; } // if (Global::emptySpaceSkip()) // { // if (PruneHandler::blend()) // shader += blendVolume(nvol); // else // shader += tagVolume(); // } if (interpolateVolumes > 0 && nvol == 2) { if (interpolateVolumes == 2) // interpolate values between the volumes shader += " gl_FragColor = color1;\n"; else // interpolate colors between the volumes shader += " gl_FragColor = mix(color1, color2, interpVol);\n"; } else shader += mixColorOpacity(nvol, mixvol, mixColor, mixOpacity); if (Global::emptySpaceSkip()) shader += " gl_FragColor.rgba = mix(vec4(0.0,0.0,0.0,0.0), gl_FragColor.rgba, prunefeather.x);\n"; // -- apply feather if (tearPresent || cropPresent || pathCropPresent) shader += " gl_FragColor.rgba = mix(gl_FragColor.rgba, vec4(0.0,0.0,0.0,0.0), feather);\n"; //--------------------------------- if (Global::emptySpaceSkip()) { shader += "if (delta.x > 1.0)\n"; shader += "{\n"; shader += " float v1 = vol1.x*step(0.001, color1.a);\n"; shader += " float v2 = vol2.x*step(0.001, color2.a);\n"; shader += " float r = v1;\n"; shader += " float a1 = color1.a;\n"; shader += " float a2 = color2.a;\n"; shader += " float a = a1;\n"; shader += " if (delta.x < 2.0) { r = max(0.0,v1-v2); a = max(0.0,a1-a2); }\n"; // A-B shader += " else if (delta.x < 3.0) { r = abs(v1-v2); a = abs(a1-a2); }\n"; // ||A-B|| shader += " else if (delta.x < 4.0) { r = min(1.0,v1+v2); a = min(1.0,a1+a2); }\n"; // A+B shader += " else if (delta.x < 5.0) { r = max(v1,v2); a = max(a1,a2); }\n"; // max(A,B) shader += " else if (delta.x < 6.0) { r = min(v1,v2); a = min(a1,a2); }\n"; // min(A,B) shader += " else if (delta.x < 7.0) { r = min(1.0,v1/v2); a = min(1.0,a1/a2); }\n"; // A/B shader += " else if (delta.x < 8.0) { r = v1*v2; a = a1*a2; }\n"; // A*B shader += " r *= step(0.001,gl_FragColor.a);\n"; shader += " gl_FragColor = vec4(r, a, prunefeather.z, 1.0);\n"; shader += " return;\n"; shader += "}\n"; } else { shader += "if (delta.x > 1.0)\n"; shader += "{\n"; shader += " float v1 = vol1.x*step(0.001, color1.a);\n"; shader += " float v2 = vol2.x*step(0.001, color2.a);\n"; shader += " float r = v1;\n"; shader += " float a1 = color1.a;\n"; shader += " float a2 = color2.a;\n"; shader += " float a = a1;\n"; shader += " if (delta.x < 2.0) { r = max(0.0,v1-v2); a = max(0.0,a1-a2); }\n"; // A-B shader += " else if (delta.x < 3.0) { r = abs(v1-v2); a = abs(a1-a2); }\n"; // ||A-B|| shader += " else if (delta.x < 4.0) { r = min(1.0,v1+v2); a = min(1.0,a1+a2); }\n"; // A+B shader += " else if (delta.x < 5.0) { r = max(v1,v2); a = max(a1,a2); }\n"; // max(A,B) shader += " else if (delta.x < 6.0) { r = min(v1,v2); a = min(a1,a2); }\n"; // min(A,B) shader += " else if (delta.x < 7.0) { r = min(1.0,v1/v2); a = min(1.0,a1/a2); }\n"; // A/B shader += " else if (delta.x < 8.0) { r = v1*v2; a = a1*a2; }\n"; // A*B shader += " r *= step(0.001,gl_FragColor.a);\n"; shader += " gl_FragColor = vec4(r, a, 0.0, 1.0);\n"; shader += " return;\n"; shader += "}\n"; } //--------------------------------- //------------------------------------ shader += "gl_FragColor = 1.0-pow((vec4(1,1,1,1)-gl_FragColor),"; shader += "vec4(lod,lod,lod,lod));\n"; //------------------------------------ shader += " if (gl_FragColor.a < 0.005)\n"; shader += " discard;\n"; shader += "\n"; if (emissive) { for(int i=1; i<=nvol; i++) { shader += QString(" emis%1.y += %2;\n").arg(i).arg(lastSet[i-1]); shader += QString(" gl_FragColor.rgb += step(0.01, color%1.a)*texture2D(lutTex, emis%1).rgb;\n").arg(i); } } // -- depth cueing shader += " gl_FragColor.rgb *= depthcue;\n"; shader += " gl_FragColor *= opmod;\n"; shader += "}\n"; return shader; }
QString ShaderFactory::genDefaultSliceShaderString(bool bit16, bool lighting, bool emissive, QList<CropObject> crops, bool peel, int peelType, float peelMin, float peelMax, float peelMix) { bool cropPresent = false; bool tearPresent = false; bool viewPresent = false; bool glowPresent = false; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() < CropObject::Tear_Tear) cropPresent = true; else if (crops[i].cropType() < CropObject::View_Tear) tearPresent = true; else if (crops[i].cropType() < CropObject::Glow_Ball) viewPresent = true; else glowPresent = true; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() >= CropObject::View_Tear && crops[i].cropType() <= CropObject::View_Block && crops[i].magnify() > 1.0) tearPresent = true; bool pathCropPresent = PathShaderFactory::cropPresent(); bool pathViewPresent = PathShaderFactory::blendPresent(); float lastSet = (Global::lutSize()-1.0)/Global::lutSize(); QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "varying vec3 pointpos;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect dataTex;\n"; shader += "uniform sampler1D paintTex;\n"; shader += "uniform float tfSet;\n"; shader += "uniform vec3 delta;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 lightpos;\n"; shader += "uniform float ambient;\n"; shader += "uniform float diffuse;\n"; shader += "uniform float specular;\n"; shader += "uniform float speccoeff;\n"; shader += "uniform int gridx;\n"; shader += "uniform int tsizex;\n"; shader += "uniform int tsizey;\n"; shader += "uniform float depthcue;\n"; shader += "uniform sampler2DRect lightTex;\n"; shader += "uniform int lightgridx;\n"; shader += "uniform int lightgridy;\n"; shader += "uniform int lightgridz;\n"; shader += "uniform int lightnrows;\n"; shader += "uniform int lightncols;\n"; shader += "uniform int lightlod;\n"; shader += "uniform sampler2DRect pruneTex;\n"; shader += "uniform int prunegridx;\n"; shader += "uniform int prunetsizex;\n"; shader += "uniform int prunetsizey;\n"; shader += "uniform float prunelod;\n"; shader += "uniform int zoffset;\n"; shader += "uniform vec2 dataMin;\n"; shader += "uniform vec2 dataSize;\n"; shader += "uniform int tminz;\n"; shader += "uniform int lod;\n"; shader += "uniform vec3 dirFront;\n"; shader += "uniform vec3 dirUp;\n"; shader += "uniform vec3 dirRight;\n"; shader += "uniform vec3 brickMin;\n"; shader += "uniform vec3 brickMax;\n"; shader += genTextureCoordinate(); if (tearPresent) shader += TearShaderFactory::generateTear(crops); if (cropPresent) shader += CropShaderFactory::generateCropping(crops); if (glowPresent) shader += GlowShaderFactory::generateGlow(crops); if (viewPresent) shader += BlendShaderFactory::generateBlend(crops); if (pathCropPresent) shader += PathShaderFactory::applyPathCrop(); if (pathViewPresent) shader += PathShaderFactory::applyPathBlend(); shader += "void main(void)\n"; shader += "{\n"; shader += " vec3 lightcol = vec3(1.0,1.0,1.0);\n"; shader += " vec3 texCoord = gl_TexCoord[0].xyz;\n"; shader += "if (any(lessThan(texCoord,brickMin)) || any(greaterThan(texCoord, brickMax)))\n"; shader += " discard;\n"; if (crops.count() > 0) { shader += " vec3 otexCoord = texCoord;\n"; shader += " float feather = 1.0;\n"; } else { if (pathCropPresent) shader += " float feather = 1.0;\n"; if (pathViewPresent) shader += " vec3 otexCoord = texCoord;\n"; } if (tearPresent) { shader += "vec4 tcf = dissect(texCoord);\n"; shader += "texCoord = tcf.xyz;\n"; shader += "feather *= tcf.w;\n"; } if (cropPresent) shader += "feather *= crop(texCoord, true);\n"; if (pathCropPresent) shader += "feather *= pathcrop(texCoord, true);\n"; shader += "texCoord.x = 1.0 + float(tsizex-2)*(texCoord.x-dataMin.x)/dataSize.x;\n"; shader += "texCoord.y = 1.0 + float(tsizey-2)*(texCoord.y-dataMin.y)/dataSize.y;\n"; //---------------------------------------------------------- // Manipulate z-coordinate for non linear depth levels // int levels = 4; // float origT[10], newT[10]; // origT[0] = 00.00; newT[0] = 00.0; // origT[1] = 01.20; newT[1] = 11.0; // origT[2] = 04.00; newT[2] = 23.0; // origT[3] = 37.62; newT[3] = 56.0; // origT[4] = 62.00; newT[4] = 62.0; // // for(int o=0; o<levels; o++) // { // if (o > 0) // shader += "else "; // shader += QString("if (texCoord.z >= float(%1) && texCoord.z < float(%2))\n").\ // arg(origT[o]).\ // arg(origT[o+1]); // shader += " {\n"; // // shader += QString(" float tz = (texCoord.z-float(%1))/(float(%2)-float(%1));\n").\ // arg(origT[o]). \ // arg(origT[o+1]); // // shader += QString(" texCoord.z = float(%1) + tz * (float(%2)-float(%1));\n").\ // arg(newT[o]).\ // arg(newT[o+1]); // shader += " }\n"; // } //---------------------------------------------------------- shader += "texCoord.z = 1.0 + (texCoord.z-float(tminz))/float(lod);\n"; shader += genVgx(); //---------------------------------- shader += " if (lightlod > 0)\n"; shader += " {\n"; // calculate light color shader += " vec3 lc;\n"; shader += " vec2 pvg = texCoord.xy / prunelod;\n"; shader += " pvg /= vec2(lightlod,lightlod);\n"; shader += " vec2 pvg0 = getTextureCoordinate(int(float(zoffset+slice)/prunelod)/lightlod, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec2 pvg1 = getTextureCoordinate(int(float(zoffset+slice+1)/prunelod)/lightlod, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec3 lc0 = texture2DRect(lightTex, pvg0).xyz;\n"; shader += " vec3 lc1 = texture2DRect(lightTex, pvg1).xyz;\n"; shader += " lightcol = mix(lc0, lc1, slicef);\n"; shader += " lightcol = 1.0-pow((vec3(1,1,1)-lightcol),vec3(lod,lod,lod));\n"; shader += " }\n"; shader += " else\n"; shader += " lightcol = vec3(1.0,1.0,1.0);\n"; //---------------------------------- if (peel || lighting || !Global::use1D()) shader += getNormal(); if (bit16) { shader += "int h0 = int(65535.0*vg.x);\n"; shader += "int h1 = h0 / 256;\n"; shader += "h0 = int(mod(float(h0),256.0));\n"; shader += "float fh0 = float(h0)/256.0;\n"; shader += "float fh1 = float(h1)/256.0;\n"; shader += QString("vg.xy = vec2(fh0, fh1*%1);\n").arg(1.0/Global::lutSize()); } else { if (Global::use1D()) shader += " vg.y = 0.0;\n"; else shader += QString(" vg.y = grad*%1;\n").arg(1.0/Global::lutSize()); } shader += " vg1 = vg;\n"; shader += " vg.y += tfSet;\n"; shader += " gl_FragColor = texture2D(lutTex, vg.xy);\n"; if (Global::emptySpaceSkip()) { shader += " gl_FragColor.rgba = mix(vec4(0.0,0.0,0.0,0.0), gl_FragColor.rgba, prunefeather.x);\n"; if (PruneHandler::blend()) shader += blendVolume(); else shader += tagVolume(); } if (tearPresent || cropPresent || pathCropPresent) shader += " gl_FragColor.rgba = mix(gl_FragColor.rgba, vec4(0.0,0.0,0.0,0.0), feather);\n"; if (viewPresent) shader += " blend(otexCoord, vg, gl_FragColor);\n"; if (pathViewPresent) shader += "pathblend(otexCoord, vg, gl_FragColor);\n"; //--------------------------------- if (Global::emptySpaceSkip()) { shader += "if (delta.x > 1.0)\n"; shader += " { gl_FragColor = vec4(vg.x*step(0.001,gl_FragColor.a),"; shader += "gl_FragColor.a, prunefeather.z, 1.0); return; }\n"; } else { shader += "if (delta.x > 1.0)\n"; shader += " { gl_FragColor = vec4(vg.x*step(0.001,gl_FragColor.a),"; shader += "gl_FragColor.a, 0.0, 1.0); return; }\n"; } //--------------------------------- //------------------------------------ shader += "gl_FragColor = 1.0-pow((vec4(1,1,1,1)-gl_FragColor),"; shader += "vec4(lod,lod,lod,lod));\n"; //------------------------------------ shader += "\n"; shader += " if (gl_FragColor.a < 0.005)\n"; shader += " discard;\n"; if (lighting) shader += addLighting(); shader += genPeelShader(peel, peelType, peelMin, peelMax, peelMix, lighting); if (emissive) { shader += QString(" vg1.y += float(%1);\n").arg(lastSet); shader += " gl_FragColor.rgb += texture2D(lutTex, vg1.xy).rgb;\n"; } // -- depth cueing shader += " gl_FragColor.rgb *= depthcue;\n"; if (glowPresent) shader += " gl_FragColor.rgb += glow(otexCoord);\n"; shader += " gl_FragColor = clamp(gl_FragColor, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n"; shader += "}\n"; return shader; }
QString ShaderFactory::genDefaultSliceShaderString(bool bit16, bool lighting, bool emissive, QList<CropObject> crops, bool peel, int peelType, float peelMin, float peelMax, float peelMix) { bool cropPresent = false; bool tearPresent = false; bool viewPresent = false; bool glowPresent = false; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() < CropObject::Tear_Tear) cropPresent = true; else if (crops[i].cropType() < CropObject::View_Tear) tearPresent = true; else if (crops[i].cropType() < CropObject::Glow_Ball) viewPresent = true; else glowPresent = true; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() >= CropObject::View_Tear && crops[i].cropType() <= CropObject::View_Block && crops[i].magnify() > 1.0) tearPresent = true; bool pathCropPresent = PathShaderFactory::cropPresent(); bool pathViewPresent = PathShaderFactory::blendPresent(); float lastSet = (Global::lutSize()-1.0)/Global::lutSize(); QString shader; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "varying vec3 pointpos;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect dataTex;\n"; shader += "uniform sampler1D paintTex;\n"; shader += "uniform float tfSet;\n"; shader += "uniform vec3 delta;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform vec3 lightpos;\n"; shader += "uniform float ambient;\n"; shader += "uniform float diffuse;\n"; shader += "uniform float specular;\n"; shader += "uniform float speccoeff;\n"; shader += "uniform int gridx;\n"; shader += "uniform int tsizex;\n"; shader += "uniform int tsizey;\n"; shader += "uniform float depthcue;\n"; shader += "uniform sampler2DRect lightTex;\n"; shader += "uniform int lightgridx;\n"; shader += "uniform int lightgridy;\n"; shader += "uniform int lightgridz;\n"; shader += "uniform int lightnrows;\n"; shader += "uniform int lightncols;\n"; shader += "uniform int lightlod;\n"; shader += "uniform sampler2DRect pruneTex;\n"; shader += "uniform int prunegridx;\n"; shader += "uniform int prunetsizex;\n"; shader += "uniform int prunetsizey;\n"; shader += "uniform float prunelod;\n"; shader += "uniform int zoffset;\n"; shader += "uniform vec2 dataMin;\n"; shader += "uniform vec2 dataSize;\n"; shader += "uniform int tminz;\n"; shader += "uniform int lod;\n"; shader += "uniform vec3 dirFront;\n"; shader += "uniform vec3 dirUp;\n"; shader += "uniform vec3 dirRight;\n"; shader += "uniform bool mixTag;\n"; shader += "uniform vec3 brickMin;\n"; shader += "uniform vec3 brickMax;\n"; shader += "uniform int shdlod;\n"; shader += "uniform sampler2DRect shdTex;\n"; shader += "uniform float shdIntensity;\n"; shader += "uniform float opmod;\n"; shader += "uniform bool linearInterpolation;\n"; shader += "uniform float dofscale;\n"; shader += genTextureCoordinate(); if (tearPresent) shader += TearShaderFactory::generateTear(crops); if (cropPresent) shader += CropShaderFactory::generateCropping(crops); if (glowPresent) shader += GlowShaderFactory::generateGlow(crops); if (viewPresent) shader += BlendShaderFactory::generateBlend(crops); if (pathCropPresent) shader += PathShaderFactory::applyPathCrop(); if (pathViewPresent) shader += PathShaderFactory::applyPathBlend(); shader += "void main(void)\n"; shader += "{\n"; shader += " vec3 lightcol = vec3(1.0,1.0,1.0);\n"; shader += " vec3 texCoord = gl_TexCoord[0].xyz;\n"; shader += "if (any(lessThan(texCoord,brickMin)) || "; shader += "any(greaterThan(texCoord, brickMax)))\n"; //shader += " if (any(lessThan(texCoord,brickMin-vec3(0.5,0.5,0.5))) || "; //shader += " any(greaterThan(texCoord, brickMax+vec3(0.5,0.5,0.5))))\n"; //shader += " if (any(lessThan(texCoord,brickMin-vec3(1,1,1))) || "; //shader += " any(greaterThan(texCoord, brickMax+vec3(1,1,1))))\n"; shader += " discard;\n"; if (crops.count() > 0) { shader += " vec3 otexCoord = texCoord;\n"; shader += " float feather = 1.0;\n"; } else { if (pathCropPresent) shader += " float feather = 1.0;\n"; if (pathViewPresent) shader += " vec3 otexCoord = texCoord;\n"; } if (tearPresent) { shader += "vec4 tcf = dissect(texCoord);\n"; shader += "texCoord = tcf.xyz;\n"; shader += "feather *= tcf.w;\n"; } if (cropPresent) shader += "feather *= crop(texCoord, true);\n"; if (pathCropPresent) shader += "feather *= pathcrop(texCoord, true);\n"; shader += "texCoord.x = 1.0 + float(tsizex-2)*(texCoord.x-dataMin.x)/dataSize.x;\n"; shader += "texCoord.y = 1.0 + float(tsizey-2)*(texCoord.y-dataMin.y)/dataSize.y;\n"; shader += "texCoord.z = 1.0 + (texCoord.z-float(tminz))/float(lod);\n"; shader += genVgx(); shader += "float value = vg.x;\n"; //---------------------------------- // this is specifically for nearest neighbour interpolating when upscaling // or volume and surface area calculations shader += " if (depthcue > 1.0) vg.x = val0;\n"; //---------------------------------- //---------------------------------- //------------------------------------ shader += "if (lightlod > 0)\n"; shader += " {\n"; // calculate light color shader += " vec2 pvg = texCoord.xy/(prunelod*float(lightlod));\n"; shader += " int lbZslc = int(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; shader += " float lbZslcf = fract(float(zoffset+slice)/(prunelod*float(lightlod)));\n"; shader += " vec2 pvg0 = getTextureCoordinate(lbZslc, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec2 pvg1 = getTextureCoordinate(lbZslc+1, "; shader += " lightncols, lightgridx, lightgridy, pvg);\n"; shader += " vec3 lc0 = texture2DRect(lightTex, pvg0).xyz;\n"; shader += " vec3 lc1 = texture2DRect(lightTex, pvg1).xyz;\n"; shader += " lightcol = mix(lc0, lc1, lbZslcf);\n"; shader += " lightcol = 1.0-pow((vec3(1,1,1)-lightcol),vec3(lod,lod,lod));\n"; shader += " }\n"; shader += "else\n"; shader += " lightcol = vec3(1.0,1.0,1.0);\n"; shader += "if (shdlod > 0)\n"; shader += " {\n"; shader += " float sa = texture2DRect(shdTex, gl_FragCoord.xy*vec2(dofscale)/vec2(shdlod)).a;\n"; shader += " sa = 1.0-smoothstep(0.0, shdIntensity, sa);\n"; shader += " sa = clamp(0.1, sa, 1.0);\n"; shader += " lightcol *= sa;\n"; shader += " }\n"; //---------------------------------- if (peel || lighting || !Global::use1D()) shader += getNormal(); if (bit16) { shader += " int h0 = int(65535.0*vg.x);\n"; shader += " int h1 = h0 / 256;\n"; shader += " h0 = int(mod(float(h0),256.0));\n"; shader += " float fh0 = float(h0)/256.0;\n"; shader += " float fh1 = float(h1)/256.0;\n"; shader += QString(" vg.xy = vec2(fh0, fh1*%1);\n").arg(1.0/Global::lutSize()); } else { if (Global::use1D()) shader += " vg.y = 0.0;\n"; else shader += QString(" vg.y = grad*%1;\n").arg(1.0/Global::lutSize()); } shader += " vg1 = vg;\n"; shader += " vg.y += tfSet;\n"; shader += " gl_FragColor = texture2D(lutTex, vg.xy);\n"; if (Global::emptySpaceSkip()) { shader += " gl_FragColor.rgba = mix(vec4(0.0,0.0,0.0,0.0), gl_FragColor.rgba, prunefeather.x);\n"; if (PruneHandler::blend()) shader += blendVolume(); else shader += tagVolume(); } if (tearPresent || cropPresent || pathCropPresent) shader += " gl_FragColor.rgba = mix(gl_FragColor.rgba, vec4(0.0,0.0,0.0,0.0), feather);\n"; if (viewPresent) shader += " blend(false, otexCoord, vg, gl_FragColor);\n"; if (pathViewPresent) shader += "pathblend(otexCoord, vg, gl_FragColor);\n"; //--------------------------------- if (Global::emptySpaceSkip()) { shader += "if (delta.x > 1.0)\n"; shader += " { gl_FragColor = vec4(value*step(0.001,gl_FragColor.a),"; shader += "gl_FragColor.a, prunefeather.z, 1.0); return; }\n"; } else { shader += "if (delta.x > 1.0)\n"; shader += " { gl_FragColor = vec4(value*step(0.001,gl_FragColor.a),"; shader += "gl_FragColor.a, 0.0, 1.0); return; }\n"; } //--------------------------------- //------------------------------------ shader += "gl_FragColor = 1.0-pow((vec4(1,1,1,1)-gl_FragColor),"; shader += "vec4(lod,lod,lod,lod));\n"; //------------------------------------ shader += "\n"; shader += " if (gl_FragColor.a < 0.005)\n"; shader += " discard;\n"; if (lighting) shader += addLighting(); shader += genPeelShader(peel, peelType, peelMin, peelMax, peelMix, lighting); if (emissive) { shader += QString(" vg1.y += float(%1);\n").arg(lastSet); shader += " gl_FragColor.rgb += texture2D(lutTex, vg1.xy).rgb;\n"; } // -- depth cueing shader += " gl_FragColor.rgb *= min(1.0,depthcue);\n"; shader += " gl_FragColor *= opmod;\n"; if (glowPresent) shader += " gl_FragColor.rgb += glow(otexCoord);\n"; shader += " gl_FragColor = clamp(gl_FragColor, vec4(0.0,0.0,0.0,0.0), vec4(1.0,1.0,1.0,1.0));\n"; shader += "}\n"; return shader; }
QString ShaderFactory::genSliceShadowShaderString(bool bit16, float shadowintensity, float r, float g, float b, QList<CropObject> crops, bool peel, int peelType, float peelMin, float peelMax, float peelMix) { bool cropPresent = false; bool tearPresent = false; bool viewPresent = false; bool glowPresent = false; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() < CropObject::Tear_Tear) cropPresent = true; else if (crops[i].cropType() < CropObject::View_Tear) tearPresent = true; else if (crops[i].cropType() < CropObject::Glow_Ball) viewPresent = true; else glowPresent = true; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() >= CropObject::View_Tear && crops[i].cropType() <= CropObject::View_Block && crops[i].magnify() > 1.0) tearPresent = true; bool pathCropPresent = PathShaderFactory::cropPresent(); bool pathViewPresent = PathShaderFactory::blendPresent(); QString shader; float maxrgb = qMax(r, qMax(g, b)); if (maxrgb > 1) maxrgb = 1.0/maxrgb; else maxrgb = 1.0; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "varying vec3 pointpos;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect dataTex;\n"; shader += "uniform sampler1D paintTex;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform float tfSet;\n"; shader += "uniform int gridx;\n"; shader += "uniform int tsizex;\n"; shader += "uniform int tsizey;\n"; shader += "\n"; shader += "uniform sampler2DRect pruneTex;\n"; shader += "uniform int prunegridx;\n"; shader += "uniform int prunetsizex;\n"; shader += "uniform int prunetsizey;\n"; shader += "uniform float prunelod;\n"; shader += "uniform int zoffset;\n"; shader += "uniform vec2 dataMin;\n"; shader += "uniform vec2 dataSize;\n"; shader += "uniform int tminz;\n"; shader += "uniform int lod;\n"; shader += "uniform vec3 dirFront;\n"; shader += "uniform vec3 dirUp;\n"; shader += "uniform vec3 dirRight;\n"; shader += "uniform vec3 brickMin;\n"; shader += "uniform vec3 brickMax;\n"; shader += genTextureCoordinate(); if (tearPresent) shader += TearShaderFactory::generateTear(crops); if (cropPresent) shader += CropShaderFactory::generateCropping(crops); if (glowPresent) shader += GlowShaderFactory::generateGlow(crops); if (viewPresent) shader += BlendShaderFactory::generateBlend(crops); if (pathCropPresent) shader += PathShaderFactory::applyPathCrop(); if (pathViewPresent) shader += PathShaderFactory::applyPathBlend(); shader += "void main(void)\n"; shader += "{\n"; shader += " vec3 texCoord = gl_TexCoord[0].xyz;\n"; shader += "if (any(lessThan(texCoord,brickMin)) || any(greaterThan(texCoord, brickMax)))\n"; shader += " discard;\n"; if (crops.count() > 0) { shader += " vec3 otexCoord = texCoord;\n"; shader += " float feather = 1.0;\n"; } else { if (pathCropPresent) shader += " float feather = 1.0;\n"; if (pathViewPresent) shader += " vec3 otexCoord = texCoord;\n"; } if (glowPresent) { shader += " vec3 glowColor = glow(otexCoord);\n"; shader += " float glowMix = max(glowColor.r, max(glowColor.g, glowColor.b));\n"; shader += " if (glowMix > 0.05) discard;"; } if (tearPresent) { shader += "vec4 tcf = dissect(texCoord);\n"; shader += "texCoord = tcf.xyz;\n"; shader += "feather *= tcf.w;\n"; } if (cropPresent) shader += "feather *= crop(texCoord, true);\n"; if (pathCropPresent) shader += "feather *= pathcrop(texCoord, true);\n"; shader += "texCoord.x = 1.0 + float(tsizex-2)*(texCoord.x-dataMin.x)/dataSize.x;\n"; shader += "texCoord.y = 1.0 + float(tsizey-2)*(texCoord.y-dataMin.y)/dataSize.y;\n"; shader += "texCoord.z = 1.0 + (float(texCoord.z)-float(tminz))/float(lod);\n"; shader += genVgx(); shader += getNormal(); if (bit16) { shader += "int h0 = int(65535.0*vg.x);\n"; shader += "int h1 = h0 / 256;\n"; shader += "h0 = int(mod(float(h0),256.0));\n"; shader += "float fh0 = float(h0)/256.0;\n"; shader += "float fh1 = float(h1)/256.0;\n"; shader += QString("vg.xy = vec2(fh0, fh1*%1 + tfSet);\n").arg(1.0/Global::lutSize()); } else { if (Global::use1D()) shader += " vg.y = tfSet;\n"; else { shader += QString(" vg.y = grad*%1;\n").arg(1.0/Global::lutSize()); shader += " vg.y += tfSet;\n"; } } shader += " gl_FragColor = texture2D(lutTex, vg.xy);\n"; shader += genPeelShader(peel, peelType, peelMin, peelMax, peelMix, false); if (Global::emptySpaceSkip()) { shader += " gl_FragColor.rgba = mix(vec4(0.0,0.0,0.0,0.0), gl_FragColor.rgba, prunefeather.x);\n"; if (PruneHandler::blend()) shader += blendVolume(); else shader += tagVolume(); } if (tearPresent || cropPresent || pathCropPresent) shader += " gl_FragColor.rgba = mix(gl_FragColor.rgba, vec4(0.0,0.0,0.0,0.0), feather);\n"; if (viewPresent) shader += "blend(otexCoord, vg, gl_FragColor);\n"; if (pathViewPresent) shader += "pathblend(otexCoord, vg, gl_FragColor);\n"; //------------------------------------ shader += "gl_FragColor = 1.0-pow((vec4(1,1,1,1)-gl_FragColor),"; shader += "vec4(lod,lod,lod,lod));\n"; //------------------------------------ // --- modulate shadow by homogenity shader += QString(" gl_FragColor.rgba *= 1.0-smoothstep(0.0, float(%1), grad);\n").arg(shadowintensity); shader += " if (gl_FragColor.a < 0.01)\n"; shader += " discard;\n"; shader += "\n"; shader += QString(" gl_FragColor.rgba *= vec4(%1, %2, %3, %4);\n").\ arg(r).arg(g).arg(b).arg(maxrgb); // shader += " gl_FragColor.r = clamp(gl_FragColor.r, 0.0, 1.0);\n"; // shader += " gl_FragColor.g = clamp(gl_FragColor.g, 0.0, 1.0);\n"; // shader += " gl_FragColor.b = clamp(gl_FragColor.b, 0.0, 1.0);\n"; // shader += " gl_FragColor.a = clamp(gl_FragColor.a, 0.0, 1.0);\n"; shader += "}\n"; return shader; }