mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Merge pull request #599 from larsbrinkhoff/glsl
Add OpenGL Shading Language.
This commit is contained in:
		| @@ -476,6 +476,18 @@ GAS: | ||||
|   extensions: | ||||
|   - .S | ||||
|  | ||||
| GLSL: | ||||
|   group: C | ||||
|   type: programming | ||||
|   primary_extension: .glsl | ||||
|   extensions: | ||||
|   - .fp | ||||
|   - .frag | ||||
|   - .geom | ||||
|   - .glslv | ||||
|   - .shader | ||||
|   - .vert | ||||
|  | ||||
| Genshi: | ||||
|   primary_extension: .kid | ||||
|  | ||||
|   | ||||
							
								
								
									
										161
									
								
								samples/GLSL/SyLens.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								samples/GLSL/SyLens.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | ||||
| #version 120 | ||||
|  | ||||
| /* | ||||
|   Original Lens Distortion Algorithm from SSontech (Syntheyes) | ||||
|   http://www.ssontech.com/content/lensalg.htm | ||||
|    | ||||
|   r2 is radius squared. | ||||
|    | ||||
|   r2 = image_aspect*image_aspect*u*u + v*v | ||||
|   f = 1 + r2*(k + kcube*sqrt(r2)) | ||||
|   u' = f*u | ||||
|   v' = f*v | ||||
|  | ||||
| */ | ||||
|  | ||||
| // Controls | ||||
| uniform float kCoeff, kCube, uShift, vShift; | ||||
| uniform float chroma_red, chroma_green, chroma_blue; | ||||
| uniform bool apply_disto; | ||||
|  | ||||
| // Uniform inputs | ||||
| uniform sampler2D input1; | ||||
| uniform float adsk_input1_w, adsk_input1_h, adsk_input1_aspect, adsk_input1_frameratio; | ||||
| uniform float adsk_result_w, adsk_result_h; | ||||
|  | ||||
| float distortion_f(float r) { | ||||
|     float f = 1 + (r*r)*(kCoeff + kCube * r); | ||||
|     return f; | ||||
| } | ||||
|  | ||||
|  | ||||
| float inverse_f(float r) | ||||
| { | ||||
|      | ||||
|     // Build a lookup table on the radius, as a fixed-size table. | ||||
|     // We will use a vec3 since we will store the multipled number in the Z coordinate. | ||||
|     // So to recap: x will be the radius, y will be the f(x) distortion, and Z will be x * y; | ||||
|     vec3[48] lut; | ||||
|      | ||||
|     // Since out LUT is shader-global check if it's been computed alrite | ||||
|     // Flame has no overflow bbox so we can safely max out at the image edge, plus some cushion | ||||
|     float max_r = sqrt((adsk_input1_frameratio * adsk_input1_frameratio) + 1) + 0.1; | ||||
|     float incr = max_r / 48; | ||||
|     float lut_r = 0; | ||||
|     float f; | ||||
|     for(int i=0; i < 48; i++) { | ||||
|         f = distortion_f(lut_r); | ||||
|         lut[i] = vec3(lut_r, f, lut_r * f); | ||||
|         lut_r += incr; | ||||
|     } | ||||
|      | ||||
|     float t; | ||||
|     // Now find the nehgbouring elements | ||||
|     // only iterate to 46 since we will need | ||||
|     // 47 as i+1 | ||||
|     for(int i=0; i < 47; i++) { | ||||
|         if(lut[i].z < r && lut[i+1].z > r) { | ||||
|             // BAM! our value is between these two segments | ||||
|             // get the T interpolant and mix | ||||
|             t = (r - lut[i].z) / (lut[i+1].z - lut[i]).z; | ||||
|             return mix(lut[i].y, lut[i+1].y, t ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| float aberrate(float f, float chroma) | ||||
| { | ||||
|    return f + (f * chroma); | ||||
| } | ||||
|  | ||||
| vec3 chromaticize_and_invert(float f) | ||||
| { | ||||
|    vec3 rgb_f = vec3(aberrate(f, chroma_red), aberrate(f, chroma_green), aberrate(f, chroma_blue)); | ||||
|    // We need to DIVIDE by F when we redistort, and x / y == x * (1 / y) | ||||
|    if(apply_disto) { | ||||
|       rgb_f = 1 / rgb_f; | ||||
|    } | ||||
|    return rgb_f; | ||||
| } | ||||
|  | ||||
| void main(void) | ||||
| { | ||||
|    vec2 px, uv; | ||||
|    float f = 1; | ||||
|    float r = 1; | ||||
|     | ||||
|    px = gl_FragCoord.xy; | ||||
|     | ||||
|    // Make sure we are still centered | ||||
|    px.x -= (adsk_result_w - adsk_input1_w) / 2; | ||||
|    px.y -= (adsk_result_h - adsk_input1_h) / 2; | ||||
|     | ||||
|    // Push the destination coordinates into the [0..1] range | ||||
|    uv.x = px.x / adsk_input1_w; | ||||
|    uv.y = px.y / adsk_input1_h; | ||||
|     | ||||
|         | ||||
|    // And to Syntheyes UV which are [1..-1] on both X and Y | ||||
|    uv.x = (uv.x *2 ) - 1; | ||||
|    uv.y = (uv.y *2 ) - 1; | ||||
|     | ||||
|    // Add UV shifts | ||||
|    uv.x += uShift; | ||||
|    uv.y += vShift; | ||||
|     | ||||
|    // Make the X value the aspect value, so that the X coordinates go to [-aspect..aspect] | ||||
|    uv.x = uv.x * adsk_input1_frameratio; | ||||
|     | ||||
|    // Compute the radius | ||||
|    r = sqrt(uv.x*uv.x + uv.y*uv.y); | ||||
|     | ||||
|    // If we are redistorting, account for the oversize plate in the input, assume that | ||||
|    // the input aspect is the same | ||||
|    if(apply_disto) { | ||||
|        r = r / (float(adsk_input1_w) / float(adsk_result_w)); | ||||
|    } | ||||
|     | ||||
|    // Apply or remove disto, per channel honoring chromatic aberration | ||||
|    if(apply_disto) { | ||||
|       f = inverse_f(r); | ||||
|    } else { | ||||
|       f = distortion_f(r); | ||||
|    } | ||||
|     | ||||
|    vec2[3] rgb_uvs = vec2[](uv, uv, uv); | ||||
|     | ||||
|    // Compute distortions per component | ||||
|    vec3 rgb_f = chromaticize_and_invert(f); | ||||
|     | ||||
|    // Apply the disto coefficients, per component | ||||
|    rgb_uvs[0] = rgb_uvs[0] * rgb_f.rr; | ||||
|    rgb_uvs[1] = rgb_uvs[1] * rgb_f.gg; | ||||
|    rgb_uvs[2] = rgb_uvs[2] * rgb_f.bb; | ||||
|     | ||||
|    // Convert all the UVs back to the texture space, per color component | ||||
|    for(int i=0; i < 3; i++) { | ||||
|        uv = rgb_uvs[i]; | ||||
|         | ||||
|        // Back from [-aspect..aspect] to [-1..1] | ||||
|        uv.x = uv.x / adsk_input1_frameratio; | ||||
|         | ||||
|        // Remove UV shifts | ||||
|        uv.x -= uShift; | ||||
|        uv.y -= vShift; | ||||
|         | ||||
|        // Back to OGL UV | ||||
|        uv.x = (uv.x + 1) / 2; | ||||
|        uv.y = (uv.y + 1) / 2; | ||||
|         | ||||
|        rgb_uvs[i] = uv; | ||||
|    } | ||||
|     | ||||
|    // Sample the input plate, per component | ||||
|    vec4 sampled; | ||||
|    sampled.r = texture2D(input1, rgb_uvs[0]).r; | ||||
|    sampled.g = texture2D(input1, rgb_uvs[1]).g; | ||||
|    sampled.b = texture2D(input1, rgb_uvs[2]).b; | ||||
|     | ||||
|    // and assign to the output | ||||
|    gl_FragColor.rgba = vec4(sampled.rgb, 1.0 ); | ||||
| } | ||||
							
								
								
									
										630
									
								
								samples/GLSL/islandScene.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										630
									
								
								samples/GLSL/islandScene.glsl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,630 @@ | ||||
| //// High quality (Some browsers may freeze or crash) | ||||
| //#define HIGHQUALITY | ||||
|  | ||||
| //// Medium quality (Should be fine on all systems, works on Intel HD2000 on Win7 but quite slow) | ||||
| //#define MEDIUMQUALITY | ||||
|  | ||||
| //// Defaults | ||||
| //#define REFLECTIONS | ||||
| #define SHADOWS | ||||
| //#define GRASS | ||||
| //#define SMALL_WAVES | ||||
| #define RAGGED_LEAVES | ||||
| //#define DETAILED_NOISE | ||||
| //#define LIGHT_AA // 2 sample SSAA | ||||
| //#define HEAVY_AA // 2x2 RG SSAA | ||||
| //#define TONEMAP | ||||
|  | ||||
| //// Configurations | ||||
| #ifdef MEDIUMQUALITY | ||||
| 	#define SHADOWS | ||||
| 	#define SMALL_WAVES | ||||
| 	#define RAGGED_LEAVES | ||||
| 	#define TONEMAP | ||||
| #endif | ||||
|  | ||||
| #ifdef HIGHQUALITY | ||||
| 	#define REFLECTIONS | ||||
| 	#define SHADOWS | ||||
| 	//#define GRASS | ||||
| 	#define SMALL_WAVES | ||||
| 	#define RAGGED_LEAVES | ||||
| 	#define DETAILED_NOISE | ||||
| 	#define LIGHT_AA | ||||
| 	#define TONEMAP | ||||
| #endif | ||||
|  | ||||
| // Constants | ||||
| const float eps = 1e-5; | ||||
| const float PI = 3.14159265359; | ||||
|  | ||||
| const vec3 sunDir = vec3(0.79057,-0.47434, 0.0); | ||||
| const vec3 skyCol = vec3(0.3, 0.5, 0.8); | ||||
| const vec3 sandCol = vec3(0.9, 0.8, 0.5); | ||||
| const vec3 treeCol = vec3(0.8, 0.65, 0.3); | ||||
| const vec3 grassCol = vec3(0.4, 0.5, 0.18); | ||||
| const vec3 leavesCol = vec3(0.3, 0.6, 0.2); | ||||
| const vec3 leavesPos = vec3(-5.1,13.4, 0.0); | ||||
|  | ||||
| #ifdef TONEMAP | ||||
| const vec3 sunCol = vec3(1.8, 1.7, 1.6); | ||||
| #else | ||||
| const vec3 sunCol = vec3(0.9, 0.85, 0.8); | ||||
| #endif | ||||
|  | ||||
| const float exposure = 1.1; // Only used when tonemapping | ||||
|  | ||||
| // Description : Array and textureless GLSL 2D/3D/4D simplex | ||||
| // noise functions. | ||||
| // Author : Ian McEwan, Ashima Arts. | ||||
| // License : Copyright (C) 2011 Ashima Arts. All rights reserved. | ||||
| // Distributed under the MIT License. See LICENSE file. | ||||
| // https://github.com/ashima/webgl-noise | ||||
| vec3 mod289(vec3 x) { | ||||
|   return x - floor(x * (1.0 / 289.0)) * 289.0; | ||||
| } | ||||
|  | ||||
| vec4 mod289(vec4 x) { | ||||
|   return x - floor(x * (1.0 / 289.0)) * 289.0; | ||||
| } | ||||
|  | ||||
| vec4 permute(vec4 x) { | ||||
|      return mod289(((x*34.0)+1.0)*x); | ||||
| } | ||||
|  | ||||
| vec4 taylorInvSqrt(vec4 r) { | ||||
|   return 1.79284291400159 - 0.85373472095314 * r; | ||||
| } | ||||
|  | ||||
| float snoise(vec3 v) { | ||||
|   const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; | ||||
|   const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); | ||||
|  | ||||
| // First corner | ||||
|   vec3 i = floor(v + dot(v, C.yyy) ); | ||||
|   vec3 x0 = v - i + dot(i, C.xxx) ; | ||||
|  | ||||
| // Other corners | ||||
|   vec3 g = step(x0.yzx, x0.xyz); | ||||
|   vec3 l = 1.0 - g; | ||||
|   vec3 i1 = min( g.xyz, l.zxy ); | ||||
|   vec3 i2 = max( g.xyz, l.zxy ); | ||||
|  | ||||
|   // x0 = x0 - 0.0 + 0.0 * C.xxx; | ||||
|   // x1 = x0 - i1 + 1.0 * C.xxx; | ||||
|   // x2 = x0 - i2 + 2.0 * C.xxx; | ||||
|   // x3 = x0 - 1.0 + 3.0 * C.xxx; | ||||
|   vec3 x1 = x0 - i1 + C.xxx; | ||||
|   vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y | ||||
|   vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y | ||||
|  | ||||
| // Permutations | ||||
|   i = mod289(i); | ||||
|   vec4 p = permute( permute( permute( | ||||
|              i.z + vec4(0.0, i1.z, i2.z, 1.0 )) | ||||
|            + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) | ||||
|            + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); | ||||
|  | ||||
| // Gradients: 7x7 points over a square, mapped onto an octahedron. | ||||
| // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) | ||||
|   float n_ = 0.142857142857; // 1.0/7.0 | ||||
|   vec3 ns = n_ * D.wyz - D.xzx; | ||||
|  | ||||
|   vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) | ||||
|  | ||||
|   vec4 x_ = floor(j * ns.z); | ||||
|   vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) | ||||
|  | ||||
|   vec4 x = x_ *ns.x + ns.yyyy; | ||||
|   vec4 y = y_ *ns.x + ns.yyyy; | ||||
|   vec4 h = 1.0 - abs(x) - abs(y); | ||||
|  | ||||
|   vec4 b0 = vec4( x.xy, y.xy ); | ||||
|   vec4 b1 = vec4( x.zw, y.zw ); | ||||
|  | ||||
|   //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; | ||||
|   //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; | ||||
|   vec4 s0 = floor(b0)*2.0 + 1.0; | ||||
|   vec4 s1 = floor(b1)*2.0 + 1.0; | ||||
|   vec4 sh = -step(h, vec4(0.0)); | ||||
|  | ||||
|   vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; | ||||
|   vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; | ||||
|  | ||||
|   vec3 p0 = vec3(a0.xy,h.x); | ||||
|   vec3 p1 = vec3(a0.zw,h.y); | ||||
|   vec3 p2 = vec3(a1.xy,h.z); | ||||
|   vec3 p3 = vec3(a1.zw,h.w); | ||||
|  | ||||
| //Normalise gradients | ||||
|   vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); | ||||
|   p0 *= norm.x; | ||||
|   p1 *= norm.y; | ||||
|   p2 *= norm.z; | ||||
|   p3 *= norm.w; | ||||
|  | ||||
| // Mix final noise value | ||||
|   vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); | ||||
|   m = m * m; | ||||
|   return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), | ||||
|                                 dot(p2,x2), dot(p3,x3) ) ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| // Main | ||||
| float fbm(vec3 p) | ||||
| { | ||||
| 	float final = snoise(p);  | ||||
| 	p *= 1.94; final += snoise(p) * 0.5; | ||||
| 	#ifdef DETAILED_NOISE | ||||
| 	p *= 3.75; final += snoise(p) * 0.25; | ||||
| 	return final / 1.75; | ||||
| 	#else | ||||
| 	return final / 1.5; | ||||
| 	#endif | ||||
| } | ||||
|  | ||||
| float waterHeight(vec3 p) | ||||
| { | ||||
| 	float d = length(p.xz); | ||||
| 	float h = sin(d * 1.5 + iGlobalTime * 3.0) * 12.0 / d; // Island waves | ||||
| 	#ifdef SMALL_WAVES | ||||
| 	h += fbm(p*0.5); // Other waves | ||||
| 	#endif | ||||
| 	return h; | ||||
| } | ||||
|  | ||||
| vec3 bump(vec3 pos, vec3 rayDir) | ||||
| { | ||||
| 	float s = 2.0; | ||||
| 	 | ||||
| 	// Fade out waves to reduce aliasing | ||||
| 	float dist = dot(pos, rayDir); | ||||
| 	s *= dist < 2.0 ? 1.0 : 1.4142 / sqrt(dist); | ||||
| 	 | ||||
| 	// Calculate normal from heightmap | ||||
| 	vec2 e = vec2(1e-2, 0.0); | ||||
| 	vec3 p = vec3(pos.x, iGlobalTime*0.5, pos.z)*0.7; | ||||
| 	float m = waterHeight(p)*s; | ||||
| 	return normalize(vec3( | ||||
| 		waterHeight(p+e.xyy)*s-m, | ||||
| 		1.0, | ||||
| 		waterHeight(p+e.yxy)*s-m | ||||
| 	)); | ||||
| } | ||||
|  | ||||
| // Ray intersections | ||||
| vec4 intersectSphere(vec3 rpos, vec3 rdir, vec3 pos, float rad) | ||||
| { | ||||
| 	vec3 op = pos - rpos; | ||||
| 	float b = dot(op, rdir);  | ||||
| 	float det = b*b - dot(op, op) + rad*rad;  | ||||
| 		 | ||||
| 	if (det > 0.0) | ||||
| 	{ | ||||
| 		det = sqrt(det); | ||||
| 		float t = b - det; | ||||
| 		if (t > eps) | ||||
| 			return vec4(-normalize(rpos+rdir*t-pos), t); | ||||
| 	} | ||||
| 	 | ||||
| 	return vec4(0.0); | ||||
| } | ||||
|  | ||||
| vec4 intersectCylinder(vec3 rpos, vec3 rdir, vec3 pos, float rad) | ||||
| { | ||||
| 	vec3 op = pos - rpos; | ||||
| 	vec2 rdir2 = normalize(rdir.yz); | ||||
| 	float b = dot(op.yz, rdir2); | ||||
| 	float det = b*b - dot(op.yz, op.yz) + rad*rad;  | ||||
| 	 | ||||
| 	if (det > 0.0) | ||||
| 	{ | ||||
| 		det = sqrt(det); | ||||
| 		float t = b - det; | ||||
| 		if (t > eps) | ||||
| 			return vec4(-normalize(rpos.yz+rdir2*t-pos.yz), 0.0, t); | ||||
| 		t = b + det; | ||||
| 		if (t > eps) | ||||
| 			return vec4(-normalize(rpos.yz+rdir2*t-pos.yz), 0.0, t); | ||||
| 	} | ||||
| 	 | ||||
| 	return vec4(0.0); | ||||
| } | ||||
|  | ||||
| vec4 intersectPlane(vec3 rayPos, vec3 rayDir, vec3 n, float d) | ||||
| { | ||||
| 	float t = -(dot(rayPos, n) + d) / dot(rayDir, n); | ||||
| 	return vec4(n * sign(dot(rayDir, n)), t); | ||||
| } | ||||
|  | ||||
| // Helper functions | ||||
| vec3 rotate(vec3 p, float theta) | ||||
| { | ||||
| 	float c = cos(theta), s = sin(theta); | ||||
| 	return vec3(p.x * c + p.z * s, p.y, | ||||
| 				p.z * c - p.x * s); | ||||
| } | ||||
|  | ||||
| float impulse(float k, float x) // by iq | ||||
| { | ||||
|     float h = k*x; | ||||
|     return h * exp(1.0 - h); | ||||
| } | ||||
|  | ||||
| // Raymarched parts of scene | ||||
| float grass(vec3 pos) | ||||
| { | ||||
| 	float h = length(pos - vec3(0.0, -7.0, 0.0)) - 8.0; | ||||
| 	 | ||||
| 	if (h > 2.0) return h; // Optimization (Avoid noise if too far away) | ||||
| 	 | ||||
| 	return h + snoise(pos * 3.0) * 0.1 + pos.y * 0.9; | ||||
| } | ||||
|  | ||||
| float tree(vec3 pos) | ||||
| { | ||||
| 	pos.y -= 0.5; | ||||
| 	float s = sin(pos.y*0.03); | ||||
| 	float c = cos(pos.y*0.03); | ||||
| 	mat2 m = mat2(c, -s, s, c); | ||||
| 	vec3 p = vec3(m*pos.xy, pos.z); | ||||
| 	 | ||||
| 	float width = 1.0 - pos.y * 0.02 - clamp(sin(pos.y * 8.0) * 0.1, 0.05, 0.1); | ||||
| 	 | ||||
| 	return max(length(p.xz) - width, pos.y - 12.5); | ||||
| } | ||||
|  | ||||
| vec2 scene(vec3 pos) | ||||
| { | ||||
| 	float vtree = tree(pos); | ||||
| 	#ifdef GRASS | ||||
| 	float vgrass = grass(pos); | ||||
| 	float v = min(vtree, vgrass); | ||||
| 	#else | ||||
| 	float v = vtree; | ||||
| 	#endif | ||||
| 	return vec2(v, v == vtree ? 2.0 : 1.0); | ||||
| } | ||||
|  | ||||
| vec3 normal(vec3 pos) | ||||
| { | ||||
| 	vec2 eps = vec2(1e-3, 0.0); | ||||
| 	float h = scene(pos).x; | ||||
| 	return normalize(vec3( | ||||
| 		scene(pos-eps.xyy).x-h, | ||||
| 		scene(pos-eps.yxy).x-h, | ||||
| 		scene(pos-eps.yyx).x-h | ||||
| 	)); | ||||
| } | ||||
|  | ||||
| float plantsShadow(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	// Soft shadow taken from iq | ||||
| 	float k = 6.0; | ||||
| 	float t = 0.0; | ||||
| 	float s = 1.0;	 | ||||
| 	for (int i = 0; i < 30; i++) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos+rayDir*t;	 | ||||
| 		vec2 res = scene(pos);		 | ||||
| 		if (res.x < 0.001) return 0.0; | ||||
| 		s = min(s, k*res.x/t);  | ||||
| 		t += max(res.x, 0.01); | ||||
| 	} | ||||
| 	 | ||||
| 	return s*s*(3.0 - 2.0*s); | ||||
| } | ||||
|  | ||||
| // Ray-traced parts of scene | ||||
| vec4 intersectWater(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	float h = sin(20.5 + iGlobalTime * 2.0) * 0.03; | ||||
| 	float t = -(rayPos.y + 2.5 + h) / rayDir.y; | ||||
| 	return vec4(0.0, 1.0, 0.0, t); | ||||
| } | ||||
|  | ||||
| vec4 intersectSand(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	return intersectSphere(rayPos, rayDir, vec3(0.0,-24.1,0.0), 24.1); | ||||
| } | ||||
|  | ||||
| vec4 intersectTreasure(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	return vec4(0.0); | ||||
| } | ||||
|  | ||||
| vec4 intersectLeaf(vec3 rayPos, vec3 rayDir, float openAmount) | ||||
| {	 | ||||
| 	vec3 dir = normalize(vec3(0.0, 1.0, openAmount)); | ||||
| 	float offset = 0.0; | ||||
| 			 | ||||
| 	vec4 res = intersectPlane(rayPos, rayDir, dir, 0.0); | ||||
| 	vec3 pos = rayPos+rayDir*res.w; | ||||
| 	#ifdef RAGGED_LEAVES | ||||
| 	offset = snoise(pos*0.8) * 0.3; | ||||
| 	#endif | ||||
| 	if (pos.y > 0.0 || length(pos * vec3(0.9, 2.0, 1.0)) > 4.0 - offset) res.w = 0.0; | ||||
| 	 | ||||
| 	vec4 res2 = intersectPlane(rayPos, rayDir, vec3(dir.xy, -dir.z), 0.0); | ||||
| 	pos = rayPos+rayDir*res2.w; | ||||
| 	#ifdef RAGGED_LEAVES | ||||
| 	offset = snoise(pos*0.8) * 0.3; | ||||
| 	#endif | ||||
| 	if (pos.y > 0.0 || length(pos * vec3(0.9, 2.0, 1.0)) > 4.0 - offset) res2.w = 0.0; | ||||
| 	 | ||||
| 	if (res2.w > 0.0 && res2.w < res.w || res.w <= 0.0) | ||||
| 		res = res2; | ||||
| 		 | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| vec4 leaves(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	float t = 1e20; | ||||
| 	vec3 n = vec3(0.0); | ||||
| 	 | ||||
| 	rayPos -= leavesPos; | ||||
| 	 | ||||
| 	float sway = impulse(15.0, fract(iGlobalTime / PI * 0.125)); | ||||
| 	float upDownSway = sway * -sin(iGlobalTime) * 0.06; | ||||
| 	float openAmount = sway * max(-cos(iGlobalTime) * 0.4, 0.0); | ||||
| 	 | ||||
| 	float angleOffset = -0.1;	 | ||||
| 	for (float k = 0.0; k < 6.2; k += 0.75) | ||||
| 	{ | ||||
| 		// Left-right | ||||
| 		float alpha = k + (k - PI) * sway * 0.015; | ||||
| 		vec3 p = rotate(rayPos, alpha); | ||||
| 		vec3 d = rotate(rayDir, alpha); | ||||
| 		 | ||||
| 		// Up-down | ||||
| 		angleOffset *= -1.0; | ||||
| 		float theta = -0.4 +  | ||||
| 			angleOffset +  | ||||
| 			cos(k) * 0.35 +  | ||||
| 			upDownSway +  | ||||
| 			sin(iGlobalTime+k*10.0) * 0.03 * (sway + 0.2); | ||||
| 		 | ||||
| 		p = rotate(p.xzy, theta).xzy; | ||||
| 		d = rotate(d.xzy, theta).xzy; | ||||
| 	 | ||||
| 		// Shift | ||||
| 		p -= vec3(5.4, 0.0, 0.0); | ||||
| 		 | ||||
| 		// Intersect individual leaf | ||||
| 		vec4 res = intersectLeaf(p, d, 1.0+openAmount); | ||||
| 		if (res.w > 0.0 && res.w < t) | ||||
| 		{ | ||||
| 			t = res.w; | ||||
| 			n = res.xyz; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	return vec4(n, t); | ||||
| } | ||||
|  | ||||
| // Lighting | ||||
| float shadow(vec3 rayPos, vec3 rayDir) | ||||
| {	 | ||||
| 	float s = 1.0; | ||||
| 	 | ||||
| 	// Intersect sand | ||||
| 	//vec4 resSand = intersectSand(rayPos, rayDir); | ||||
| 	//if (resSand.w > 0.0) return 0.0; | ||||
| 	 | ||||
| 	// Intersect plants | ||||
| 	s = min(s, plantsShadow(rayPos, rayDir)); | ||||
| 	if (s < 0.0001) return 0.0; | ||||
| 	 | ||||
| 	// Intersect leaves | ||||
| 	vec4 resLeaves = leaves(rayPos, rayDir); | ||||
| 	if (resLeaves.w > 0.0 && resLeaves.w < 1e7) return 0.0; | ||||
| 	 | ||||
| 	return s; | ||||
| } | ||||
|  | ||||
| vec3 light(vec3 p, vec3 n) | ||||
| { | ||||
| 	float s = 1.0; | ||||
| 	 | ||||
| 	#ifdef SHADOWS | ||||
| 	s = shadow(p-sunDir*0.01, -sunDir); | ||||
| 	#endif | ||||
| 	 | ||||
| 	vec3 col = sunCol * min(max(dot(n, sunDir), 0.0), s); | ||||
| 	col += skyCol * (-n.y * 0.5 + 0.5) * 0.3; | ||||
| 	return col; | ||||
| } | ||||
|  | ||||
| vec3 lightLeaves(vec3 p, vec3 n) | ||||
| { | ||||
| 	float s = 1.0; | ||||
| 	 | ||||
| 	#ifdef SHADOWS | ||||
| 	s = shadow(p-sunDir*0.01, -sunDir); | ||||
| 	#endif | ||||
| 	 | ||||
| 	float ao = min(length(p - leavesPos) * 0.1, 1.0); | ||||
| 	 | ||||
| 	float ns = dot(n, sunDir); | ||||
| 	float d = sqrt(max(ns, 0.0)); | ||||
| 	vec3 col = sunCol * min(d, s); | ||||
| 	col += sunCol * max(-ns, 0.0) * vec3(0.3, 0.3, 0.1) * ao; | ||||
| 	col += skyCol * (-n.y * 0.5 + 0.5) * 0.3 * ao; | ||||
| 	return col; | ||||
| } | ||||
|  | ||||
| vec3 sky(vec3 n) | ||||
| { | ||||
| 	return skyCol * (1.0 - n.y * 0.8); | ||||
| } | ||||
|  | ||||
| // Ray-marching | ||||
| vec4 plants(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	float t = 0.0; | ||||
| 	 | ||||
| 	for (int i = 0; i < 40; i++) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos+rayDir*t;	 | ||||
| 		vec2 res = scene(pos); | ||||
| 		float h = res.x; | ||||
| 		 | ||||
| 		if (h < 0.001) | ||||
| 		{ | ||||
| 			vec3 col = res.y == 2.0 ? treeCol : grassCol; | ||||
| 			float uvFact = res.y == 2.0 ? 1.0 : 10.0; | ||||
| 			 | ||||
| 			vec3 n = normal(pos); | ||||
| 			vec2 uv = vec2(n.x, pos.y * 0.5) * 0.2 * uvFact; | ||||
| 			vec3 tex = texture2D(iChannel0, uv).rgb * 0.6 + 0.4; | ||||
| 			float ao = min(length(pos - leavesPos) * 0.1, 1.0); | ||||
| 			return vec4(col * light(pos, n) * ao * tex, t); | ||||
| 		} | ||||
| 		 | ||||
| 		t += h; | ||||
| 	} | ||||
| 	 | ||||
| 	return vec4(sky(rayDir), 1e8); | ||||
| } | ||||
|  | ||||
| // Final combination | ||||
| vec3 traceReflection(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	vec3 col = vec3(0.0); | ||||
| 	float t = 1e20; | ||||
| 			 | ||||
| 	// Intersect plants | ||||
| 	vec4 resPlants = plants(rayPos, rayDir); | ||||
| 	if (resPlants.w > 0.0 && resPlants.w < t) | ||||
| 	{ | ||||
| 		t = resPlants.w; | ||||
| 		col = resPlants.xyz; | ||||
| 	} | ||||
| 	 | ||||
| 	// Intersect leaves | ||||
| 	vec4 resLeaves = leaves(rayPos, rayDir); | ||||
| 	if (resLeaves.w > 0.0 && resLeaves.w < t) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos + rayDir * resLeaves.w; | ||||
| 		vec2 uv = (pos.xz - leavesPos.xz) * 0.3; | ||||
| 		float tex = texture2D(iChannel0, uv).r * 0.6 + 0.5; | ||||
| 		 | ||||
| 		t = resLeaves.w; | ||||
| 		col = leavesCol * lightLeaves(pos, resLeaves.xyz) * tex; | ||||
| 	} | ||||
| 		 | ||||
| 	if (t > 1e7) return sky(rayDir); | ||||
| 	 | ||||
| 	return col; | ||||
| } | ||||
|  | ||||
| vec3 trace(vec3 rayPos, vec3 rayDir) | ||||
| { | ||||
| 	vec3 col = vec3(0.0); | ||||
| 	float t = 1e20; | ||||
| 	 | ||||
| 	// Intersect sand | ||||
| 	vec4 resSand = intersectSand(rayPos, rayDir); | ||||
| 	if (resSand.w > 0.0) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos + rayDir * resSand.w; | ||||
| 		t = resSand.w; | ||||
|  | ||||
| 		col = sandCol * light(pos, resSand.xyz); | ||||
| 	} | ||||
| 	 | ||||
| 	// Intersect treasure chest | ||||
| 	vec4 resTreasure = intersectTreasure(rayPos, rayDir); | ||||
| 	if (resTreasure.w > 0.0 && resTreasure.w < t) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos + rayDir * resTreasure.w; | ||||
| 		t = resTreasure.w; | ||||
| 		col = leavesCol * light(pos, resTreasure.xyz); | ||||
| 	} | ||||
| 	 | ||||
| 	// Intersect leaves | ||||
| 	vec4 resLeaves = leaves(rayPos, rayDir); | ||||
| 	if (resLeaves.w > 0.0 && resLeaves.w < t) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos + rayDir * resLeaves.w; | ||||
| 		vec2 uv = (pos.xz - leavesPos.xz) * 0.3; | ||||
| 		float tex = texture2D(iChannel0, uv).r * 0.6 + 0.5; | ||||
| 		 | ||||
| 		t = resLeaves.w; | ||||
| 		col = leavesCol * lightLeaves(pos, resLeaves.xyz) * tex; | ||||
| 	} | ||||
| 	 | ||||
| 	// Intersect plants | ||||
| 	vec4 resPlants = plants(rayPos, rayDir); | ||||
| 	if (resPlants.w > 0.0 && resPlants.w < t) | ||||
| 	{ | ||||
| 		t = resPlants.w; | ||||
| 		col = resPlants.xyz; | ||||
| 	} | ||||
| 		 | ||||
| 	// Intersect water	 | ||||
| 	vec4 resWater = intersectWater(rayPos, rayDir); | ||||
| 	if (resWater.w > 0.0 && resWater.w < t) | ||||
| 	{ | ||||
| 		vec3 pos = rayPos + rayDir * resWater.w; | ||||
| 		float dist = t - resWater.w; | ||||
| 		vec3 n = bump(pos, rayDir); | ||||
| 		 | ||||
| 		float ct = -min(dot(n,rayDir), 0.0); | ||||
| 		float fresnel = 0.9 - 0.9 * pow(1.0 - ct, 5.0); | ||||
| 		 | ||||
| 		vec3 trans = col * exp(-dist * vec3(1.0, 0.7, 0.4) * 3.0); | ||||
| 		vec3 reflDir = normalize(reflect(rayDir, n)); | ||||
| 		vec3 refl = sky(reflDir); | ||||
| 		 | ||||
| 		#ifdef REFLECTIONS | ||||
| 		if (dot(pos, rayDir) < -2.0) | ||||
| 			refl = traceReflection(pos, reflDir).rgb; | ||||
| 		#endif | ||||
| 				 | ||||
| 		t = resWater.t; | ||||
| 		col = mix(refl, trans, fresnel); | ||||
| 	} | ||||
| 	 | ||||
| 	if (t > 1e7) return sky(rayDir); | ||||
| 	 | ||||
| 	return col; | ||||
| } | ||||
|  | ||||
| // Ray-generation | ||||
| vec3 camera(vec2 px) | ||||
| { | ||||
| 	vec2 rd = (px / iResolution.yy - vec2(iResolution.x/iResolution.y*0.5-0.5, 0.0)) * 2.0 - 1.0; | ||||
| 	float t = sin(iGlobalTime * 0.1) * 0.2; | ||||
| 	vec3 rayDir = normalize(vec3(rd.x, rd.y, 1.0)); | ||||
| 	vec3 rayPos = vec3(0.0, 3.0, -18.0); | ||||
| 	return trace(rayPos, rayDir); | ||||
| } | ||||
|  | ||||
| void main(void) | ||||
| { | ||||
| 	#ifdef HEAVY_AA | ||||
| 		vec3 col = camera(gl_FragCoord.xy+vec2(0.0,0.5))*0.25; | ||||
| 		col += camera(gl_FragCoord.xy+vec2(0.25,0.0))*0.25; | ||||
| 		col += camera(gl_FragCoord.xy+vec2(0.5,0.75))*0.25; | ||||
| 		col += camera(gl_FragCoord.xy+vec2(0.75,0.25))*0.25; | ||||
| 	#else | ||||
| 		vec3 col = camera(gl_FragCoord.xy); | ||||
| 		#ifdef LIGHT_AA | ||||
| 			col = col * 0.5 + camera(gl_FragCoord.xy+vec2(0.5,0.5))*0.5; | ||||
| 		#endif | ||||
| 	#endif | ||||
| 	 | ||||
| 	#ifdef TONEMAP | ||||
| 	// Optimized Haarm-Peter Duiker’s curve | ||||
| 	vec3 x = max(vec3(0.0),col*exposure-0.004); | ||||
| 	col = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06); | ||||
| 	#else | ||||
| 	col = pow(col, vec3(0.4545)); | ||||
| 	#endif | ||||
| 	 | ||||
| 	gl_FragColor = vec4(col, 1.0); | ||||
| } | ||||
							
								
								
									
										68
									
								
								samples/GLSL/shader.fp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								samples/GLSL/shader.fp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| /* | ||||
|  * Copyright (C) 2010 Josh A. Beam | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  *   1. Redistributions of source code must retain the above copyright | ||||
|  *      notice, this list of conditions and the following disclaimer. | ||||
|  *   2. Redistributions in binary form must reproduce the above copyright | ||||
|  *      notice, this list of conditions and the following disclaimer in the | ||||
|  *      documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||||
|  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
|  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
|  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
|  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| const int NUM_LIGHTS = 3; | ||||
| const vec3 AMBIENT = vec3(0.1, 0.1, 0.1); | ||||
| const float MAX_DIST = 2.5; | ||||
| const float MAX_DIST_SQUARED = MAX_DIST * MAX_DIST; | ||||
|  | ||||
| uniform vec3 lightColor[NUM_LIGHTS]; | ||||
|  | ||||
| varying vec3 fragmentNormal; | ||||
| varying vec3 cameraVector; | ||||
| varying vec3 lightVector[NUM_LIGHTS]; | ||||
|  | ||||
| void | ||||
| main() | ||||
| { | ||||
| 	// initialize diffuse/specular lighting | ||||
| 	vec3 diffuse = vec3(0.0, 0.0, 0.0); | ||||
| 	vec3 specular = vec3(0.0, 0.0, 0.0); | ||||
|  | ||||
| 	// normalize the fragment normal and camera direction | ||||
| 	vec3 normal = normalize(fragmentNormal); | ||||
| 	vec3 cameraDir = normalize(cameraVector); | ||||
|  | ||||
| 	// loop through each light | ||||
| 	for(int i = 0; i < NUM_LIGHTS; ++i) { | ||||
| 		// calculate distance between 0.0 and 1.0 | ||||
| 		float dist = min(dot(lightVector[i], lightVector[i]), MAX_DIST_SQUARED) / MAX_DIST_SQUARED; | ||||
| 		float distFactor = 1.0 - dist; | ||||
|  | ||||
| 		// diffuse | ||||
| 		vec3 lightDir = normalize(lightVector[i]); | ||||
| 		float diffuseDot = dot(normal, lightDir); | ||||
| 		diffuse += lightColor[i] * clamp(diffuseDot, 0.0, 1.0) * distFactor; | ||||
|  | ||||
| 		// specular | ||||
| 		vec3 halfAngle = normalize(cameraDir + lightDir); | ||||
| 		vec3 specularColor = min(lightColor[i] + 0.5, 1.0); | ||||
| 		float specularDot = dot(normal, halfAngle); | ||||
| 		specular += specularColor * pow(clamp(specularDot, 0.0, 1.0), 16.0) * distFactor; | ||||
| 	} | ||||
|  | ||||
| 	vec4 sample = vec4(1.0, 1.0, 1.0, 1.0); | ||||
| 	gl_FragColor = vec4(clamp(sample.rgb * (diffuse + AMBIENT) + specular, 0.0, 1.0), sample.a); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user