PDA

View Full Version : Modding - Mirror Material Shader


teko
7th Oct 2006, 2:48 PM
I've done some researches about the Mirror Material Shader (0xFF123570) and tried to understand it. I followed up the MirrorReflectionMaterial which is responsible for the reflection on mirrors.

The shader code in the MirrorReflectionMaterial is written in Assembler language. Assembler is a really primitive code language but not so difficult to understand when you know what it does. ;)
Below in SetSpecifiedZOnMirrorRTT(zValue) there is some shader code written in HLSL (High Level Shading Language) but I'm not 100% sure. It looks just like this. :P

This is how a vertexshader in Assembler works.
http://img165.imageshack.us/img165/848/vertexprocessingeu6.gif

The adress-registers (vertexattributes and constant-registers) are where the data is taken from. The computations are saved in the temporary registers where they can be used later. The output register is the final data.

Then some informations about the assembler-opperands which are used in the MirrorReflectionMaterial.

def : define
m4x4 : multiplication with a vector and a matrix
mov : move data
mul : scalar multiplication of all components of two vectors
mad : multiplication and addition in one
rcp : divide


Ok, let's have a look at the first vertex program in the MirrorReflectionMaterial.

(Bold notes added by me)
# vertex program
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClipFromParentView -constantCount 4 # set the matrices from the parent (i.e. the main view) so that the stencil is written to the right place

shaderSource
; vertext shader version 1.1
vs_1_1
; write position of world-/objectcoordinates (?) in the register v0
dcl_position v0

; color output for debugging (write values for xyzw in the constantregister c5)
def c5, 1,0,0,1

; project vertex to clip coords (multiply vertexattribute v0 with constantregister c0 and put the result in the temporarely register r0)
m4x4 r0, v0, c0

; flip the x coordinate so the stencil is marked in the right place (stencil = mask (mask = the reflection is only rendered on the mirrorplane))
mov oPos.x, -r0 ; kind of flipping the x axis and move the data to the outputregister for position (final)
mov oPos.yzw, r0 ; move the data of position yzw to the outputregister for position (final)
endShaderSource
end
Note please the X axis flipping. I'm gonna test if it's possible to flipp the Z axis so there isn't needed a transform bone to display the reflection correctly. This should help for reflective ponds. ;)

Let's have a look at the second shader program what's going on there. :)

(Bold notes added by me)
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClip -constantCount 4
bindConstants 4 -bindingID clipToViewTarget -constantCount 4
shaderSource
vs_1_1
dcl_position v0

#data for xyzw is written into constantregisters c8/c9/c10
def c8, -0.5, -0.5, 1, 1
def c9, 0.5, 0.5, 0, 0

def c10, 0.25, 0.25, 0, 0

# project vertex to clip coords (multiply v0 with c0 and move data into r0)
m4x4 r0, v0, c0
# move data from r0 in outputregister position (final)
mov oPos, r0

# I guess the part below resizes the textures but I'm not sure!

# multiply 0.5 * w so homogenous divide will make it 0.5 again (multiply c9 (data above) with w from r0 and move data into r2)
mul r2, c9, r0.w

# scale projected xy by .5 and re-center so it's in 0-w range (multiplication and addition in one - no idea how. saved in r4)
mad r4, r0, c8, r2

# Try to get an exact texel to pixel mapping by shifting texture coordinates
# slightly.
# A texture coordinate of 0 must map to 1/2*(texture dimension) and a
# coordinate of 1 must map to (1 - 1/2*(texture dimension)).
# Note: This does not seem to eliminate the wobble on the mirror
# reflection entirely.
rcp r3.x, c4.x ;# 2/width (not sure were c4 does come frome, maybe from above bindConstants 4 and not sure how rcp works)
rcp r3.y, c5.y ;# 2/height (c5 is known from the upper shader source)
mov r3.zw, c9.zw ;# r3 = (2/width, 2/height, 0, 0) (the values for z,w = 0,0 are saved in zw of r3)

mul r3, r3, c10 ;# r3 = (1/2*width, 1/2*height, 0, 0) (multiply r3 with c10 from above and save it again in r3)
mad r6, r0, r3, r4 ;# multiplication and addition in one (how?) saved in r6
mov oT0, r6.xyww ;# move w into z so we can divide by z in the texture stage; some cards don't handle division by w correctly
endShaderSource
end

I actually don't know what this second shader program really does but I guess it resizes the textures to don't slow down the game too much. There's a third shader program but it's more or less the same so I don't want pay much attention to it. ;)

I have the following problem. I can't make a shader to be standalone - to be a totally new shader. The thing is, I want to have a transparent mirror material without affecting all mirrors. :blink:

http://img308.imageshack.us/img308/7860/muranotransparentmirrorsmaix6.jpg

niol
8th Oct 2006, 1:08 PM
Hallo,
I don't know much and just learnt something from this thread...
Anyway, the neighbourhood shader has its way to do the reflection and this's proably what you skip to tell here. http://www.modthesims2.com/showpost.php?p=1343193&postcount=11

I also still fail to make a stand-alone material shader, but I'm trying to do a an additional replacement instead. In other words, I'm gonna add the new material definitions and integrate it into a material shader which will override the original one. This way, all additional definitions may become available without erasing the orignal one...

If this approach works and as more modders add in custom material definitions to the corresponding material shaders as over-riding mod. It may be good for modders to do a flavour to one another by having a place to discuss or list out their definition integrations, so other modders can relatively easily to make compatible material shader mods...

Yet, if there's a way to make a stand-alone additional material shader, that'll be great... Please tell... Thanks in advance... :bow:

teko
24th Nov 2006, 10:52 PM
Hey niol,

Sorry for my late answer but I needed a bit of time to brainstrom about this whole shader-thing. ;)

Finally I got my transparent mirror shader to work without affecting the other mirrors. The shader is actually not stand-alone. I've included the code in the mirror shader - at least, that works. :) If you want to have a look at the shader code, the transparent mirrors are available for download at my site.

Then to the modding potential of the shaders... my next goal is to find out how to imcomplement own HLSL in the Maxis Material Shaders. Here (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/HLSL_Shaders.asp) you'll find a explenation from Microsoft about HLSL if you are interested.


Teko

niol
28th Nov 2006, 6:34 AM
Teko,

I like the nifty way of your modding the mirror shader... :D
Sometimes, just some simple additions can already make wonder... Maxis TS2 team should learn that... :gigler:

added:
Will you make custom-object-based ceiling reflective as well? Can you make the mirror floor compatible to the base game, too...? :anime:

added:

Modding - Mirror-related Linkage

How do mirrors work?
http://www.modthesims2.com/showthread.php?t=221429

Making a mirror surface
http://www.modthesims2.com/showthread.php?t=225081

Modding - Mirror Material Shader [teko @ MTS2 & Reflexsims / murano @ muranomobilia.com]
http://www.modthesims2.com/showthread.php?t=194918

mirror material shader codes of different versions
http://www.sims2wiki.info/wiki.php?title=Talk:ShaderMirror