Archive for October, 2008

29
Oct
08

Subsurface Scatter Shader

GLSL translation of this fake sub-surface scattering shader by InvalidPointer.

I’m always amazed when these things actually work…

Vertex Shader:

////////////////////////////
// SUB-SURFACE SCATTER VS //
////////////////////////////

/* --------------------------
SubScatter Vertex Shader:

Fake sub-surface scatter lighting shader by InvalidPointer 2008.
Found at
http://www.gamedev.net/community/forums/topic.asp?topic_id=481494

HLSL > GLSL translation
toneburst 2008
-------------------------- */

// Set light-position
uniform vec3 LightPosition;

// Varying variables to be sent to Fragment Shader
varying vec3 worldNormal, eyeVec, lightVec, vertPos, lightPos;

void subScatterVS(in vec4 ecVert)
{
	lightVec = LightPosition - ecVert.xyz;
	eyeVec = -ecVert.xyz;
	vertPos = ecVert.xyz;
	lightPos = LightPosition;
}

////////////////
//  MAIN LOOP //
////////////////

void main()
{
	worldNormal = gl_NormalMatrix * gl_Normal;
	
	vec4 ecPos = gl_ModelViewProjectionMatrix * gl_Vertex;
	
	// Call function to set varyings for subscatter FS
	subScatterVS(ecPos);
	
	//Transform vertex by modelview and projection matrices
	gl_Position = ecPos;

	//Forward current texture coordinates after applying texture matrix
	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}

Fragment Shader:

////////////////////////////
// SUB-SURFACE SCATTER FS //
////////////////////////////

/* --------------------------
SubScatter Fragment Shader:

Fake sub-surface scatter lighting shader by InvalidPointer 2008.
Found at
http://www.gamedev.net/community/forums/topic.asp?topic_id=481494

HLSL > GLSL translation
toneburst 2008
-------------------------- */

// Variables for lighting properties
uniform float MaterialThickness;
uniform vec3 ExtinctionCoefficient; // Will show as X Y and Z ports in QC, but actually represent RGB values.
uniform vec4 LightColor;
uniform vec4 BaseColor;
uniform vec4 SpecColor;
uniform float SpecPower;
uniform float RimScalar;
//uniform sampler2D Texture;

// Varying variables to be sent to Fragment Shader
varying vec3 worldNormal, eyeVec, lightVec, vertPos, lightPos;

float halfLambert(in vec3 vect1, in vec3 vect2)
{
	float product = dot(vect1,vect2);
	return product * 0.5 + 0.5;
}

float blinnPhongSpecular(in vec3 normalVec, in vec3 lightVec, in float specPower)
{
	vec3 halfAngle = normalize(normalVec + lightVec);
	return pow(clamp(0.0,1.0,dot(normalVec,halfAngle)),specPower);
}

// Main fake sub-surface scatter lighting function

vec4 subScatterFS()
{
	float attenuation = 10.0 * (1.0 / distance(lightPos,vertPos));
	vec3 eVec = normalize(eyeVec);
	vec3 lVec = normalize(lightVec);
	vec3 wNorm = normalize(worldNormal);
	
	vec4 dotLN = vec4(halfLambert(lVec,wNorm) * attenuation);
	//dotLN *= texture2D(Texture, gl_TexCoord[0].xy);
	dotLN *= BaseColor;
	
	vec3 indirectLightComponent = vec3(MaterialThickness * max(0.0,dot(-wNorm,lVec)));
	indirectLightComponent += MaterialThickness * halfLambert(-eVec,lVec);
	indirectLightComponent *= attenuation;
	indirectLightComponent.r *= ExtinctionCoefficient.r;
	indirectLightComponent.g *= ExtinctionCoefficient.g;
	indirectLightComponent.b *= ExtinctionCoefficient.b;
	
	vec3 rim = vec3(1.0 - max(0.0,dot(wNorm,eVec)));
	rim *= rim;
	rim *= max(0.0,dot(wNorm,lVec)) * SpecColor.rgb;
	
	vec4 finalCol = dotLN + vec4(indirectLightComponent,1.0);
	finalCol.rgb += (rim * RimScalar * attenuation * finalCol.a);
	finalCol.rgb += vec3(blinnPhongSpecular(wNorm,lVec,SpecPower) * attenuation * SpecColor * finalCol.a * 0.05);
	finalCol.rgb *= LightColor.rgb;
	
	return finalCol;	
}

////////////////
//  MAIN LOOP //
////////////////

void main()
{
	gl_FragColor = subScatterFS();
}
28
Oct
08

soundFlower Update

I realised I hadn’t spent enough time optimising the controls of my tb soundFlower qcClip, so I’m uploading an updated version. Same effect, but the control ranges make a bit more sense, and the audio-response is a bit better.

Also, I didn’t mention in my previous post that you need the excellent Kineme Audio Tools plugin to run this QTZ.

New version in the Box.net widget ‘tb soundFlower 1.01.qtz’

28
Oct
08

tb MetaImage Update (CIFilter Code)

Updated version of the Meta-Image filter I did ages ago, originally based on one of Pete Warden’s original free FreeFrame effects. This one has a couple of nice new options and the whole thing has been implemented in a single CIFilter patch, this time.

CIFilter Kernel Code:

/*
	'Meta-Image' effect.
	Original image is scaled and tiled, optionally recoloured
	by multiplication with colour of centre pixel of each tile.
	Based on original FreeFrame effect by Pete Warden.
	
	toneburst 2008
	https://machinesdontcare.wordpress.com
*/

///////////////////
//   Pre-zoom    //
///////////////////

kernel vec4 vvZoom(sampler Image, vec2 Center, float Level) 
{	
	// Based on VVZoom effect, from
	// http://www.vidvox.com/phpBB2/viewtopic.php?t=1785&highlight=vvzoom
	
	vec2 loc = destCoord();
	loc = samplerTransform(Image,loc);
	vec2 modifiedCenter = samplerTransform(Image, Center);
	loc = (loc - modifiedCenter)*(1.0/Level) + modifiedCenter;
	
	return sample(Image,loc); 
}

/////////////////////////////////////////
// Simple version, without recolouring //
/////////////////////////////////////////

kernel vec4 tbMetaImage(sampler Image, vec2 Divisor, float Mix)
{
	// Input image dimensions
	vec2 dims = samplerSize(Image);
	// Normalised coords of current pixel
	vec2 xyNorm = samplerCoord(Image) / dims;
	
	// Coords to sample tiled image
	vec2 miniImagePos = fract(xyNorm / Divisor);
	
	// Output tiled image
	return sample(Image, mix(xyNorm,miniImagePos,Mix) * dims);
}

//////////////////////
// With recolouring //
//////////////////////

kernel vec4 tbMetaImageClr(sampler Image, vec2 Divisor, float Mix)
{
	// Input image dimensions
	vec2 dims = samplerSize(Image);
	// Normalised coords of current pixel
	vec2 xyNorm = samplerCoord(Image) / dims;
	
	// Coords to sample tiled image
	vec2 miniImagePos = fract(xyNorm / Divisor);
	// Coords to sample centre pixel of each tile
	vec2 colorPos = (floor(xyNorm / Divisor) * Divisor) + 0.5 * Divisor;
	
	// Color at centre of current tile
	vec4 centreColor = sample(Image, colorPos * dims);
	// Sample scaled input image for current tile
	vec4 miniImage = sample(Image, mix(xyNorm,miniImagePos,Mix) * dims);
	
	// Output tiled image * centre color
	// mixed with original mini image color
	return mix(miniImage,miniImage * centreColor,Mix);
}

.. and the JavaScript from the bottom panel:

