Last active
May 8, 2016 01:50
-
-
Save wanabe/8564e6b9fa804e27b250f1c785906792 to your computer and use it in GitHub Desktop.
Three.js on Opal test with sepated files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #three-canvas { | |
| height: 100%; | |
| width: 100%; | |
| } | |
| html { | |
| height: 100%; | |
| } | |
| body { | |
| height: 100%; | |
| margin: 0px; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class MyVertexShader < VertexShader | |
| def main | |
| gl_Position = vec4( position, 1.0 ) | |
| end | |
| end | |
| class MyFragmentShader < FragmentShader | |
| def main(resolution = vec2, time = float) | |
| p = vec2 -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy | |
| a = float time * 40.0 | |
| g = float 1.0 / 40.0 | |
| d = e = f = h = i = r = q = float | |
| e = 400.0 * (p.x * 0.5 + 0.5) | |
| f = 400.0 * (p.y * 0.5 + 0.5) | |
| i = 200.0 + sin(e * g + a / 150.0) * 20.0 | |
| d = 200.0 + cos(f * g / 2.0) * 18.0 + cos(e * g) * 7.0 | |
| r = sqrt(pow(abs(i - e), 2.0) + pow(abs(d - f), 2.0)) | |
| q = f / r | |
| e = (r * cos(q)) - a / 2.0 | |
| f = (r * sin(q)) - a / 2.0 | |
| d = sin(e * g) * 176.0 + sin(e * g) * 164.0 + r | |
| h = ((f + d) + a / 2.0) * g | |
| i = cos(h + r * p.x / 1.3) * (e + e + a) + cos(q * g * 6.0) * (r + h / 3.0) | |
| h = sin(f * g) * 144.0 - sin(e * g) * 212.0 * p.x | |
| h = (h + (f - e) * q + sin(r - (a + h) / 7.0) * 10.0 + i / 4.0) * g | |
| i += cos(h * 2.3 * sin(a / 350.0 - q)) * 184.0 * sin(q - (r * 4.3 + a / 12.0) * g) + tan(r * g + h) * 184.0 * cos(r * g + h) | |
| i = mod(i / 5.6, 256.0) / 64.0 | |
| i += 4.0 if i < 0.0 | |
| i = 4.0 - i if i >= 2.0 | |
| d = r / 350.0 | |
| d += sin(d * d * 8.0) * 0.52 | |
| f = (sin(a * g) + 1.0) / 2.0 | |
| gl_FragColor = vec4(vec3(f * i / 1.6, i / 2.0 + d / 13.0, i) * d * p.x + vec3(i / 1.3 + d / 8.0, i / 2.0 + d / 18.0, i) * d * (1.0 - p.x), 1.0) | |
| end | |
| end | |
| class MyApp < App | |
| def initialize | |
| @margin = 10 | |
| super | |
| @container.on :click do |event| | |
| @running = !@running | |
| animate if @running | |
| end | |
| @camera.position.z = 1 | |
| geometry = THREE::PlaneGeometry.new(2, 2) | |
| vertex_shader = MyVertexShader.new | |
| fragment_shader = MyFragmentShader.new(time: 1.0, resolution: THREE::Vector2.new) | |
| @uniforms = fragment_shader.uniforms | |
| material_arg = { | |
| uniforms: @uniforms, | |
| vertexShader: vertex_shader.to_s, | |
| fragmentShader: fragment_shader.to_s | |
| } | |
| material = THREE::ShaderMaterial.new material_arg | |
| mesh = THREE::Mesh.new geometry, material | |
| @scene.add mesh | |
| @sensor = ResizeSensor.new(@container, method("on_resize")) | |
| end | |
| def render | |
| @uniforms.time.value += 0.05 | |
| end | |
| def on_resize | |
| @renderer.set_size @container.width - @margin, @container.height - @margin | |
| @uniforms.resolution.value.x = @renderer.domElement.width | |
| @uniforms.resolution.value.y = @renderer.domElement.height | |
| end | |
| end | |
| MyApp.run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <link rel="stylesheet" href="app.css"> | |
| <script src="//cdn.opalrb.org/opal/0.9.2/opal.min.js"></script> | |
| <script src="//cdn.opalrb.org/opal/0.9.2/opal-parser.min.js"></script> | |
| <script src="//cdn.opalrb.org/opal/0.9.2/external/opal-browser-0.2.0.js"></script> | |
| <script src="https://raw.githubusercontent.com/mrdoob/three.js/r76/build/three.min.js"></script> | |
| <script src="https://raw.githubusercontent.com/marcj/css-element-queries/master/src/ResizeSensor.js"></script> | |
| <script>Opal.load('opal-parser')</script> | |
| <script type="text/ruby" src="native_class.rb"></script> | |
| <script type="text/ruby" src="three.rb"></script> | |
| <script type="text/ruby" src="resize_sensor.rb"></script> | |
| <script type="text/ruby" src="three_ext.rb"></script> | |
| <script type="text/ruby" src="app.rb"></script> | |
| </head> | |
| <body> | |
| <div id="three-canvas"></div> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class NativeClass | |
| include Native | |
| def initialize(*args) | |
| @native = native(*args) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class ResizeSensor < NativeClass | |
| def native(element, proc) | |
| element = element.to_n | |
| proc = proc.to_proc unless proc.is_a? Proc | |
| `new ResizeSensor(element, proc)` | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module THREE | |
| class Base < NativeClass | |
| end | |
| class Camera < Base | |
| def native | |
| `new THREE.Camera()` | |
| end | |
| alias_native :position | |
| end | |
| class Scene < Base | |
| def native | |
| `new THREE.Scene()` | |
| end | |
| alias_native :add | |
| end | |
| class WebGLRenderer < Base | |
| def native | |
| `new THREE.WebGLRenderer()` | |
| end | |
| alias_native :pixel_ratio=, :setPixelRatio | |
| alias_native :domElement | |
| alias_native :set_size, :setSize | |
| alias_native :render | |
| end | |
| class PlaneGeometry < Base | |
| def native(width, height, width_segments = nil, height_segments = nil) | |
| `new THREE.PlaneGeometry(width, height, width_segments, height_segments)` | |
| end | |
| end | |
| class ShaderMaterial < Base | |
| def native(parameters) | |
| parameters = parameters.to_n | |
| `new THREE.ShaderMaterial(parameters)` | |
| end | |
| end | |
| class Mesh < Base | |
| def native(geometry, material) | |
| geometry, material = geometry.to_n, material.to_n | |
| `new THREE.Mesh(geometry, material)` | |
| end | |
| end | |
| class Vector2 < Base | |
| def native | |
| `new THREE.Vector2()` | |
| end | |
| alias_native :x | |
| alias_native :y | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class App | |
| class << self | |
| def run | |
| new.animate | |
| end | |
| end | |
| def initialize | |
| @camera = THREE::Camera.new | |
| @scene = THREE::Scene.new | |
| @renderer = THREE::WebGLRenderer.new | |
| @renderer.pixel_ratio = $$.devicePixelRatio | |
| @container = $document['three-canvas'] | |
| @container << @renderer.domElement.to_n | |
| @renderer.set_size @container.width, @container.height | |
| @animate = method(:animate).to_proc | |
| @running = true | |
| end | |
| def animate | |
| return unless @running | |
| $$.requestAnimationFrame @animate | |
| render | |
| @renderer.render(@scene, @camera) | |
| end | |
| end | |
| class Shader | |
| BRACE_TABLE = { "(" => [1, 0], ")" => [-1, 1], "," => [0, 0] } | |
| OP_TABLE = { | |
| "plus" => "+", "minus" => "-", "times" => "*", "divide" => "/", | |
| "lt" => "<", "gt" => "<", "le" => "<=", "ge" => ">=" | |
| } | |
| TYPE_TABLE = { "float" => "f", "vec2" => "v2" } | |
| def initialize(**initial_values) | |
| @initial_values = initial_values | |
| parse | |
| end | |
| def to_s | |
| @shader | |
| end | |
| def uniforms | |
| uniforms = Native(@uniforms.to_n) | |
| @initial_values.each do |name, value| | |
| uniforms[name].value = value | |
| end | |
| uniforms | |
| end | |
| private | |
| def parse | |
| meth = method(:main) | |
| c = 0 | |
| str = `String(meth.method)` | |
| .sub(/function */, 'void main') | |
| .sub(/ *var( .*)? self = .*\n *\n/, '') | |
| .gsub(/ return /, ' ') | |
| .gsub(/(gl_Position|gl_FragColor)\$/) { $1 } | |
| .gsub(/[(),]/) { | |
| d, o = BRACE_TABLE[$&] | |
| c += d | |
| "#{$&}<#{c + o}>" | |
| } | |
| str = str.sub(/void main\(<1>(.+?)\)<1>/, "void main(<1>)<1>") | |
| if $1 | |
| uniforms = $1.split(/,<1> /) | |
| @uniforms = {} | |
| uniforms.each_with_index do |uniform, i| | |
| str = str.sub(/ *if \(<1>#{uniform} == null\)<1> {\n *#{uniform} = self\.\$([^()]+)\(<1>\)<1>\n *}\n/, "") | |
| raise "shader parse error" unless $1 | |
| str = "uniform #{$1} #{uniform};\n" + str | |
| @uniforms[uniform] = { type: TYPE_TABLE[$1] } | |
| end | |
| end | |
| str = str | |
| .gsub(/( *)(.*) = self.\$(float)\(<\d+>\)<\d+>;$/) { | |
| "#{$1}#{$3} #{$2.gsub(/ += +/, ', ')};" | |
| } | |
| .gsub(/^( *)(\w+) = self.\$(float|vec[2])\(<1>(.*?)\)<1>;$/) { | |
| "#{$1}#{$3} #{$2} = #{$4};" | |
| } | |
| .gsub(/(?:self\.|(\.))?\$([^()]*)\(<\d+>\)<\d+>/) { | |
| "#{$1}#{$2}" | |
| } | |
| .gsub(/if \(<1>\(<2>\(<3>\$a = (.*?)\)<3> !== nil && \(<3>!\$a.\$\$is_boolean \|\| \$a == true\)<3>\)<2>\)<1> {/) { | |
| "if (#{$1}) {" | |
| } | |
| .gsub(/ ( *)(.*)};/) { | |
| " #{$1}#{$2};\n#{$1}}" | |
| } | |
| .gsub(/([>\- ])(\d+)([), ])/) { | |
| "#{$1}#{$2}.0#{$3}" | |
| } | |
| str2 = nil | |
| while str != str2 | |
| str = str2 || str | |
| str2 = str | |
| .gsub(/\$rb_(plus|minus|times|divide|lt|le|gt|ge)\(<(\d+)>(.*?),<\2> *(.*?)\)<\2>/) { | |
| "#{$3} #{OP_TABLE[$1]} #{$4}" | |
| } | |
| .gsub(/self\.\$([^()]+)\(<(\d+)>(.*?)\)<\2>/) { | |
| "#{$1}(#{$3})" | |
| } | |
| end | |
| @shader = str.gsub(/([(),])<\d+>/) { $1 } | |
| end | |
| end | |
| class VertexShader < Shader | |
| end | |
| class FragmentShader < Shader | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment