*/}}
Browse Source

Use halftone for 3d canvas

YimingWu 1 năm trước cách đây
mục cha
commit
87c39c0ff1

+ 3 - 0
la_interface.h

@@ -516,6 +516,9 @@ STRUCTURE(LA){
 
     //color
     real ColorPickerGamma;
+    real ViewportHalftoneFactor;
+    real ViewportHalftoneSize;
+
     int NextWireColor, WireColorSlices;
     real WireThickness;
     real WireSaggyness;

+ 3 - 0
la_kernel.c

@@ -1003,6 +1003,9 @@ int laGetReadyWith(laInitArguments* ia){
     MAIN.ColorPickerGamma=1.5;
     MAIN.EnableColorManagement=MAIN.InitArgs.UseColorManagement;
 
+    MAIN.ViewportHalftoneFactor=0.5;
+    MAIN.ViewportHalftoneSize=3.7;
+
     tnsInitRenderKernel(64);
     tnsInitBuiltinShaders();
 

+ 8 - 0
la_tns.h

@@ -106,6 +106,7 @@ struct _tnsShader{
     int iInputColorSpace, iOutputColorSpace, iShowStripes;
     int iComposing, iComposingGamma, iComposingBlackpoint;
     int iDoOffset;
+    int iUseHalftone,iHalftoneSize;
 
     int uViewDir,uViewPos,uFOV,uNear,uFar;
 };
@@ -123,6 +124,7 @@ STRUCTURE(tnsCommand){
     GLenum PolyMode; //0-solid 1-wire
     GLenum Shade;    //0-falt 1-smooth
     GLfloat UniformColor[4];
+    real UseHalftone;
 
     int NumVert;
     int NumIndex;
@@ -241,6 +243,9 @@ struct _tnsMain {
     int StateMultiplyColor;
     int StateUseNormal;
     int SetUseNormal;
+    real StateUseHalftone;
+    real SetUseHalftone;
+    real SetHalftoneSize;
     
     tnsShader* StateShader;
 
@@ -1197,6 +1202,7 @@ int tnsLoadSystemFont(char* from, char* name);
 int tnsGetTextureMemoryComponetCount(tnsTexture *t);
 
 void tnsUseNormal(int Use);
+void tnsUseHalftone(real Use);
 
 void tnsUniformUseOffset(tnsShader* s, int use);
 
@@ -1218,6 +1224,8 @@ void tnsActiveTexture(GLenum tex);
 void tnsBindTexture(tnsTexture *t);
 void tnsUnbindTexture();
 void tnsUniformUseNormal(tnsShader* s, int Use);
+void tnsUniformUseHalftone(tnsShader* s, real Use);
+void tnsUniformHalftoneSize(tnsShader* s, real Use);
 void tnsUniformUseTexture(tnsShader* s, int mode, int sample);
 void tnsUniformColorMode(tnsShader *s, int mode);
 void tnsUniformHCYGamma(tnsShader* s, float Gamma);

+ 39 - 19
la_tns_kernel.c

@@ -269,6 +269,8 @@ void tnsShaderMakeIndex(tnsShader *tns){
     if(tns->iTexColor>=0){glUniform1i(tns->iTexColor, 0);}
     if(tns->iTexColorMS>=0){glUniform1i(tns->iTexColorMS, 1);}
     tns->iDoOffset = glGetUniformLocation(program, "DoOffset");
+    tns->iUseHalftone = glGetUniformLocation(program, "UseHalftone");
+    tns->iHalftoneSize = glGetUniformLocation(program, "HalftoneSize");
 
     tns->uViewDir = glGetUniformLocation(program, "uViewDir");
     tns->uViewPos = glGetUniformLocation(program, "uViewPos");
@@ -1574,7 +1576,7 @@ int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUni
     if(cs->iNormal>=0){
         if(batch->HasNormal){
             glBindBuffer(GL_ARRAY_BUFFER, batch->NBO); glEnableVertexAttribArray(cs->iNormal);
-            glVertexAttribPointer(cs->iNormal, batch->NormalDimension, GL_FLOAT, 0, 0, 0); tnsUniformUseNormal(cs,T->SetUseNormal);
+            glVertexAttribPointer(cs->iNormal, batch->NormalDimension, GL_FLOAT, 0, 0, 0); tnsUniformUseNormal(cs,T->StateUseNormal);
         }else{ glDisableVertexAttribArray(cs->iNormal); glVertexAttrib3f(cs->iNormal,0,0,1); tnsUniformUseNormal(cs,0); }
     }
     if(cs->iColor>=0){
@@ -1709,24 +1711,32 @@ void tnsConfigure3DTexture(tnsTexture *t){
 
 void tnsReconfigureTextureParameters(int Multisample){
     laListHandle* l = tKnlGetTextureList();
-    for(tnsOffscreen* o=T->Offscreens.pFirst;o;o=o->Item.pNext){
-        tnsTexture* t=o->pColor[0];
-        if(t){
+    for(tnsOffscreen* o=T->Offscreens.pFirst;o;o=o->Item.pNext){ tnsTexture* t;
+        for(int i=0;i<4;i++){
+            t=o->pColor[i];
+            if(t){
+                t->Multisample = Multisample;
+                int recreate=0;
+                if(t->Multisample){ if(t->GLTexType==GL_TEXTURE_2D){t->GLTexType=GL_TEXTURE_2D_MULTISAMPLE; recreate=1;}}
+                else { if(t->GLTexType==GL_TEXTURE_2D_MULTISAMPLE){t->GLTexType=GL_TEXTURE_2D; recreate=1;}}
+                if(recreate){
+                    glDeleteTextures(1, &t->GLTexHandle);
+                    glGenTextures(1, &t->GLTexHandle);
+                }
+                T->TexColor=0;
+                tnsConfigure2DTexture(t);
+                tnsAttach2DOffscreenBuffer(o, GL_COLOR_ATTACHMENT0+i, t);
+            }
+        }
+        t=o->pDepth;
+        if(t){ int recreate=0; 
+            if((!t->Multisample && Multisample)||(t->Multisample && !Multisample)){ recreate=1; }
+            if(Multisample){ t->GLTexType=GL_TEXTURE_2D_MULTISAMPLE; }else{ t->GLTexType=GL_TEXTURE_2D; }
             t->Multisample = Multisample;
-            int recreate=0;
-            if(t->Multisample){ if(t->GLTexType==GL_TEXTURE_2D){t->GLTexType=GL_TEXTURE_2D_MULTISAMPLE; recreate=1;}}
-            else { if(t->GLTexType==GL_TEXTURE_2D_MULTISAMPLE){t->GLTexType=GL_TEXTURE_2D; recreate=1;}}
             if(recreate){
                 glDeleteTextures(1, &t->GLTexHandle);
                 glGenTextures(1, &t->GLTexHandle);
-            }
-            T->TexColor=0;
-            tnsConfigure2DTexture(t);
-            tnsAttach2DOffscreenBuffer(o, GL_COLOR_ATTACHMENT0, t);
-        }
-        t=o->pDepth;
-        if(t){
-            t->Multisample = Multisample; T->TexColor=0;
+            } T->TexColor=0;
             tnsConfigure2DTexture(t);
             tnsAttach2DOffscreenBuffer(o, GL_DEPTH_ATTACHMENT, t);
         }
@@ -1776,9 +1786,16 @@ void tnsUseMultiplyColor(int enable){
 }
 
 void tnsUniformUseNormal(tnsShader* s, int Use){
-    if(T->StateUseNormal!=Use){ T->StateUseNormal=Use; glUniform1i(s->iUseNormal,Use); }
+    if(T->SetUseNormal!=Use){ T->SetUseNormal=Use; glUniform1i(s->iUseNormal,Use); }
+}
+void tnsUseNormal(int Use){ T->StateUseNormal=Use; }
+void tnsUniformUseHalftone(tnsShader* s, real Use){
+    if(T->SetUseHalftone!=Use){ T->SetUseHalftone=Use; glUniform1f(s->iUseHalftone,Use); }
+}
+void tnsUniformHalftoneSize(tnsShader* s, real Use){
+    if(T->SetHalftoneSize!=Use){ T->SetHalftoneSize=Use; glUniform1f(s->iHalftoneSize,Use); }
 }
-void tnsUseNormal(int Use){ T->SetUseNormal=Use; }
+void tnsUseHalftone(real Factor){ T->StateUseHalftone=Factor; }
 
 void tnsActiveTexture(GLenum tex){
     if (T->GlTextureSets != tex) glActiveTexture(tex);
@@ -2220,6 +2237,7 @@ void tnsPackAs(GLenum Mode){
     c->MultiplyColor = T->StateMultiplyColor;
     c->LineWidth=T->StateLineWidth;
     c->PointSize=T->StatePointSize;
+    c->UseHalftone = T->StateUseHalftone;
 
     memset(nc, 0, sizeof(tnsCommand));
     nc->VertBegin = nc->VertEnd = c->VertEnd;
@@ -2315,8 +2333,10 @@ void tnsFlush(){
             tnsUniformUseTexture(cs, 0, 0); //tnsUnbindTexture(); 
         }
 
-        if(cs->iMultiplyColor != -1){
-            tnsUniformUseMultiplyColor(cs, c->MultiplyColor);
+        if(cs->iMultiplyColor != -1){ tnsUniformUseMultiplyColor(cs, c->MultiplyColor); }
+        if(cs->iUseHalftone != -1){
+            tnsUniformUseHalftone(cs, c->UseHalftone);
+            tnsUniformHalftoneSize(cs, MAIN.ViewportHalftoneSize);
         }
 
         if (c->UseIndex){

+ 1 - 1
la_tns_mesh.c

@@ -262,7 +262,7 @@ void tnsInvalidateMeshBatch(tnsMeshObject* mo){
 void tnsRegenerateMeshBatch(tnsMeshObject* mo){
     if(!mo) return;
     if(mo->Batch) tnsDeleteBatch(mo->Batch); mo->Batch=0;
-    real meshcolor[4]={0.8,0.8,0.8,0.5};
+    real meshcolor[4]={0.8,0.8,0.8,1.0};
 
     int tottri; int* elem = tnsGetTriangulatedBatch(mo, &tottri,-1);
     float* idcolors=0,*editcolors=0; int docolors=mo->Mode==TNS_MESH_EDIT_MODE;

+ 8 - 0
resources/la_properties.c

@@ -705,6 +705,12 @@ void lapost_UserPreferences(void* unused){
 void laset_ColorPickerGamma(void* unused, real gamma){
     MAIN.ColorPickerGamma=gamma; laRedrawCurrentWindow();
 }
+void laset_ViewportHalftoneFactor(void* unused, real v){
+    MAIN.ViewportHalftoneFactor=v; laNotifyUsers("tns.world");
+}
+void laset_ViewportHalftoneSize(void* unused, real v){
+    MAIN.ViewportHalftoneSize=v; laNotifyUsers("tns.world");
+}
 
 void laset_EnableGLDebug(void* unused, int e){ MAIN.EnableGLDebug=e; la_NotifyGLDebugChanges(); }
 void laset_GLDebugSync(void* unused, int e){ MAIN.GLDebugSync=e; la_NotifyGLDebugChanges(); }
@@ -1522,6 +1528,8 @@ void la_RegisterInternalProps(){
             }
 
             laAddFloatProperty(p, "color_picker_gamma", "Color Picker Gamma", "Allows less saturated colors to have more areas", 0,0,0,3.0,1.0, 0.05,1.5, 0,offsetof(LA, ColorPickerGamma), 0,laset_ColorPickerGamma,0,0,0,0,0,0,0,0,0);
+            laAddFloatProperty(p, "viewport_halftone_factor", "Halftone Factor", "Viewport halftone mixing factor", 0,0,0,1.0,0.0,0.05,0.5, 0,offsetof(LA, ViewportHalftoneFactor), 0,laset_ViewportHalftoneFactor,0,0,0,0,0,0,0,0,0);
+            laAddFloatProperty(p, "viewport_halftone_size", "Halftone Size", "Viewport halftone size", 0,0,0,8.0,1.9, 0.05,3.7, 0,offsetof(LA, ViewportHalftoneSize), 0,laset_ViewportHalftoneSize,0,0,0,0,0,0,0,0,0);
         }
 
         p = laAddPropertyContainer("la_translation_language", "Language", "Translation language pack", 0,0,sizeof(laTranslationNode), 0,0,1);{

+ 4 - 0
resources/la_templates.c

@@ -1229,6 +1229,10 @@ void laui_UserPreference(laUiList *uil, laPropPack *Base, laPropPack *OperatorIn
             laShowItem(muil, mcl, 0, "la.user_preferences.color_picker_gamma");
             laShowItem(muil, mcr, 0, "la.user_preferences.enable_color_management");
 
+            laShowLabel(muil, mc, "Viewport:", 0, 0);
+            laShowItem(muil, mcl, 0, "la.user_preferences.viewport_halftone_factor");
+            laShowItem(muil, mcr, 0, "la.user_preferences.viewport_halftone_size");
+
             laShowSeparator(muil, mc);
 
             laShowLabel(muil, mc, "Nodes:", 0, 0);

+ 35 - 8
resources/la_tns_shaders.cpp

@@ -20,6 +20,8 @@
 
 extern "C" const char* TNS_SHADER_COLOR_COMMON=R"(
 #define M_PI 3.1415926535897932384626433832795
+float rad(float d){ return d/180.0*M_PI; }
+float deg(float r){ return r*180.0/M_PI; }
 float cbrt( float x ){
     return sign(x)*pow(abs(x),1.0f/3.0f);
 }
@@ -622,6 +624,8 @@ uniform int ColorMode;
 uniform int MultiplyColor;
 uniform int SampleAmount;
 uniform int UseNormal;
+uniform float UseHalftone;
+uniform float HalftoneSize;
 uniform int InputColorSpace;
 uniform int OutputColorSpace;
 uniform int Composing;
@@ -634,6 +638,7 @@ in vec4 fColor;
 in vec2 fUV;
 flat in vec3 fNormal;
 in vec3 fGPos;
+out float gl_FragDepth;
 layout(location = 0) out vec4 outColor;
 layout(location = 1) out vec3 outNormal;
 layout(location = 2) out vec3 outGPos;
@@ -662,18 +667,38 @@ vec3 ConvertColorSpace(vec3 color){
     }
     return color;
 }
-vec4 rgb2cmyk(vec3 rgb);
-float HalftoneSingle(float a,float theta){
-	float psize=5; vec2 ctr=vec2(psize/2,psize/2); vec2 pt=vec2(psize,psize);
+float htsize=HalftoneSize;
+vec4 rgb2cmyk(vec3 rgb){
+	vec4 cmyk; cmyk.w=1-max(max(rgb.r,rgb.g),rgb.b);
+	float k1=1-cmyk.w;
+	cmyk.r=(k1-rgb.r)/k1; cmyk.g=(k1-rgb.g)/k1; cmyk.b=(k1-rgb.b)/k1;
+	return cmyk;
+}
+vec3 cmyk2rgb(vec4 cmyk){
+	vec3 rgb; float k1=1-cmyk.w;
+	rgb.r=(1-cmyk.r)*k1; rgb.g=(1-cmyk.g)*k1; rgb.b=(1-cmyk.b)*k1;
+	return rgb;
+}
+float rand(vec2 co){
+    return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
+}
+float HalftoneSingle(float a,float ps,float theta,float sm){
+	float psize=ps; vec2 ctr=vec2(psize/2,psize/2); vec2 pt=vec2(psize,psize);
     vec2 xy=gl_FragCoord.xy; xy=vec2(sin(theta)*xy.x-cos(theta)*xy.y,cos(theta)*xy.x+sin(theta)*xy.y);
-	ivec2 xyi=ivec2(int(xy.x/psize),int(xy.y/psize));
+	xy.x=xy.x+rand(xy)/1; xy.y=xy.y+rand(xy)/1; ivec2 xyi=ivec2(int(xy.x/psize),int(xy.y/psize));
 	vec2 xyf=mod(xy,pt);
-	float px1=0.000001; //2.0f/psize;
-	float cmp=(pow(a,1.5)*psize/2*(1.414+px1)); float fac=distance(xyf,ctr)/cmp;
+	float px1=(sm==1)?(3.0f/psize):(0.000001);
+	float cmp=(pow(a,1)*psize/2*(1.414+px1)); float fac=distance(xyf,ctr)/cmp;
 	return smoothstep(1+px1,1-px1,fac);
 }
 vec4 halftone(vec4 color){
-	color.a=HalftoneSingle(color.a,15.0/180.0*3.14);
+	vec4 cmyk=rgb2cmyk(color.rgb); float a=color.a*(gl_FragCoord.x/400.0f);
+	cmyk.r=HalftoneSingle(cmyk.r,htsize,rad(15.0),1);
+	cmyk.g=HalftoneSingle(cmyk.g,htsize,rad(75.0),1);
+	cmyk.b=HalftoneSingle(cmyk.b,htsize,rad(0),1);
+	cmyk.a=HalftoneSingle(cmyk.a,htsize,rad(45.0),1);
+	color.rgb=cmyk2rgb(cmyk);
+	//color.a=HalftoneSingle(a,htsize,rad(30),0);
 	return color;
 }
 void main(){
@@ -691,7 +716,8 @@ void main(){
         if(MultiplyColor!=0){color*=fColor;}
     }
     if(UseNormal!=0){
-		color=halftone(color); if(color.a==0) discard;
+		color.a=HalftoneSingle(color.a,htsize,rad(7),0);
+		if(color.a==0) discard;
         float light_factor=dot(fNormal,vec3(0,0,1));
         float view=dot(fNormal,fGPos-uViewPos);
         float factor=abs(light_factor);
@@ -715,6 +741,7 @@ void main(){
 			color.rgb=vec3(ComposingBlackpoint,ComposingBlackpoint,ComposingBlackpoint);
 		}
 	}
+	if(UseHalftone>1e-6){ color=mix(color,halftone(color),UseHalftone); }
     outColor = color;
     outGPos = fGPos;
 })";

+ 3 - 0
resources/la_widgets_viewers.c

@@ -211,7 +211,10 @@ void la_RootObjectDrawOverlay(laUiItem *ui, int h){
     laCanvasExtra *e = ui->Extra;
     laBoxedTheme *bt = (*ui->Type->Theme);
 
+    tnsUseHalftone(MAIN.ViewportHalftoneFactor);
+    tnsUniformHalftoneSize(T->immShader,MAIN.ViewportHalftoneSize);
     tnsDraw2DTextureDirectly(e->OffScr->pColor[0], ui->L, ui->U, ui->R - ui->L, ui->B - ui->U);
+    tnsUseHalftone(0);
 
     //if(e->OffScrShadow){
         //tnsDraw2DTextureDirectly(e->OffScrShadow->pDepth, ui->L, ui->U, ui->R - ui->L, ui->B - ui->U);