Skip to content

Instantly share code, notes, and snippets.

@edom18
Created May 14, 2013 00:19
Show Gist options
  • Save edom18/5572647 to your computer and use it in GitHub Desktop.
Save edom18/5572647 to your computer and use it in GitHub Desktop.
CSS Shaderで遊ぶ
#CSS ShaderでGoogle Mapを地球儀風にしてみる
参考: [Getting started with CSS custom filters](http://alteredqualia.com/css-shaders/article/)
* {
margin: 0;
padding: 0;
border: 0;
}
body {
background: #111;
}
img {
vertical-align: top;
}
#test {
position: absolute;
width: 425px;
height: 350px;
}
<script id="vs">
precision mediump float;
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec2 a_meshCoord;
uniform mat4 u_projectionMatrix;
uniform mat4 u_transform;
uniform vec2 u_textureSize;
varying vec3 vNormal;
const float PI = 3.1415;
const float zero = 0.0;
const float one = 1.0;
/**
* @param uv texture coord.
* @param r sphere radius.
*/
vec3 computeSpherePosition(vec2 uv, float r) {
vec3 np;
float ro = uv.x * 2.0 * PI + PI * 0.5;
float fi = uv.y * PI;
np.x = r * sin(fi) * cos(ro);
np.z = -r * sin(fi) * sin(ro);
np.y = r * cos(fi);
return np;
}
void main() {
float r = u_textureSize.x / PI * 3.0;
vec2 textureSize = u_textureSize;
float aspect = textureSize.x / textureSize.y;
float sphereRadius = 0.45;
vec4 position = a_position;
// Map plane to sphere using UV coordinates
// `1.0 - a_texCoord.y` inverce unit.
vec3 spherePosition = computeSpherePosition(vec2(a_texCoord.x, 1.0 - a_texCoord.y), sphereRadius);
vec3 sphereNorm = normalize(spherePosition);
spherePosition *= vec3(one / aspect, one, one);
spherePosition.z *= r;
vNormal = normalize(sphereNorm.xyz);
gl_Position = u_projectionMatrix * u_transform * vec4(spherePosition.xyz, 1.0);
}
</script>
<script id="fs">
precision mediump float;
varying vec3 vNormal;
const float zero = 0.0;
const float one = 1.0;
void main() {
vec3 l = normalize(vec3(-one, -one, one));
vec3 eye = normalize(vec3(zero, zero, one));
vec3 hp = normalize(l + eye);
float ndoth = max(zero, dot(vNormal, hp));
float i = max(0.0, dot(vNormal, l)) + 0.1;
float specular_exponent = 15.0;
vec4 light_specular_color = vec4(one, one, one, one);
vec4 color = vec4(zero, zero, zero, zero);
if (ndoth > zero) {
color = (pow(ndoth, specular_exponent) * light_specular_color);
}
css_MixColor = vec4(i, i, i, one) + color;
}
</script>
<div id="test">
<p><iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.co.jp/?ie=UTF8&amp;ll=63.470145,141.855469&amp;spn=77.97783,270.527344&amp;t=h&amp;z=3&amp;brcurrent=3,0x34674e0fd77f192f:0xf54275d47c665244,1&amp;output=embed"></iframe><br /><small><a href="https://maps.google.co.jp/?ie=UTF8&amp;ll=63.470145,141.855469&amp;spn=77.97783,270.527344&amp;t=h&amp;z=3&amp;brcurrent=3,0x34674e0fd77f192f:0xf54275d47c665244,1&amp;source=embed" style="color:#0000FF;text-align:left">大きな地図で見る</a></small></p>
<!--p><iframe src="http://css-eblog.com/" width="1200" height="400"></iframe></p-->
</div>
do (win = window, doc = window.document) ->
getSource = (id) ->
target = doc.getElementById id
text = target.innerHTML
blob = new Blob [text]
url = webkitURL.createObjectURL blob
return url
vsUrl = getSource('vs')
fsUrl = getSource('fs')
test = doc.getElementById 'test'
angle = 0
do _loop = ->
angle = (angle + 1) % 360
test.style.webkitFilter = "custom(url(#{vsUrl}) mix(url(#{fsUrl}) multiply source-atop), 32 32, u_transform translateX(-0px) rotateX(#{angle}deg))"
setTimeout _loop, 32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment