ソースを参照

Material system updated.

Mark Sibly 8 年 前
コミット
1fec011140

+ 21 - 1
modules/mojo/graphics/uniformblock.monkey2

@@ -220,8 +220,25 @@ Class UniformBlock Extends Resource
 
 
 	'***** Texture *****
 	'***** Texture *****
 	'
 	'
+	Property NumTextures:Int()
+		
+		Return _ntextures
+	End
+	
+	Property DefaultTexture:Texture()
+		
+		Return _defaultTexture
+	
+	Setter( texture:Texture )
+		
+		_defaultTexture=texture
+	End
+	
 	Method SetTexture( uniform:String,value:Texture )
 	Method SetTexture( uniform:String,value:Texture )
 		Local id:=GetUniformId( uniform )
 		Local id:=GetUniformId( uniform )
+		If (value<>Null)<>(_uniforms[id].texture<>Null)
+			If value _ntextures+=1 Else _ntextures-=1
+		End
 		_uniforms[id].texture=value
 		_uniforms[id].texture=value
 		_uniforms[id].type=Type.Texture
 		_uniforms[id].type=Type.Texture
 		_seq=_gseq
 		_seq=_gseq
@@ -236,7 +253,8 @@ Class UniformBlock Extends Resource
 	
 	
 	Method GetTexture:Texture( id:Int )
 	Method GetTexture:Texture( id:Int )
 		DebugAssert( _uniforms[id].type=Type.Texture,"Invalid uniform type" )
 		DebugAssert( _uniforms[id].type=Type.Texture,"Invalid uniform type" )
-		Return _uniforms[id].texture
+		Local texture:=_uniforms[id].texture
+		Return texture ? texture Else _defaultTexture
 	End
 	End
 	
 	
 	#rem monkeydoc @hidden
 	#rem monkeydoc @hidden
@@ -283,6 +301,8 @@ Class UniformBlock Extends Resource
 	Field _seq:Int
 	Field _seq:Int
 	Field _linearColors:bool
 	Field _linearColors:bool
 	Field _uniforms:=New Uniform[64]
 	Field _uniforms:=New Uniform[64]
+	Field _ntextures:Int
+	Field _defaultTexture:Texture
 	
 	
 	Method SetData<T>( uniform:String,data:T,type:Type )
 	Method SetData<T>( uniform:String,data:T,type:Type )
 		Local id:=GetUniformId( uniform )
 		Local id:=GetUniformId( uniform )

+ 1 - 3
modules/mojo3d-loaders/loaders/assimp.monkey2

@@ -221,9 +221,7 @@ Class AssimpLoader
 		aiGetMaterialColor( aimaterial,AI_MATKEY_COLOR_DIFFUSE,0,0,Varptr aicolor )
 		aiGetMaterialColor( aimaterial,AI_MATKEY_COLOR_DIFFUSE,0,0,Varptr aicolor )
 		diffuseColor=New Color( Pow( aicolor.r,2.2 ),Pow( aicolor.g,2.2 ),Pow( aicolor.b,2.2 ),aicolor.a )
 		diffuseColor=New Color( Pow( aicolor.r,2.2 ),Pow( aicolor.g,2.2 ),Pow( aicolor.b,2.2 ),aicolor.a )
 
 
-		Local textured:=diffuseTexture<>Null
-
-		Local material:=New PbrMaterial( textured,False,boned )
+		Local material:=New PbrMaterial( boned )
 		
 		
 		If diffuseTexture material.ColorTexture=diffuseTexture
 		If diffuseTexture material.ColorTexture=diffuseTexture
 		material.ColorFactor=diffuseColor
 		material.ColorFactor=diffuseColor

+ 1 - 4
modules/mojo3d/graphics/gltf2loader.monkey2

@@ -115,10 +115,7 @@ Class Gltf2Loader
 			normalTexture=GetTexture( material.normalTexture )
 			normalTexture=GetTexture( material.normalTexture )
 		Endif
 		Endif
 			
 			
-		local bumpmapped:=normalTexture<>Null
-		Local boned:=False
-
-		Local mat:=New PbrMaterial( textured,bumpmapped,boned )
+		Local mat:=New PbrMaterial
 
 
 		mat.ColorFactor=New Color( material.baseColorFactor.x,material.baseColorFactor.y,material.baseColorFactor.z )
 		mat.ColorFactor=New Color( material.baseColorFactor.x,material.baseColorFactor.y,material.baseColorFactor.z )
 		mat.MetalnessFactor=material.metallicFactor
 		mat.MetalnessFactor=material.metallicFactor

+ 29 - 9
modules/mojo3d/graphics/material.monkey2

