lib/mittsu/renderers/shaders/shader_lib.rb in mittsu-0.1.1 vs lib/mittsu/renderers/shaders/shader_lib.rb in mittsu-0.1.2
- old
+ new
@@ -1,420 +1,43 @@
require 'mittsu/renderers/shaders/uniforms_utils'
require 'mittsu/renderers/shaders/uniforms_lib'
require 'mittsu/renderers/shaders/shader_chunk'
+require 'mittsu/renderers/shaders/rbsl_loader'
module Mittsu
class ShaderLib_Instance
attr_accessor :uniforms, :vertex_shader, :fragment_shader
def initialize(options = {})
@uniforms = options.fetch(:uniforms)
@vertex_shader = options.fetch(:vertex_shader)
@fragment_shader = options.fetch(:fragment_shader)
end
+
+ def self.load_from_file(name)
+ ShaderLib_Instance.new(
+ uniforms: RBSLLoader.load_uniforms(File.read(File.join(__dir__, 'shader_lib', name, "#{name}_uniforms.rbslu")), UniformsLib),
+ vertex_shader: RBSLLoader.load_shader(File.read(File.join(__dir__, 'shader_lib', name, "#{name}_vertex.rbsl")), ShaderChunk),
+ fragment_shader: RBSLLoader.load_shader(File.read(File.join(__dir__, 'shader_lib', name, "#{name}_fragment.rbsl")), ShaderChunk)
+ )
+ end
end
+ private_constant :ShaderLib_Instance
- ShaderLib = {
- basic: ShaderLib_Instance.new(
- uniforms: UniformsUtils.merge([
- UniformsLib[:common],
- UniformsLib[:fog],
- UniformsLib[:shadowmap]
- ]),
+ SHADER_LIB_HASH = Hash.new { |h, k|
+ h[k] = ShaderLib_Instance.load_from_file(k.to_s)
+ }
- vertex_shader: [
- ShaderChunk[:common],
- ShaderChunk[:map_pars_vertex],
- ShaderChunk[:lightmap_pars_vertex],
- ShaderChunk[:envmap_pars_vertex],
- ShaderChunk[:color_pars_vertex],
- ShaderChunk[:morphtarget_pars_vertex],
- ShaderChunk[:skinning_pars_vertex],
- ShaderChunk[:shadowmap_pars_vertex],
- ShaderChunk[:logdepthbuf_pars_vertex],
+ class ShaderLib
+ def self.create_shader(id, options={})
+ shader = self[id]
+ {
+ uniforms: UniformsUtils.clone(shader.uniforms),
+ vertex_shader: shader.vertex_shader,
+ fragment_shader: shader.fragment_shader
+ }.merge(options)
+ end
- "void main() {",
-
- ShaderChunk[:map_vertex],
- ShaderChunk[:lightmap_vertex],
- ShaderChunk[:color_vertex],
- ShaderChunk[:skinbase_vertex],
-
- " #ifdef USE_ENVMAP",
-
- ShaderChunk[:morphnormal_vertex],
- ShaderChunk[:skinnormal_vertex],
- ShaderChunk[:defaultnormal_vertex],
-
- " #endif",
-
- ShaderChunk[:morphtarget_vertex],
- ShaderChunk[:skin_vertex],
- ShaderChunk[:default_vertex],
- ShaderChunk[:logdepthbuf_vertex],
-
- ShaderChunk[:worldpos_vertex],
- ShaderChunk[:envmap_vertex],
- ShaderChunk[:shadowmap_vertex],
-
- "}"
-
- ].join("\n"),
-
- fragment_shader: [
-
- "uniform vec3 diffuse;",
- "uniform float opacity;",
-
- ShaderChunk[:common],
- ShaderChunk[:color_pars_fragment],
- ShaderChunk[:map_pars_fragment],
- ShaderChunk[:alphamap_pars_fragment],
- ShaderChunk[:lightmap_pars_fragment],
- ShaderChunk[:envmap_pars_fragment],
- ShaderChunk[:fog_pars_fragment],
- ShaderChunk[:shadowmap_pars_fragment],
- ShaderChunk[:specularmap_pars_fragment],
- ShaderChunk[:logdepthbuf_pars_fragment],
-
- "void main() {",
-
- " vec3 outgoingLight = vec3( 0.0 );", # outgoing light does not have an alpha, the surface does
- " vec4 diffuseColor = vec4( diffuse, opacity );",
-
- ShaderChunk[:logdepthbuf_fragment],
- ShaderChunk[:map_fragment],
- ShaderChunk[:color_fragment],
- ShaderChunk[:alphamap_fragment],
- ShaderChunk[:alphatest_fragment],
- ShaderChunk[:specularmap_fragment],
-
- " outgoingLight = diffuseColor.rgb;", # simple shader
-
- ShaderChunk[:lightmap_fragment], # TODO: Light map on an otherwise unlit surface doesn't make sense.
- ShaderChunk[:envmap_fragment],
- ShaderChunk[:shadowmap_fragment], # TODO: Shadows on an otherwise unlit surface doesn't make sense.
-
- ShaderChunk[:linear_to_gamma_fragment],
-
- ShaderChunk[:fog_fragment],
-
- " fragColor = vec4( outgoingLight, diffuseColor.a );", # TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
-
- "}"
-
- ].join("\n")
- ),
- lambert: ShaderLib_Instance.new(
- uniforms: UniformsUtils.merge([
- UniformsLib[:common],
- UniformsLib[:fog],
- UniformsLib[:lights],
- UniformsLib[:shadow_map],
- {
- 'emissive' => Uniform.new(:c, Color.new(0x000000)),
- 'wrapRGB' => Uniform.new(:v3, Vector3.new(1.0, 1.0, 1.0))
- }
- ]),
- vertex_shader: [
- '#define LAMBERT',
- 'out vec3 vLightFront;',
- '#ifdef DOUBLE_SIDED',
- ' out vec3 vLightBack;',
- '#endif',
- ShaderChunk[:common],
- ShaderChunk[:map_pars_vertex],
- ShaderChunk[:lightmap_pars_vertex],
- ShaderChunk[:envmap_pars_vertex],
- ShaderChunk[:lights_lambert_pars_vertex],
- ShaderChunk[:color_pars_vertex],
- ShaderChunk[:morphtarget_pars_vertex],
- ShaderChunk[:skinning_pars_vertex],
- ShaderChunk[:shadowmap_pars_vertex],
- ShaderChunk[:logdepthbuf_pars_vertex],
- 'void main() {',
-
- ShaderChunk[:map_vertex],
- ShaderChunk[:lightmap_vertex],
- ShaderChunk[:color_vertex],
-
- ShaderChunk[:morphnormal_vertex],
- ShaderChunk[:skinbase_vertex],
- ShaderChunk[:skinnormal_vertex],
- ShaderChunk[:defaultnormal_vertex],
-
- ShaderChunk[:morphtarget_vertex],
- ShaderChunk[:skinning_vertex],
- ShaderChunk[:default_vertex],
- ShaderChunk[:logdepthbuf_vertex],
-
- ShaderChunk[:worldpos_vertex],
- ShaderChunk[:envmap_vertex],
- ShaderChunk[:lights_lambert_vertex],
- ShaderChunk[:shadowmap_vertex],
-
- '}',
- ].join("\n"),
- fragment_shader: [
- 'uniform vec3 diffuse;',
- 'uniform vec3 emissive;',
- 'uniform float opacity;',
-
- 'in vec3 vLightFront;',
-
- '#ifdef DOUBLE_SIDED',
- ' in vec3 vLightBack;',
- '#endif',
-
- ShaderChunk[:common],
- ShaderChunk[:color_pars_fragment],
- ShaderChunk[:map_pars_fragment],
- ShaderChunk[:alphamap_pars_fragment],
- ShaderChunk[:lightmap_pars_fragment],
- ShaderChunk[:envmap_pars_fragment],
- ShaderChunk[:fog_pars_fragment],
- ShaderChunk[:shadowmap_pars_fragment],
- ShaderChunk[:specularmap_pars_fragment],
- ShaderChunk[:logdepthbuf_pars_fragment],
-
- 'void main() {',
-
- ' vec3 outgoingLight = vec3( 0.0 );', # outgoing light does not have an alpha, the surface does
- ' vec4 diffuseColor = vec4( diffuse, opacity );',
-
- ShaderChunk[:logdepthbuf_fragment],
- ShaderChunk[:map_fragment],
- ShaderChunk[:color_fragment],
- ShaderChunk[:alphamap_fragment],
- ShaderChunk[:alphatest_fragment],
- ShaderChunk[:specularmap_fragment],
-
- ' #ifdef DOUBLE_SIDED',
-
- #'float isFront = float( gl_FrontFacing );',
- #'fragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;',
-
- ' if ( gl_FrontFacing )',
- ' outgoingLight += diffuseColor.rgb * vLightFront + emissive;',
- ' else',
- ' outgoingLight += diffuseColor.rgb * vLightBack + emissive;',
-
- ' #else',
-
- ' outgoingLight += diffuseColor.rgb * vLightFront + emissive;',
-
- ' #endif',
-
- ShaderChunk[:lightmap_fragment],
- ShaderChunk[:envmap_fragment],
- ShaderChunk[:shadowmap_fragment],
-
- ShaderChunk[:linear_to_gamma_fragment],
-
- ShaderChunk[:fog_fragment],
-
- # ' fragColor = vec4( outgoingLight, diffuseColor.a );', # TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
-
- ' fragColor = vec4(outgoingLight, diffuseColor.a);',
- '}'
- ].join("\n")
- ),
- phong: ShaderLib_Instance.new(
- uniforms: UniformsUtils.merge([
- UniformsLib[:common],
- UniformsLib[:bump],
- UniformsLib[:normal_map],
- UniformsLib[:fog],
- UniformsLib[:lights],
- UniformsLib[:shadow_map],
- {
- 'emissive' => Uniform.new(:c, Color.new(0x000000)),
- 'specular' => Uniform.new(:c, Color.new(0x111111)),
- 'shininess' => Uniform.new(:f, 30.0),
- 'wrapRGB' => Uniform.new(:v3, Vector3.new(1.0, 1.0, 1.0))
- }
- ]),
- vertex_shader: [
- '#define PHONG',
- 'out vec3 vViewPosition;',
- '#ifndef FLAT_SHADED',
- ' out vec3 vNormal;',
- '#endif',
-
- ShaderChunk[:common],
- ShaderChunk[:map_pars_vertex],
- ShaderChunk[:lightmap_pars_vertex],
- ShaderChunk[:envmap_pars_vertex],
- ShaderChunk[:lights_phong_pars_vertex],
- ShaderChunk[:color_pars_vertex],
- ShaderChunk[:morphtarget_pars_vertex],
- ShaderChunk[:skinning_pars_vertex],
- ShaderChunk[:shadowmap_pars_vertex],
- ShaderChunk[:logdepthbuf_pars_vertex],
-
- 'void main() {',
-
- ShaderChunk[:map_vertex],
- ShaderChunk[:lightmap_vertex],
- ShaderChunk[:color_vertex],
-
- ShaderChunk[:morphnormal_vertex],
- ShaderChunk[:skinbase_vertex],
- ShaderChunk[:skinnormal_vertex],
- ShaderChunk[:defaultnormal_vertex],
-
- '#ifndef FLAT_SHADED', # Normal computed with derivatives when FLAT_SHADED
- ' vNormal = normalize( transformedNormal );',
- '#endif',
-
- ShaderChunk[:morphtarget_vertex],
- ShaderChunk[:skinning_vertex],
- ShaderChunk[:default_vertex],
- ShaderChunk[:logdepthbuf_vertex],
-
- ' vViewPosition = -mvPosition.xyz;',
-
- ShaderChunk[:worldpos_vertex],
- ShaderChunk[:envmap_vertex],
- ShaderChunk[:lights_phong_vertex],
- ShaderChunk[:shadowmap_vertex],
- '}'
- ].join("\n"),
- fragment_shader: [
- '#define PHONG',
-
- 'uniform vec3 diffuse;',
- 'uniform vec3 emissive;',
- 'uniform vec3 specular;',
- 'uniform float shininess;',
- 'uniform float opacity;',
-
- ShaderChunk[:common],
- ShaderChunk[:color_pars_fragment],
- ShaderChunk[:map_pars_fragment],
- ShaderChunk[:alphamap_pars_fragment],
- ShaderChunk[:lightmap_pars_fragment],
- ShaderChunk[:envmap_pars_fragment],
- ShaderChunk[:fog_pars_fragment],
- ShaderChunk[:lights_phong_pars_fragment],
- ShaderChunk[:shadowmap_pars_fragment],
- ShaderChunk[:bumpmap_pars_fragment],
- ShaderChunk[:normalmap_pars_fragment],
- ShaderChunk[:specularmap_pars_fragment],
- ShaderChunk[:logdepthbuf_pars_fragment],
-
- 'void main() {',
-
- ' vec3 outgoingLight = vec3( 0.0 );', # outgoing light does not have an alpha, the surface does
- ' vec4 diffuseColor = vec4( diffuse, opacity );',
-
- ShaderChunk[:logdepthbuf_fragment],
- ShaderChunk[:map_fragment],
- ShaderChunk[:color_fragment],
- ShaderChunk[:alphamap_fragment],
- ShaderChunk[:alphatest_fragment],
- ShaderChunk[:specularmap_fragment],
-
- ShaderChunk[:lights_phong_fragment],
-
- ShaderChunk[:lightmap_fragment],
- ShaderChunk[:envmap_fragment],
- ShaderChunk[:shadowmap_fragment],
-
- ShaderChunk[:linear_to_gamma_fragment],
-
- ShaderChunk[:fog_fragment],
-
- ' fragColor = vec4( outgoingLight, diffuseColor.a );', # TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
-
- '}'
- ].join("\n")
- ),
- # TODO:
- # particle_basic
- # dashed
- # depth
- # normal
- cube: ShaderLib_Instance.new(
- uniforms: {
- 'tCube' => Uniform.new(:t, nil),
- 'tFlip' => Uniform.new(:f, -1.0)
- },
- vertex_shader: [
- 'out vec3 vWorldPosition;',
-
- ShaderChunk[:common],
- ShaderChunk[:logdepthbuf_pars_vertex],
-
- 'void main() {',
- ' vWorldPosition = transformDirection( position, modelMatrix );',
- ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
- ShaderChunk[:logdepthbuf_vertex],
- '}'
- ].join("\n"),
- fragment_shader: [
- 'uniform samplerCube tCube;',
- 'uniform float tFlip;',
-
- 'in vec3 vWorldPosition;',
-
- ShaderChunk[:common],
- ShaderChunk[:logdepthbuf_pars_fragment],
-
- 'void main() {',
- ' fragColor = texture( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );',
- ShaderChunk[:logdepthbuf_fragment],
- '}'
- ].join("\n")
- ),
- # equirect
- depth_rgba: ShaderLib_Instance.new(
- uniforms: {},
- vertex_shader: [
- ShaderChunk[:common],
- ShaderChunk[:morphtarget_pars_vertex],
- ShaderChunk[:skinning_pars_vertex],
- ShaderChunk[:logdepthbuf_pars_vertex],
-
- 'void main() {',
- ShaderChunk[:skinbase_vertex],
- ShaderChunk[:morphtarget_vertex],
- ShaderChunk[:skinning_vertex],
- ShaderChunk[:default_vertex],
- ShaderChunk[:logdepthbuf_vertex],
- '}'
- ].join("\n"),
- fragment_shader: [
- ShaderChunk[:common],
- ShaderChunk[:logdepthbuf_pars_fragment],
-
- 'vec4 pack_depth( const in float depth ) {',
-
- ' const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );',
- ' const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );',
- ' vec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );', # ' vec4 res = fract( depth * bit_shift );',
- ' res -= res.xxyz * bit_mask;',
- ' return res;',
-
- '}',
-
- 'void main() {',
- ShaderChunk[:logdepthbuf_fragment],
-
- ' #ifdef USE_LOGDEPTHBUF_EXT',
-
- ' fragColor = pack_depth( gl_FragDepthEXT );',
-
- ' #else',
-
- ' fragColor = pack_depth( gl_FragCoord.z );',
-
- ' #endif',
-
- #'fragColor = pack_depth( gl_FragCoord.z / gl_FragCoord.w );',
- #'float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );',
- #'fragColor = pack_depth( z );',
- #'fragColor = vec4( z, z, z, 1.0 );',
- '}'
- ].join("\n")
- )
- }
+ def self.[](id)
+ SHADER_LIB_HASH[id]
+ end
+ end
end