shader's triangular mosaic effect

Original Link: http://www.cnblogs.com/riasky/p/3465028.html

Not long ago, I made a hexagonal mosaic. Interestingly, I made a triangular mosaic by hot iron.

First of all, it must be an equilateral triangle so that it can be truly seamless.Observations show that triangles can be stitched together into hexagons previously made.

As follows:


We can see that six triangles make up exactly one hexagon.

To determine which triangle a point belongs to, we must first determine which hexagon it belongs to, which was before Bowen Already mentioned.

OK, we know the hexagon, that is, we know the coordinates of the O point above.We started to think about how to tell which triangle it is.

Well, I think you can all imagine that, judging from the angle between the point and the center point O, calling atan is OK:

 

float a = atan((x-O.x)/(y-O.y));//included angle

Then you can tell which triangle belongs according to their angle. Note here that atan calculates a range of -180 to 180 degrees, and the corresponding values are -PI to PI.

 

Then calculate the center point coordinates of six triangles, which triangle belongs to which coordinate point's pixel value.

The frag shader of the fragment shader is as follows:

 

#version 400
#extension GL_ARB_texture_rectangle : enable

uniform float len;
uniform sampler2DRect colorTex0;
void main (void){
	float TR = 0.866025f;
	float PI6 = 0.523599f; //PI/6
	float x = gl_TexCoord[0].x;
	float y = gl_TexCoord[0].y;
	int wx = int(x/1.5f/len);
	int wy = int(y/TR/len);
	vec2 v1, v2, vn;
	if(wx/2 * 2 == wx) {
		if(wy/2 * 2 == wy) {
				v1 = vec2(len*1.5f*wx, len*TR*wy);
				v2 = vec2(len*1.5f*(wx+1), len*TR*(wy+1));
			} else {
				v1 = vec2(len*1.5f*wx, len*TR*(wy+1));
				v2 = vec2(len*1.5f*(wx+1), len*TR*wy);
			}
		} else {
		if(wy/2 * 2 == wy) {
			v1 = vec2(len*1.5f*wx, len*TR*(wy+1));
			v2 = vec2(len*1.5f*(wx+1), len*TR*wy);
			} else {
				v1 = vec2(len*1.5f*wx, len*TR*wy);
				v2 = vec2(len*1.5f*(wx+1), len*TR*(wy+1));
			}
	}
	float s1 = sqrt( pow(v1.x-x, 2) + pow(v1.y-y, 2) );
	float s2 = sqrt( pow(v2.x-x, 2) + pow(v2.y-y, 2) );
	if(s1 < s2)
		vn = v1;
	else
		vn = v2;
	vec4	mid = texture2DRect(colorTex0, vn);
	float a = atan((x-vn.x)/(y-vn.y));//included angle
	vec2 area1 = vec2(vn.x, vn.y-len/TR/2);
	vec2 area2 = vec2(vn.x+len/2, vn.y-len/TR/4);
	vec2 area3 = vec2(vn.x+len/2, vn.y+len/TR/4);
	vec2 area4 = vec2(vn.x, vn.y+len/TR/2);
	vec2 area5 = vec2(vn.x-len/2, vn.y+len/TR/4);
	vec2 area6 = vec2(vn.x-len/2, vn.y-len/TR/4);
	if(a>=PI6 && a<PI6*3)
		vn = area1;
	else if(a>=PI6*3 && a<PI6*5)
		vn = area2;
	else if((a>=PI6*5 && a<=PI6*6) || (a<-PI6*5 && a>-PI6*6))
		vn = area3;
	else if(a<-PI6*3 && a>=-PI6*5)
		vn = area4;
	else if(a<=-PI6 && a>-PI6*3)
		vn = area5;
	else if(a>-PI6 && a<PI6)
		vn = area6;
	vec4  color = texture2DRect(colorTex0, vn);
	gl_FragColor = color;
}

Where len is the unilateral length of the hexagon and the triangle passed into the shader.TR is actually 3/2.PI6 is obviously PI/6, corresponding to 30 degrees.

 

In fact, the core idea is to determine which triangle belongs to.

The results are as follows:


Similarly, by changing len's value in real time, the graph can move:


Still cool, ^^.

Main code in openframework:

 

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
	img.loadImage("bg.jpg");

	fbo.allocate(640, 480);

	shader.load("triangle.vert", "triangle.frag");
	len = 100.0f;
	bAdd = false;
}

//--------------------------------------------------------------
void testApp::update(){
	if(len < 10.0f)
		bAdd = true;
	if(len > 100.0f)
		bAdd = false;
	len += bAdd ? (0.05f):(-0.05f);
}

//--------------------------------------------------------------
void testApp::draw(){
	ofEnableAlphaBlending();

	fbo.begin();
	img.draw(0, 0, 640, 480);
	fbo.end();

	shader.begin();
	shader.setUniform1f("len", len);
	shader.setUniformTexture("colorTex0", fbo.getTextureReference(), 0);
	fbo.draw(0, 0, 640, 480);
	shader.end();

	ofDisableAlphaBlending();
}


OK, if you're interested, try it.

 

 

Reprinted at: https://www.cnblogs.com/riasky/p/3465028.html

Keywords: Fragment

Added by nitestryker on Fri, 26 Jul 2019 20:28:13 +0300