From 2ed407b3fdc531996e630467f382a37412c80a2d Mon Sep 17 00:00:00 2001 From: Irwin Zaid Date: Fri, 7 Oct 2016 14:01:21 +0100 Subject: [PATCH 1/2] Added emulation of 3D textures --- examples/assets/compressedtexture.vert | 6 ++++ examples/assets/emulatedtexture3D.frag | 27 ++++++++++++++++++ examples/emulatedtexture3D.jl | 38 ++++++++++++++++++++++++++ src/render.jl | 3 ++ 4 files changed, 74 insertions(+) create mode 100644 examples/assets/compressedtexture.vert create mode 100644 examples/assets/emulatedtexture3D.frag create mode 100644 examples/emulatedtexture3D.jl diff --git a/examples/assets/compressedtexture.vert b/examples/assets/compressedtexture.vert new file mode 100644 index 0000000..cbd8d3a --- /dev/null +++ b/examples/assets/compressedtexture.vert @@ -0,0 +1,6 @@ +varying vec2 v_uv; + +void main() { + v_uv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); +} diff --git a/examples/assets/emulatedtexture3D.frag b/examples/assets/emulatedtexture3D.frag new file mode 100644 index 0000000..d8d7d49 --- /dev/null +++ b/examples/assets/emulatedtexture3D.frag @@ -0,0 +1,27 @@ +varying vec2 v_uv; +uniform float w; + +uniform sampler2D data; + +vec4 texture2DAs3D(sampler2D tex, vec3 texcoord) { + vec3 shape = vec3(512.0, 512.0, 2.0); + float r = 1.0; + float c = 2.0; + + // Don't let adjacent frames be interpolated into this one + texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5); + texcoord.x = max(0.5, texcoord.x) / shape.x; + + texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5); + texcoord.y = max(0.5, texcoord.y) / shape.y; + + float index = floor(texcoord.z * shape.z); + + // Do a lookup in the 2D texture + float u = (mod(index, r) + texcoord.x) / r; + float v = (floor(index / r) + texcoord.y) / c; + + return texture2D(tex, vec2(u, v)); +} + +void main() { gl_FragColor = texture2DAs3D(data, vec3(v_uv, w)); } diff --git a/examples/emulatedtexture3D.jl b/examples/emulatedtexture3D.jl new file mode 100644 index 0000000..02b6c54 --- /dev/null +++ b/examples/emulatedtexture3D.jl @@ -0,0 +1,38 @@ +import ThreeJS +import FileIO: load +import Reactive: every + +ascent = load("assets/ascent.png") +a = reinterpret(UInt8, ascent.data) + +# 1024 +#depth, width = 512, 512 +#r = 1024 // width +#c = depth // r +#if math.fmod(depth, r): +# c += 1 + +main(window) = begin + push!(window.assets,("ThreeJS","threejs")) + push!(window.assets,"nested-props") + + b = Array{UInt8}(512, 512, 2) + b[:, :, 1] = a[:, :] * 0.0 + b[:, :, 2] = a[:, :] * 1.0 + println(typeof(b)) + println(size(b)) + + ThreeJS.outerdiv() << + (ThreeJS.initscene() << + [ + ThreeJS.mesh(0.0, 0.0, 0.0) << + [ + ThreeJS.plane(512.0, 512.0), + ThreeJS.shadermaterial(open(readall, "assets/compressedtexture.vert", "r"), open(readall, "assets/emulatedtexture3D.frag", "r"); + :uniforms => Dict(:w => Dict(:type => "f", :value => 0.2))) << + ThreeJS.datatexture("data", b) + ], + ThreeJS.camera(0.0, 0.0, 768.0) + ] + ) +end diff --git a/src/render.jl b/src/render.jl index 4708ea9..dd7afbc 100644 --- a/src/render.jl +++ b/src/render.jl @@ -515,6 +515,9 @@ function datatexture(name::ASCIIString, data::Array{UInt8, 2}; kwds...) :format => "LuminanceFormat", :type => "UnsignedByteType", kwds...) end +function datatexture(name::AbstractString, data::Array{UInt8, 3}; kwds...) + datatexture(name, base64encode(data), 512, 1024; :format => "LuminanceFormat", :type => "UnsignedByteType", kwds...) +end """ Creates a point cloud tag. From 3ef08ef6e25735cd235229da189cda1b4cfc7e3d Mon Sep 17 00:00:00 2001 From: Irwin Zaid Date: Fri, 7 Oct 2016 18:05:13 +0100 Subject: [PATCH 2/2] Committing progress so far --- examples/assets/emulatedtexture3D.frag | 21 ------ examples/emulatedtexture3D.jl | 94 ++++++++++++++++++++------ src/render.jl | 2 +- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/examples/assets/emulatedtexture3D.frag b/examples/assets/emulatedtexture3D.frag index d8d7d49..e470c7c 100644 --- a/examples/assets/emulatedtexture3D.frag +++ b/examples/assets/emulatedtexture3D.frag @@ -3,25 +3,4 @@ uniform float w; uniform sampler2D data; -vec4 texture2DAs3D(sampler2D tex, vec3 texcoord) { - vec3 shape = vec3(512.0, 512.0, 2.0); - float r = 1.0; - float c = 2.0; - - // Don't let adjacent frames be interpolated into this one - texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5); - texcoord.x = max(0.5, texcoord.x) / shape.x; - - texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5); - texcoord.y = max(0.5, texcoord.y) / shape.y; - - float index = floor(texcoord.z * shape.z); - - // Do a lookup in the 2D texture - float u = (mod(index, r) + texcoord.x) / r; - float v = (floor(index / r) + texcoord.y) / c; - - return texture2D(tex, vec2(u, v)); -} - void main() { gl_FragColor = texture2DAs3D(data, vec3(v_uv, w)); } diff --git a/examples/emulatedtexture3D.jl b/examples/emulatedtexture3D.jl index 02b6c54..19ff0fd 100644 --- a/examples/emulatedtexture3D.jl +++ b/examples/emulatedtexture3D.jl @@ -2,8 +2,8 @@ import ThreeJS import FileIO: load import Reactive: every -ascent = load("assets/ascent.png") -a = reinterpret(UInt8, ascent.data) +#ascent = load("assets/ascent.png") +#a = reinterpret(UInt8, ascent.data) # 1024 #depth, width = 512, 512 @@ -12,27 +12,83 @@ a = reinterpret(UInt8, ascent.data) #if math.fmod(depth, r): # c += 1 +function emulated_size(width, height, depth) + gl_max_texture_size = 1024 + + r = div(gl_max_texture_size, height) + c = div(width, r) + + if mod(width, r) != 0 + c += 1 + end + + 1, 4 +end + +n = 4 + +a = Array(UInt8, 64, 64, n) +println(strides(a)) +println(emulated_size(size(a)...)) + +for k in 1:n + j = round(Int, k / n * size(a, 2)) + a[:, 1:j, k] = 128 + a[:, j:size(a, 2), k] = 0 +end + + +function texture2DAs3D(width::Real, height::Real, depth::Real, name = "texture2DAs3D") + r = 1.0 + c = 4.0 + + """ + vec4 $name(sampler2D tex, vec3 texcoord) { + vec3 shape = vec3($width, $height, $depth); + + // Don't let adjacent frames be interpolated into this one + texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5); + texcoord.x = max(0.5, texcoord.x) / shape.x; + + texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5); + texcoord.y = max(0.5, texcoord.y) / shape.y; + + float index = floor(texcoord.z * shape.z); + + // Do a lookup in the 2D texture + float u = (mod(index, $r) + texcoord.x) / $r; + float v = (floor(index / $r) + texcoord.y) / $c; + + return texture2D(tex, vec2(u, v)); + } + """ +end + main(window) = begin push!(window.assets,("ThreeJS","threejs")) push!(window.assets,"nested-props") - b = Array{UInt8}(512, 512, 2) - b[:, :, 1] = a[:, :] * 0.0 - b[:, :, 2] = a[:, :] * 1.0 - println(typeof(b)) - println(size(b)) + frag = string(texture2DAs3D(size(a)...), open(readall, "assets/emulatedtexture3D.frag", "r")) + + i = 0 + map(every(1)) do _ + i += 1 + if (i > size(a, 3)) + i = 1 + end - ThreeJS.outerdiv() << - (ThreeJS.initscene() << - [ - ThreeJS.mesh(0.0, 0.0, 0.0) << + ThreeJS.outerdiv() << + (ThreeJS.initscene() << [ - ThreeJS.plane(512.0, 512.0), - ThreeJS.shadermaterial(open(readall, "assets/compressedtexture.vert", "r"), open(readall, "assets/emulatedtexture3D.frag", "r"); - :uniforms => Dict(:w => Dict(:type => "f", :value => 0.2))) << - ThreeJS.datatexture("data", b) - ], - ThreeJS.camera(0.0, 0.0, 768.0) - ] - ) + ThreeJS.mesh(0.0, 0.0, 0.0) << + [ + ThreeJS.plane(size(a, 1), size(a, 2)), + ThreeJS.shadermaterial(open(readall, "assets/compressedtexture.vert", "r"), frag; + :uniforms => Dict(:w => Dict(:type => "f", :value => i / size(a, 3)))) << + ThreeJS.datatexture("data", a) + ], + ThreeJS.camera(0.0, 0.0, 768.0) + ] + ) + end end diff --git a/src/render.jl b/src/render.jl index dd7afbc..4e314dc 100644 --- a/src/render.jl +++ b/src/render.jl @@ -516,7 +516,7 @@ function datatexture(name::ASCIIString, data::Array{UInt8, 2}; kwds...) end function datatexture(name::AbstractString, data::Array{UInt8, 3}; kwds...) - datatexture(name, base64encode(data), 512, 1024; :format => "LuminanceFormat", :type => "UnsignedByteType", kwds...) + datatexture(name, base64encode(data), 64 * 1, 64 * 4; :format => "LuminanceFormat", :type => "UnsignedByteType", kwds...) end """