@@ -6,7 +6,8 @@ Namespace mojo3d.graphics
 Class Material Extends Resource
 Class Material Extends Resource
 	
 	
 	Method New()
 	Method New()
-	
+
+		_shader=Null	
 		_uniforms=New UniformBlock( 3,True )
 		_uniforms=New UniformBlock( 3,True )
 		_blendMode=BlendMode.Opaque
 		_blendMode=BlendMode.Opaque
 		_cullMode=CullMode.Back
 		_cullMode=CullMode.Back
@@ -17,7 +18,8 @@ Class Material Extends Resource
 	#rem monkeydoc Creates a new material
 	#rem monkeydoc Creates a new material
 	#end
 	#end
 	Method New( shader:Shader )
 	Method New( shader:Shader )
-		Self.New()
+		Self.new()
+		
 		_shader=shader
 		_shader=shader
 	End
 	End
 	
 	
@@ -102,10 +104,33 @@ Class Material Extends Resource
 		
 		
 		TextureMatrix=TextureMatrix.Scale( sx,sy )
 		TextureMatrix=TextureMatrix.Scale( sx,sy )
 	End
 	End
+	
+	Method ValidateShader:Shader()
+		
+		If Not _shader _shader=OnValidateShader()
+			
+		Return _shader
+	End
 
 
 	Protected
 	Protected
-	#rem monkeydoc @hidden
-	#end
+	
+	Method OnValidateShader:Shader() Virtual
+		
+		RuntimeError( "Material.OnValidateShader unimplemented" )
+		
+		Return Null
+	End
+	
+	Method InvalidateShader()
+		
+		_shader=Null
+	End
+	
+	Method SetShader( shader:Shader )
+		
+		_shader=shader
+	End
+	
 	Method New( material:Material )
 	Method New( material:Material )
 
 
 		_shader=material._shader
 		_shader=material._shader
@@ -117,11 +142,6 @@ Class Material Extends Resource
 		TextureMatrix=material.TextureMatrix
 		TextureMatrix=material.TextureMatrix
 	End
 	End
 	
 	
-	Method SetShader( shader:Shader )
-		
-		_shader=shader
-	End
-	
 	Private
 	Private
 
 
 	Field _shader:Shader
 	Field _shader:Shader

+ 104 - 69
modules/mojo3d/graphics/pbrmaterial.monkey2

@@ -7,7 +7,9 @@ Class PbrMaterial Extends Material
 	
 	
 	#rem monkeydoc Creates a new pbr material.
 	#rem monkeydoc Creates a new pbr material.
 	
 	
-	All properties default to white or '1' except for emissive factor which defaults to black. If you set an emissive texture, don't forget to set emissive factor to white to 'enable' it.
+	All properties default to white or '1' except for emissive factor which defaults to black. 
+	
+	If you set an emissive texture, you will also need to set emissive factor to white to 'enable' it.
 	
 	
 	The metalness value should be stored in the 'blue' channel of the metalness texture if the texture has multiple color channels.
 	The metalness value should be stored in the 'blue' channel of the metalness texture if the texture has multiple color channels.
 	
 	
@@ -18,47 +20,27 @@ Class PbrMaterial Extends Material
 	The above last 3 rules allow you to pack metalness, roughness and occlusion into a single texture.
 	The above last 3 rules allow you to pack metalness, roughness and occlusion into a single texture.
 	
 	
 	#end
 	#end
-	Method New( textured:Bool=True,bumpmapped:Bool=True,boned:Bool=False )
-		Super.New()	'WTF?
+	Method New( boned:Bool=False )
 		
 		
-		Local defs:=""
+		_boned=boned
 		
 		
-		If textured
-			defs+="MX2_TEXTURED~n"
-			If bumpmapped
-				defs+="MX2_BUMPMAPPED~n"
-			Endif
-		Endif
-		If boned defs+="MX2_BONED~n"
-			
-		Local shader:="material-pbr-deferred"
-		defs+=Renderer.GetCurrent().ShaderDefs
-			
-		If Cast<ForwardRenderer>( Renderer.GetCurrent() )
-			shader="material-pbr-forward"
-		Endif
-			
-		SetShader( Shader.Open( shader,defs ) )
+		Uniforms.DefaultTexture=Texture.ColorTexture( Color.White )
 		
 		
-		ColorTexture=Texture.ColorTexture( Color.White )
-		ColorFactor=Color.White
+		ColorTexture=Null
+		EmissiveTexture=Null
+		MetalnessTexture=Null
+		RoughnessTexture=Null
+		OcclusionTexture=Null
+		NormalTexture=Null
 		
 		
-		EmissiveTexture=Texture.ColorTexture( Color.White )
+		ColorFactor=Color.White
 		EmissiveFactor=Color.Black
 		EmissiveFactor=Color.Black
