summaryrefslogtreecommitdiff
path: root/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
blob: 2505afea65ce0d92cead240da67ccc41d518d452 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec3 baseCol);
mat4 getSkinnedTransform();
void default_scatter(vec3 viewVec, vec3 lightDir);

attribute vec4 materialColor; //2

attribute vec4 binormal; //6
attribute vec4 clothing; //4

attribute vec4 gWindDir;		//7
attribute vec4 gSinWaveParams; //3
attribute vec4 gGravity;		//5

const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542);	 // #minimax-generated coefficients
const vec4 gPiConstants	= vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); //	# {1/2PI, 2PI, PI, PI/2}

void main()
{
	gl_TexCoord[0] = gl_MultiTexCoord0;
		
	vec4 pos;
	mat4 trans = getSkinnedTransform();
		
	vec3 norm;
	norm.x = dot(trans[0].xyz, gl_Normal);
	norm.y = dot(trans[1].xyz, gl_Normal);
	norm.z = dot(trans[2].xyz, gl_Normal);
	norm = normalize(norm);
		
	vec3 binorm;
	binorm.x = dot(trans[0].xyz, binormal.xyz);
	binorm.y = dot(trans[1].xyz, binormal.xyz);
	binorm.z = dot(trans[2].xyz, binormal.xyz);
	norm = normalize(norm);
	
	//wind
	vec4 windEffect;
	windEffect = vec4(dot(norm, gWindDir.xyz));				//	DP3 windEffect, blendNorm, gWindDir;
	pos.x = dot(trans[2].xyz, gl_Vertex.xyz);				//	DP3 blendPos.x, blendMatZ, iPos;
	windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
						+ windEffect.xyz;					//	MAD windEffect.xyz, blendPos.x, {0.015, 0.015, 0.015, 0}, windEffect;
	windEffect.w = windEffect.w * 2.0 + 1.0;				//	MAD	windEffect.w, windEffect, {0, 0, 0, 2}, {0, 0, 0, 1};	# move wind offset value to [-1, 3]
	windEffect.w = windEffect.w*gWindDir.w;					//	MUL windEffect.w, windEffect, gWindDir;								# modulate wind strength 
	
	windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
						+vec3(gSinWaveParams.w);			//	MAD windEffect.xyz, windEffect, gSinWaveParams, gSinWaveParams.w;		# use sin wave params to scale and offset input

		
	//reduce to period of 2 PI
	vec4 temp1, temp0, temp2, offsetPos;
	temp1.xyz = windEffect.xyz * gPiConstants.x;			//	MUL    temp1.xyz, windEffect, gPiConstants.x;						# change input as multiple of [0-2PI] to [0-1]
	temp0.y = mod(temp1.x,1.0);								//	EXP    temp0, temp1.x;												# find mod(x, 1)
	windEffect.x = temp0.y * gPiConstants.y;				//	MUL    windEffect.x, temp0.y, gPiConstants.y;						# scale from [0,1] to [0, 2PI]
	temp1.z = temp1.z - gPiConstants.w;						//	ADD    temp1.z, temp1.z, -gPiConstants.w;							# shift normal oscillation by PI/2
	temp0.y = mod(temp1.z,1.0);								//	EXP    temp0, temp1.z;												# find mod(x, 1)
	
	windEffect.z = temp0.y * gPiConstants.y;				//	MUL    windEffect.z, temp0.y, gPiConstants.y;						# scale from [0,1] to [0, 2PI]
	windEffect.xyz = windEffect.xyz + vec3(-3.141592);		//	# offset to [-PI, PI]
															//	ADD    windEffect.xyz, windEffect, {-3.141592, -3.141592, -3.141592, -3.141592};

	//calculate sinusoid
	vec4 sinWave;
	temp1 = windEffect*windEffect;							//	MUL    temp1,    windEffect, windEffect;							# x^2
	sinWave = -temp1 * gMinMaxConstants.w 
				+ vec4(gMinMaxConstants.z);					//	MAD    sinWave, -temp1, gMinMaxConstants.w, gMinMaxConstants.z;		# y = -(x^2)/7! + 1/5!
	sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y);	//	MAD    sinWave, sinWave, -temp1, gMinMaxConstants.y;				# y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
	sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x);	//	MAD    sinWave, sinWave, -temp1, gMinMaxConstants.x;				# y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
	sinWave = sinWave * windEffect;							//	MUL    sinWave, sinWave, windEffect;								# y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
	
	// sinWave.x holds sin(norm . wind_direction) with primary frequency
	// sinWave.y holds sin(norm . wind_direction) with secondary frequency
	// sinWave.z hold cos(norm . wind_direction) with primary frequency
	sinWave.xyz = sinWave.xyz * gWindDir.w 
				+ vec3(windEffect.w);						//	MAD sinWave.xyz, sinWave, gWindDir.w, windEffect.w;					# multiply by wind strength in gWindDir.w [-wind, wind]

	// add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
	temp1 = vec4(dot(norm, gGravity.xyz));					//	DP3 temp1, blendNorm, gGravity;										# how much is this normal facing in direction of gGravity?
	temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0));				//	MIN temp1, temp1, {0.2, 0, 0, 0};									# clamp [-1, 1] to [-1, 0.2]
	temp1 = temp1*vec4(1.5,0.0,0.0,0.0);					//	MUL temp1, temp1, {1.5, 0, 0, 0};									# scale from [-1,0.2] to [-1.5, 0.3]
	sinWave.x = sinWave.x + temp1.x;						//	ADD sinWave.x, sinWave, temp1;										# add gGravity effect to sinwave (only primary frequency)
	sinWave.xyz = sinWave.xyz * clothing.w;					//	MUL sinWave.xyz, sinWave, iClothing.w;								# modulate by clothing coverage
	
	sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0));	//	MAX sinWave.xyz, sinWave, {-1, -1, -1, -1};							# clamp to underlying body shape
	offsetPos = clothing * sinWave.x;						//	MUL offsetPos, iClothing, sinWave.x;								# multiply wind effect times clothing displacement
	temp2 = gWindDir*sinWave.z + vec4(norm,0);				//	MAD temp2, gWindDir, sinWave.z, blendNorm;							# calculate normal offset due to wind oscillation
	offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+gl_Vertex;	//	MAD offsetPos, {1.0, 1.0, 1.0, 0.0}, offsetPos, iPos;				# add to offset vertex position, and zero out effect from w
	norm += temp2.xyz*2.0;									//	MAD blendNorm, temp2, {2, 2, 2, 2}, blendNorm;						# add sin wave effect on normals (exaggerated)
	
	//add "backlighting" effect
	float colorAcc;
	colorAcc = 1.0 - clothing.w;							//	SUB colorAcc, {1, 1, 1, 1}, iClothing;
	norm.z -= colorAcc * 0.2;								//	MAD blendNorm, colorAcc.w, {0, 0, -0.2, 0}, blendNorm;
	
	//renormalize normal (again)
	norm = normalize(norm);									//	DP3 divisor.w, blendNorm, blendNorm;
															// RSQ divisor.xyz, divisor.w;
															// MUL blendNorm.xyz, blendNorm, divisor;

	//project binormal to normal plane to ensure orthogonality
	temp2 = vec4(dot(norm, binorm));						//	DP3 temp2, blendNorm, blendBinorm;
	binorm = binorm - temp2.xyz;							//	SUB blendBinorm, blendBinorm, temp2;

	//renormalize binormal
	binorm = normalize(binorm);								//	DP3 divisor.w, blendBinorm, blendBinorm;
															//	RSQ divisor.xyz, divisor.w;
															//	MUL blendBinorm.xyz, blendBinorm, divisor;

	pos.x = dot(trans[0], offsetPos);
	pos.y = dot(trans[1], offsetPos);
	pos.z = dot(trans[2], offsetPos);
	pos.w = 1.0;
	
	vec4 color = calcLighting(pos.xyz, norm, materialColor, gl_Color.rgb);			
	gl_FrontColor = color; 
					
	gl_Position = gl_ProjectionMatrix * pos;
	
	vec3 N = norm;
	vec3 B = binorm;
	vec3 T = cross(N,B);
	
	//gl_TexCoord[1].xy = gl_MultiTexCoord0.xy + 1.0/512.0 * vec2(dot(T,gl_LightSource[0].position.xyz),
	//												dot(B,gl_LightSource[0].position.xyz));

	gl_TexCoord[2] = vec4(pos.xyz, 1.0);
	default_scatter(pos.xyz, gl_LightSource[0].position.xyz);
										 
}