function __image main(__image Image, __vec2 Divisor, __number Type, __number PreZoom, __number Mix)
{
	// Scale and round control values
	Divisor.x = 1 / Math.round(Divisor.x); // Range 50 > 1, exponential-in
	Divisor.y = 1 / Math.round(Divisor.y); // Range 50 > 1, exponential-in
	
	// Pre-zoom
	center = new Vec(0.5 * Image.extent.width,0.5 * Image.extent.width);
	var zoomedImage = vvZoom.apply(Image.definition,null,Image,center,PreZoom);
	
	if(Type == 0.0) {
		return tbMetaImage.apply(zoomedImage.definition, null, zoomedImage, Divisor,Mix);
	} else if(Type == 1.0) {
		return tbMetaImageClr.apply(Image.definition, null, Image, Divisor,Mix);	}	
}

One nice new feature I’ve added is the ability to ‘mix’ between the effect and original image, but not as a simple crossfade- it’s actually mixing between the coordinates the image is sampled at, so you get this weird zooming effect.

I’ve realised I should be thinking more about making my effects start in an interesting way. Rather than just being on or off, I could have them transition in some interesting way from the original image to the effected version. Or maybe this wouldn’t be such a great idea, usability-wise. Anyone any thoughts on this?

28
Oct
08

tb SoundFlower

An audio-reactive circular oscilloscope-type thing, with feedback.
Requires Kineme Audio Tools plugin.

This is an old project resurrected. I’ve finally got around to adding the ability to choose the audio interface and channel for the effect via a little info box, overlaid on top of the output. It’s a not-particularly elegant hack, but I can’t see any other way of doing it, since you can’t populate an Index splitter with names items programmatically from inside QC (as far as I know).

tb_soundFlower.qtz in the widget.

26
Oct
08

tb Tunnel

I’ve been working on a QTZ tunnel effect, but taking a different approach to the one goto10 used for his excellent take on the theme.

Since I’ve been working a lot with GLSL, I thought I’d try writing a shader to do something similar. In fact, all the shader does, is create a bendy tube, and apply a texture to it. All the rest of the work is done with a series of CIFiltes. My brainwave, and the germ for the project, was the realisation that if I applied a frame-roll type effect to the texture on the tube and positioned it so that we were looking down the inside of the tube, I could make it look the viewer was travelling down a tunnel. Obvious, really.

I’ve added a few other controls, too, and setup the texture movement to be synced to VDMXs Measure Position.

Controls:

Rate Select:
Rate of tunnel movement, based on Measure Position.

Curve Controls:
Rate and amount of bends in tunnel

Tile Controls:
Controls for mirroring, and tiling the input image.

Live/Capture:
This is an important one.
Live Input
uses the realtime input (as you’d expect). The only problem with this is that movement in the image can conflict with the movement of the tunnel effect, making it look jerky, so I’ve added
Captured Input
Grabs a still-frame at regular intervals (set by the rate control), and uses this as the texture. The downside is that you won’t see changes to the tile controls until the next cycle.

Color Controls:
Obvious, really.

Thanks to aienn for the footage used in the screenshots

10
Oct
08

From The Archives

Some screenshots of a version of the Maths Surfaces QTZ I found on my Desktop (really need to tidy up a bit).

I may have uploaded these before, so apologies if that’s the case.

10
Oct
08

Velvet Heart

Cheesy, I know, but really just a test of normal-calculation in the Vertex Shader. The velvet/rim-lighting effect was just the first lighting shader that came to hand, as it were…

I’ll post the sourcecode and QTZ soon, for what it’s worth.




Twitter

  • RT @qikipedia: "Anyone who is capable of getting themselves made President should on no account be allowed to do the job." DOUGLAS ADAMS 2 days ago
  • RT @_psonice: @johnreppion Did they really put Paul Nuttal's orgasm face on the bus? That has to be photoshopped. 1 week ago
  • RT @_psonice: Also happened by Lacy's Caves. Good spot. Path was washed away further up, nearly lost a bollock to barb wire going round. Wo… 1 week ago
October 2008
M T W T F S S
« Sep   Nov »
 12345
6789101112
13141516171819
20212223242526
2728293031  

Links

Blog Stats

  • 470,063 hits