-	
-		MetalnessTexture=Texture.ColorTexture( Color.White )
 		MetalnessFactor=0.0
 		MetalnessFactor=0.0
-		
-		RoughnessTexture=Texture.ColorTexture( Color.White )
 		RoughnessFactor=1.0
 		RoughnessFactor=1.0
-		
-		OcclusionTexture=Texture.ColorTexture( Color.White )
-		
-		NormalTexture=Texture.ColorTexture( New Color( 0.5,0.5,1.0,0.0 ) )
 	End
 	End
 	
 	
-	Method New( color:Color,metalness:Float=0.0,roughness:Float=1.0 )
-		Self.New( False,False,False )
+	Method New( color:Color,metalness:Float=0.0,roughness:Float=1.0,boned:Bool=False )
+		Self.New( boned )
 		
 		
 		ColorFactor=color
 		ColorFactor=color
 		MetalnessFactor=metalness
 		MetalnessFactor=metalness
@@ -66,8 +48,11 @@ Class PbrMaterial Extends Material
 	End
 	End
 	
 	
 	Method New( material:PbrMaterial )
 	Method New( material:PbrMaterial )
-		
 		Super.New( material )
 		Super.New( material )
+		
+		_textured=material._textured
+		_bumpmapped=material._bumpmapped
+		_boned=material._boned
 	End
 	End
 	
 	
 	#rem monkeydoc Creates a copy of the pbr material.
 	#rem monkeydoc Creates a copy of the pbr material.
@@ -77,6 +62,8 @@ Class PbrMaterial Extends Material
 		Return New PbrMaterial( Self )
 		Return New PbrMaterial( Self )
 	End
 	End
 	
 	
+	'***** textures *****
+	
 	Property ColorTexture:Texture()
 	Property ColorTexture:Texture()
 	
 	
 		Return Uniforms.GetTexture( "ColorTexture" )
 		Return Uniforms.GetTexture( "ColorTexture" )
@@ -84,15 +71,8 @@ Class PbrMaterial Extends Material
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "ColorTexture",texture )
 		Uniforms.SetTexture( "ColorTexture",texture )
-	End
-	
-	Property ColorFactor:Color()
-	
-		Return Uniforms.GetColor( "ColorFactor" )
 		
 		
-	Setter( color:Color )
-	
-		Uniforms.SetColor( "ColorFactor",color )
+		If (Uniforms.NumTextures<>0)<>_textured InvalidateShader()
 	End
 	End
 	
 	
 	Property EmissiveTexture:Texture()
 	Property EmissiveTexture:Texture()
@@ -102,15 +82,8 @@ Class PbrMaterial Extends Material
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "EmissiveTexture",texture )
 		Uniforms.SetTexture( "EmissiveTexture",texture )
-	End
-	
-	Property EmissiveFactor:Color()
-	
-		Return Uniforms.GetColor( "EmissiveFactor" )
 		
 		
-	Setter( color:Color )
-	
-		Uniforms.SetColor( "EmissiveFactor",color )
+		If (Uniforms.NumTextures<>0)<>_textured InvalidateShader()
 	End
 	End
 	
 	
 	Property MetalnessTexture:Texture()
 	Property MetalnessTexture:Texture()
@@ -120,17 +93,10 @@ Class PbrMaterial Extends Material
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "MetalnessTexture",texture )
 		Uniforms.SetTexture( "MetalnessTexture",texture )
-	End
-
-	Property MetalnessFactor:Float()
-	
-		Return Uniforms.GetFloat( "MetalnessFactor" )
 		
 		
-	Setter( factor:Float )
-
-		Uniforms.SetFloat( "MetalnessFactor",factor )
+		If (Uniforms.NumTextures<>0)<>_textured InvalidateShader()
 	End
 	End
-	
+
 	Property RoughnessTexture:Texture()
 	Property RoughnessTexture:Texture()
 	
 	
 		Return Uniforms.GetTexture( "RoughnessTexture" )
 		Return Uniforms.GetTexture( "RoughnessTexture" )
@@ -138,24 +104,19 @@ Class PbrMaterial Extends Material
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "RoughnessTexture",texture )
 		Uniforms.SetTexture( "RoughnessTexture",texture )
-	End
-	
-	Property RoughnessFactor:Float()
-	
-		Return Uniforms.GetFloat( "RoughnessFactor" )
 		
 		
-	Setter( factor:Float )
-	
-		Uniforms.SetFloat( "RoughnessFactor",factor )
+		If (Uniforms.NumTextures<>0)<>_textured InvalidateShader()
 	End
 	End
