implemented fragment shader parallax occlusion mapping & add some assets to test it
This commit is contained in:
@ -3,6 +3,9 @@ package gay.pizza.CavesOfJolk
|
||||
import com.badlogic.gdx.graphics.g3d.Attributes
|
||||
import com.badlogic.gdx.graphics.g3d.Renderable
|
||||
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute
|
||||
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute
|
||||
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute
|
||||
import com.badlogic.gdx.graphics.g3d.shaders.BaseShader
|
||||
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
|
||||
|
||||
class CustomDefaultShader(renderable: Renderable, config: Config):
|
||||
@ -18,6 +21,13 @@ class CustomDefaultShader(renderable: Renderable, config: Config):
|
||||
renderable.environment.let { attribs.set(it) }
|
||||
renderable.material.let { attribs.set(it) }
|
||||
|
||||
if (attribs.has(CustomFloatAttribute.BumpHeight) && attribs.has(TextureAttribute.Bump))
|
||||
{
|
||||
prefix += "#define " + CustomFloatAttribute.BumpHeightAlias + "Flag\n"
|
||||
prefix += "#define " + TextureAttribute.BumpAlias + "Flag\n"
|
||||
prefix += "#define " + TextureAttribute.BumpAlias + "Coord texCoord0\n"
|
||||
}
|
||||
|
||||
if (attribs.has(ColorAttribute.Fog))
|
||||
{
|
||||
prefix += "#define fog${
|
||||
@ -50,6 +60,41 @@ class CustomDefaultShader(renderable: Renderable, config: Config):
|
||||
val fogNear = Uniform("u_fogNear")
|
||||
val fogFar = Uniform("u_fogFar")
|
||||
val fogDensity = Uniform("u_fogDensity")
|
||||
|
||||
val bumpHeight = Uniform("u_bumpHeight")
|
||||
|
||||
val bumpTexture = Uniform("u_bumpTexture")
|
||||
val bumpUVTransform = Uniform("u_bumpUVTransform")
|
||||
}
|
||||
|
||||
object Setters
|
||||
{
|
||||
val bumpHeight = object: LocalSetter()
|
||||
{
|
||||
override fun set(shader: BaseShader, inputId: Int, renderable: Renderable, combAttribs: Attributes)
|
||||
{
|
||||
val attr = combAttribs.get(CustomFloatAttribute.BumpHeight) as FloatAttribute
|
||||
shader.set(inputId, attr.value)
|
||||
}
|
||||
}
|
||||
|
||||
val bumpTexture = object: LocalSetter()
|
||||
{
|
||||
override fun set(shader: BaseShader, inputId: Int, renderable: Renderable, combAttribs: Attributes)
|
||||
{
|
||||
val texAttr = combAttribs.get(TextureAttribute.Bump) as TextureAttribute
|
||||
val unit = shader.context.textureBinder.bind(texAttr.textureDescription)
|
||||
shader.set(inputId, unit)
|
||||
}
|
||||
}
|
||||
var bumpUVTransform = object: LocalSetter()
|
||||
{
|
||||
override fun set(shader: BaseShader, inputId: Int, renderable: Renderable, combAttribs: Attributes)
|
||||
{
|
||||
val ta = combAttribs.get(TextureAttribute.Normal) as TextureAttribute
|
||||
shader.set(inputId, ta.offsetU, ta.offsetV, ta.scaleU, ta.scaleV)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,6 +102,10 @@ class CustomDefaultShader(renderable: Renderable, config: Config):
|
||||
private val u_fogFar = register(Inputs.fogFar)
|
||||
private val u_fogDensity = register(Inputs.fogDensity)
|
||||
|
||||
private val u_bumpHeight = register(Inputs.bumpHeight, Setters.bumpHeight)
|
||||
private val u_bumpTexture = register(Inputs.bumpTexture, Setters.bumpTexture)
|
||||
private val u_bumpUVTransform = register(Inputs.bumpUVTransform, Setters.bumpUVTransform)
|
||||
|
||||
override fun bindLights(renderable: Renderable?, attributes: Attributes?)
|
||||
{
|
||||
if (attributes == null)
|
||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.graphics.g3d.Renderable
|
||||
import com.badlogic.gdx.graphics.g3d.Shader
|
||||
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute
|
||||
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute
|
||||
import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader
|
||||
import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider
|
||||
|
||||
@ -29,6 +30,11 @@ class CustomDefaultShaderProvider(config: DefaultShader.Config): DefaultShaderPr
|
||||
CustomFloatAttribute.FogDensity
|
||||
if ((renderableMask and ColorAttribute.Fog == ColorAttribute.Fog) && (renderableMask and fogMask != 0L))
|
||||
return CustomDefaultShader(renderable, config)
|
||||
|
||||
val bumpMask = CustomFloatAttribute.BumpHeight or TextureAttribute.Bump
|
||||
if (renderableMask and bumpMask == bumpMask)
|
||||
return CustomDefaultShader(renderable, config)
|
||||
|
||||
return super.createShader(renderable)
|
||||
}
|
||||
}
|
||||
|
@ -17,5 +17,9 @@ class CustomFloatAttribute private constructor(type: Long, value: Float): FloatA
|
||||
const val FogDensityAlias = "fogDensity"
|
||||
val FogDensity = register(FogDensityAlias)
|
||||
fun createFogDensity(value: Float) = CustomFloatAttribute(FogDensity, value)
|
||||
|
||||
const val BumpHeightAlias = "bumpHeight"
|
||||
val BumpHeight = register(BumpHeightAlias)
|
||||
fun createBumpHeight(value: Float) = CustomFloatAttribute(BumpHeight, value)
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ import ktx.math.times
|
||||
|
||||
class Game: ApplicationAdapter()
|
||||
{
|
||||
private lateinit var texJolk: Texture
|
||||
private lateinit var fntComic: BitmapFont
|
||||
private lateinit var cube: Model
|
||||
private lateinit var floor: Model
|
||||
private lateinit var toybox: Model
|
||||
|
||||
private lateinit var spriteBatch: SpriteBatch
|
||||
private lateinit var modelBatch: ModelBatch
|
||||
@ -41,23 +41,17 @@ class Game: ApplicationAdapter()
|
||||
private lateinit var suzanneInstance: ModelInstance
|
||||
private lateinit var rockBatch: ModelCache
|
||||
private lateinit var knux: ModelInstance
|
||||
private lateinit var toyboxInstance: ModelInstance
|
||||
|
||||
private fun makeCube(texture: Texture): Model
|
||||
private fun makeCube(size: Float, material: Material): Model
|
||||
{
|
||||
val modelBuilder = ModelBuilder()
|
||||
val size = 2.0f
|
||||
val material = Material(
|
||||
ColorAttribute.createDiffuse(XnaColor.White),
|
||||
TextureAttribute(TextureAttribute.Diffuse,
|
||||
TextureDescriptor(texture,
|
||||
Texture.TextureFilter.Linear,
|
||||
Texture.TextureFilter.Linear,
|
||||
Texture.TextureWrap.ClampToEdge,
|
||||
Texture.TextureWrap.ClampToEdge)),
|
||||
ColorAttribute.createSpecular(XnaColor.Gray),
|
||||
FloatAttribute.createShininess(20.0f))
|
||||
val attribs = VertexAttributes.Usage.Position or VertexAttributes.Usage.TextureCoordinates or VertexAttributes.Usage.Normal
|
||||
return modelBuilder.createBox(size, size, size, material, attribs.toLong())
|
||||
ModelBuilder().apply {
|
||||
val attribs =
|
||||
VertexAttributes.Usage.Position or
|
||||
VertexAttributes.Usage.TextureCoordinates or
|
||||
VertexAttributes.Usage.Normal
|
||||
return createBox(size, size, size, material, attribs.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeFloor(size: Float): Model
|
||||
@ -103,8 +97,9 @@ class Game: ApplicationAdapter()
|
||||
shininess = 65.0f
|
||||
textures = Array()
|
||||
textures.add(
|
||||
modelTexture(ModelTexture.USAGE_DIFFUSE, "cobblestone.png"),
|
||||
modelTexture(ModelTexture.USAGE_NORMAL, "cobblestone_normal.png"),
|
||||
modelTexture(ModelTexture.USAGE_DIFFUSE, "cobblestone.png"),
|
||||
modelTexture(ModelTexture.USAGE_NORMAL, "cobblestone_normal.png"),
|
||||
modelTexture(ModelTexture.USAGE_BUMP, "cobblestone_bump.png"),
|
||||
modelTexture(ModelTexture.USAGE_SPECULAR, "cobblestone_specular.png"))
|
||||
})
|
||||
nodes.add(ModelNode().apply {
|
||||
@ -115,7 +110,9 @@ class Game: ApplicationAdapter()
|
||||
materialId = "floormat"
|
||||
})
|
||||
})
|
||||
}, AssetTextureProvider(assetManager))
|
||||
}, AssetTextureProvider(assetManager)).apply {
|
||||
materials[0].set(CustomFloatAttribute.createBumpHeight(0.0075f))
|
||||
}
|
||||
}
|
||||
|
||||
override fun create()
|
||||
@ -123,11 +120,20 @@ class Game: ApplicationAdapter()
|
||||
Resources.instance.loadAssets()
|
||||
assetManager.finishLoading()
|
||||
|
||||
texJolk = assetManager.get("jolkmeup.jpg")
|
||||
fntComic = assetManager.get("Comic Sans MS.ttf")
|
||||
|
||||
cube = makeCube(texJolk)
|
||||
var joeMany = 56.0f
|
||||
cube = makeCube(2.0f, Material(
|
||||
ColorAttribute.createDiffuse(XnaColor.White),
|
||||
TextureAttribute(TextureAttribute.Diffuse, TextureDescriptor(assetManager.get("jolkmeup.jpg"))),
|
||||
ColorAttribute.createSpecular(XnaColor.Gray),
|
||||
FloatAttribute.createShininess(20.0f)))
|
||||
toybox = assetManager.get("toybox.g3db", Model::class.java).apply { materials[0].set(
|
||||
TextureAttribute(TextureAttribute.Diffuse, TextureDescriptor(assetManager.get("toybox_albedo.png"))),
|
||||
TextureAttribute(TextureAttribute.Normal, TextureDescriptor(assetManager.get("toybox_normal.png"))),
|
||||
TextureAttribute(TextureAttribute.Bump, TextureDescriptor(assetManager.get("toybox_displace.png"))),
|
||||
CustomFloatAttribute.createBumpHeight(0.04f),
|
||||
FloatAttribute.createShininess(35.0f)) }
|
||||
val joeMany = 56.0f
|
||||
floor = makeFloor(joeMany)
|
||||
|
||||
spriteBatch = SpriteBatch()
|
||||
@ -190,6 +196,7 @@ class Game: ApplicationAdapter()
|
||||
|
||||
suzanneInstance.transform = Matrix4().translate(3.0f, 1.0f, -3.5f)
|
||||
knux = ModelInstance(assetManager.get("knux.g3db", Model::class.java))
|
||||
toyboxInstance = ModelInstance(toybox)
|
||||
}
|
||||
|
||||
override fun resize(width: Int, height: Int)
|
||||
@ -247,12 +254,19 @@ class Game: ApplicationAdapter()
|
||||
knux.transform.rotate(Quaternion().slerp(rand.nextQuaternion(), deltaTime))
|
||||
knux.transform.translate(knux.transform * Util.forward * deltaTime)
|
||||
|
||||
toyboxInstance.transform = Matrix4(
|
||||
Vector3(6.0f, 0.667f, -3.5f),
|
||||
Quaternion().setEulerAnglesRad(lightTheta * 0.5f, 0.0f, 0.0f),
|
||||
Util.one * 0.25f
|
||||
)
|
||||
|
||||
modelBatch.begin(colin.camera)
|
||||
modelBatch.render(floorInstance, env)
|
||||
modelBatch.render(rockBatch, env)
|
||||
modelBatch.render(cubeInstance, env)
|
||||
modelBatch.render(suzanneInstance, env)
|
||||
modelBatch.render(knux, env)
|
||||
modelBatch.render(toyboxInstance, env)
|
||||
modelBatch.end()
|
||||
|
||||
spriteBatch.begin()
|
||||
|
@ -31,18 +31,25 @@ class Resources private constructor()
|
||||
assetManager.setLoader(BitmapFont::class.java, ".ttf", FreetypeFontLoader(resolver))
|
||||
}
|
||||
|
||||
val linearMipped = TextureLoader.TextureParameter().apply {
|
||||
minFilter = Texture.TextureFilter.MipMapLinearLinear
|
||||
magFilter = Texture.TextureFilter.Linear
|
||||
wrapU = Texture.TextureWrap.Repeat
|
||||
wrapV = Texture.TextureWrap.Repeat
|
||||
genMipMaps = true
|
||||
}
|
||||
val linearMipped = TextureLoader.TextureParameter().apply {
|
||||
minFilter = Texture.TextureFilter.MipMapLinearLinear
|
||||
magFilter = Texture.TextureFilter.Linear
|
||||
wrapU = Texture.TextureWrap.Repeat
|
||||
wrapV = Texture.TextureWrap.Repeat
|
||||
genMipMaps = true
|
||||
}
|
||||
|
||||
val linearClamp = TextureLoader.TextureParameter().apply {
|
||||
minFilter = Texture.TextureFilter.Linear
|
||||
magFilter = Texture.TextureFilter.Linear
|
||||
wrapU = Texture.TextureWrap.ClampToEdge
|
||||
wrapV = Texture.TextureWrap.ClampToEdge
|
||||
}
|
||||
|
||||
fun loadAssets()
|
||||
{
|
||||
assetManager.load("colin.png", Texture::class.java)
|
||||
assetManager.load("jolkmeup.jpg", Texture::class.java)
|
||||
assetManager.load("jolkmeup.jpg", Texture::class.java, linearClamp)
|
||||
assetManager.loadFont("Comic Sans MS.ttf", 20)
|
||||
assetManager.load("suzanne.g3db", Model::class.java)
|
||||
assetManager.load("nut.wav", Sound::class.java)
|
||||
@ -51,6 +58,11 @@ class Resources private constructor()
|
||||
assetManager.load("cobblestone_specular.png", Texture::class.java, linearMipped)
|
||||
assetManager.load("rock.g3db", Model::class.java)
|
||||
assetManager.load("knux.g3db", Model::class.java)
|
||||
assetManager.load("toybox.g3db", Model::class.java)
|
||||
assetManager.load("cobblestone_bump.png", Texture::class.java, linearMipped)
|
||||
assetManager.load("toybox_albedo.png", Texture::class.java, linearMipped)
|
||||
assetManager.load("toybox_normal.png", Texture::class.java, linearMipped)
|
||||
assetManager.load("toybox_displace.png", Texture::class.java, linearMipped)
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
src/main/resources/cobblestone_bump.png
Normal file
BIN
src/main/resources/cobblestone_bump.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 KiB |
@ -13,7 +13,7 @@ precision mediump float;
|
||||
varying vec3 v_normal;
|
||||
#endif // normalFlag
|
||||
|
||||
#if defined(tangentFlag) && defined(binormalFlag)
|
||||
#if (defined(tangentFlag) && defined(binormalFlag)) || (defined(bumpHeightFlag) && defined(bumpTextureFlag))
|
||||
varying mat3 v_tbn;
|
||||
#endif // tangentFlag && bitangentFlag
|
||||
|
||||
@ -28,6 +28,10 @@ varying vec4 v_color;
|
||||
varying MEDP vec2 v_diffuseUV;
|
||||
uniform sampler2D u_diffuseTexture;
|
||||
#endif // diffuseTextureFlag
|
||||
#ifdef bumpTextureFlag
|
||||
varying MEDP vec2 v_bumpUV;
|
||||
uniform sampler2D u_bumpTexture;
|
||||
#endif // bumpTextureFlag
|
||||
#ifdef normalTextureFlag
|
||||
varying MEDP vec2 v_normalUV;
|
||||
uniform sampler2D u_normalTexture;
|
||||
@ -60,6 +64,10 @@ uniform float u_shininess;
|
||||
const float u_shininess = 20.0;
|
||||
#endif // shininessFlag
|
||||
|
||||
#ifdef bumpHeightFlag
|
||||
uniform float u_bumpHeight;
|
||||
#endif // bumpHeightFlag
|
||||
|
||||
#if numDirectionalLights > 0
|
||||
struct DirectionalLight
|
||||
{
|
||||
@ -114,14 +122,30 @@ vec3 linearDecode(vec3 v) { return vec3(pow(v.r, 1.0 / 2.2), pow(v.g, 1.0 / 2.2)
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(specularFlag) || (defined(bumpHeightFlag) && defined(bumpTextureFlag))
|
||||
vec3 eyeVec = normalize(u_cameraPosition.xyz - v_worldPosition.xyz);
|
||||
#endif // specularFlag || (bumpHeightFlag && bumpTextureFlag)
|
||||
|
||||
#if defined(bumpHeightFlag) && defined(bumpTextureFlag)
|
||||
float bumpHeight = (1.0 - texture2D(u_bumpTexture, v_bumpUV).r) * u_bumpHeight;
|
||||
vec3 tbnEyeVec = normalize(mat3(
|
||||
-v_tbn[0][0], v_tbn[1][0], v_tbn[2][0],
|
||||
-v_tbn[0][1], v_tbn[1][1], v_tbn[2][1],
|
||||
-v_tbn[0][2], v_tbn[1][2], v_tbn[2][2]
|
||||
) * -eyeVec);
|
||||
vec2 uvOffset = -tbnEyeVec.xy * bumpHeight;
|
||||
#else // !(bumpHeightFlag && bumpTextureFlag)
|
||||
vec2 uvOffset = vec2(0.0);
|
||||
#endif // bumpHeightFlag && bumpTextureFlag
|
||||
|
||||
#if defined(diffuseTextureFlag) && defined(diffuseColorFlag) && defined(colorFlag)
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV) * u_diffuseColor * v_color;
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV + uvOffset) * u_diffuseColor * v_color;
|
||||
#elif defined(diffuseTextureFlag) && defined(diffuseColorFlag)
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV) * u_diffuseColor;
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV + uvOffset) * u_diffuseColor;
|
||||
#elif defined(diffuseTextureFlag) && defined(colorFlag)
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV) * v_color;
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV + uvOffset) * v_color;
|
||||
#elif defined(diffuseTextureFlag)
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV);
|
||||
vec4 diffuse = texture2D(u_diffuseTexture, v_diffuseUV + uvOffset);
|
||||
#elif defined(diffuseColorFlag) && defined(colorFlag)
|
||||
vec4 diffuse = u_diffuseColor * v_color;
|
||||
#elif defined(diffuseColorFlag)
|
||||
@ -136,7 +160,7 @@ void main()
|
||||
#ifdef lightingFlag
|
||||
|
||||
#if defined(normalFlag) && defined(tangentFlag) && defined(binormalFlag) && defined(normalTextureFlag)
|
||||
vec3 normal = vec3(2.0 * texture2D(u_normalTexture, v_normalUV).rgb - 1.0);
|
||||
vec3 normal = vec3(2.0 * texture2D(u_normalTexture, v_normalUV + uvOffset).rgb - 1.0);
|
||||
normal = normalize(v_tbn * normal);
|
||||
#elif defined(normalFlag)
|
||||
vec3 normal = normalize(v_normal);
|
||||
@ -149,7 +173,6 @@ void main()
|
||||
#endif // ambientFlag
|
||||
|
||||
#ifdef specularFlag
|
||||
vec3 eyeVec = normalize(u_cameraPosition.xyz - v_worldPosition.xyz);
|
||||
vec3 specAccum = vec3(0.0);
|
||||
#endif // specularFlag
|
||||
|
||||
@ -201,7 +224,7 @@ void main()
|
||||
vec3 fragment;
|
||||
#ifdef specularFlag
|
||||
#ifdef specularTextureFlag
|
||||
vec3 specularColorTex = texture2D(u_specularTexture, v_specularUV).rgb;
|
||||
vec3 specularColorTex = texture2D(u_specularTexture, v_specularUV + uvOffset).rgb;
|
||||
specularColorTex = linearEncode(specularColorTex);
|
||||
specAccum *= specularColorTex;
|
||||
#endif // specularTextureFlag
|
||||
|
@ -7,7 +7,7 @@ uniform mat3 u_normalMatrix;
|
||||
varying vec3 v_normal;
|
||||
#endif // normalFlag
|
||||
|
||||
#if defined(tangentFlag) && defined(binormalFlag)
|
||||
#if (defined(tangentFlag) && defined(binormalFlag)) || (defined(bumpHeightFlag) && defined(bumpTextureFlag))
|
||||
attribute vec3 a_tangent;
|
||||
attribute vec3 a_binormal;
|
||||
varying mat3 v_tbn;
|
||||
@ -35,6 +35,11 @@ uniform vec4 u_diffuseUVTransform;
|
||||
varying vec2 v_diffuseUV;
|
||||
#endif // diffuseTextureFlag
|
||||
|
||||
#ifdef bumpTextureFlag
|
||||
uniform vec4 u_bumpUVTransform;
|
||||
varying vec2 v_bumpUV;
|
||||
#endif // bumpTextureFlag
|
||||
|
||||
#ifdef normalTextureFlag
|
||||
uniform vec4 u_normalUVTransform;
|
||||
varying vec2 v_normalUV;
|
||||
@ -104,6 +109,10 @@ void main()
|
||||
v_diffuseUV = u_diffuseUVTransform.xy + a_texCoord0 * u_diffuseUVTransform.zw;
|
||||
#endif // diffuseTextureFlag
|
||||
|
||||
#ifdef bumpTextureFlag
|
||||
v_bumpUV = u_bumpUVTransform.xy + a_texCoord0 * u_bumpUVTransform.zw;
|
||||
#endif // bumpTextureFlag
|
||||
|
||||
#ifdef normalTextureFlag
|
||||
v_normalUV = u_normalUVTransform.xy + a_texCoord0 * u_normalUVTransform.zw;
|
||||
#endif // normalTextureFlag
|
||||
|
BIN
src/main/resources/toybox.g3db
Normal file
BIN
src/main/resources/toybox.g3db
Normal file
Binary file not shown.
BIN
src/main/resources/toybox_albedo.png
Normal file
BIN
src/main/resources/toybox_albedo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
BIN
src/main/resources/toybox_displace.png
Normal file
BIN
src/main/resources/toybox_displace.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 KiB |
BIN
src/main/resources/toybox_normal.png
Normal file
BIN
src/main/resources/toybox_normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 231 KiB |
Reference in New Issue
Block a user