Hello,
(test project at the bottom of the post)
I am trying to write a shader with some environment mapping, but i can't seem to access mipmaps of skycube in the shader.
I simplified it to this:
This is basically envBump shader from the built-in shader library with minimal modifications(listed below the shader):
#include <transform>
#include <fog>
#include <pos>
#include <normal>
#include <light>
#include <vecskill>
#include <color>
float vecSunColor;
float fAlbedo;
texture entSkin1; // texture
texture entSkin2; // normal map
texture mtlSkin1;
sampler sBaseTex = sampler_state { Texture = <entSkin1>; MipFilter = Linear; };
sampler sBump = sampler_state { Texture = <entSkin2>; MipFilter = None; };
sampler sEnviro = sampler_state { Texture = <mtlSkin1>; MipFilter = Linear; MagFilter = Linear; MinFilter = Linear; };
struct bumpOut
{
float4 Pos: POSITION;
float Fog: FOG;
float4 Ambient: COLOR0;
float2 Tex: TEXCOORD0;
float3 PosWorld: TEXCOORD1;
float3 Vecskill: TEXCOORD2;
float3 Normal: TEXCOORD3;
};
bumpOut perPixel_VS(
in float4 inPos: POSITION,
in float3 inNormal: NORMAL,
in float2 inTex: TEXCOORD0,
in float3 inTangent: TEXCOORD2)
{
bumpOut Out;
Out.Pos = DoTransform(inPos);
Out.Tex = inTex;
Out.Fog = DoFog(inPos);
Out.Ambient = DoAmbient();
float facBump = DoDefault(vecSkill41.x*0.01,50*0.01);
float facTex = DoDefault(vecSkill41.y*0.01,50*0.01);
Out.Vecskill.x = facBump;
Out.Vecskill.y = facTex;
Out.Vecskill.z = vecSkill41.z;
Out.PosWorld = DoPos(inNormal);
Out.Normal = DoNormal(inNormal);
return Out;
}
float4 diffuseBump_PS(bumpOut In): COLOR
{
float4 base = tex2D(sBaseTex,In.Tex);
float3 bumpNormal = tex2D(sBump,In.Tex)*2-1;
float facBump = In.Vecskill.x;
float3 cubeTexCoord = normalize(reflect(In.PosWorld - vecViewPos,In.Normal));
cubeTexCoord = cubeTexCoord + (bumpNormal - cubeTexCoord )*facBump;
float4 newCubeTexCoord = float4(cubeTexCoord.x,cubeTexCoord.y,cubeTexCoord.z,In.Vecskill.z);
float4 environment = texCUBElod(sEnviro,newCubeTexCoord)*(vecColor+vecSunColor*vecDiffuse)*base.w;
float facTex = In.Vecskill.y;
float4 resultingBase = lerp(environment,base,facTex);
return resultingBase * (0.5+In.Ambient);
}
technique bump
{
pass One
{
VertexShader = compile vs_3_0 perPixel_VS();
PixelShader = compile ps_3_0 diffuseBump_PS();
}
}
technique fallback { pass one { } }
Changes:
- Added skill43 (vecSkill41.z) as miplevel
- Changed texCUBE to texCUBElod and since texCUBElod expects mip level on w component of texCoord i added skill43 as w of newCubeTexCoord.
- bumped versions up to 3_0 because texCUBElod
This is the lite-c code to test the material:
#include <acknex.h>
#include <default.c>
#include <mtlfx.c>
#define PRAGMA_POINTER
BMAP* bmap_skycube = "desertsky+6.tga";
MATERIAL* matTEST = {
effect = "skymap.fx";
}
function materialInit()
{
bmap_skycube = bmap_to_mipmap(bmap_skycube);
bmap_to_cubemap(bmap_skycube); // <------ THIS LINE !!!!!
matTEST->skin1 = bmap_skycube;
}
void main(){
var facbump = 1;
var factext = 1;
var mipLevel = 1;
d3d_anisotropy = 7;
d3d_mipmapping = 4;
mip_levels = 10;
level_load("");
materialInit();
ENTITY* box = ent_create("cube.mdl",nullvector,NULL);
box->material = matTEST;
box->skill41 = floatv(facbump);
box->skill42 = floatv(factext);
box->skill43 = floatv(mipLevel);
camera->x = -31;
camera->z = 20;
camera->y = -4;
camera->pan = 16;
camera->tilt = -32;
video_set(800,600,0,0);
while(!key_esc){
DEBUG_VAR(mipLevel,50);
if(key_5 || key_6){
mipLevel += (key_5 - key_6)*time_step/6;
box->skill43 = floatv(mipLevel);
}
wait(1);
}
}
It creates a cube, applies the material, keys 5 and 6 modifies the mip level.
Expected result is that when i press 5 i get a more blurry environment map.
Actual result is that it does not change a thing which leds me to believe that the cubemap loses mipmaps when bmap_to_cubemap is called.
When i remove this line
bmap_to_cubemap(bmap_skycube);
from materialInit() function, i get the expected result:
(except it's not a cubemap anymore and everything is garbled)
Test project:
Link (try commenting line 17 in cubemiptest.c)