-
+	
 	Property OcclusionTexture:Texture()
 	Property OcclusionTexture:Texture()
 	
 	
-		Return Uniforms.GetTexture( "occlusion" )
+		Return Uniforms.GetTexture( "OcclusionTexture" )
 		
 		
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "OcclusionTexture",texture )
 		Uniforms.SetTexture( "OcclusionTexture",texture )
+		
+		If (Uniforms.NumTextures<>0)<>_textured InvalidateShader()
 	End
 	End
 	
 	
 	Property NormalTexture:Texture()
 	Property NormalTexture:Texture()
@@ -165,6 +126,46 @@ Class PbrMaterial Extends Material
 	Setter( texture:Texture )
 	Setter( texture:Texture )
 	
 	
 		Uniforms.SetTexture( "NormalTexture",texture )
 		Uniforms.SetTexture( "NormalTexture",texture )
+		
+		If (texture<>null)<>_bumpmapped InvalidateShader()
+	End
+	
+	'***** factors *****
+
+	Property ColorFactor:Color()
+	
+		Return Uniforms.GetColor( "ColorFactor" )
+		
+	Setter( color:Color )
+	
+		Uniforms.SetColor( "ColorFactor",color )
+	End
+	
+	Property EmissiveFactor:Color()
+	
+		Return Uniforms.GetColor( "EmissiveFactor" )
+		
+	Setter( color:Color )
+	
+		Uniforms.SetColor( "EmissiveFactor",color )
+	End
+	
+	Property MetalnessFactor:Float()
+	
+		Return Uniforms.GetFloat( "MetalnessFactor" )
+		
+	Setter( factor:Float )
+
+		Uniforms.SetFloat( "MetalnessFactor",factor )
+	End
+	
+	Property RoughnessFactor:Float()
+	
+		Return Uniforms.GetFloat( "RoughnessFactor" )
+		
+	Setter( factor:Float )
+	
+		Uniforms.SetFloat( "RoughnessFactor",factor )
 	End
 	End
 
 
 	#rem monkeydoc Loads a PbrMaterial from a 'file'.
 	#rem monkeydoc Loads a PbrMaterial from a 'file'.
@@ -218,5 +219,39 @@ Class PbrMaterial Extends Material
 		Return material
 		Return material
 	End
 	End
 	
 	
+	Protected
+	
+	Field _textured:Bool
+	Field _bumpmapped:Bool
+	Field _boned:Bool
+	
+	Method OnValidateShader:Shader() Override
+		
+		_textured=False
+		_bumpmapped=False
+		
+		If Uniforms.NumTextures
+			_textured=True
+			_bumpmapped=(Uniforms.GetTexture( "NormalTexture" )<>null)
+		Endif
+		
+		Local renderer:=Renderer.GetCurrent()
+
+		Local defs:=renderer.ShaderDefs
+		
+		If _textured
+			defs+="MX2_TEXTURED~n"
+			If _bumpmapped
+				defs+="MX2_BUMPMAPPED~n"
+			Endif
+		Endif
+		If _boned defs+="MX2_BONED~n"
+			
+		Local shader:="material-pbr-deferred"
+		If Cast<ForwardRenderer>( renderer ) shader="material-pbr-forward"
+			
+		Return Shader.Open( shader,defs )
+	End
+	
 	
 	
 End
 End

+ 1 - 1
modules/mojo3d/graphics/renderer.monkey2

@@ -587,7 +587,7 @@ Class Renderer
 				
 				
 				material=op.material
 				material=op.material
 				
 				
-				_device.Shader=material.Shader
+				_device.Shader=material.ValidateShader()
 				_device.BindUniformBlock( material.Uniforms )
 				_device.BindUniformBlock( material.Uniforms )
 				If material.BlendMode<>BlendMode.Opaque
 				If material.BlendMode<>BlendMode.Opaque
 					_device.BlendMode=material.BlendMode
 					_device.BlendMode=material.BlendMode

+ 2 - 0
modules/mojo3d/graphics/renderqueue.monkey2

@@ -61,6 +61,8 @@ Class RenderQueue
 	
 	
 	Method AddRenderOp( op:RenderOp )
 	Method AddRenderOp( op:RenderOp )
 		
 		
+		op.material.ValidateShader()
+		
 		If op.material.BlendMode<>BlendMode.Opaque
 		If op.material.BlendMode<>BlendMode.Opaque
 			_transparentOps.Push( op )
 			_transparentOps.Push( op )
 		Else
 		Else